Webhooks

General

SMARTy Pay can notify an external systems of different events occurring via webhooks.

The following rules apply to webhook notifications:

  1. Webhook is fired using HTTP POST.
  2. Payload/body is in JSON format (see table below for attributes).
  3. Payload is signed by SMARTy Pay using API Secret.
  4. Webhook is considered successfully delivered when the remote endpoint returns HTTP 200.
  5. Webhook is delivered with at least-once semantics.
  6. SMARTy Pay retries webhook delivery several times with exponential backoff.

To ensure the authenticity of the webhook signature is placed inside the x-sp-digest HTTP header and is calculated using HMAC-SHA256 from the whole request body using ApiSecret as a secret.

It's important to ensure that the receiving system can handle events coming in out of order. This can happen due to network delays or other issues. If the order of events is critical, you can use an eventTs attribute to restore order.

In some cases, the same event might be sent more than once. You can use eventId attribute for deduplication purposes.

Payments

For payments, the system will send notifications via webhook in the case of:

  1. Creation of a new payment
  2. Change in payment status

Example payload for a new payment

{
  "eventId": "PHLNhtC2g7GqQ2aVWE4bRk",
  "eventType": "PaymentCreated",
  "eventTs": "2022-08-29T16:13:53+04:00",
  "payment": {
    "id": "wv7xbaSP4ljdITbrFI995v",
    "amount": {
        "value": "15",
        "currency": "bUSDT"
    },
    "createdAt": "2021-06-21T14:44:58Z",
    "expiresAt": "2021-06-22T20:19:38Z",
    "status": "Created",
    "metadata": {
        "orderId": 1002112
    }
  }
}

Example payload for payment status change

{
  "eventId": "PHLNhtC2g7GqQ2aVWE4bRk",
  "eventType": "PaymentStatusChanged",
  "eventTs": "2022-08-29T16:13:53+04:00",
  "payment": {
    "id": "wv7xbaSP4ljdITbrFI995v",
    "amount": {
        "value": "15",
        "currency": "bUSDT"
    },
    "createdAt": "2021-06-21T14:44:58Z",
    "expiresAt": "2021-06-22T20:19:38Z",
    "status": "InProgress",
    "metadata": {
        "orderId": 1002112
    }
  }
}

Subscriptions

When a subscription state change is detected SMARTy Pay notifies the external e-commerce system via webhook.

Payload attributes:

AttributeRequiredDescription
eventIdYesUnique Id of the event
eventTypeYesType of event
eventTsYesTimestamp (iso8601) of the event
contractAddress or sidYesID of subscription, contract address
planIdYesID of the plan
assetYesToken code
blockchainYesBlockchain mnemonic code
customerIdYesCustomer correlation ID
payerYesPayer address
metadataYesAdditional correlation data
newStatusYesNew subscription status
oldStatusYesOld subscription status

On new subscription creation:

Example payload for a new subscription

{
  "eventId": "5FRJRK9D492gpeWjiKAo4k",
  "eventType": "SubscriptionCreated",
  "eventTs": "2023-05-29T11:11:53.875442729+04:00",
  "subscription": {
    "contractAddress": "0xf265d80e9715f6f38b775af3bc859afcc54f8a59",
    "planId": "zXA5uAniS3-fc743RE0yAg",
    "asset": "btMNXe",
    "blockchain": "BinanceTestNet",
    "customerId": "customer-500060001",
    "nextChargeAt": "2023-01-14T15:31:39.698Z",
    "payer": "0x14186C8215985f33845722730c6382443Bf9EC65",
    "mode": "Simple",
    "status": "Draft",
    "startFrom": "2023-01-13T15:31:39.698Z",
    "maxPeriods": 24,
    "createdAt": "2023-01-13T15:31:40.035098Z",
    "metadata": "correlation-order-0012",
  }
}

On subscription status change:

Example payload for subscription status change

{
  "eventId": "1FRJRK9D492gpeWjiKAo41",
  "eventType": "SubscriptionStatusChanged",
  "eventTs": "2023-05-29T11:11:53.875442729+04:00",
  "sid": "0x5692cf273644f77ea1bcc06b1fe25be4c4ad298a",
  "oldStatus": "Pending",
  "newStatus": "Active"
}

Subscription Charges

When a subscription charge is scheduled (created) and later processed the following events are dispatched via webhook.

Example payload for subscription charge

{
  "eventId": "Exxc54kqygZo7ouTHep8Zo",
  "eventType": "SubscriptionChargeCreated",
  "eventTs": "2024-01-16T10:13:49.463181849+04:00",
  "charge": {
    "id": "e8b596cc-5189-4c53-944f-d51a8ad848c5",
    "contractAddress": "0x76368Eafc5Ce663BeF7aBd4DD425f0431f9307b1",
    "companyId": 1,
    "amount": "0.01 bUSDT",
    "planId": "g-nT6MdYTo2UhTLH4R3bow",
    "chargeDate": "2024-01-16T07:13:21Z",
    "status": "Succeeded"
  }
}

Example payload for subscription charge status change

{
  "eventId": "KtnqGyNxxWoAC589DyzX2v",
  "eventType": "SubscriptionChargeStatusChanged",
  "eventTs": "2024-01-16T10:13:49.510298645+04:00",
  "charge": {
    "id": "e8b596cc-5189-4c53-944f-d51a8ad848c5",
    "contractAddress": "0x76368Eafc5Ce663BeF7aBd4DD425f0431f9307b1",
    "amount": "0.01 bUSDT",
    "planId": "g-nT6MdYTo2UhTLH4R3bow",
    "chargeDate": "2024-01-16T07:13:21Z",
    "oldStatus": "Pending",
    "newStatus": "Succeeded"
  }
}

All possible charge statuses can be found here.