PaymentSDK
Mobile payment SDK
Signature

Authentication by Signature

As payment information is exchanged between the merchant's system, the consumer's application, and Wirecard´s Payment Processing Gateway, it is important that the data exchange safeguards against man-in-the-middle attacks.

Mobile payment endpoint uses a digital signature for all message exchanges. This digital signature is a mathematical scheme for demonstrating the authenticity of a digital message or document. A valid digital signature let a recipient believe that the message was created by a known sender, and that it was not altered, while transmitting.

Secret Key Exchange

To ensure the authenticity of the request and response messages, it is required that a Secret Key is shared with the merchant.

The Secret Key is used in Signature generation.

It is important that the Secret Key is never shared with anyone and is protected within the merchant server (only used in server side code for generating the request signature or validating the response signature). Never store your secret key inside your application nor on the phone.

The Secret Key will be communicated at the time of Merchant Account setup. Please contact your support representative if you did not receive a Secret Key or require Secret Key regeneration.

Signature v1

Merchant needs to create a digital signature on his own server as it is the only place where the Secret is stored. The client's server also provides the Merchant Account ID to the mobile app client. To calculate the signature, following conditions need to be met:

  • Fields need to be concatenated,
  • leading and trailing space removed,
  • SHA-256 signature follows the combined string.

Please note that the order of the fields is important. Also note, the same values used in the request signature must be placed into the client side form/data (with the exception of the secret key).

  1. request_time_stamp
  2. request_id
  3. merchant_account_id
  4. transaction_type
  5. requested_amount (must be with a dot decimal mark)
  6. requested_amount_currency
  7. [Secret Key] (provided by your support representative)

The SHA-256 hash value is then presented on the merchants client side form as request_signature field.

An example of request signature generation is as follows:

1 request_time_stamp = '20120430123012'
2 request_id = 'order-12345'
3 merchant_account_id = 'b19fb056-d8da-449b-ac85-cfbfd0558914'
4 transaction_type = 'purchase'
5 requested_amount = '1.01'
6 requested_amount_currency = 'USD'
7 secret_key = 'efabf47b-e43b-4785-873f-1c5bc65b7cd2'

Pre SHA-256 string

20120430123012order-12345b19fb056-d8da-449b-ac85-cfbfd0558914purchase1.01USDefabf47b-e43b-4785-873f-1c5bc65b7cd2

SHA-256 signature

4510af4db06fd3a3c9952d5beb56be1e7bfaf73ff7842f691c1c0e7269da5e44

Signature v1 Generation Code Samples

  • PHP
    $request_signature = hash('sha256', trim($request_time_stamp . $request_id . $merchant_account_id . $transaction_type . $requested_amount . $request_amount_currency . $secret_key));
  • C#/ASP.NET
    public static string GetSHA256(string text) {
    byte[] hashValue;
    byte[] message = Encoding.UTF8.GetBytes(text);
    SHA256Managed hashString = new SHA256Managed();
    string hex = "";
    hashValue = hashString.ComputeHash(message);
    foreach( byte x in hashValue) {
    hex += String.Format("{0:x2}", x);
    }
    return hex.Trim();
    }
  • JAVA
    private static String tosha256(String... fields) {
    StringBuffer sb = null;
    try {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    sb = new StringBuffer();
    for (String field : fields) {
    sb.append(field.trim());
    }
    md.update(sb.toString().getBytes("utf-8"));
    byte[] mdbytes = md.digest();
    return DatatypeConverter.printHexBinary(mdbytes);
    } catch (NoSuchAlgorithmException e) {
    sb = null;
    } catch (UnsupportedEncodingException e) {
    sb = null;
    }
    return sb == null ? null : sb.toString();
    }
  • GROOVY
    import java.security.MessageDigest;
    ...
    def messageDigest = MessageDigest.getInstance("SHA256");
    def secret_key = 'XXXXXXXXXXXXXXXXXXXXXX';
    def stringToHash = time_stamp + request_id + merchant_account_id + transaction_type + requested_amount + requested_amount_currency + secret_key;
    messageDigest.update( stringToHash.trim().getBytes() );
    def shaHex = new BigInteger(1, messageDigest.digest()).toString(16);

Signature v2

Merchant needs to create a digital signature on his own server as it is the only place where the Secret is stored. Signature v2 consists from 2 parts: signature payload and calculated value, both Base64 URL safe encoded and separated with a period.

Example of Signature v2:

1 SFMyNTYKcmVxdWVzdF90aW1lX3N0YW1wPTIwMTYtMDctMjdUMTQ6MzM6NDkrMDI6MDAKbWVyY2hhbnRfYWNjb3VudF9pZD05ODczYWM2NS02ZjI4LTRiNzUtYWU1NS05ZDU0OWNmNTcwZTM.2VTPD7hAiCW-NdDaUqN7pjwizuwHvirVEs1HdGU-iz0

Signature v2 Payload

The signature payload contains algorithm name that is used to calculate signature and fields in NVP format delimited with the new line (‘\n’), as following:

1 algorithm\n
2 field1=value1\n
3 field2=value2\n
4 …
5 fieldX=valueX

Supported algorithms:

AlgorithmDescription
HS256 HMAC with SHA-256

Supported fields:

Name Details
request_time_stamp in ISO 8601 format with timezone, e.g. 2016-07-27T14:33:49+02:00
merchant_account_ide.g. 9873ac65-6f28-4b75-ae55-9d549cf570e3
request_id e.g. 0c06f2b9-f47e-41d1-9eec-9c9352f0247f
transaction_type e.g. debit
requested_amount should follow ISO 4217, e.g. 1.01
requested_amount_currency should follow ISO 4217, e.g. EUR

Example of payload before base64 encoding:

1 HS256
2 request_time_stamp=2017-03-23T09:14:51Z
3 merchant_account_id=33f6d473-3036-4ca5-acb5-8c64dac862d1
4 request_id=A7B51ED4-9EB0-48D1-82AA-2145A7792C6B
5 transaction_type=authorization
6 requested_amount=1.01
7 requested_amount_currency=EUR

Algorithm name and fields in bold are mandatory to calculate and validate signature, so they need to be always included in the signature payload. Presence of all other fields can vary based on different endpoint needs. Algorithm name has to be at the first position of payload, but all other fields can be specified in any order.

Example of signature base64 encoded payload and value generated with secret key 9e0130f6-2e1e-4185-b0d5-dc69079c75cc:

1 SFMyNTYKcmVxdWVzdF90aW1lX3N0YW1wPTIwMTctMDMtMjNUMDk6MTQ6NTFaCm1lcmNoYW50X2FjY291bnRfaWQ9MzNmNmQ0NzMtMzAzNi00Y2E1LWFjYjUtOGM2NGRhYzg2MmQxCnJlcXVlc3RfaWQ9QTdCNTFFRDQtOUVCMC00OEQxLTgyQUEtMjE0NUE3NzkyQzZCCnRyYW5zYWN0aW9uX3R5cGU9YXV0aG9yaXphdGlvbgpyZXF1ZXN0ZWRfYW1vdW50PTEuMDEKcmVxdWVzdGVkX2Ftb3VudF9jdXJyZW5jeT1FVVI=.HZKtk+UfuA9IV6082jR+OLuZUZnlpSKW6lNFgZX2BEk=

Signature v2 Validation

Signature value is calculated from payload using the merchant secret key and specified algorithm and then it is compared to provided value. Signature is also checked for expiration using timestamp included in payload. For expiration period is used the same value as for payment page (default 30 minutes).