---
url: >-
https://acquirer-api-docs-v4-en.pingpongx.com/en/notes/onlinePayment/features/tokenization/codeGrant/index.md
description: >-
CodeGrant applies to selected local payment methods. The merchant first
obtains authUrl to guide the buyer through wallet-side authorization, and then
charges later with the saved token.
---
This page describes the CodeGrant agreement-payment flow for selected local payment methods. The buyer completes a one-time wallet-side authorization, after which the merchant stores the resulting payment credential `token` and uses it within the agreed business scope for later charges without repeating the agreement flow or re-entering wallet account details on every payment.
This solution fits membership services, subscription renewals, recurring benefit fulfilment, auto-charge flows, and other “authorize first, fulfil later” business models. It is also suitable when the goal is to reduce repeat-payment friction and improve conversion for local-wallet scenarios.
## Solution overview
CodeGrant can be viewed as a “local-wallet agreement token payment” capability with four core parts:
1. **Agreement setup**: the merchant calls the bind API, receives `authUrl`, and guides the buyer through the wallet-side agreement flow.
2. **Credential storage**: after success, the merchant stores the mapping among `token`, `merchantUserId`, payment method, and agreement state.
3. **Follow-up payment**: the merchant server charges later with `token + bizType=CodeGrant`.
4. **Lifecycle management**: notifications, query APIs, and unbind operations keep the token state in sync.
In PingPong Checkout, the typical implementation path is: the merchant first calls the [Binding Interface](/en/notes/tokenization/oneClickPayment/bind/) to obtain `authUrl` and guide the buyer through the agreement flow; after agreement success, the merchant stores the `token`; later payments are created through [Order Creation and Payment](/en/notes/checkout/api/uniformly/) with `token`, `bizType=CodeGrant`, and `merchantUserId`. The final agreement result should be confirmed by the [agreement-success notification](/en/notes/notify/bindNotify/APM/accTokenCreation/) or the [agreement list query](/en/notes/tokenization/oneClickPayment/bindList/). The final payment result should be confirmed by the [transaction notification](/en/notes/notify/payment/notify/) or [transaction query](/en/notes/checkout/api/getOne/).
## Supported payment methods
CodeGrant is only available for wallets or local payment methods that support this capability. For the current scope, see the [CodeGrant payment-method list](/en/notes/appendix/codeGrant/).
## Interface list
CodeGrant integration usually involves the following APIs and notifications:
## Integration flow
```mermaid
%%{init: {
'theme': 'base',
'themeVariables': {
'primaryColor': '#E3F2FD',
'primaryTextColor': '#0D47A1',
'primaryBorderColor': '#1976D2',
'lineColor': '#1565C0',
'secondaryColor': '#BBDEFB',
'tertiaryColor': '#90CAF9',
'background': '#F8FBFF',
'mainBkg': '#E3F2FD',
'secondBkg': '#BBDEFB',
'tertiaryBkg': '#90CAF9',
'actorBkg': '#2196F3',
'actorBorder': '#1976D2',
'actorTextColor': '#FFFFFF',
'actorLineColor': '#1565C0',
'signalColor': '#0D47A1',
'signalTextColor': '#0D47A1',
'noteBkgColor': '#E1F5FE',
'noteTextColor': '#01579B',
'noteBorderColor': '#0288D1',
'loopTextColor': '#0D47A1',
'activationBkgColor': '#B3E5FC',
'activationBorderColor': '#0277BD'
}
}}%%
sequenceDiagram
participant Buyer as 👤 Buyer
participant Client as 💻 Merchant Frontend
participant Server as 🏪 Merchant Server
participant PP as 🔄 PingPongCheckout
participant Wallet as 💰 Wallet / Local Payment Channel
Note over Buyer,Wallet: Agreement phase
Buyer->>Client: 1. Select a payment method that supports CodeGrant
Client->>Server: 2. Submit agreement request
Server->>PP: 3. Call /v4/paymethod/bind
PP-->>Server: 4. Return token and authUrl
Server-->>Client: 5. Return redirect info
Client->>Wallet: 6. Redirect to authUrl
Buyer->>Wallet: 7. Complete agreement or authorization
Wallet-->>PP: 8. Return agreement result
PP-->>Server: 9. Push agreement notification
Server-->>PP: 10. Return HTTP 2xx acknowledgement
Note over Server,Wallet: Follow-up payment phase
Server->>PP: 11. Call order and payment (token + bizType + merchantUserId)
PP-->>Server: 12. Return synchronous payment result
PP-->>Server: 13. Push payment notification
Server->>PP: 14. Query transaction if notification is missing
```
Flow summary:
1. The buyer chooses a payment method that supports CodeGrant on the merchant page.
2. The merchant frontend sends an agreement request to the merchant server.
3. The merchant server calls the [Binding Interface](/en/notes/tokenization/oneClickPayment/bind/) and returns `authUrl` to the frontend.
4. The buyer is redirected to the wallet page and completes the agreement or authorization.
5. PingPongCheckout pushes the agreement result through the [agreement-success notification](/en/notes/notify/bindNotify/APM/accTokenCreation/).
6. The merchant stores the agreement result, `token`, `merchantUserId`, and payment-method mapping.
7. For later charges, the merchant server calls [Order Creation and Payment](/en/notes/checkout/api/uniformly/) with the saved token.
8. The merchant uses [transaction notifications](/en/notes/notify/payment/notify/) or [transaction queries](/en/notes/checkout/api/getOne/) as the source of truth for payment results.
## Integration checklist
Before integrating CodeGrant, complete the common setup in [Prerequisites](/en/notes/start/step/).
Also confirm the following CodeGrant-specific items:
- The target wallet or local payment method supports CodeGrant and has been enabled
- Publicly reachable `notificationUrl` endpoints are ready for agreement and payment callbacks, and `merchantResultUrl` / `payResultUrl` are prepared
- A stable merchant-side `merchantUserId` is available and reused across bind, pay, and authorization cancellation
- Your system can persist the mapping among `token`, payment method, agreement status, and merchant user
## Agreement integration
Complete the integration with the following steps:
### Step 1: Create the agreement request
Call the [Binding Interface](/en/notes/tokenization/oneClickPayment/bind/) from the merchant server. On success, PingPongCheckout returns an `authUrl` that the buyer must open to complete the wallet agreement flow.
Key request parameters:
| Parameter | Required | Description |
|:---|:---:|:---|
| `bizContent.requestId` | M | Globally unique agreement request ID |
| `bizContent.merchantUserId` | M | Merchant-side user ID that must remain the same for payment and authorization cancellation |
| `bizContent.paymentMethod.type` | M | Payment-method type for this agreement |
| `bizContent.merchantResultUrl` | M | Merchant page to return the buyer to after agreement completion |
| `bizContent.notificationUrl` | M | Agreement-result notification endpoint |
| `bizContent.bizType` | M | Fixed value `CodeGrant` |
| `bizContent.device.orderTerminal` | M | Terminal type. `01` H5, `02` PC, `04` iOS App, `05` Android App |
::: warning Important
`merchantResultUrl` is only the buyer return page after agreement completion. It does not prove the agreement succeeded. Use the server-side notification or agreement query result as the source of truth.
:::
Request example:
```json
{
"accId": "2022102018024210348883",
"clientId": "2022102018024210348",
"signType": "SHA256",
"sign": "{{Sign}}",
"version": "1.0",
"bizContent": {
"requestId": "BIND_202606220001",
"merchantUserId": "MEMBER_10001",
"merchantResultUrl": "https://www.example.com/codegrant/result",
"notificationUrl": "https://www.example.com/codegrant/bind-notify",
"bizType": "CodeGrant",
"paymentMethod": {
"type": "AlipayHK"
},
"device": {
"orderTerminal": "02"
}
}
}
```
Response key parameters:
| Field | Description |
|:---|:---|
| `bizContent.token` | Business token associated with the agreement request |
| `bizContent.authUrl` | Wallet agreement page URL that the frontend should open |
Response example:
```json
{
"bizContent": "{\"token\":\"a15b5f3f79c739f39cc551273b542a90\",\"authUrl\":\"https://g.alipayplus.com/page/aplus-linker/acwallet/authorization.html?scopes=AGREEMENT_PAY%2CUSER_LOGIN_ID&bizContent=%7B%22acquirerId%22%3A%22Z02TE5520000000A%22%2C%22authClientDisplayName%22%3A%22ces%22%2C%22authClientId%22%3A%222023121216311410287%22%2C%22authClientName%22%3A%22xiaodian%22%2C%22authRedirectUrl%22%3A%22https%3A%2F%2Fg.alipayplus.com%2Fpage%2Fac-auth-payment%2Fresult%2Fmobile%2Findex.html%3FloadMode%3D2%26callbackType%3DCommon%26terminalType%3DWEB%26referenceAgreementId%3D17821172581855474%26authRequestId%3D2026062219091305000000002861103%26pspId%3D102216000000000000A%26clientId%3DT_4GGO000000000001%22%2C%22authState%22%3A%2217821172581855474%22%2C%22customerBelongsTo%22%3A%22ALIPAY_HK%22%2C%22pspId%22%3A%22102216000000000000A%22%2C%22referenceAgreementId%22%3A%2217821172581855474%22%2C%22referenceMerchantId%22%3A%222023121216311410287%22%2C%22scopes%22%3A%5B%22AGREEMENT_PAY%22%2C%22USER_LOGIN_ID%22%5D%2C%22terminalType%22%3A%22WEB%22%7D&source=AlipayConnect&needCallback=false\"}",
"sign": "08F61A05EA606424B8EA0F97AF2B0773CD3B082733A77A6AEF54BA38309D4572",
"signType": "SHA256"
}
```
::: warning Important
Returning `token` and `authUrl` in the synchronous response does not mean the agreement is already effective. Only use the token for later payments after you receive the [agreement-success notification](/en/notes/notify/bindNotify/APM/accTokenCreation/) or confirm `status=ACTIVE` through the [Binding List Interface](/en/notes/tokenization/oneClickPayment/bindList/).
:::
### Step 2: Redirect the buyer to complete the agreement
After the merchant server receives `authUrl`, return it to the client and open it in the appropriate terminal environment.
::: tabs
@tab Web
```js
function redirectToCodeGrantAuth(authUrl) {
if (!authUrl) return;
const authWindow = window.open(authUrl, '_blank');
if (!authWindow) {
window.location.assign(authUrl);
}
}
```
@tab WAP
```js
function redirectToCodeGrantAuthOnWap(authUrl) {
if (!authUrl) return;
window.location.href = authUrl;
}
```
@tab App (iOS)
```objc
NSURL *url = [NSURL URLWithString:authUrl];
if (url) {
[[UIApplication sharedApplication] openURL:url
options:@{}
completionHandler:^(BOOL success) {
if (!success) {
// Ask the buyer to retry or choose another payment method
}
}];
}
```
@tab App (Android)
```java
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
```
:::
### Step 3: Receive the agreement result and persist the token
After the buyer completes authorization, the merchant can confirm the agreement result through either of the following methods:
1. Receive the agreement result pushed by PingPongCheckout to the `notificationUrl` from the bind request.
2. Actively call `/v4/paymethod/bind/list` to query the agreement result.
In actual integrations, asynchronous notifications are better suited for real-time result delivery, while the agreement query can be used both as an active confirmation method and for scenarios such as delayed notifications, callback-processing exceptions, and result verification. No matter which method is used, the final result should be based on the server-verified notification or query response.
Agreement notification request example:
```json
{
"accId": "2023121216311410287522",
"bizContent": "{\"notifyType\":\"ACCESS_TOKEN_CREATION\",\"payMethod\":\"AlipayHK\",\"merchantUserId\":\"user00001\",\"token\":\"a15b5f3f79c739f39cc551273b542a90\"}",
"clientId": "2023121216311410287",
"sign": "0FFE63EE9CA214DA745131EDAAC15971C7087C9144E87017C4949F015EB55310",
"signType": "SHA256"
}
```
After your service receives the notification, it should return HTTP `2xx` first as the acknowledgement, and then execute the internal processing logic. There is no fixed response-body schema, and the following example shows a common response pattern:
```http
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 2
OK
```
The merchant can also actively call `/v4/paymethod/bind/list` based on its own system design to query the agreement status. This query can be used as a regular confirmation method, and it is also useful for cases such as delayed notifications, callback-processing exceptions, immediate verification after the buyer returns, or routine status checks. Do not treat the frontend return page or the bind API synchronous response as final proof of agreement success.
Agreement query key request parameters:
| Parameter | Description |
|:---|:---|
| `bizContent.token` | Agreement token to confirm. Reuse the token returned by the bind API synchronous response |
| `bizContent.merchantUserId` | Merchant-side user ID. Keep it consistent with the bind request and later payments |
| `bizContent.requestId` | Query request ID. It should be globally unique for tracing and idempotent handling |
Agreement query request example:
```json
{
"accId": "2022102018024210348883",
"clientId": "2022102018024210348",
"signType": "SHA256",
"sign": "{{Sign}}",
"version": "1.0",
"bizContent": {
"token": "a15b5f3f79c739f39cc551273b542a90",
"merchantUserId": "user00001",
"requestId": "2026062217440001"
}
}
```
Agreement query response key parameters:
| Field | Description |
|:---|:---|
| `bizContent.bindInfos[].token` | Agreement token returned by the query and expected to match the requested token |
| `bizContent.bindInfos[].merchantUserId` | Merchant-side user ID bound to this token |
| `bizContent.bindInfos[].payMethod` | Wallet or local payment method bound to the agreement |
| `bizContent.bindInfos[].status` | Agreement status. `ACTIVE` means usable, `INVALID` means no longer usable |
Agreement query response example:
```json
{
"bizContent": "{\"bindInfos\":[{\"bizType\":\"CodeGrant\",\"payMethod\":\"AlipayHK\",\"clientId\":\"2022102018024210348\",\"token\":\"a15b5f3f79c739f39cc551273b542a90\",\"accId\":\"2022102018024210348883\",\"merchantUserId\":\"user00001\",\"status\":\"ACTIVE\"}],\"managementURL\":\"https://sandbox-acquirer-static.pingpongx.com/payment/bindManage/index.html?code=aUW5WtMMzDltikAcGyKxBc746y8R9su6llj98pE6ut4hMDVf5kVZSkfpBqXh6Zi6EPyHdmsfROgdwb1bvp3tO91Me1qm7zfXFqOy7WcxRxOUfuSphTZuJ6MxmzxhzWW1jdgrdfNhDCSWxq_NsbKdVg==\"}",
"code": "001000",
"description": "Successful request",
"sign": "F253140644209B4A5527613FBD31056B8567584E9EF885CE1CB4A25625A14FAA",
"signType": "SHA256"
}
```
Handling recommendations:
1. If `bindInfos` contains the matching token and `status=ACTIVE`, mark the token as active and allow later payment or authorization-cancellation flows.
2. If `status=INVALID`, mark the token as unusable and stop using it for later charges.
3. If no matching record is returned or the state is not yet usable, do not initiate payment yet. Retry the query after a short delay or wait for the agreement notification before confirming.
## Follow-up payment integration
### Step 4: Charge with the saved token
After the agreement succeeds, the merchant server can call [Order Creation and Payment](/en/notes/checkout/api/uniformly/) for follow-up charges. In CodeGrant mode, you usually do not need to collect account details again or display checkout again. The server only needs to pass the saved `token`, `bizType=CodeGrant`, and the same `merchantUserId` used during agreement creation.
Key payment parameters:
| Parameter | Required | Description |
|:---|:---:|:---|
| `bizContent.captureDelayHours` | M | Fixed `0`, meaning immediate capture |
| `bizContent.amount` | M | Transaction amount |
| `bizContent.currency` | M | ISO 4217 currency code |
| `bizContent.requestId` | M | Globally unique payment request ID |
| `bizContent.merchantTransactionId` | M | Merchant order ID |
| `bizContent.notificationUrl` | M | Payment-result notification endpoint |
| `bizContent.payResultUrl` | O | Buyer return page URL |
| `bizContent.shopperIP` | M | Buyer IP address |
| `bizContent.token` | M | Previously activated business token |
| `bizContent.bizType` | M | Fixed `CodeGrant` |
| `bizContent.merchantUserId` | M | Same merchant user ID used during agreement creation |
| `bizContent.paymentMethod.type` | M | Wallet or local-payment method type bound to the token |
| `bizContent.customer.email` | C | Buyer email. Required for physical-goods merchants and some payment methods |
| `bizContent.device.orderTerminal` | M | Terminal type |
Request example:
```json
{
"accId": "2023042011040310224447",
"clientId": "2023042011040310224",
"signType": "SHA256",
"sign": "{{Sign}}",
"version": "1.0",
"bizContent": {
"captureDelayHours": 0,
"amount": 100,
"currency": "HKD",
"requestId": "2026062313592001",
"payResultUrl": "https://www.example.com/codegrant/pay-result",
"notificationUrl": "https://www.example.com/codegrant/pay-notify",
"merchantTransactionId": "2026062313592001",
"shopperIP": "192.168.1.1",
"token": "502e597aa83bf423a3b8ec8484e7301f",
"bizType": "CodeGrant",
"merchantUserId": "user00001",
"paymentMethod": {
"type": "AlipayHK"
},
"customer": {
"email": "buyer@example.com"
},
"device": {
"orderTerminal": "02"
}
}
}
```
Response example:
```json
{
"accId": "2023042011040310224447",
"bizContent": "{\"transactionTime\":\"1782194370000\",\"requestId\":\"PMT-U6Q622OZ7I1782194369342\",\"merchantTransactionId\":\"2026062313592001\",\"action\":{\"type\":\"QR_CODE\"},\"currency\":\"HKD\",\"exchangedAmount\":\"100\",\"payResultUrl\":\"https://www.example.com/codegrant/pay-result\",\"exchangedCurrency\":\"HKD\",\"amount\":\"100\",\"transactionId\":\"26062300000450891549\",\"captureDelayHours\":0,\"status\":\"SUCCESS\"}",
"clientId": "2023042011040310224",
"code": "000000",
"description": "Transaction succeeded",
"sign": "4D294D16A4C91886992B630A1D48809749221CCFCF76D41E0BBADB0A709963FD",
"signType": "SHA256"
}
```
::: warning Important
`merchantUserId` must remain identical to the value used in the agreement request. If it does not match, the token may be treated as non-existent, invalid, or unusable for this buyer.
:::
Synchronous response status:
| `bizContent.status` | Meaning | Handling recommendation |
|:---|:---|:---|
| `SUCCESS` | Synchronous response already succeeded | You may update the order state, but still verify final consistency through notification or query |
| `FAILED` | Payment failed | Record the failure reason and let the buyer retry or use another payment method |
| `PROCESSING` | Payment is still processing | Wait for the notification, and call [Transaction Query](/en/notes/checkout/api/getOne/) if the result is delayed |
### Step 5: Get the payment result
After payment processing, the merchant can obtain the payment result through either of the following methods:
1. Receive the transaction result pushed by PingPongCheckout to the `notificationUrl` from the payment request.
2. Actively call [Transaction Query](/en/notes/checkout/api/getOne/) to query the transaction result.
Payment-result notification example:
```json
{
"clientId": "2023042011040310224",
"code": "000000",
"bizContent": "{\"exchangedCurrency\":\"HKD\",\"amount\":\"100.000000\",\"transactionTime\":\"1782194370000\",\"transactionId\":\"26062300000450891549\",\"token\":\"502e597aa83bf423a3b8ec8484e7301f\",\"notifyType\":\"RECHARGE\",\"transactionEndTime\":\"1782194377229\",\"requestId\":\"PMT-U6Q622OZ7I1782194369342\",\"merchantTransactionId\":\"2026062313592001\",\"paymentMethod\":{\"type\":\"AlipayHK\"},\"currency\":\"HKD\",\"exchangedAmount\":\"100.000000\",\"captureDelayHours\":0,\"status\":\"SUCCESS\"}",
"sign": "8005BA10CFF17D377322423579D0EEBDAA6FA4EE99D4D3FE28CA0BE9D073E68E",
"accId": "2023042011040310224447",
"description": "Transaction succeeded",
"signType": "SHA256"
}
```
If the result is received through an asynchronous notification, your service should return HTTP `2xx` first to acknowledge receipt, and then execute the internal processing logic.
Notification response example:
```http
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 2
OK
```
If the notification is delayed, missed, or if the merchant wants to reconfirm the final status, it can actively call [Transaction Query](/en/notes/checkout/api/getOne/) to query the transaction result. In most cases, `merchantTransactionId` can be used as the query condition.
Transaction query request example:
```json
{
"accId": "2023042011040310224447",
"clientId": "2023042011040310224",
"signType": "SHA256",
"sign": "{{Sign}}",
"version": "1.0",
"bizContent": {
"merchantTransactionId": "2026062313592001"
}
}
```
Transaction query response example:
```json
{
"accId": "2023042011040310224447",
"bizContent": "{\"threeDSecure\":\"\",\"resultCode\":\"000000\",\"transactionTime\":\"1782194370000\",\"requestId\":\"PMT-U6Q622OZ7I1782194369342\",\"merchantTransactionId\":\"2026062313592001\",\"currency\":\"HKD\",\"exchangedAmount\":\"100.000000\",\"resultMessage\":\"Transaction succeeded\",\"exchangedCurrency\":\"HKD\",\"amount\":\"100.000000\",\"transactionEndingTime\":\"1782194377000\",\"transactionId\":\"26062300000450891549\",\"token\":\"502e597aa83bf423a3b8ec8484e7301f\",\"paymentMethod\":{\"type\":\"AlipayHK\"},\"captureDelayHours\":0,\"status\":\"SUCCESS\"}",
"clientId": "2023042011040310224",
"code": "001000",
"description": "Successful request",
"sign": "B2EC288714CFB3F1892ADADFF8C0053C02FE337BDB0F4F9276EC415E0D0DF6EA",
"signType": "SHA256"
}
```
Query response key parameters:
| Field | Description |
|:---|:---|
| `bizContent.merchantTransactionId` | Merchant order ID used to map the transaction back to the merchant order |
| `bizContent.transactionId` | PingPong transaction ID |
| `bizContent.status` | Transaction status that should be used together with server-side notification or query results to confirm the final state |
::: warning Important
Even if the buyer has already returned to `payResultUrl`, you should not directly treat the payment as successful. The server-side result must be the source of truth.
:::
## Cancel authorization
After authorization is completed, the merchant must provide a cancellation entry on the merchant page so the buyer can actively manage the established authorization relationship, for the following reasons:
1. It ensures the buyer can manage the authorization relationship autonomously and cancel an existing authorization at any time based on account-security policies or actual usage needs.
2. Some payment methods have system-level limits, and the same wallet account can usually keep only one or a small number of valid authorization credentials under the same merchant, so the merchant needs to support cancellation of historical authorizations.
### Merchant-side cancellation
If the buyer cancels authorization within your application, you need to call the [Unbind Interface](/en/notes/tokenization/oneClickPayment/unbind/) to invalidate the payment-method token. In addition to the synchronous response, PingPong will also push an authorization-cancellation notification to the `notificationUrl` provided in this request so the final result can be confirmed. See the notification example below for the notification format.
Authorization-cancellation request key parameters:
| Parameter | Description |
|:---|:---|
| `bizContent.merchantUserId` | Merchant-side user ID. It should stay consistent with the bind request and later payments |
| `bizContent.requestId` | Authorization-cancellation request ID |
| `bizContent.token` | Authorization token to invalidate |
| `bizContent.notificationUrl` | Asynchronous notification endpoint for the authorization-cancellation result |
Authorization-cancellation request example:
```json
{
"accId": "2023042011040310224447",
"clientId": "2023042011040310224",
"signType": "SHA256",
"sign": "{{Sign}}",
"version": "1.0",
"bizContent": {
"merchantUserId": "user00001",
"requestId": "202606230338001",
"token": "a15b5f3f79c739f39cc551273b542a90",
"notificationUrl": "https://www.example.com/codegrant/unbind-notify"
}
}
```
Authorization-cancellation response key parameters:
| Field | Description |
|:---|:---|
| `bizContent.token` | Token that has been cancelled |
| `bizContent.merchantUserId` | Merchant-side user ID associated with the token |
| `bizContent.status` | Cancellation result status. `INVALID` means the token has been invalidated |
Response example:
```json
{
"bizContent": "{\"token\":\"a15b5f3f79c739f39cc551273b542a90\",\"merchantUserId\":\"user00001\",\"status\":\"INVALID\"}",
"code": "001000",
"description": "Successful request",
"sign": "03D06D5F9882B8D3410BB1622487ED63F73B0141ED9084823B492CCF903B43F4",
"signType": "SHA256"
}
```
When `bizContent.status=INVALID` in the response, the authorization credential has become invalid and can no longer be used for later CodeGrant payments.
### Payment-method-side cancellation
If the buyer cancels authorization on the payment-method side and the payment method supports authorization-cancellation notifications, you will also receive an authorization-cancellation notification sent by PingPong. PingPong sends this notification to the `notificationUrl` that was provided when creating the bind request through the [Binding Interface](/en/notes/tokenization/oneClickPayment/bind/); if the payment method does not support this capability, no such notification will be sent.
Authorization-cancellation notification example:
```json
{
"accId": "2023042011040310224447",
"bizContent": "{\"notifyType\":\"ACCESS_TOKEN_CANCEL_OF_MERCHANT\",\"payMethod\":\"AlipayHK\",\"merchantUserId\":\"user00001\",\"token\":\"502e597aa83bf423a3b8ec8484e7301f\"}",
"clientId": "2023042011040310224",
"sign": "E5960BAAE68C98506318F8C67D27BD4A347F3236E42FACC28B6A52B77773F171",
"signType": "SHA256"
}
```
After receiving the authorization-cancellation notification, your service should return HTTP `2xx` first to acknowledge receipt, then execute the internal processing logic, and promptly mark the local token state as unusable.
Notification response example:
```http
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 2
OK
```