This webhook is used to notify the partner that a transaction has been completed and a top up needs to take place in the app/game.
Used in Shop Integration and Gateway Integration
Overview
This webhook is used to conclude a transaction and the user/player needs to be credited after making a successful purchase.
In the Summary Webhook call, the Carry1st Platform will sign the request using the Basic Auth credentials that have been set up in the Product Configuration.
The request includes a X-SIGNATURE
header, generated by signing the request payload using the basic auth key. To verify the request, sign the request and verify the signature before crediting customers.
Request Signing
The signature is a hex encoded HMAC-SHA256 and is generated and sent using the X-SIGNATURE HTTP request header.
The signature can be generated using the following steps:
- Get the payload JSON string as received in request
- Trim all whitespace from either end of the data.
- Generate a SHA-256 HMAC, using the payload JSON string, and the Basic Auth key. This is a Base64 encoded string of the Basic Auth credentials in the format username:password.
- Hex encode the result HMAC. (note: In some cases (like PHP's hash_hmac function), the returned value is hex encoded by default, and this step is not required).
- This will result in a 64 character length string.
Verify the string against the X-SIGNATURE header value
#!/bin/bash
KEY="YXBpdXNlcjphcGlwYXNzd29yZA=="
PAYLOAD="{\"reference\":\"C1st_d6213ccf-e838-4c42-9222-4356bb67a7a2\",\"playerId\":\"12345\",\"productBundleId\":1,\"amount\":1000,\"currency\":\"ZAR\",\"tokensPurchased\":11,\"digitalCurrency\":{\"name\":\"Credits\",\"code\":\"CRE\"},\"status\":\"SUCCESSFUL\"}"
echo -en "$PAYLOAD" \
| openssl sha256 -hmac "$KEY" \
| awk '{print $2}'
<?php
$payload = "{\"reference\":\"C1st_d6213ccf-e838-4c42-9222-4356bb67a7a2\",\"playerId\":\"12345\",\"productBundleId\":1,\"amount\":1000,\"currency\":\"ZAR\",\"tokensPurchased\":11,\"digitalCurrency\":{\"name\":\"Credits\",\"code\":\"CRE\"},\"status\":\"SUCCESSFUL\"}";
$key = "YXBpdXNlcjphcGlwYXNzd29yZA==";
echo hash_hmac('sha256', trim($payload), $key);
import java.nio.charset.Charset;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public class Signature {
public static void main(String[] args) throws Exception {
String payload = "{\"reference\":\"C1st_d6213ccf-e838-4c42-9222-4356bb67a7a2\",\"playerId\":\"12345\",\"productBundleId\":1,\"amount\":1000,\"currency\":\"ZAR\",\"tokensPurchased\":11,\"digitalCurrency\":{\"name\":\"Credits\",\"code\":\"CRE\"},\"status\":\"SUCCESSFUL\"}";
String key = "YXBpdXNlcjphcGlwYXNzd29yZA==";
Mac hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(Charset.defaultCharset()), "HmacSHA256");
hmac.init(secretKeySpec);
String signature = new String(Hex.encodeHex(hmac.doFinal(String.format(payload).trim().getBytes(Charset.defaultCharset()))));
System.out.println(signature);
}
}
using System;
using System.Text;
using System.Security.Cryptography;
class Signature
{
public static void Main (string[] args)
{
string payload = "{\"reference\":\"C1st_d6213ccf-e838-4c42-9222-4356bb67a7a2\",\"playerId\":\"12345\",\"productBundleId\":1,\"amount\":1000,\"currency\":\"ZAR\",\"tokensPurchased\":11,\"digitalCurrency\":{\"name\":\"Credits\",\"code\":\"CRE\"},\"status\":\"SUCCESSFUL\"}";
string key = "YXBpdXNlcjphcGlwYXNzd29yZA==";
HMACSHA256 hmac = new HMACSHA256 (Encoding.Default.GetBytes (key));
byte[] hash = hmac.ComputeHash (Encoding.Default.GetBytes(payload).Trim()));
string signature = String.Concat(Array.ConvertAll(hash, x => x.ToString("X2")));
Console.Write (signature);
}
}
import hmac
import hashlib
key = 'YXBpdXNlcjphcGlwYXNzd29yZA=='
payload = '{"reference":"C1st_d63f1f41-d1f1-4521-9178-2c28cbe0ec9c","playerId":"selectiveplane71","productBundleId":1,"amount":1000,"currency":"ZAR","tokensPurchased":150,"digitalCurrency":{"name":"Carry1st Credits","code":"C1C"},"status”:”SUCCESSFUL”}'
print hmac.new(key, (payload).strip(), hashlib.sha256).hexdigest()
API Description
HTTP Headers
Header Name | Description |
---|---|
X-SIGNATURE | This is the header that will contain the signature of the request. Refer to the Request Signing section above. |
URL Format
The URL is configured in the Product Settings
POST: https\://\<webhook_url>
POST Request Fields
Field | Format | Description |
---|---|---|
reference | String | The payment unique reference. |
externalReference | String | The merchant unique reference that was passed in payment redirect. |
playerId | String | The user identifier. This should be a unique identifier used to identify the user in the game. |
productBundleId | Number | The bundle identifier as configured in Platform. |
productBundleExternalId | String | The bundle identifier for the Provider |
amount | Integer | The amount paid, in CENTS. |
currency | String | The currency code for amount paid. |
tokensPurchased | Number | The value of tokens purchased from the bundle. |
digitalCurrency | Digital Currency Object | The type of tokens purchased. |
status | String | The status of the transaction. |
List of Statuses
Status | Description |
---|---|
NEW | Transaction created, but payment has not been processed. |
PENDING | Payment is processing. |
SUCCESSFUL | Payment has been completed successfully. |
FAILED | Payment has failed. |
Success Response
Valid HTTP Success Status Codes:
- 200 - Success
- 208 - Already redeemed
HTTP Response Body:
{
"reference": "C-12345679887665-P",
"externalReference": "EXT_REF",
"playerId": "12345",
"productBundleId": 1,
"productBundleExternalId": "1",
"amount": 1000,
"currency": "ZAR",
"tokensPurchased": 11,
"digitalCurrency": {
"name": "Credits",
"code": "CRE"
},
"status": "SUCCESSFUL"
}
Error Response
Valid HTTP Error Status Codes:
- 400 - Bad Request
Http Response Body:
{
"errorMessage": "ERROR_MESSAGE",
"errorCode": "ERROR_CODE"
}
If an error response is received, the request will be retried periodically for a period of 24 hours.