> ## Documentation Index
> Fetch the complete documentation index at: https://sdk.qfapi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscription Webhook (Recurring Payment Notifications)

> This document describes the webhook notification system for recurring payments (subscriptions), including token creation, subscription status changes, and billing result notifications.

This page describes asynchronous notifications for the subscription system:

* Subscription state changes
* Recurring billing results

<Info>
  Token Creation Notifications are independent of subscriptions. See [Token Notification](/integration/online-shop/integration-by-use-case/saved-payment-methods/token-notification).
</Info>

## How to configure the notification URL

<Note>
  To set your webhook endpoint, email your webhook URL, merchant ID, and store ID to [technical.support@qfpay.com](mailto:technical.support@qfpay.com).
</Note>

## Subscription status change

Sent when a subscription changes state.

| Field | Description |
| - | - |
| `notify_type` | Notification type: `subscription`. |
| `subscription_id` | Subscription identifier. |
| `state` | Current state, such as `ACTIVE`, `COMPLETED`, or `INCOMPLETE`. |
| `sysdtm` | System timestamp. |

```json theme={null}
{
  "state": "COMPLETED",
  "sysdtm": "2024-04-24 15:19:39",
  "notify_type": "subscription",
  "subscription_id": "sub_e51bb914919*****f6b0fe36d"
}
```

## Subscription payment result

Sent when a recurring billing attempt succeeds or fails.

| Field | Description |
| - | - |
| `notify_type` | Value: `subscription_payment`. |
| `subscription_id` | Subscription ID. |
| `subscription_order_id` | Format: `sub_ord_{subscription_id}_{0001}`. |
| `respcd` | Response code. `0000` indicates success. |
| `respmsg` | Response message. |
| `syssn` | System transaction ID. |
| `txdtm` | Transaction timestamp. |
| `txamt` | Transaction amount. |
| `txcurrcd` | Currency. |
| `customer_id` | Customer ID. |
| `product_id` | Product ID or IDs. |
| `cardcd` | Masked card number. |
| `card_scheme` | Card scheme, when present. |
| `current_iteration` | Billing iteration number. |

```json theme={null}
{
  "txcurrcd": "HKD",
  "reason": "AUTHORISED",
  "subscription_order_id": "sub_ord_a360f06eb*****ad6aff24c3a",
  "product_id": "prod_8c838c17ddb043b9***11f1a85c30",
  "txdtm": "2024-04-24 15:19:37",
  "txamt": "300",
  "card_scheme": "VISA_DEBIT-SSL",
  "syssn": "20240424180500020000015704",
  "respcd": "0000",
  "subscription_id": "sub_e51bb914919***31d800f6b0fe36d",
  "customer_id": "cust_a9c0bcf2717f4***786a10e5f8f2",
  "notify_type": "subscription_payment",
  "current_iteration": "1"
}
```

## Retry logic and idempotency

<Tip>
  Make your webhook receiver idempotent. The same notification can be delivered more than once if delivery fails.
</Tip>

Return HTTP 200 after successful processing. If your server does not respond with HTTP 200, QFPay retries delivery with exponential backoff. The maximum retry count depends on internal configuration.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.