PageSourceSearch

https://doc.payprotocol.network/assets/js/b53c1645.6b9c96de.js

js payprotocol.network collected 2026-10-04 02:50:10 UTC 41,978 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkdocsite=globalThis.webpackChunkdocsite||[]).push([[6330],{9020:(e,n,s)=>{s.d(n,{A:()=>i});const i=s.p+"assets/images/approve_plan-a6687656d44beb0b6dd6404dad87021a.jpg"},24442:(e,n,s)=>{s.d(n,{A:()=>i});const i=s.p+"assets/images/add_plan-b46ef60ce3fc9e010bfe9c1bfe140dab.jpg"},26350:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"api/quick-start/subscription","title":"Subscription Quick Start","description":"Quick start guide for integrating the subscription feature","source":"@site/docs/api/quick-start/subscription.mdx","sourceDirName":"api/quick-start","slug":"/api/quick-start/subscription","permalink":"/docs/api/quick-start/subscription","draft":false,"unlisted":false,"tags":[],"version":"current","lastUpdatedAt":1788773627000,"sidebarPosition":3,"frontMatter":{"sidebar_position":3,"description":"Quick start guide for integrating the subscription feature"},"sidebar":"apiSidebar","previous":{"title":"Recharge & Withdrawal Quick Start","permalink":"/docs/api/quick-start/recharge"},"next":{"title":"Merchant Integration Guide","permalink":"/docs/api/guide"}}');var r=s(74848),t=s(28453);const c={sidebar_position:3,description:"Quick start guide for integrating the subscription feature",title:void 0},l="Subscription Quick Start",a={},o=[{value:"Process Overview",id:"process-overview",level:2},{value:"1. Overview",id:"1-overview",level:2},{value:"2. Prerequisites",id:"2-prerequisites",level:2},{value:"3. API Signature Authentication",id:"3-api-signature-authentication",level:2},{value:"\ud83d\udd39 Signature Generation Rules",id:"-signature-generation-rules",level:3},{value:"\ud83d\udd39 Request Header Example (HTTPS)",id:"-request-header-example-https",level:3},{value:"\ud83d\udd39 Notes",id:"-notes",level:3},{value:"4. Create a Subscription Plan (Admin Console)",id:"4-create-a-subscription-plan-admin-console",level:2},{value:"\ud83d\udd39 Step 1: Log in to the Admin Console",id:"-step-1-log-in-to-the-admin-console",level:3},{value:"\ud83d\udd39 Step 2: Navigate to Subscription Plans",id:"-step-2-navigate-to-subscription-plans",level:3},{value:"\ud83d\udd39 Step 3: Create a Subscription Plan",id:"-step-3-create-a-subscription-plan",level:3},{value:"\ud83d\udd39 Step 4: Multi-sig Approval",id:"-step-4-multi-sig-approval",level:3},{value:"\ud83d\udd39 Step 5: Plan Created Successfully",id:"-step-5-plan-created-successfully",level:3},{value:"5. Create a Subscription Link (createSubscribeOrder)",id:"5-create-a-subscription-link-createsubscribeorder",level:2},{value:"Request Body Parameters",id:"request-body-parameters",level:3},{value:"Request Example",id:"request-example",level:3},{value:"Request Body Example",id:"request-body-example",level:3},{value:"Response Example",id:"response-example",level:3},{value:"\ud83d\udd39 Build the Subscription Page URL",id:"-build-the-subscription-page-url",level:3},{value:"\ud83d\udd39 Integrate into the Merchant Platform",id:"-integrate-into-the-merchant-platform",level:3},{value:"6. Subscription Callback (subscriptionCallback)",id:"6-subscription-callback-subscriptioncallback",level:2},{value:"\ud83d\udd39 Callback Types",id:"-callback-types",level:3},{value:"\ud83d\udd39 Callback Example",id:"-callback-example",level:3},{value:"\ud83d\udd39 Retry Policy",id:"-retry-policy",level:3},{value:"7. Automatic Billing Flow",id:"7-automatic-billing-flow",level:2},{value:"\ud83d\udd39 Flow Overview",id:"-flow-overview",level:3},{value:"\ud83d\udd39 Query Chargeable Subscription List",id:"-query-chargeable-subscription-list",level:3},{value:"\ud83d\udd39 Call the Signer for Billing",id:"-call-the-signer-for-billing",level:3},{value:"\ud83d\udd39 Billing Response Details",id:"-billing-response-details",level:3},{value:"8. Deploy the Signer",id:"8-deploy-the-signer",level:2},{value:"9. Create an Unsubscription Link (createUnsubscribeOrder)",id:"9-create-an-unsubscription-link-createunsubscribeorder",level:2},{value:"Request Body Parameters",id:"request-body-parameters-1",level:3},{value:"Request Example",id:"request-example-1",level:3},{value:"Request Body Example",id:"request-body-example-1",level:3},{value:"Response Example",id:"response-example-1",level:3},{value:"10. Query Subscription Information",id:"10-query-subscription-information",level:2}];function d(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",img:"img",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"subscription-quick-start",children:"Subscription Quick Start"})}),"\n",(0,r.jsx)(n.h2,{id:"process-overview",children:"Process Overview"}),"\n",(0,r.jsx)(n.mermaid,{value:'%%{init: {"themeVariables": {"fontSize": "22px"}, "flowchart": {"nodeSpacing": 75, "rankSpacing": 90}} }%%\nflowchart TB\n    subgraph Stage1["Stage 1 \xb7 Create Subscription Plan"]\n        direction LR\n        A1[Fill in plan parameters<br/>amount, cycle, trial]\n        A2[Multi-sig approval<br/>two admins sign]\n        A3[Plan goes on-chain<br/>
1planId obtained]\n        A1 --\x3e A2 --\x3e A3\n    end\n\n    subgraph Stage2["Stage 2 \xb7 User Subscription"]\n        direction LR\n        B1[createSubscribeOrder<br/>merchant calls API]\n        B2[Build subscription URL<br/>domain + paymentUrl]\n        B3[User redirected to payment page<br/>connect wallet]\n        B4[Sign agreement<br/>wallet signature confirmation]\n        B5[Authorize deduction allowance<br/>approve on-chain transaction]\n        B6[Callback notification<br/>Register + Approve]\n        B1 --\x3e B2 --\x3e B3 --\x3e B4 --\x3e B5 --\x3e B6\n    end\n\n    subgraph Stage3["Stage 3 \xb7 Periodic Auto-billing"]\n        direction LR\n        C1[Query chargeable subscriptions<br/>merchant scheduled task]\n        C2[Signer billing<br/>EVM / TVM interface]\n        C3[On-chain deduction + callback<br/>SubscriptionBilling]\n        C1 --\x3e C2 --\x3e C3\n        C3 -.next cycle loop.-> C1\n    end\n\n    subgraph Stage4["Stage 4 \xb7 Unsubscription (user-initiated)"]\n        direction LR\n        D1[createUnsubscribe<br/>merchant generates unsubscription link]\n        D2[User cancels authorization<br/>wallet confirmation]\n        D3[Callback notification<br/>SubscriptionCancel]\n        D1 --\x3e D2 --\x3e D3\n    end\n\n    Stage1 --\x3e Stage2 --\x3e Stage3\n    Stage2 -.optional.-> Stage4\n\n    classDef admin fill:#EEEDFE,stroke:#534AB7,color:#3C3489\n    classDef merchant fill:#E1F5EE,stroke:#0F6E56,color:#085041\n    classDef user fill:#FAECE7,stroke:#993C1D,color:#712B13\n    classDef protocol fill:#F1EFE8,stroke:#5F5E5A,color:#2C2C2A\n\n    class A1,A2 admin\n    class A3 protocol\n    class B1,B2 merchant\n    class B3,B4,B5 user\n    class B6 protocol\n    class C1,C2 merchant\n    class C3 protocol\n    class D1 merchant\n    class D2 user\n    class D3 protocol'}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"1-overview",children:"1. Overview"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Subscription"}),': Pay Protocol\'s subscription feature allows merchants to pre-create "subscription plans" in the admin console, then generate dedicated subscription links for users via the API. After being redirected, users complete signing and authorization through their wallets. The merchant then uses the Signer to actively initiate charges at intervals defined by the plan. A callback is triggered for the merchant on each event.']}),"\n",(0,r.jsxs)(n.p,{children:["Flow:\n\ud83d\udc49 Admin console ",(0,r.jsx)(n.strong,{children:"create subscription plan"})," \u2192 Merchant calls ",(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.a,{href:"/docs/api/merchant/create-subscribe-order",children:"createSubscribeOrder"})})," \u2192 Build subscription page URL \u2192 User redirected to complete signing and authorization \u2192 Merchant periodically calls ",(0,r.jsx)(n.strong,{children:"query chargeable subscriptions + Signer billing"})," \u2192 Various ",(0,r.jsx)(n.strong,{children:"subscription callbacks"})," triggered \u2192 Merchant handles."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Note: API request calls require signature authentication"})}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"2-prerequisites",children:"2. Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Register a merchant account: ",(0,r.jsx)(n.a,{href:"https://adm-sandbox.payprotocol.network/signUp",children:"Sandbox registration"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Obtain API Key / Secret: ",(0,r.jsx)(n.a,{href:"/docs/quick-start/get-api-key",children:"Get API Key / Secret"})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Configure a ",(0,r.jsxs)(n.strong,{children:["callback URL (",(0,r.jsx)(n.code,{children:"notifyUrl"}),")"]})," and a ",(0,r.jsxs)(n.strong,{children:["redirect URL (",(0,r.jsx)(n.code,{children:"redirectionUrl"}),")"]})]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"A subscription plan must be created in the admin console in advance (see Step 4 below)"}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Signer service must be deployed"})," (for automatic billing, see Step 8 below)"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Confirm the environment base URL:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Sandbox: ",(0,r.jsx)(n.code,{children:"https://api-sandbox.payprotocol.network/api/mer"})]}),"\n",(0,r.jsxs)(n.li,{children:["Production: ",(0,r.jsx)(n.code,{children:"https://api.payprotocol.network/api/mer"})]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"3-api-signature-authentication",children:"3. API Signature Authentication"}),"\n",(0,r.jsx)(n.p,{children:"All requests must include the following headers:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Header"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"X-PAY-KEY"})}),(0,r.jsx)(n.td,{children:"Merchant API Key"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"X-PAY-TIMESTAMP"})}),(0,r.jsx)(n.td,{children:"Current Unix timestamp in seconds (drift must be \u2264 60 s)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"X-PAY-SIGN"})}),(0,r.jsx)(n.td,{children:'Signature \u2014 see "Signature Generation Rules" below'})]})]})]}),"\n",(0,r.jsx)(n.h3,{id:"-signature-generation-rules",children:"\ud83d\udd39 Signature Generation Rules"}),"\n",(0,r.jsxs)(n.p,{children:["Refer to the official documentation: ",(0,r.jsx)(n.a,{href:"/docs/api/guide/signature",children:"Signature Rules"})]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.strong,{children:"Concatenate the string"})}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"signString = timestamp + method + requestPath + body\n"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"timestamp"}),": Unix timestamp of the request (seconds)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"method"}),": HTTP method, e.g. ",(0,r.jsx)(n.code,{children:"GET"}),", ",(0,r.jsx)(n.code,{children:"POST"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"requestPath"}),": API path without the domain, e.g. ",(0,r.jsx)(n.code,{children:"/api/mer/subscribe/payment/create"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"body"}),": JSON string of the POST request body; empty string for GET requests"]}),"\n"]}),"\n",(0,r.jsxs)(n.ol,{start:"2",children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.strong,{children:"Apply HMAC-SHA256"})}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"HMAC_SHA256(apiSecret, signString)\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"3",children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Base64 encode"})}),"\n",(0,r.jsxs)(n.p,{children:["Base64-encode the hash from the previous step to obtain the final ",(0,r.jsx)(n.code,{children:"X-PAY-SIGN"}),"."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-request-header-example-https",children:"\ud83d\udd39 Request Header Example (HTTPS)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-https",children:"POST /api/mer/subscribe/payment/create\nHost: api-sandbox.payprotocol.network\nContent-Type: application/json\nX-PAY-KEY: <your_api_key>\nX-PAY-TIMESTAMP: 1723971200\nX-PAY-SIGN: <generated_signature>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"-notes",children:"\ud83d\udd39 Notes"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["All POST requests must include ",(0,r.jsx)(n.code,{children:"Content-Type: application/json"})]}),"\n",(0,r.jsxs)(n.li,{children:["The ",(0,r.jsx)(n.code,{children:"timestamp"})," must not differ from server time by more than 60 seconds to prevent replay attacks"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"body"})," must be valid JSON, otherwise signature verification will fail"]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"4-create-a-subscription-plan-admin-console",children:"4. Create a Subscription Plan (Admin Console)"}),"\n",(0,r.jsx)(n.p,{children:"Subscription plans must be created in the admin console in advance. The plan only goes on-chain after multi-sig approval, at which point the merchant can generate subscription links."}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"\ud83d\udca1"})," A subscription plan requires multi-sig approval before it takes effect on-chain. Make sure at least two admin accounts are available."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-step-1-log-in-to-the-admin-console",children:"\ud83d\udd39 Step 1: Log in to the Admin Console"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Sandbox: ",(0,r.jsx)(n.a,{href:"https://adm-sandbox.payprotocol.network/login",children:"https://adm-sandbox.payprotocol.network/login"})]}),"\n",(0,r.jsxs)(n.li,{children:["Production: ",(0,r.jsx)(n.a,{href:"https://adm.payprotocol.network/login",children:"https://adm.payprotocol.network/login"})]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"After logging in, confirm the current chain and wallet address in the top-right corner."}),"\n",(0,r.jsx)(n.h3,{id:"-step-2-navigate-to-subscription-plans",children:"\ud83d\udd39 Step 2: Navigate to Subscription Plans"}
1),"\n",(0,r.jsxs)(n.p,{children:["Top navigation: ",(0,r.jsx)(n.strong,{children:"Payment Tools \u2192 Subscription Plans"})]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Subscription Plans Page",src:s(54724).A+"",width:"1760",height:"269"})}),"\n",(0,r.jsx)(n.h3,{id:"-step-3-create-a-subscription-plan",children:"\ud83d\udd39 Step 3: Create a Subscription Plan"}),"\n",(0,r.jsxs)(n.p,{children:['Click the "',(0,r.jsx)(n.strong,{children:"Add"}),'" button, fill in the plan parameters, and click "',(0,r.jsx)(n.strong,{children:"Submit"}),'".\nA Signature request will appear in the wallet \u2014 verify the parameters and click Confirm to complete the first signature.']}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Add Plan",src:s(24442).A+"",width:"1671",height:"866"})}),"\n",(0,r.jsx)(n.admonition,{type:"info",children:(0,r.jsx)(n.p,{children:"The plan ID must be filled in by the merchant. It must be unique and immutable on the merchant side (numeric IDs only). This plan ID is required for subsequent API calls."})}),"\n",(0,r.jsx)(n.h3,{id:"-step-4-multi-sig-approval",children:"\ud83d\udd39 Step 4: Multi-sig Approval"}),"\n",(0,r.jsxs)(n.p,{children:["Switch to ",(0,r.jsx)(n.strong,{children:"another admin account"}),", log in to the admin console, go to ",(0,r.jsx)(n.strong,{children:"Payment Tools \u2192 Subscription Plans"}),", initiate approval for the plan, and sign again with the wallet."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Multi-sig Approval",src:s(9020).A+"",width:"1865",height:"891"})}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The plan parameters only take effect on-chain after multi-sig approval passes. Before approval, the plan is in a pending state and cannot be used."})}),"\n",(0,r.jsx)(n.h3,{id:"-step-5-plan-created-successfully",children:"\ud83d\udd39 Step 5: Plan Created Successfully"}),"\n",(0,r.jsxs)(n.p,{children:['After multi-sig approval, the plan status changes to "',(0,r.jsx)(n.strong,{children:"Active"}),'" and can be used by the merchant to create subscription links. ',(0,r.jsx)(n.strong,{children:"Record the plan ID"})," \u2014 it is required for subsequent API calls."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Multi-sig Success",src:s(66481).A+"",width:"1680",height:"275"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"5-create-a-subscription-link-createsubscribeorder",children:"5. Create a Subscription Link (createSubscribeOrder)"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"/docs/api/merchant/create-subscribe-order",children:"createSubscribeOrder API Reference"})}),"\n",(0,r.jsx)(n.h3,{id:"request-body-parameters",children:"Request Body Parameters"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Parameter"}),(0,r.jsx)(n.th,{children:"Type"}),(0,r.jsx)(n.th,{children:"Required"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"chainId"})}),(0,r.jsx)(n.td,{children:"int32"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"Platform chain ID, obtainable from the chain list API"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"planId"})}),(0,r.jsx)(n.td,{children:"int64"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"Subscription plan ID"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"externalUserId"})}),(0,r.jsx)(n.td,{children:"string"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"Merchant-side user identifier"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"redirectionUrl"})}),(0,r.jsx)(n.td,{children:"uri"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"URL to redirect the user to after successful subscription"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"notifyUrl"})}),(0,r.jsx)(n.td,{children:"uri"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"Merchant callback URL \u2014 must be a publicly accessible HTTPS address"})]})]})]}),"\n",(0,r.jsx)(n.h3,{id:"request-example",children:"Request Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-https",children:"POST /api/mer/subscribe/payment/create\nHost: api-sandbox.payprotocol.network\nContent-Type: application/json\nX-PAY-KEY: your_api_key\nX-PAY-TIMESTAMP: 1723971200\nX-PAY-SIGN: RlpTCwGT7lECP7achGM4oqT+Y5fXYjOqTRAJ9VPdY2U=\n"})}),"\n",(0,r.jsx)(n.h3,{id:"request-body-example",children:"Request Body Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "chainId": 1,\n  "planId": 3,\n  "externalUserId": "USER10001",\n  "redirectionUrl": "https://merchant.com/subscribe-success",\n  "notifyUrl": "https://merchant.com/api/subscription-callback"\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"response-example",children:"Response Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "code": 200,\n  "msg": "success",\n  "data": {\n    "subscriptionId": 123,\n    "paymentUrl": "/subscription?apiSign=CSetiUau5zInfAZukEGsSfelBSmlVB3XVh5t7Ozoits%3D",\n    "expiration": 1723974800\n  }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:"Notes:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"paymentUrl"})," \u2192 Subscription page path \u2014 ",(0,r.jsx)(n.strong,{children:"must be prepended with the official domain"})," before use"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"subscriptionId"})," \u2192 Pay Protocol subscription order ID (save for later queries)"]}
1),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"expiration"})," \u2192 Link expiration timestamp"]}),"\n"]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"\ud83d\udca1"})," There is no need to pre-create a sub-contract address for users before subscribing. Users simply connect their wallet on the subscription page to complete signing. ",(0,r.jsx)(n.code,{children:"externalUserId"})," serves only as the merchant-side user identifier."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-build-the-subscription-page-url",children:"\ud83d\udd39 Build the Subscription Page URL"}),"\n",(0,r.jsxs)(n.p,{children:["The returned ",(0,r.jsx)(n.code,{children:"paymentUrl"})," is a relative path. It must be prepended with the Pay Protocol official domain:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Production:"})," ",(0,r.jsx)(n.code,{children:"https://payment.payprotocol.network"})," + ",(0,r.jsx)(n.code,{children:"paymentUrl"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Sandbox:"})," ",(0,r.jsx)(n.code,{children:"https://payment-sandbox.payprotocol.network"})," + ",(0,r.jsx)(n.code,{children:"paymentUrl"})]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Example:\n",(0,r.jsx)(n.code,{children:"https://payment.payprotocol.network/subscription?apiSign=CSetiUau5zInfAZukEGsSfelBSmlVB3XVh5t7Ozoits%3D"})]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["Never use the raw ",(0,r.jsx)(n.code,{children:"paymentUrl"})," returned by the API directly. Always prepend the official domain to avoid misuse or security risks."]})}),"\n",(0,r.jsx)(n.h3,{id:"-integrate-into-the-merchant-platform",children:"\ud83d\udd39 Integrate into the Merchant Platform"}),"\n",(0,r.jsxs)(n.p,{children:['Add the assembled URL to your subscription platform \u2014 for example, a "',(0,r.jsx)(n.strong,{children:"Pay with USDT"}),'" button:']}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-html",children:'<a href="https://payment.payprotocol.network/subscription?apiSign=...">\n  Pay with USDT\n</a>\n'})}),"\n",(0,r.jsxs)(n.p,{children:["When the user clicks the button, they are redirected to the Pay Protocol subscription page to complete the ",(0,r.jsx)(n.strong,{children:"confirm plan \u2192 sign agreement \u2192 authorize allowance"})," three-step flow."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"User Subscription",src:s(77719).A+"",width:"879",height:"802"})}),"\n",(0,r.jsxs)(n.admonition,{type:"warning",children:[(0,r.jsx)(n.p,{children:"\ud83d\udca1 In the sandbox environment, you can claim test tokens to simulate subscription transactions:"}),(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["Follow the ",(0,r.jsx)(n.a,{href:"/docs/quick-start/get-test-tokens",children:"Test Token Faucet Guide"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Based on the selected chain (Tron Nile or Ethereum Sepolia), open the corresponding official faucet website."}),"\n",(0,r.jsx)(n.li,{children:"Enter your test wallet address and claim test tokens (USDT, ETH, TRX, etc.)."}),"\n",(0,r.jsxs)(n.li,{children:["Use the claimed test tokens to subscribe via the generated ",(0,r.jsx)(n.code,{children:"paymentUrl"})," and complete the subscription flow test."]}),"\n"]}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.em,{children:(0,r.jsx)(n.strong,{children:"Note: All testnet tokens are only valid in the sandbox environment and have no real value."})})}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.em,{children:(0,r.jsx)(n.strong,{children:"Note: Testnets and mainnets are completely independent blockchain networks. Never send mainnet assets to a testnet address, or vice versa."})})})]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"6-subscription-callback-subscriptioncallback",children:"6. Subscription Callback (subscriptionCallback)"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"/docs/api/merchant/subscription-callback",children:"subscriptionCallback API Reference"})}),"\n",(0,r.jsxs)(n.p,{children:["Pay Protocol asynchronously POSTs to ",(0,r.jsx)(n.code,{children:"notifyUrl"}),". Upon receiving a callback, the merchant must:"]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["Verify that the ",(0,r.jsx)(n.code,{children:"sign"})," signature is valid"]}),"\n",(0,r.jsxs)(n.li,{children:["Handle the corresponding business logic based on ",(0,r.jsx)(n.code,{children:"subscriptionType"})]}),"\n",(0,r.jsxs)(n.li,{children:["Return HTTP 200 with the body ",(0,r.jsx)(n.code,{children:"success"})," to acknowledge receipt"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-callback-types",children:"\ud83d\udd39 Callback Types"}),"\n",(0,r.jsxs)(n.p,{children:["Use the ",(0,r.jsx)(n.code,{children:"subscriptionType"})," field to distinguish callback types:"]}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"subscriptionType"}),(0,r.jsx)(n.th,{children:"Trigger"}),(0,r.jsx)(n.th,{children:"Recommended Merchant Action"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SubscriptionRegister"})}),(0,r.jsx)(n.td,{children:"User completes signing on the subscription page"}),(0,r.jsx)(n.td,{children:"Record subscription relationship, mark user as signed"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SubscriptionApprove"})}),(0,r.jsx)(n.td,{children:"User completes wallet authorization"}),(0,r.jsx)(n.td,{children:"Mark authorization status, subscription becomes active"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SubscriptionBilling"})}),(0,r.jsx)(n.td,{children:"Each periodic deduction completes (incl. first)"}),(0,r.jsx)(n.td,{children:"Update subscription validity period, grant entitlements"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SubscriptionCancel"})}),(0,r.jsx)(n.td,{children:"User actively unsubscribes"}),(0,r.jsx)(n.td,{children:"Mark subscription as cancelled, stop further services"})]})]})]}),"\n",(0,r.jsx)(n.h3,{id:"-callback-example",children:"\ud83d\udd39 Callback Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "subscriptionType": "SubscriptionBilling",\n  "outTradeNo": "SUB202508191519455758358",\n  "externalUserId": "USER10001",\n  "planId": 3,\n  "planVersion": 1,\n  "chainId": 1,\n  "userWallet": "0xF631...90A9",\n  "amount": "1000000",\n  "currencySymbol": "USDT",\n  "transferHash": "0x928b3243...",\n  "blockTime": 1712122830,\n  "createTime": "2025-08-19 15:19:45"\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"-retry-policy",children:"\ud83d\udd39 Retry Policy"}),"\n",(0,r.jsxs)(n.p,{children:["Callbacks are sent up to ",(0,r.jsx)(n.strong,{children:"6 times"})," after the event is confirmed, at intervals of ",(0,r.jsx)(n.strong,{children:"0 s, 15 s, 30 s, 3 min, 5 min, and 10 min"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Once the merchant returns ",(0,r.jsx)(n.code,{children:"success"}),", the system considers the callback successful and stops further retries."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"\ud83d\udccc"})," Merchants must verify the signature of the callback notification. The signing method is the same as for regular API requests."]}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"7-automatic-billing-flow",children:"7. Automatic Billing Flow"}),"\n",(0,r.jsxs)(n.p,{children:["After the subscription is created and the user has completed authorization, the merchant must ",(0,r.jsx)(n.strong,{children:"actively invoke the billing flow"}
1)," to trigger periodic charges. The overall flow consists of two steps: ",(0,r.jsx)(n.strong,{children:"query chargeable subscriptions \u2192 call the Signer to bill"}),". The Signer automatically broadcasts the transaction on-chain; no manual handling is required from the merchant."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"\ud83d\udca1"})," The call frequency is up to the merchant and should be triggered according to actual business needs (e.g. hourly or daily scheduled tasks)."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-flow-overview",children:"\ud83d\udd39 Flow Overview"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"Merchant scheduled task\n\u2193\n1. getChargeableSubscriptionList \u2014 query chargeable subscriptions\n\u2193\n2. signProcessSubscribePlan \u2014 call Signer for billing (EVM or TVM depending on chain)\n\u2193\nSuccess \u2192 Signer auto-broadcasts on-chain \u2192 SubscriptionBilling callback (success)\nFailure \u2192 Returns failure reason \u2192 SubscriptionBilling callback (failure)\n"})}),"\n",(0,r.jsx)(n.h3,{id:"-query-chargeable-subscription-list",children:"\ud83d\udd39 Query Chargeable Subscription List"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"/docs/api/merchant/get-chargeable-subscription-list",children:"getChargeableSubscriptionList API Reference"})}),"\n",(0,r.jsx)(n.p,{children:"The merchant calls this interface on a schedule to retrieve the list of subscriptions due for billing."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-https",children:"GET /api/mer/subscribe/chargeable/list?page=1&size=20\nHost: api-sandbox.payprotocol.network\nX-PAY-KEY: your_api_key\nX-PAY-TIMESTAMP: 1723971200\nX-PAY-SIGN: <generated_signature>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Each subscription in the returned list contains ",(0,r.jsx)(n.code,{children:"subscribeId"})," and the necessary on-chain information, which serve as inputs for the next Signer call."]}),"\n",(0,r.jsx)(n.h3,{id:"-call-the-signer-for-billing",children:"\ud83d\udd39 Call the Signer for Billing"}),"\n",(0,r.jsxs)(n.admonition,{type:"warning",children:[(0,r.jsx)(n.p,{children:"The Signer interface to call differs by chain:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"EVM chains (ETH):"})," ",(0,r.jsx)(n.code,{children:"POST /PayTool/EVM/subscribe/signProcessSubscribePlan"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"TVM chains (TRON):"})," ",(0,r.jsx)(n.code,{children:"POST /PayTool/TVM/subscribe/signProcessSubscribePlan"})]}),"\n"]})]}),"\n",(0,r.jsx)(n.p,{children:"API References:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/docs/api/signer/sign-evm-subscribe",children:"Sign EVM Subscription Billing"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/docs/api/signer/sign-tvm-subscribe",children:"Sign TVM Subscription Billing"})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Pass the queried chargeable subscription data to the Signer. The Signer will complete the ",(0,r.jsx)(n.strong,{children:"sign + auto-broadcast"})," flow entirely."]}),"\n",(0,r.jsx)(n.h3,{id:"-billing-response-details",children:"\ud83d\udd39 Billing Response Details"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\u2705 Billing Successful (code = 1)"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "code": 1,\n  "msg": "SUCCESS",\n  "data": {\n    "address": "0xf0d2db2740ca0cd94e76c1af85fc9e5ef88ee011",\n    "chainId": 139,\n    "gasRequired": "117803",\n    "signedTransactionData": "0xf8cc3983e441a88301cc2b943e8d3c579817fa235901096c64107c8c8867554f80b86452429e7f...",\n    "subscriptionIds": [49],\n    "txHash": "0xe222a81f39b38cc50a14a3539086066bcf4d0a2582dc5a81abab27ef158f4ed9"\n  },\n  "description": null\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:"Field descriptions:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"signedTransactionData"})," \u2192 Signed transaction data (the Signer broadcasts it automatically; no merchant action needed)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"subscriptionIds"})," \u2192 List of subscription IDs covered by this billing"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"txHash"})," \u2192 On-chain transaction hash (useful for tracking and reconciliation)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"gasRequired"})," \u2192 Gas consumed by this transaction"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["After a successful billing, simply wait for Pay Protocol to trigger the ",(0,r.jsx)(n.code,{children:"SubscriptionBilling"})," callback."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\u274c Billing Failed (code = 2)"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "code": 2,\n  "msg": "SUCCESS",\n  "data": [\n    {\n      "amount": 8000000,\n      "failReason": "Allowance insufficient",\n      "planId": 6,\n      "subscribeId": 44,\n      "tokenAllowance": "0",\n      "tokenBalance": "944000000",\n      "userHash": "0xde1469a7d688f10c46f3a25f12c23bce48dfc52f999031664cca22df931a4382"\n    }\n  ],\n  "description": null\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The response array lists each subscription that could not be charged along with the specific reason. Common ",(0,r.jsx)(n.code,{children:"failReason"})," values:"]}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"failReason"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Recommended Merchant Action"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"Allowance insufficient"})}),(0,r.jsx)(n.td,{children:"User's authorized allowance is low"}),(0,r.jsx)(n.td,{children:"Guide user to re-authorize or unsubscribe"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"Balance insufficient"})}),(0,r.jsx)(n.td,{children:"User's wallet balance is too low"}),(0,r.jsx)(n.td,{children:"Notify user to top up or suspend the service"})]})]})]}),"\n",(0,r.jsxs)(n.p,{children:["Regardless of success or failure, Pay Protocol will send a ",(0,r.jsx)(n.code,{children:"subscriptionType=SubscriptionBilling"})," callback to the merchant's ",(0,r.jsx)(n.code,{children:"notifyUrl"}),". Merchants must use this to ",(0,r.jsx)(n.strong,{children:"update subscription status, grant services, or stop entitlements"}),". See Section 6 above for callback handling logic."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"8-deploy-the-signer",children:"8. Deploy the Signer"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"/docs/api/signer/signer",children:"Signer Deployment Documentation"})}),"\n",(0,r.jsxs)(n.p,{children:["The Signer is a service for ",(0,r.jsx)(n.strong,{children:"securely managing private keys and signing on-chain transactions"}),". It is deployed and operated by the merchant. Automatic subscription billing depends on the Signer to complete signing and broadcasting."]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The Signer must be fully deployed and running before the billing flow is invoked."})}),"\n",(0,r.jsx)(n.p,{children:"Once deployed, the Signer exposes HTTP interfaces for the merchant to call:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Sign EVM subscription billing: ",(0,r.jsx)(n.code,{children:"POST /PayTool/EVM/subscribe/signProcessSubscribePlan"})]}),"\n",(0,r.jsxs)(n.li,{children:["Sign TVM subscription billing: ",(0,r.jsx)(n.code,{children:"POST /PayTool/TVM/subscribe/signProcessSubscribePlan"})]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["For the full list of Signer interfaces, see: ",(0,r.jsx)(n.a,{href:"/docs/category/api/signer/api-reference",children:"Signer API Reference"})]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"9-create-an-unsubscription-link-createunsubscribeorder",children:"9. Create an Unsubscription Link (createUnsubscribeOrder)"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"/docs/api/merchant/create-unsubscribe-order",children:"createUnsubscribeOrder API Reference"})}),"\n",(0,r.jsx)(n.h3,{id:"request-body-parameters-1",children:"Request Body Parameters"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Parameter"}),(0,r.jsx)(n.th,{children:"Type"}),(0,r.jsx)(n.th,{children:"Required"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"outTradeNo"})}),(0,r.jsx)(n.td,{children:"string"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"Pay Protocol subscription order ID"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"redirectionUrl"})}),(0,r.jsx)(n.td,{children:"uri"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"URL to redirect the user to after successful unsubscription"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"notifyUrl"})}),(0,r.jsx)(n.td,{children:"uri"}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"Merchant callback URL \u2014 must be a publicly accessible HTTPS address"})]})]})]}),"\n",(0,r.jsx)(n.h3,{id:"request-example-1",children:"Request Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-https",children:"POST /api/mer/subscribe/cancel/create\nHost: api-sandbox.payprotocol.network\nContent-Type: application/json\nX-PAY-KEY: your_api_key\nX-PAY-TIMESTAMP: 1723971200\nX-PAY-SIGN: <generated_signature>\n"})}),"\n",(0,r.jsx)(n.h3,{id:"request-body-example-1",children:"Request Body Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "outTradeNo": "SUB202508191519455758358",\n  "redirectionUrl": "https://merchant.com/unsub
1scribe-success",\n  "notifyUrl": "https://merchant.com/api/subscription-callback"\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"response-example-1",children:"Response Example"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "code": 200,\n  "msg": "success",\n  "data": {\n    "paymentUrl": "/unsubscription?apiSign=...",\n    "expiration": 1723974800\n  }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:"The URL assembly rules for unsubscription links are the same as for subscription links:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Production:"})," ",(0,r.jsx)(n.code,{children:"https://payment.payprotocol.network"})," + ",(0,r.jsx)(n.code,{children:"paymentUrl"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Sandbox:"})," ",(0,r.jsx)(n.code,{children:"https://payment-sandbox.payprotocol.network"})," + ",(0,r.jsx)(n.code,{children:"paymentUrl"})]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:['Provide the assembled URL to the user (e.g. a "',(0,r.jsx)(n.strong,{children:"Cancel Subscription"}),"\" button on the merchant's subscription management page). The user is redirected to cancel their wallet authorization and complete unsubscription."]}),"\n",(0,r.jsxs)(n.p,{children:["After unsubscription, the merchant will receive a ",(0,r.jsx)(n.code,{children:"subscriptionType=SubscriptionCancel"})," callback notification."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"10-query-subscription-information",children:"10. Query Subscription Information"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/docs/api/merchant/get-subscription-list",children:"Get Subscription List"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/docs/api/merchant/get-chargeable-subscription-list",children:"Get Chargeable Subscription List"})}),"\n"]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:["\u2705 You have now completed the ",(0,r.jsx)(n.strong,{children:"full subscription integration flow"}),":"]}),"\n",(0,r.jsx)(n.mermaid,{value:"flowchart LR\n    A[Create Subscription Plan] --\x3e B[Generate Subscription Link]\n    B --\x3e C[User Signs & Authorizes]\n    C --\x3e D[Periodic Billing]\n    D --\x3e E[Callback Confirmation]\n    E --\x3e F[Query Status]"})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>l});var i=s(96540);const r={},t=i.createContext(r);function c(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),i.createElement(t.Provider,{value:n},e.children)}},54724:(e,n,s)=>{s.d(n,{A:()=>i});const i=s.p+"assets/images/subscription_plan-f2320e4b750b521e8181e8a9a216655c.jpg"},66481:(e,n,s)=>{s.d(n,{A:()=>i});const i=s.p+"assets/images/plan_added-80ed27e8251840b786002556039e30d6.jpg"},77719:(e,n,s)=>{s.d(n,{A:()=>i});const i=s.p+"assets/images/user_subscribe-48e454a0226434feac836ef5a93666e7.jpg"}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.