WyWallet WyWallet SMS Payment API Version 0.4 Issued 2016-03-22 2016-03-22 WyWallet SMS Payment API v0.4 Page 1 (37) Table of contents 1 Introduction ............................................................................................................... 5 1.1 1.2 1.3 2 API - Overview ........................................................................................................... 7 2.1 2.2 2.3 2.4 3 Purpose .......................................................................................................................... 5 Requirements ................................................................................................................. 5 Definitions and abbreviations .......................................................................................... 6 WSDL URL ....................................................................................................................... 7 Method overview ........................................................................................................... 7 Synchronous Payment overview ...................................................................................... 8 Asynchronous Payment overview .................................................................................... 9 API – details ............................................................................................................... 9 3.1 General........................................................................................................................... 9 3.1.1 Header ............................................................................................................................... 9 3.1.2 Status ............................................................................................................................... 10 3.1.3 Footer .............................................................................................................................. 11 3.2 Status codes ................................................................................................................. 12 3.2.1 Transaction status codes ................................................................................................. 12 3.2.2 Operation status codes.................................................................................................... 15 3.3 SmsPaymentService ...................................................................................................... 16 3.3.1 Purchase .......................................................................................................................... 16 3.3.2 Reversal ........................................................................................................................... 19 3.3.3 Credit ............................................................................................................................... 21 3.3.4 CheckOrder ...................................................................................................................... 22 3.3.5 Ping .................................................................................................................................. 24 3.4 Postback service ........................................................................................................... 25 3.4.1 PostbackRequest ............................................................................................................. 25 4 ProductID ................................................................................................................. 27 5 Appendix A ............................................................................................................... 28 5.1 Hash description ........................................................................................................... 28 5.1.1 SHA1 Hash .Net ............................................................................................................... 28 5.1.2 SHA1 Hash – JAVA............................................................................................................ 28 5.2 Postback service examples ............................................................................................ 32 5.2.1 Java JSP postback ............................................................................................................. 32 5.2.2 ASP.net postback service ................................................................................................. 33 6 Appendix C: Simulator for API development ............................................................. 34 2016-03-22 WyWallet SMS Payment API v0.4 Page 2 (37) 6.1 6.2 6.3 6.4 6.5 URL............................................................................................................................... 34 Valid request parameters .............................................................................................. 34 Response codes ............................................................................................................ 35 Frequently asked questions ........................................................................................... 36 Merchant support ......................................................................................................... 37 2016-03-22 WyWallet SMS Payment API v0.4 Page 3 (37) Version history Version 0.1 0.2 Date 2012-07-25 2012-07-27 0.3 2012-08-28 0.4 2012-11-13 2016-03-22 Comment First draft General updates, added payment sequence diagrams Updated simulator and postback examples Fixed error in MAC calculation for credit/reversal. Updated transaction statuses. Name Jonas Jansson Jonas Jansson Jonas Jansson Jonas Jansson WyWallet SMS Payment API v0.4 Page 4 (37) 1 Introduction 1.1 Purpose This document (WyWallet SMS Payment API) describes how merchants, content providers and aggregators can implement the functionality for premium SMS (and other CPA services) payments via the end-user WyWallet account. This API is a Server-to-Server API built on the operating system independent technology webservices and the API is very similar to the WyWallet Online Payment API which is more targeted for Web/Mobile Web and “in-app” payments. Online payments have higher security and therefor also has higher amount limits. There are also some technical differences between the interfaces: SMS payments only supports 1 phase billing and Authorize / Capture are combined in the same request, purchase(). The SMS API only requires MSISDN (phone number) to identify the account and no end-user interaction is needed to authorize the payment. Only the SMS API allows end-customers to use the mobile invoice or prepaid subscription as payment method. There are two different merchant account types (configured by WyWallet), synchronous and asynchronous payments. Synchronous (Default) o Payments are accepted and processed immediately o All received payment statuses are final. Asynchronous o Asynchronous requests are used for merchants with very high performance requirements o All payments requests are accepted but set in an unconfirmed payment status and put in an internal queue for further processing. o When the payments are processed the final status of the payment is sent in a XML to the merchant using HTTPS POST to the postbackURL set in the initial request. o The post-back requires the merchant to implement online receiver / listener.. o Please not that all post-backs are sent via HTTPS/SSL and that you therefore need a SSL certificated installed (from a trusted CA e.g. www.thawte.com or others) The MAP service will perform a lookup and identify the operator and preferred account. This service is based upon an asynchronous design. This means users of the API must implement a “postback service”, in order to receive the final transaction status. The “postback service” is based on HTTP POST and XML. In periods of high load and lengthy operations, the response is asynchronous. 1.2 Requirements 2016-03-22 WyWallet SMS Payment API v0.4 Page 5 (37) 1.3 Definitions and abbreviations Terms, acronyms, abbreviations IP MAC MSISDN Portal SHA1 SOAP UTF8 VAT WSDL MAP PSP SSL 2016-03-22 Definition/Description Internet Protocol Message Authentication Control Mobile Subscriber ISDN Number (Mobile phone number) In this context, the website where end users can manage their WyWallet Account A cryptographic hash function designed by the National Security Agency (NSA) Simple Object Access Protocol A multi byte character encoding for Unicode Value Added Tax (Moms) Web Services Description Language Mobile payment Access Point Payment Service Provider. Secure Socket Layer WyWallet SMS Payment API v0.4 Page 6 (37) 2 API - Overview 2.1 WSDL URL Test URL MAP SmsPaymentService: https://mpaymenttest.payex.com/MAP/SmsPaymentService?wsdl Simulator URL MAP SmsPaymentService: https://mpaymenttest.payex.com/MAP/PaymentServiceTest?wsdl Production URL MAP SmsPaymentService: https://mps.payex.com/MAP/SmsPaymentService?wsdl See also section 6.1 2.2 Method overview General Header Status Footer SmsPaymentService Purchase Reversal CheckOrder Credit Ping 2016-03-22 WyWallet SMS Payment API v0.4 Page 7 (37) 2.3 Synchronous Payment overview WyWallet SMS Payement API End-customer Merchant PurchaseRequest (e.g. SMS via shortcode) Primary Input Parameters ClientID (MSISDN) Amount CurrencyISOString VatAmount OrderID ProductID Description MAC WyWallet API Purchase() Debit WyWallet account PurchaseResponse Deliver content / service 2016-03-22 Primary Return Parameters TransactionID OperationStatus TransactionStatus WyWallet SMS Payment API v0.4 Page 8 (37) 2.4 Asynchronous Payment overview WyWallet SMS Payement API End-customer Merchant PurchaseRequest (e.g. SMS via shortcode) Primary Input Parameters ClientID (MSISDN) Amount CurrencyISOString VatAmount OrderID ProductID Description MAC PostBackURL WyWallet API Webservice - Purchase() WebService - PurchaseResponse Queue transaction Primary Return Parameters TransactionID OperationStatus TransactionStatus (preliminary) Debit WyWallet account XML HTTPS POST - PostBackURL Verify MAC Primary PostBack Parameters TransactionID ProductID Amount OperationStatus TransactionStatus (final) MAC Deliver content / service 3 API – details 3.1 General 3.1.1 Header Name Data type Description AcquirerID String AgreementID String This ID is provided by WyWallet and identifies the application using the API. The AcquirerID and MAC key in the footer are linked. This ID is provided by WyWallet and describes the link between merchant / acquirer / product / merchant account 2016-03-22 WyWallet SMS Payment API v0.4 Mandatory / Optional Mandatory Mandatory Page 9 (37) TransmissionTime String ClientIP String PostbackURL String PostbackTimeout int number etc. Format: yyyy-MM-dd HH:mm:ss e.g. 2010-12-04 14:45:53 Must be UTC IP address of end-customer/client. This can be used as an additional option for fraud detection and other security issues. See chapter 3.4 for further details Desired max number of seconds between initial request and the postback. Should be set to at least a few minutes for operations that require user confirmation / pin code etc. Mandatory Optional Mandatory but only for asynchronous accounts Optional If set to 0, the MAP system default timeout is used (e.g. 15 minutes). 3.1.2 Status Name Data type Description TransactionsStatus Int 0 is general OK Mandatory / Optional Mandatory See specific list for each operation for other statuses. TransactionStatusDesc OperationStatus String (200) String (30) OperationStatusDesc String (200) 2016-03-22 This parameter reports the technical status of the request. Short description of status This parameter states the logical status of the request, may also be a 3rd party error code. Short Description of OperationStatus. WyWallet SMS Payment API v0.4 Mandatory Optional Optional Page 10 (37) 3.1.3 Footer Name Data type Description MAC String (256) Message Authentication Control. This is a calculated field. WyWallet provides the key (shared secret) used when generating this field. 2016-03-22 WyWallet SMS Payment API v0.4 Mandatory / Optional Mandatory Page 11 (37) 3.2 Status codes 3.2.1 Transaction status codes TransactionStatus 0 1 2 3 5 Description OK Technical error Input error Wrong AgreementID Unauthorized action 5 Unauthorized action 6 Client account not found 7 8 Client account blocked Insufficient funds 11 Client account is expired 53 Connection limit exceeded Notes One or more of the input parameters is missing or has the wrong format or value. Comment: This is an implementation error. AgreementID not found Comment: This is a configuration error or implementation error (e.g. sending request to the wrong system) The merchant/aggregator is not permitted to perform the requested operation. Comment: This is a implementation error. The provided AgreementID is not allowed to execute this action. The merchant/aggregator is not permitted to perform the requested operation. Comment: The end user has no account in this system. The end user has not enough money on the selected account to perform the purchase. Comment: This will rarely occur. Must be treated the same way as status 7. The number of allowed concurrent active requests has been exceeded. This is implemented to prevent a single acquirer to use 100% of the API capacity. The request may be retried later. Avoid this problem by reducing traffic and/or implement flow control in your 2016-03-22 WyWallet SMS Payment API v0.4 Page 12 (37) application. 60 Acknowledge 61 Deprecated 62 Deprecated 63 Generic decline Comment: Try again. Valid request received and queued for processing. Final response will be sent to the PostbackURL. Comment: Only used for asynchronous payments. Replaced with status code 63 (Generic decline). Replaced with status code 63 (Generic decline). This status code is returned when a payment transaction is rejected and the system either cannot or will not specify the exact reason. Examples of conditions that causes this status code to be returned include: - A purchase amount limit has been exceeded - Accumulated transaction amount has been exceeded - Suspected fraud - Generic errors returned by external (3rd party) payment instruments 99 Rejected by business rule 105 107 110 Deprecated Deprecated Order not found 114 Third party error. 2016-03-22 Payment is currently not available to the requested payee/client/subscriber/ on the current payment channel. Comment: This is a general error, and should be treated as status 6. The customer is not allowed to use this payment instrument. Replaced with status code 6 Replaced with status code 1 The order search for with the CheckOrder function could not be found Third party error for external account. WyWallet SMS Payment API v0.4 Page 13 (37) 116 117 118 119 120 121 No suitable payment instrument found Max number of purchases for Easy Registration exceeded Max purchase amount for Easy registration exceeded Deprecated User not identified by mobile operator, MNO billing disabled MSISDN does not belong to a WyWallet operator Comment: This should be treated as “host down”, meaning that the account provider is not responding for the time. This is not a permanent error and retries are possible. The user does not have a payment instrument / account that is permitted in this scenario. Comment: Should be treated as status 6.The customer may have an account, but cannot use the account in this scenario. The user needs to register on the portal to continue using the system Comment: This is a customer error response. Due to anti fraud restrictions, the payment will not be approved. Should be treated as status 6. The purchase amount is higher than permitted amount for users that are not fully registered. Comment: This is a customer error response. Due to anti fraud restrictions, the payment will not be approved. Should be treated as status 6. Replaced with status code 6 Cannot charge to phone bill because the mobile operator could not identify the user of the given MSISDN Comment: This is a customer error response. Should be treated as status 6. The MSISDN / phone number does not belong to a 4T telecom operator (Telia, Telenor,Tele2 or 3.) Comment: This is a customer error response. Should be treated as status 6. 2016-03-22 WyWallet SMS Payment API v0.4 Page 14 (37) 3.2.2 Operation status codes OperationStatus 0 1 <others> 2016-03-22 Description OK Technical error Description is contained in OperationStatusDesc Action WyWallet SMS Payment API v0.4 Page 15 (37) 3.3 SmsPaymentService This API is used for financial transactions. 3.3.1 Purchase This method will perform a normal sales transaction, transferring a specified amount from the micro account to a merchant account. This is a one-phase transaction. PurchaseRequestWrapper Header -> see section 3.1.1 SalesRequest -> see section 3.3.1.1 Footer -> see section 3.1.3 PurchaseResponseWrapper Header -> see section 3.1.1 SalesResp -> see section 3.3.1.2 Status -> see section 0 3.3.1.1 SalesRequest SalesRequest is used in Purchase and Credit operations. It has the following parameters: Name Type Description Amount VatFormat Int String (9) VatAmount Int CurrencyISOString ClientIdType String (3) String (30) ClientId String (50) AccountName String (20) Price in cent/öre, including VAT Specifies format of VatAmount . One of o Amount: VAT is specified in cent/öre o Percent: VAT is specified as VAT percent*100, e.g. 25% VAT is specified as 2500. Default format is Amount. VAT (Moms) in percent or cent/öre, according to VatFormat One of DKK, EUR, GBP, NOK, SEK or USD SMS Payments only supports only supports one type of clientID which is MSISDN. Identifies the account owner by id type specified by ClientIdType, e.g. MSISDN if ClientIdType =MSISDN. Format of MSISDN is 00<country code><phone number without 0> Example 0046701234567 Currently not used in this context 2016-03-22 WyWallet SMS Payment API v0.4 Mandatory / Optional Mandatory Optional Mandatory Mandatory Mandatory Mandatory Optional Page 16 (37) OrderId String (60) ReconciliationTime String (19) Unique ID identifying the Sale. Can be used in multiple transactions of the same Sale (E.g. the same OrderId is used in both Authorize and Capture). Max length 50 characters. Timestamp stored with the transaction both in WyWallet system and merchant. Used for reconciliation. Mandatory Mandatory Format: yyyy-MM-dd HH:mm:ss ProductId String (50) Description String (35) CustomParameters String (2048) 2016-03-22 UTC Merchant product number/reference for this specific product. Max 50 characters. See chapter 4 for detailed description. Merchant’s description of the purchase. Max 35 characters. URL encoded ‘QueryString’: Name/value pairs separated with ‘&’ (param1=value1&param2=value2…) WyWallet SMS Payment API v0.4 Mandatory Mandatory Optional Page 17 (37) MAC implementation: Create a UTF8 encoded SHA1 hash of the following string. AcquirerID+AgreementID+TransmissionTime+ PostbackURL+ Amount+VatAmount+CurrencyISOString+ClientIdType+ClientId+ OrderId+ReconciliationTime+ProductId+Description+CustomParameters+ SharedSecret Return the first half. If a field does not contain content, do not send the content (null / “ “ / ) in MAC. See 5.1Hash description. 3.3.1.2 SalesResp This response definition is primarily for Purchase() requests. Name Type Description TransactionID String (60) BatchID Int Unique id that must be used in reversal operations ID used for reconciliation, stored on all financial transaction. The batch ID is changed on regular intervals, typically once per day. 2016-03-22 WyWallet SMS Payment API v0.4 Mandatory / Optional Mandatory Mandatory Page 18 (37) 3.3.2 Reversal This operation will reverse all or part of a Purchase or Capture operation ReversalRequestWrapper Header -> see section 3.1.1 ReversalRequest Footer -> see section 3.1.3 ReversalResponseWrapper Header -> see section 3.1.1 ReversalResp Status -> see section 3.1.2 3.3.2.1 Name ReversalRequest Type Description TransactionID String (60) OrderId String (60) Amount Int VatFormat String (9) VatAmount Int ReconciliationTime String (19) Description String (160) 3.3.2.2 Name ReversalResp Type TransactionID BatchID 2016-03-22 String (60) Int Must match the TransactionID returned in the Purchase operation. Normally the OrderId sent with the original Purchase request, but a new unique OrderId is permitted. A blank (zero length) string will Amount of money (cent/øre) to reverse, including VAT Amount: VAT is specified in cent/øre Percent: VAT is specified as VAT percent*100, e.g. 25% VAT is specified as 2500. Default format is Amount. VAT (MVA) in cent/øre or percent, according to VatFormat Timestamp stored with the transaction both in PayEx system and merchant. Used for reconciliation. Format: yyyy-MM-dd HH:mm:ss Used for logging Description ID of the reversal transaction ID used for reconciliation, stored on all WyWallet SMS Payment API v0.4 Mandatory / Optional Mandatory Mandatory Mandatory Optional Mandatory Mandatory Optional Mandatory / Optional Mandatory Mandatory Page 19 (37) financial transaction. The batch ID is changed on regular intervals, typically once per day. MAC implementation: Create a UTF8 encoded SHA1 hash of the following string: AcquirerID+AgreementID+TransmissionTime+ PostbackURL+ TransactionID+ Amount+VatAmount+ReconciliationTime+SharedSecret Return the first half. If a field does not contain content, do not send the content (null / “ “ / ) in MAC. See 5.1Hash description. 2016-03-22 WyWallet SMS Payment API v0.4 Page 20 (37) 3.3.3 Credit This method can be used as an alternative to the Reversal operation to undo a sales transaction and transfer a specified amount from the merchant account to the client account. The main difference from Reversal is that reference to the original sales transaction is not required. This is the opposite of a purchase. Note: Access to this API may be restricted to specific merchants/aggregators. Use the Reversal operation when possible. CreditRequestWrapper Header -> see section 3.1.1 SalesRequest -> see section 3.3.1.1 Footer -> see section 3.1.3 CreditResponseWrapper Header -> see section 3.1.1 CreditResp Status -> see section 3.1.2 3.3.3.1 Name CreditResp TransactionID BatchID Type Description String (60) Int ID of the credit transaction ID used for reconciliation, stored on all financial transaction. The batch ID is changed on regular intervals, typically once per day. Mandatory / Optional Mandatory Mandatory MAC implementation: Create a UTF8 encoded SHA1 hash of the following string: AcquirerID+AgreementID+TransmissionTime+ PostbackURL+ Amount+VatAmount+CurrencyISOString+ClientIdType+ClientId+ ReconciliationTime+ProductId+Description+CustomParameters+SharedSecret Return the first half. If a field does not contain content, do not send the content (null / “ “ / ) in MAC. See 5.1Hash description. 2016-03-22 WyWallet SMS Payment API v0.4 Page 21 (37) 3.3.4 CheckOrder This operation can be used to check the status of a sale in case a network communication error or timeout prevents the caller/merchant to receive a response from the API. The merchant / API user can then perform actions/cleanups according to the status of the order. CheckOrderRequestWrapper Header -> see section 3.1.1 CheckOrderRequest Footer -> see section 3.1.3 CheckOrderResponseWrapper Header -> see section 3.1.1 CheckOrderResp Status -> see section 3.1.2 3.3.4.1 Name CheckOrderRequest Type Description OrderId ClientIdType String (60) String (30) ClientId String (50) 3.3.4.2 Name CheckOrderResp Type Description TransactionID String (60) AmountAuthorized Int AmountCaptured AmountCancelled AmountReversed Int Int Int LastBatchId Int LastTransactionID String (60) 2016-03-22 OrderId of the transaction(s) to check. Specifies what ClientId refers to. For Sms payment service value must be MSISDN Format of MSISDN is 00+<country code>+ phone number, for example 0046123456789 Same value as in response from the original purchase operation. The string will be empty if the order cannot be found The amount authorized. If the original authorize failed, this value will be 0. The amount captured. The amount cancelled The amount reversed using the Reverse operation Batch ID of the most recent transaction of the order. (Will be > 0 only for successful financial transactions) TransactionID of the most recent transaction of the order. WyWallet SMS Payment API v0.4 Mandatory / Optional Mandatory Mandatory Mandatory Mandatory / Optional Mandatory Mandatory Mandatory Mandatory Mandatory Mandatory Page 22 (37) LastTransactionStatus Int LastTransactionType Int Transaction status code of the last transaction of the sale. 0=Purchase, 2=Reversal, 3=Authorize, 4=CancelAuth, 6=Capture Mandatory Optional MAC implementation: Create a UTF8 encoded SHA1 hash of the following string: AcquirerID+AgreementID+TransmissionTime+ PostbackURL+ OrderId+ClientIdType+ClientId+SharedSecret Return the first half. If a field does not contain content, do not send the content (null / “ “ / ) in MAC. See 5.1Hash description. 2016-03-22 WyWallet SMS Payment API v0.4 Page 23 (37) 3.3.5 Ping This operation can be used to check connectivity to the AdminService API. It can be used for test/development. Applications may also want to call this once after startup before sending transactions to ensure that the communication is working. PingRequestWrapper Header -> see section 3.1.1 Footer -> see section 3.1.3 PingResponseWrapper Header -> see section 3.1.1 Status -> see section 3.1.2 MAC implementation: Create a UTF8 encoded SHA1 hash of the following string: AcquirerID+AgreementID+TransmissionTime+ PostbackURL+ SharedSecret Return the first half. If a field does not contain content, do not send the content (null / “ “ / ) in MAC. See 5.1Hash description. 2016-03-22 WyWallet SMS Payment API v0.4 Page 24 (37) 3.4 Postback service Please note that the Postback service only is activated (manually by WyWallet) when the merchant needs high performance (e.g. tv voting) and the merchant account is configured as an Asynchronous account. The default setting for a merchant account id Synchronous where postbacks are not used. In order to receive a receipt from an asynchronous request (transaction), each merchant (or aggregator/PSP) must implement a Postback service. The WyWallet MAP system will send out payment status as soon as the transaction is processed. The system will send an ordinary XML over HTTP POST over SSL with a single parameter named PostbackRequestWrapper that contains an XML document (se example below). We strongly recommend you to verify the MAC code in the XML using your shared key and the submitted data to authenticate the request before delivering the purchased service/goods. PostbackRequestWrapper Header -> see section 3.1.1 PostbackRequest -> Footer -> see section 3.1.3 PostbackResponseWrapper Header -> see section 3.1.1 Status -> see section 3.1.2 3.4.1 PostbackRequest Name Type Description Operation String (30) Specifies the operation. One of o Purchase o Reversal o Credit OrderID TransactionID BatchID String (60) String Int Amount Int OrderID of the original request Payment transaction ID ID used for reconciliation, stored on all financial transaction. The batch ID is changed on regular intervals, typically once per day. Amount of money (cent/öre) to reverse, including VAT 2016-03-22 WyWallet SMS Payment API v0.4 Mandatory / Optional Mandatory Mandatory Optional Optional Optional Page 25 (37) MAC implementation: The MAC sent in the footer of the XML document is computed the same way as in the requests. The following parameters are used to compute the hash: AcquirerID+AgreementID+TransmissionTime+ PostbackURL+ Operation+ OrderID+SharedSecret The post back service should validate the MAC sent by the MAP service to protect against fraud. Sample PostbackWrapper XML sent by MAP: <?xml version="1.0" encoding="utf-8"?> <PostbackRequestWrapper> <Header> <AcquirerID>string</AcquirerID> <AgreementID>string</AgreementID> <TransmissionTime>string</TransmissionTime> <ClientIP>string</ClientIP> <PostbackURL>string</PostbackURL> </Header> <PostbackRequest> <Operation>string</Operation> <BatchID>int</BatchID> <OrderID>string</OrderID> <TransactionID>string</TransactionID> <Amount>int</Amount> </PostbackRequest> <Status> <TransactionStatus>int</TransactionStatus> <TransactionStatusDesc>string</TransactionStatusDesc> <OperationStatus>string</OperationStatus> <OperationStatusDesc>string</OperationStatusDesc> </Status> <Footer> <MAC>string</MAC> </Footer> </PostbackRequestWrapper> The Postback service should return an XML document in the HTTP BODY in the response to acknowledge that the postback XML has been received. Sample reply message: <?xml version="1.0" encoding="utf-8"?> <PostbackResponseWrapper> <Header> <AcquirerID>string</AcquirerID> <AgreementID>string</AgreementID> <TransmissionTime>string</TransmissionTime> <ClientIP>string</ClientIP> <PostbackURL>string</PostbackURL> </Header> <Status> <TransactionStatus>0</TransactionStatus> <TransactionStatusDesc>OK</TransactionStatusDesc> <OperationStatus>0</OperationStatus> <OperationStatusDesc>OK</OperationStatusDesc> </Status> </PostbackResponseWrapper> 2016-03-22 WyWallet SMS Payment API v0.4 Page 26 (37) 4 ProductID This is the list of valid productID:s that needs to specified for each purchase. The productID are used for end-customer that has selected payment method is via the operator subscription and these productID will render specific descriptions on the invoice. Product id Description Lottery 1 2 3 WiFi Personal Ring Back Tone 4 Tickets 5 Business 6 Charity 7 Parking 8 Ring Back Tone 10 Charging 12 Auction 13 Vending machine 14 Adult content (All adult content regardless of type) 15 Positioning 16 Security product 17 18 19 Mobile Entertainment (Music, Music videos, Games, Wallpapers, animations, Themes, Videos) News (Access to news sites or content bought on a news site) Mobile TV (Mobile TV services) 20 Applications (software for mobile, any applications that don’t fall under any other categories. Includes content bought through a free application, for example an audiobook client) 21 Voting (Voting for TV shows or other competitions) 22 Betting & gambling 23 Classified ads 24 Mobile marketing 25 Internet Portals (Access to Internet portals that is not news, community or adult) 26 Chat (Chatting services, for example dating chats) 27 Personal ad (Dating ads, contact ad, dating-sites) 28 29 30 31 32 Location Based Services 2016-03-22 Information Service (Charging for weather services,snow reports etc) Coupons (For example mobile gift vouchers (ice cream, magazines etc)) M-Payment (For example e-school, mobile dictionaries etc) Physical goods (Physical goods like, books, drinks, food etc) WyWallet SMS Payment API v0.4 Page 27 (37) 5 Appendix A 5.1 Hash description Returns only the first half of the generated Hash. This is to make brute force attack harder. It’s easier to guess the MAC key for a single request, but harder to know if this is the correct key since many keys can generate the first half of the output. 5.1.1 SHA1 Hash .Net public static String GetMAC(String generatedString) { Encoding enc = Encoding.UTF8; Byte[] rawMessage = enc.GetBytes(generatedString); SHA1 sha1 = new SHA1CryptoServiceProvider(); Byte[] result = sha1.ComputeHash(rawMessage); string mac = Convert.ToBase64String(result); //split the string in 2 and return the first half mac = mac.Substring(0, mac.Length / 2); return mac; } 5.1.2 SHA1 Hash – JAVA public class Sha1Hash { /** Creates a new instance of Sha1Hash */ public Sha1Hash() { } /** * @param inputData * @return */ public String getHashedValue(String inputData) { String sResp = null; try { byte byteHash[]; MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); sha1.update(inputData.getBytes("utf-8")); byteHash = sha1.digest(); sha1.reset(); // see code snippet below.. String hash = Base64Util.encode(byteHash); return hash.substring(0, (hash.length()/2)); } catch (Exception e) { 2016-03-22 WyWallet SMS Payment API v0.4 Page 28 (37) System.err.println("getHashedValue failed: " + e.getMessage()); return null; } } private String toHexString(byte[] array) { StringBuilder sb = new StringBuilder (); for (int i=0; i< array.length; i++) { String hex = "0"+Integer.toHexString(array[i]); String end = hex.substring(hex.length()-2); sb.append(end.toUpperCase()); } System.err.println("HASH:"+sb.toString()); return sb.toString(); } } /** * Freeware from: * Roedy Green * Canadian Mind Products * #208 - 525 Ninth Street * New Westminster, BC Canada V3M 5T9 * tel: (604) 777-1804 * mailto:roedy@mindprod.com */ /** * Encode arbitrary binary into printable ASCII using BASE64 encoding. * very loosely based on the Base64 Reader by * Dr. Mark Thornton * Optrak Distribution Software Ltd. * http://www.optrak.co.uk * and Kevin Kelley's *http://www.ruralnet.net/~kelley/java/Base64.java */ public class Base64Util { /** * how we separate lines, e.g. \n, \r\n, \r etc. **/ static String lineSeparator = System.getProperty( "line.separator"); /** * max chars per line. A multiple of 4. **/ private static int lineLength = 72; /** * determines how long the lines are that are generated by encode. * Ignored by decode. * @param length 0 means no newlines inserted. */ public static void setLineLength(int length) { lineLength = length; } /** 2016-03-22 WyWallet SMS Payment API v0.4 Page 29 (37) * letter of the alphabet used to encode binary values 0..63 **/ static final char[] valueToChar = new char[64]; /** * binary value encoded by a given letter of the alphabet 0..63 **/ static final int[] charToValue = new int[256]; /** * Marker value for chars we just ignore, e.g. \n \r high ascii */ static final int IGNORE = -1; /** * Marker for = trailing pad */ static final int PAD = -2; static { // build translate valueToChar table only once. // 0..25 -> 'A'..'Z' for ( int i=0; i<=25; i++ ) valueToChar[i] = (char)('A'+i); // 26..51 -> 'a'..'z' for ( int i=0; i<=25; i++ ) valueToChar[i+26] = (char)('a'+i); // 52..61 -> '0'..'9' for ( int i=0; i<=9; i++ ) valueToChar[i+52] = (char)('0'+i); valueToChar[62] = '+'; valueToChar[63] = '/'; // build translate charToValue table only once. for ( int i=0; i<256; i++ ) { charToValue[i] = IGNORE; // default is to ignore } for ( int i=0; i<64; i++ ) { charToValue[valueToChar[i]] = i; } charToValue['='] = PAD; } /** * Encode an arbitrary array of bytes as Base64 printable ASCII. * It will be broken into lines of 72 chars each. The last line * is not * terminated with a line separator. */ public static String encode(byte[] b) { // Each group or partial group of 3 bytes becomes four chars int outputLength = ((b.length + 2) / 3) * 4; // account for embedded newlines outputLength += (outputLength / lineLength) * lineSeparator.length(); 2016-03-22 WyWallet SMS Payment API v0.4 Page 30 (37) // must be local for recursion to work. StringBuffer sb = new StringBuffer( outputLength ); // must be local for recursion to work. int linePos = 0; // first deal with even multiples of 3 bytes. int len = (b.length / 3) * 3; int leftover = b.length - len; for ( int i=0; i<len; i+=3 ) { // Start a new line if next 4 chars won't fit on the current line // We don't encapsulate so that linePos and sb will work recursively { linePos += 4; if ( linePos > lineLength ) { linePos = 0; if ( lineLength != 0) {sb.append(lineSeparator);} } } // get next three bytes in unsigned form lined up, // in big-endian order int combined = b[i+0] & 0xff; combined <<= 8; combined |= b[i+1] & 0xff; combined <<= 8; combined |= b[i+2] & 0xff; // break those 24 // working LSB to int c3 = combined combined >>>= 6; int c2 = combined combined >>>= 6; int c1 = combined combined >>>= 6; int c0 = combined bits into a 4 groups of 6 bits, MSB. & 0x3f; & 0x3f; & 0x3f; & 0x3f; // Translate into the equivalent alpha character // emitting them in big-endian order. sb.append( valueToChar[c0]); sb.append( valueToChar[c1]); sb.append( valueToChar[c2]); sb.append( valueToChar[c3]); } // deal with leftover bytes switch ( leftover ) { case 0: default: // nothing to do break; case 1: // One leftover byte generates xx== // Start a new line if next 4 chars won't fit on the current line // We don't encapsulate so that linePos and sb will work recursively { 2016-03-22 WyWallet SMS Payment API v0.4 Page 31 (37) linePos += 4; if ( linePos > lineLength ) { linePos = 0; if ( lineLength != 0) {sb.append(lineSeparator);} } } // Handle this recursively with a faked complete triple. // Throw away last two chars and replace with == sb.append(encode(new byte[] {b[len], 0, 0} ).substring(0,2)); sb.append("=="); break; case 2: // Two leftover bytes generates xxx= // Start a new line if next 4 chars won't fit on the current line // We don't encapsulate so that linePos and sb will work recursively { linePos += 4; if ( linePos > lineLength ) { linePos = 0; if ( lineLength != 0) {sb.append(lineSeparator);} } } // Handle this recursively with a faked complete triple. // Throw away last char and replace with = sb.append(encode(new byte[] {b[len], b[len+1], 0} ).substring(0,3)); sb.append("="); break; } // end switch; if ( outputLength != sb.length() ) System.out.println("oops"); return sb.toString(); }// end encode } 5.2 Postback service examples 5.2.1 Java JSP postback <%@page import="org.w3c.dom.*,javax.xml.xpath.*,javax.xml.parsers.*,java.io.IOException,org.xml.sax.SAXException" %> <%@page import="javax.servlet.ServletInputStream,javax.servlet.http.HttpServletRequest"%> <%@page import="java.io.BufferedReader,java.io.InputStreamReader"%> <%@page import="java.io.*" %> <%@page import="org.xml.sax.InputSource" %> <% try { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); DocumentBuilder builder = domFactory.newDocumentBuilder(); //Load the XML document in the parser Document doc = builder.parse(new InputSource(newStringReader(request.getParameter("PostbackRequestWrapper")))); XPath xpath = XPathFactory.newInstance().newXPath(); // XPath Query for showing all nodes value XPathExpression expr; //Set the filter to find the elements //Header parameters 2016-03-22 WyWallet SMS Payment API v0.4 Page 32 (37) expr = xpath.compile("//PostbackRequestWrapper/Header/AcquirerID/text()"); String AcquirerID = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Header/AgreementID/text()"); String AgreementID = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Header/MerchantID/text()"); String MerchantID = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Header/TransmissionTime/text()"); String TransmissionTime = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Header/ClientIP/text()"); String ClientIP = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Header/PostbackURL/text()"); String PostbackURL = (String) expr.evaluate(doc, XPathConstants.STRING); //PostbackRequest parameters expr = xpath.compile("//PostbackRequestWrapper/PostbackRequest/Operation/text()"); String Operation = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/PostbackRequest/Amount/text()"); String Amount = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/PostbackRequest/BatchID/text()"); String BatchID = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/PostbackRequest/OrderID/text()"); String OrderID = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/PostbackRequest/TransactionID/text()"); String TransactionID = (String) expr.evaluate(doc, XPathConstants.STRING); //Status parameters expr = xpath.compile("//PostbackRequestWrapper/Status/TransactionStatus/text()"); String TransactionStatus = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Status/TransactionStatusDesc/text()"); String TransactionStatusDesc = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Status/OperationStatus/text()"); String OperationStatus = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Status/OperationStatusDesc/text()"); String OperationStatusDesc = (String) expr.evaluate(doc, XPathConstants.STRING); expr = xpath.compile("//PostbackRequestWrapper/Footer/MAC/text()"); String MAC = (String) expr.evaluate(doc, XPathConstants.STRING); } catch (Exception e) { throw e; } %> 5.2.2 ASP.net postback service // Read the incoming HTTPS stream StreamReader reader = new StreamReader(Request.InputStream, Encoding.Default); if (!reader.EndOfStream) { string xmlString = reader.ReadToEnd(); xmlString = HttpUtility.UrlDecode(xmlString.Replace("PostbackRequestWrapper=", "")); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); // Create a Hashtable to store values Hashtable values = new Hashtable(); values.Add("AcquirerID", xmlDoc.GetElementsByTagName("AcquirerID").Item(0).FirstChild.InnerText); values.Add("AgreementID", xmlDoc.GetElementsByTagName("AgreementID").Item(0).FirstChild.InnerText); values.Add("MerchantID", xmlDoc.GetElementsByTagName("MerchantID").Item(0).FirstChild.InnerText); values.Add("TransmissionTime",xmlDoc.GetElementsByTagName("TransmissionTime").Item(0).FirstChild.InnerText); values.Add("ClientIP", xmlDoc.GetElementsByTagName("ClientIP").Item(0).FirstChild.InnerText); values.Add("PostbackURL", xmlDoc.GetElementsByTagName("PostbackURL").Item(0).FirstChild.InnerText); values.Add("PostbackRequest",xmlDoc.GetElementsByTagName("PostbackRequest").Item(0).FirstChild.InnerText); values.Add("Operation", xmlDoc.GetElementsByTagName("Operation").Item(0).FirstChild.InnerText); values.Add("Amount", xmlDoc.GetElementsByTagName("Amount").Item(0).FirstChild.InnerText); values.Add("BatchID", xmlDoc.GetElementsByTagName("BatchID").Item(0).FirstChild.InnerText); values.Add("OrderID", xmlDoc.GetElementsByTagName("OrderID").Item(0).FirstChild.InnerText); values.Add("TransactionID", xmlDoc.GetElementsByTagName("TransactionID").Item(0).FirstChild.InnerText); values.Add("TransactionStatus", xmlDoc.GetElementsByTagName("TransactionStatus").Item(0).FirstChild.InnerText); values.Add("TransactionStatusDesc",xmlDoc.GetElementsByTagName("TransactionStatusDesc").Item(0).FirstChild.InnerText); values.Add("OperationStatus", xmlDoc.GetElementsByTagName("OperationStatus").Item(0).FirstChild.InnerText); values.Add("OperationStatusDesc", xmlDoc.GetElementsByTagName("OperationStatusDesc").Item(0).FirstChild.InnerText); values.Add("MAC", xmlDoc.GetElementsByTagName("MAC").Item(0).FirstChild.InnerText); } 2016-03-22 WyWallet SMS Payment API v0.4 Page 33 (37) 6 Appendix C: Simulator for API development The API provides a simulator returning predefined transaction status codes depending on input parameters in the request. Developers using the API can use this simulator to force errors and test error handling in their application. The WSDL (service description) is identical to the actual API to be used in production. The simulator tries to emulate the behavior of the real service by maintaining a transaction history of the last 200 transactions and return an appropriate response code, but does not guarantee 100% compatibility. 6.1 URL URL for MAP PaymentService simulator: https://mpaymenttest.payex.com/MAP/PaymentServiceTest?wsdl 6.2 Valid request parameters Parameter AquirerID AgreementID ClientType ClientID MAC 2016-03-22 Value WyWallet One of 99990095, 99990096 or 99990097 MSISDN 004699999nnn Remarks nnn is a number in the range 000…999. Other values will return transaction status 6 (Account not found) Shared secret = map123 WyWallet SMS Payment API v0.4 Page 34 (37) 6.3 Response codes The API will return a non-zero transaction status or timeout for the following combinations of Operation and ClientID: Operation Transaction status Remarks CheckOrder CheckOrder Purchase ClientID /MSISDN 0046999994nn 004699999499 0046999995nn nn Timeout nn Purchase 004699999599 Timeout Reversal Reversal 0046999996nn 004699999699 nn Timeout Credit Credit 0046999997nn 004699999799 nn Timeout nn = 01..20 Takes 1 minute to complete nn = 01..20 ClientID is fetched from original Purchase transaction Takes 1 minute to complete nn = 01..20 ClientID is fetched from original Purchase nn = 01..20 Takes 1 minute to complete nn = 01..20 nn = 01..20 Takes 1 minute to complete 2016-03-22 WyWallet SMS Payment API v0.4 Page 35 (37) 6.4 Frequently asked questions Question I have problems calculating the MAC Key for my request. Answer The most common problem is that there are missing parameters in the concatenated string. Please see our source code examples for examples on how to generate the MAC. If you are using another programming language or still have problems you can try and use our Online MAC generator to get help and compare your calculations with a verified source. Why do I get the error code 3 “Agreement not found”? https://shop.wywallet.se/mac-generator.aspx Most probably this is due to the fact that the payment request is sent to the wrong payment system / URL. Please see section for relevant systems and URL:s If you still get the same error code after confirming that the correct system is used it could be a misconfiguration in our system. Please contact merchant support for further assistance. I’ve submitted my PostbackURL in the payment request but I’ve waited and there is no HTTP POST to my URL. Most merchant accounts are configured to be synchronous where you receive the payment status immediately and postbacks aren’t used. If you have a synchronous account you can ignore to set the PostbackURL parameter in your request. If you have service with high performance requirements (e.g. TV & event votings) you should ask WyWallet merchant support (re)configure your account to asynchronous. Is there a time limit for requesting a reversal on a transaction? Do you provide mobile short codes or SMS services? 2016-03-22 If you have an asynchronous account and you don’t receive and callbacks please check that you have entered a HTTPS url (we only allow postbacks via SSL port 443 due to security restrictions) and that your firewall accepts incoming traffic on this IP & port. There are no technical time limit implemented and reversals are always accepted as long as the end user still has a WyWallet account. No, WyWallet is a dedicated payment service and only handle the actual payment. Short codes and SMS services can either be ordered via each MNO/Operator or by using a SMS aggregator. If you don’t have WyWallet SMS Payment API v0.4 Page 36 (37) 6.5 Merchant support For questions regarding the integration please contact our helpdesk merchant-support@wywallet.se 2016-03-22 WyWallet SMS Payment API v0.4 Page 37 (37)