Skip to content

Payment Webhook ​

This is a webhook interface, implemented by the Game SVR with the callback URL configured in the SUD OP console. The SUD OP SVR calls this interface when a payment or refund status changes, notifying the Game SVR to handle the delivery or refund result.

Interface Description ​

Interface Name pay.notify

Description Payment webhook. The SUD OP SVR proactively calls the callback URL configured by the Game SVR, notifying the Game SVR to handle item delivery or refund results.

Note: This interface requires service communication secondary encryption and signatures: the callback request must be signature-verified and decrypted before any business logic runs. This effectively prevents data tampering and leakage.

Interface Information ​

ItemValue
CallerSUD OP SVR
ProviderGame SVR
Trigger timingWhen a payment or refund status changes

Call Method ​

HTTPS Call ​

http
POST <Game custom callback URL>

The callback URL is configured by the Game in the SUD OP console. Please use an HTTPS address.

Request Parameters - Body ​

FieldTypeDefaultRequiredDescription
idstringYesWebhook notification ID. Globally unique, remains unchanged when SUD OP retries; the Game SVR should use this field as the idempotency key
create_timenumberYesWebhook notification creation time (second-level timestamp)
eventstringYesEvent type, enum value
payloadobjectYesEvent data. Different event types correspond to different data structures, see the description below

Item Delivery Notification: pay_goods_deliver_notify ​

payload field description:

FieldTypeDefaultRequiredDescription
envnumberYesEnvironment: 0-production, 1-sandbox
out_trade_nostringYesBusiness order number
sud_trade_nostringYesSUD order number
product_idstringYesProduct ID
product_namestringYesProduct name
quantitynumberYesPurchase quantity
unit_pricenumberYesUnit price (in cents)
attachstringNoPass-through data

Request example:

json
{
  "id": "xxx",
  "create_time": 1745136000,
  "event": "pay_goods_deliver_notify",
  "payload": {
    "env": 0,
    "out_trade_no": "BIZ20250420001",
    "sud_trade_no": "SUD20250420001",
    "product_id": "product_001",
    "product_name": "Coin Pack",
    "quantity": 1,
    "unit_price": 600,
    "attach": ""
  }
}

Refund Notification: pay_refund_notify ​

payload field description:

FieldTypeDefaultRequiredDescription
envnumberYesEnvironment: 0-production, 1-sandbox
sud_refund_nostringYesSUD refund number
out_trade_nostringYesBusiness order number corresponding to the refund
sud_trade_nostringYesSUD order number corresponding to the refund
refund_amountnumberYesRefund amount (in cents)
reasonstringNoRefund reason

Request example:

json
{
  "id": "xxx",
  "create_time": 1745136000,
  "event": "pay_refund_notify",
  "payload": {
    "env": 0,
    "out_trade_no": "BIZ20250420001",
    "sud_trade_no": "SUD20250420001",
    "sud_refund_no": "REF20250420001",
    "refund_amount": 600,
    "reason": "deliver pay products failed"
  }
}

Response ​

The returned JSON data package

FieldTypeDescription
errcodeint32Error code. 0 indicates the Game SVR has successfully processed this notification (including a duplicate request that passed idempotency judgment), and SUD OP will not retry; a non-0 value indicates processing failure, and SUD OP will retry according to the "Timeout and Retry" policy below
errmsgstringError message

Response Example ​

json
{
  "errcode": 0,
  "errmsg": "ok"
}

Timeout and Retry ​

ItemRequirement
Game response timeout threshold≤ 5 s
Conditions that trigger a retryThe Game SVR does not respond within the timeout threshold, returns a non-200 HTTP status code, or returns a non-zero errcode
Total retry countUp to 15 times
Retry interval (seconds)15, 15, 30, 180, 600, 1200, 1800, 1800, 1800, 3600, 10800, 10800, 10800, 21600, 21600 (approximately 24 hours in total)

Retry requests keep the same top-level id as the first request. The Game SVR must use id for idempotency judgment; when an idempotency hit occurs, simply return errcode: 0 and do not deliver or refund again.

Authentication ​

When SUD OP calls this interface, it always carries encryption and signature information in the request; there is no plaintext webhook mode. The Game SVR must verify the signature and decrypt the request to confirm the request source is legitimate. If verification fails, reject the request directly (return a non-200 HTTP status code); do not enter the business response flow.

Notes ​

  1. The Game SVR must verify the signature. If verification fails, reject the request directly (return a non-200 HTTP status code) to avoid forged requests triggering delivery or refund processing.
  2. Idempotency key: use the top-level id as the unique idempotency key. The id remains unchanged when SUD OP retries; the "delivery notification" and "refund notification" for the same order use different ids, so they are naturally distinguished.
  3. At the business layer, it is recommended to also perform order status validation based on out_trade_no / sud_trade_no / sud_refund_no to prevent out-of-order arrival (such as a refund callback arriving before the delivery callback).
  4. Requests whose create_time differs from the server's current time by more than 5 minutes should be rejected directly to prevent replay attacks.