Handling the Callback

After the customer completes the payment (or if the payment fails or is canceled) on the APM side, Exirom will send an HTTP callback (webhook) to the callbackUrl specified in your request. This callback is a server-to-server POST request containing a JSON body with the transaction’s final status and details.

It’s crucial to verify that this callback is authentic and hasn’t been tampered with. Each callback request includes an X-Checksum header, which is an HMAC-SHA256 signature of certain fields from the callback payload (such as accountId, amount, currency, transactionId). Using your secret key, you should recompute the expected checksum and compare it to the X-Checksum header value. This ensures the callback truly came from Exirom and the data wasn’t altered in transit. (See the Checksum Authentication Guide for the exact algorithm and fields used in the signature.)

Callback Data Fields (ApmPaymentTxInfoDto)

The JSON payload of the callback (referred to as ApmPaymentTxInfoDto) contains the following fields:

FieldTypeDescription
transactionIdStringThe unique transaction ID (as provided in the initial response).
requestIdStringThe original requestId you sent in the payment request.
accountIdLongYour merchant account ID associated with this transaction.
transactionStatusEnum (TxStatus)Final status of the transaction (e.g., COMPLETED, DECLINED, EXPIRED, etc.).
declineCodeIntegerIf the transaction was declined, this is the error or decline code. Null if not applicable.
declineSubReasonStringAdditional details about why the transaction was declined, if available.
orderCurrencyStringThe currency of the original order (same as the currency you sent).
processedCurrencyStringThe currency in which the transaction was processed by the APM. (This could differ from orderCurrency if conversion occurred.)
orderAmountDoubleThe original order amount (as a numeric value) that was requested.
processedAmountDoubleThe amount that was processed in the processedCurrency. This might differ if currency conversion or fees applied.
conversionRateDoubleThe exchange rate used if any currency conversion took place (otherwise 1.0).
apmRequestPayloadObject (ApmPayload)The payment method payload from your original request (apmPayload), echoing what was sent.
apmResponseDataObject (ApmResponseData)The APM-specific response data, similar to what was returned in the initial response. It may include information like the redirect URL or transaction IDs from the provider.
callbackUrlStringThe callback URL that this notification was sent to (i.e., the URL you provided in the request).
successRedirectUrlStringThe success redirect URL that was provided in the original request (if any).
failureRedirectUrlStringThe failure redirect URL provided in the original request (if any).
billingDetailsObject (ApmBillingDetails)The billing details from the original request (same data you sent).
orderObject (Order)The order information from the original request.
createdAtStringTimestamp when the transaction was created (in ISO date-time format).

All the above information allows your system to reconcile the transaction. For instance, you can look up the transaction by requestId in your records, see the final transactionStatus, and update your order or payment records accordingly. The presence of your original order and billingDetails data can help link the callback to internal objects, but you should primarily use the requestId or transactionId for lookup.

Example Callback Data

Here is an example of a callback payload for the earlier example transaction, assuming the payment was completed successfully by the customer:

{
  "transactionId": "tx-987654321",
  "requestId": "req-123456789",
  "accountId": 12345,
  "transactionStatus": "COMPLETED",
  "declineCode": null,
  "declineSubReason": null,
  "orderCurrency": "USD",
  "processedCurrency": "USD",
  "orderAmount": 100.0,
  "processedAmount": 100.0,
  "conversionRate": 1.0,
  "apmRequestPayload": {
    "paymentMethod": "ExPay", //All the payment methods are defined in the section below
    "paymentType": "E_WALLET" //All the payment types are defined in the section below
    // (Original request payload details would appear here)
  },
  "apmResponseData": {
    "paymentMethod": "ExPay",
    "paymentType": "E_WALLET",
    "redirectUrl": "https://pay.expay.example.com/checkout/tx-987654321",
    "providerTransactionId": "ExPay-tx-12345"
  },
  "callbackUrl": "https://merchant.example.com/callbacks/payments",
  "billingDetails": {
    // (Original billingDetails from the request)
  },
  "order": {
    // (Original order details from the request)
  },
  "createdAt": "2023-01-01T12:00:00Z"
}

When your server receives this callback, it should:

  • Verify the X-Checksum header (to ensure the data is authentic).
  • Check the transactionStatus and update your system accordingly (e.g., mark the order as paid if COMPLETED, or handle a failure if DECLINED).
  • (Optional) Respond with a 200 OK to acknowledge receipt. Exirom’s system will typically expect a successful response; otherwise, it might retry the callback.

Note: The paymentMethod and paymentType in apmRequestPayload, apmResponseData specify the APM (ExPay e-wallet in this case).