tpay Notifications
tpay sends notifications to your Notification URL whenever there is a subscription payment or one-time transaction update. These notifications help keep your platform updated with the latest statuses.
Merchant Responsibilities
After receiving and processing a notification successfully, your system should return an HTTP 200-OK response. Any other response means the notification was not received successfully, and tpay may resend it. This helps ensure no payment updates are missed.
tpay notification types
There are five notification kinds below. You only receive the ones that match your product/service and what happened for them — not every callback on every integration.
SubscriptionOptInNotification
Sent when someone completes subscription signup outside your own checkout — for example via tpay Checkout, a mobile operator (MO) flow, or an operator app.
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
action | String | Yes | Always set to "SubscriptionOptInNotification" for this notification. |
subscriptionContractId | Int | Yes | The ID of the subscription contract that opted in. |
operatorCode | Int | Yes | Operator code (MCC + MNC). Refer to your operator / coverage documentation for valid values. |
msisdn | String | Yes | Customer MSISDN. This parameter may be encrypted depending on operator policy. |
renewalFrequency | String | Yes | Subscription plan frequency (for example daily, weekly, or monthly). |
trialPeriod | Int | Yes | Free trial length in days before the first charge. Use 0 or omit when there is no trial. |
nextPaymentDate | String | Yes | Date/time of the next recurring payment (URL-encoded timestamp as sent in the callback). |
initialPaymentTranId | Int | No | Initial payment transaction ID in the tpay system, when applicable. |
initialPaymentAmount | Int | No | Initial payment amount when the product uses an upfront charge. |
productCatalogName | String | Yes | Catalog name created in the tpay dashboard and used for the subscription. |
productId | String | Yes | Product SKU / id created in the tpay dashboard and used for the subscription. |
recurringAmount | Int | Yes | Amount charged on each billing cycle after signup. |
customerAccountNumber | String | Yes | Partner-side account identifier for the subscribed contract (unique per your integration). |
digest | String | Yes | A secret way to encrypt parameters. |
How to build the digest string
Signature = PublicKey + ":" + HexString(HMACSHA256(PrivateKey, message)) message = action + subscriptionContractId + operatorCode + msisdn + renewalFrequency + trialPeriod + nextPaymentDate + initialPaymentTranId + initialPaymentAmount + productCatalogName + productId + recurringAmount + customerAccountNumber
Use the same field names and order as in the callback when you verify the digest.
Subscription charging notifications
tpay performs charging on your behalf. You receive a notification for every attempt, successful or failed. There are two actions:
- SubscriptionInitialChargingNotification — first charge (initial payment plan).
- SubscriptionChargingNotification — recurring renewals after the first successful charge.
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
action | String | Yes | SubscriptionInitialChargingNotification or SubscriptionChargingNotification, depending on whether this is the first charge or a renewal. |
subscriptionContractId | Int | Yes | The subscription contract that was charged. |
customerAccountNumber | String | Yes | Unique partner-side identifier for the subscriber. |
paymentTransactionStatusCode | String | Yes | Charging outcome (for example PaymentCompletedSuccessfully or NotEnoughCredit). |
transactionId | Int | Yes | The charging transaction ID in tpay. |
amountCharged | Int | Yes | Amount deducted from them in this attempt. |
currencyCode | String | Yes | ISO currency code of the charge. |
billAmount | Int | Yes | Total bill amount or the charging limit applied for this bill. |
collectedAmount | Int | Yes | Total collected on the same bill (after partial collection rules). |
paymentDate | String | Yes | Date/time of the charging attempt. |
errorMessage | String | No | Error description when the charge did not complete successfully. |
nextPaymentDate | String | Yes | Date/time of the next recurring payment when applicable. |
productCatalogName | String | Yes | Catalog name created in the tpay dashboard and used for the subscription. |
productId | String | Yes | Product name / id created in the tpay dashboard and used for the subscription. |
billNumber | Int | Yes | Charging cycle / bill sequence number. |
billAction | String | Yes | Bill type:
• RecurringPayment — periodic balance charge per plan.
• RetrailPayment — operator spelling in callbacks: retrial after a failed recurring charge.
• Other values may appear for specialized flows (for example on-demand charging). |
msisdn | String | Yes | Customer MSISDN; may be encrypted for some operators. |
digest | String | Yes | A secret way to encrypt parameters. |
How to build the digest string
Signature = PublicKey + ":" + HexString(HMACSHA256(PrivateKey, message)) message = Action + SubscriptionContractId + CustomerAccountNumber + PaymentTransactionStatusCode + TransactionId + AmountCharged + CurrencyCode + PaymentDate + NextPaymentDate + ProductCatalogName + ProductId
SubscriptionContractStatusChanged
Sent when a subscription contract changes state — activation, suspension, cancellation, and similar transitions. Use it to sync entitlement in your product and support tooling.
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
action | String | Yes | Always "SubscriptionContractStatusChanged". |
subscriptionContractId | Int | Yes | The subscription contract whose status changed. |
customerAccountNumber | String | Yes | Customer identifier shared between you and tpay; unique on the partner side (any stable format you define). |
status | String | Yes | New contract status, for example Active or Canceled.
• Active — after successful verification.
• Cancelled — cancellation through API or mobile operator (MO).
Note: partners are typically not notified while the contract is still New if they may not finish verification. |
reason | String | No | Why the status changed (for example "Activated", "Canceled By Merchant", or operator-specific text when canceled via MO). |
digest | String | Yes | A secret way to encrypt parameters. |
How to build the digest string
digest = merchantPublicKey + ":" + HexString(HMACSHA256(merchantPrivateKey, message)) message = action + subscriptionContractId + customerAccountNumber + status + reason
TransactionStatusUpdate
Covers one-time payments. You will see whether the charge worked, plus amounts and references. Some fields (such as messagebody) may be blank depending on how they paid.
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
action | String | Yes | Always TransactionStatusUpdate for one-time payment callbacks. |
paymentTransactionStatusCode | String | Yes | Outcome of the one-time payment attempt. |
transactionId | String | Yes | tpay transaction id for the payment. |
msisdn | String | Yes | Payer MSISDN when applicable. |
amount | String | Yes | Charged amount. |
currencyCode | String | Yes | ISO 4217 currency code. |
paymentDate | String | Yes | When the payment completed or failed. |
productCatalogName | String | Yes | Product catalog name. |
productId | String | Yes | Product id within the catalog. |
messagebody | String | No | Optional channel payload; may be empty depending on payment path. |
orderInfo | String | No | Merchant order or reference metadata. |
paymentProviderCode | String | Yes | Wallet or payment provider code. |
smsID | String | No | SMS or session correlation id when present. |
digest | String | Yes | A secret way to encrypt parameters. |
How to build the digest string
message = action + paymentTransactionStatusCode + transactionId + msisdn + amount + currencyCode + paymentDate + productCatalogName + productId + moMessageBody + orderInfo + paymentProviderCode
SubscriptionOnDemandChargingNotification
Only for merchants who use the on-demand charging feature. It looks like a normal charge notification, but it applies to subscribers who are already active. When it applies, you may see billAction=OnDemandCharging.
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
action | String | Yes | Always SubscriptionOnDemandChargingNotification for on-demand charges against active subscribers. |
subscriptionContractId | Int | Yes | The subscription contract that was charged. |
customerAccountNumber | String | Yes | Unique partner-side identifier for the subscriber. |
paymentTransactionStatusCode | String | Yes | Charging outcome (for example PaymentCompletedSuccessfully or NotEnoughCredit). |
transactionId | Int | Yes | The charging transaction ID in tpay. |
amountCharged | Int | Yes | Amount deducted from them in this attempt. |
currencyCode | String | Yes | ISO currency code of the charge. |
billAmount | Int | Yes | Total bill amount or the charging limit applied for this bill. |
collectedAmount | Int | Yes | Total collected on the same bill (after partial collection rules). |
paymentDate | String | Yes | Date/time of the charging attempt. |
errorMessage | String | No | Error description when the charge did not complete successfully. |
nextPaymentDate | String | Yes | Date/time of the next recurring payment when applicable. |
productCatalogName | String | Yes | Catalog name created in the tpay dashboard and used for the subscription. |
productId | String | Yes | Product name / id created in the tpay dashboard and used for the subscription. |
billNumber | Int | Yes | Charging cycle / bill sequence number. |
billAction | String | Yes | Often OnDemandCharging when the charge is triggered on demand (see your product configuration). |
msisdn | String | Yes | Customer MSISDN; may be encrypted for some operators. |
digest | String | Yes | A secret way to encrypt parameters. |
How to build the digest string
Signature = PublicKey + ":" + HexString(HMACSHA256(PrivateKey, message)) message = subscriptionContractId + customerAccountNumber + paymentTransactionStatusCode + transactionId + amountCharged + currencyCode + paymentDate + errorMessage + nextPaymentDate + productCatalogName + productId + billNumber + billAction + msisdn + billAmount + collectedAmount