APIs integration

Subscriptions

Subscriptions bill a customer's card on a schedule (weekly, monthly, or yearly) after a one-time tokenization step: the customer authorizes their card once on the gateway's hosted page, and the gateway then executes the scheduled charges. Your site never sees the card.

Requirements

  • A subscription product: an approved product with all three recurring fields set — recurring_frequency (WEEKLY | MONTHLY | YEARLY), recurring_intervals, recurring_total_execution_times. Managed in the Merchant Portal like any product.
  • Product currency must be HKD.
  • Your merchant must have the CreditCard network enabled (subscriptions are card-only).
  • Exactly one product per enrollment — subscription products can't be mixed into an ordinary cart. (/pa/checkout rejects carts containing recurring products.)
  • The schedule starts on the next calendar day in Asia/Hong_Kong.
  • One extra callback endpoint on your site: a payment notify URL that receives each recurring execution result for the life of the schedule.

Enrollment flow

1. Create the subscription intent

Same endpoint as ordinary checkout, different intent_details:

curl -X POST "$BASE/intent" -H "..." -H "Content-Type: application/json" -d '{
  "customer_id": 42,
  "store_id": 12,
  "currency": "HKD",
  "amount": "29.90",
  "status": "C",
  "reference": "5c1d33f7-9d21-4c8a-b7ee-91d5a1b7cdef",
  "intent_details": "{\"source\":\"my_site_subscription\",\"merchant_reference\":\"5c1d33f7-9d21-4c8a-b7ee-91d5a1b7cdef\",\"checkout_kind\":\"subscription\",\"payment_network\":\"CreditCard\",\"subscription\":{\"product_id\":301,\"quantity\":1},\"line_items\":[{\"product_id\":301,\"quantity\":1,\"unit_amount\":\"29.90\",\"amount\":\"29.90\"}],\"subject\":\"Subscription Example Plan\"}"
}'

amount is the per-execution charge (unit price × quantity). Note checkout_kind: "subscription" and the single-line snapshot.

2. Request the tokenization launch

curl -X POST "$BASE/recurring/checkout" -H "..." -H "Content-Type: application/json" -d '{
  "intent_identifier": "1a2b3c4d-....",
  "customer_ip": "203.0.113.10",
  "return_url": "https://shop.example.com/pingbiz/sub/return/1a2b3c4d-....",
  "notify_url": "https://shop.example.com/pingbiz/sub/notify/1a2b3c4d-....",
  "payment_notify_url": "https://shop.example.com/pingbiz/sub/payment-notify",
  "subject": "Subscription Example Plan",
  "token_valid_date": "2027-08-14"
}'
Field Required Notes
intent_identifier Yes The subscription intent from step 1.
customer_ip Yes The customer's IP address.
return_url Yes Browser return after tokenization.
notify_url Yes Server-to-server tokenization result.
payment_notify_url Yes Server-to-server endpoint for every future execution — must stay live for the whole schedule.
subject No Statement/display subject.
token_valid_date No Card-token expiry hint forwarded to the gateway (YYYY-MM-DD).

A successful response has accepted: true and a redirect_link (top-level, or under normalized_provider_result.redirect_link / provider_response.payload.redirect_link — check in that order). Redirect the customer's browser to it.

3. Record the tokenization result

When the gateway calls your subscription notify_url (or the browser returns with a signed payload), forward it:

curl -X POST "$BASE/recurring/tokenization/record" -H "..." -H "Content-Type: application/json" -d '{
  "intent_identifier": "1a2b3c4d-....",
  "payload": { "...raw gateway payload..." }
}'
{
  "ok": true,
  "checkout": {
    "order_id": 123,
    "status": "COMPLETE",
    "idempotent": false,
    "order_items": [ { "recurring_status": "ACTIVE", "recurring_merchant_reference": "…" } ]
  }
}

On verified acceptance, Ping Business creates the order with exactly one order item carrying the schedule — no one-time Payment row is created for enrollment. The endpoint is idempotent; forward duplicates safely.

Confirm enrollment the same way as ordinary checkout: poll GET /intents?identifier=... for S, then read the order item and require recurring_status: "ACTIVE" and a non-empty recurring_merchant_reference before showing "subscribed".

Recurring executions

Each time the gateway executes a scheduled charge, it POSTs to your payment_notify_url. Forward every one:

curl -X POST "$BASE/recurring/payment/record" -H "..." -H "Content-Type: application/json" -d '{
  "payload": { "...raw gateway payload..." }
}'
{
  "ok": true,
  "recurring_payment": {
    "id": 801,
    "order_item_id": 901,
    "execution_number": 2,
    "amount": "29.90",
    "currency": "HKD",
    "status": "SUCCESS",
    "idempotent": false
  }
}

Ping Business verifies the signature, matches the schedule by its merchant reference, and records the execution idempotently. Use these results to grant/extend the customer's entitlement each period.

Subscription state

The order item is the durable view of a subscription:

recurring_status Meaning
PENDING Enrollment started, schedule not yet accepted.
ACTIVE Schedule accepted; executions will occur.
CANCELLED Schedule cancelled.
COMPLETED All executions finished.
ERROR Provider reported a schedule error.
UNKNOWN State couldn't be determined — reconcile.

subscription_details on the order item carries sanitized audit data (raw card/tokenization material is never returned). Read schedules with GET /order_items and watch recurring_status + execution results from your payment_notify_url.