billing

POST /v1/payment-methods/paypal/confirm

Finish saving a PayPal account after the buyer approved it.

All billing endpoints

All developer docs

Authentication

Send an API key as a bearer token. This endpoint does not state a specific permission in the specification, so give your key the least it needs and check the response rather than assuming.

Where your organisation id goes

This endpoint takes org_id as a field in the JSON body.

Your organisation id is on the API keys screen in your dashboard, beside the key itself. It is the same id in every call you make.

Try it

Replace anything in angle brackets with your own values, and the key placeholder with a key from your dashboard.

curl -X POST https://api.zinndigital.com/v1/payment-methods/paypal/confirm \
  -H "Authorization: Bearer zdk_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "setup_token_id": <string> }'

Signed in? The API console in your dashboard fills in your real organisation id and your own key, and runs the request against the live API so you can see the actual response. Open this endpoint in the API console

Details

Exchanges an approved setup token for the permanent vault token and stores the mandate. The organization is read from PayPal's answer and must match the caller's, so a setup token belonging to another account cannot be attached here. Idempotent, and it deliberately races PayPal's VAULT.PAYMENT-TOKEN.CREATED webhook: whichever arrives first writes the mandate and the other converges on it, so a buyer whose browser never returns still ends up with a saved method.

Request body

NameTypeRequiredWhat it is
setup_token_idstringYesThe setup_token_id returned by POST /v1/payment-methods/paypal.
org_idstringNoOrganization to attach the mandate to. The caller must hold billing.payment.manage in that organization, and PayPal's own answer must name the same organization.

Response

NameTypeRequiredWhat it is
idstringYes
gatewaystring<stripe, paypal>YesThe rail holding the mandate. Crypto (NOWPayments) is absent by design — it has no mandate primitive, so those customers are invoiced ahead rather than rebilled (ADR 0011 §6).
statusstring<pending, active, expired, revoked>YesOnly active is chargeable; pending means the gateway has not confirmed it yet.
rolestring<, primary, backup>YesWhich job this mandate does for the organisation. primary is charged first; backup is charged immediately if the primary declines; "" is simply stored. ⛔ Replaced…
removal_blocked_bystring<, subscription, adhoc_charge, reseller_programme>YesEmpty when this method may be removed. Otherwise the obligation that keeps the floor binding: this is the account's last operational way to pay and the named thing is still…
method_typestringYesThe gateway's own name for what kind of mandate this is — Stripe's PaymentMethod.type (card, sepa_debit, klarna, kakao_pay, …). Empty on a rail that does not type its…
can_auto_renewbooleanYesWhether this mandate can be charged off-session, i.e. whether a renewal can be taken without the customer present. false means the subscription renews manually: the…
brandstringYes
last4stringYes
exp_monthintegerNo
exp_yearintegerNo
holder_namestringNo
confirmed_atstringNoWhen the gateway confirmed the mandate. Null while pending.
created_atstringYes

Errors this endpoint can return

401 · 403 · 409 · 422 · 429 · 503