The end-to-end flow for handing a customer to Topiic's PCI-safe card-capture page and receiving them back via webhook.
Hosted checkout is the recommended way to onboard a paying customer. Your product handles the “Subscribe” click; Topiic handles the rest — contact confirmation, secure card capture, and provisioning of the member + payment method + subscription. You get a signed webhook when it’s done.
The card number never touches your server, so you stay out of PCI scope.
What “success” means
Section titled “What “success” means”A successful hosted checkout produces three things on Topiic’s side:
- A Member (created or updated from the contact details).
- A PaymentMethod with the card token from the gateway.
- An active Subscription on the merchant’s chosen Plan, billed against that payment method.
The checkout.completed webhook fires once all three exist. Topiic does not wait for the first charge to clear before firing — if a trial period is configured the first charge may be days away.
If anything fails, checkout.failed fires with a failureReason.
End-to-end flow
Section titled “End-to-end flow”sequenceDiagram
autonumber
participant U as User browser
participant S as Your server
participant T as Topiic
participant G as Gateway
U->>S: Click "Subscribe"
S->>S: Build signed deep link (HMAC)
S-->>U: 303 redirect → /c?d=…&s=…
U->>T: GET /c?d=…&s=…
T->>T: Verify HMAC, mint session JWT
U->>T: Confirm contact details
T->>G: Init capture
G-->>T: Iframe URL
U->>G: Enter card in gateway iframe
G-->>T: Card token
T->>T: Create Member + PaymentMethod + Subscription, enqueue webhook
T-->>U: 303 redirect → ret URL
U->>S: GET ret URL?status=ok
T-)S: Webhook POST (signed)
S->>S: Verify signature, mark customer subscribed
The numbers map to the steps in the Quickstart.
The signed deep link
Section titled “The signed deep link”https://pay.topiic.com/c?d=<base64url(payload)>&s=<base64url(HMAC-SHA256(secret, d))>The payload identifies:
- Which integration (
akid— your API key id) — Topiic uses this to find the signing secret to verify the signature. - Which merchant + plan (
mid,plan). - Who the customer is on your side (
ref) — echoed in the webhook so you can match. - Optional prefill contact (
contact) — pre-fills the contact form so the user only confirms. - Where to send them back (
ret). - Which events to subscribe to (
evts). - Replay protection (
nonce— single-use;exp— Unix timestamp expiry).
See Signing deep links for the full schema, signing algorithm, and code samples.
How Topiic validates the link
Section titled “How Topiic validates the link”When the browser hits pay.topiic.com/c, Topiic verifies the HMAC, checks that the merchant + plan are valid, confirms the link hasn’t expired, and rejects any nonce that’s already been used. If anything fails the user sees a friendly error page and your server is not notified.
A breakdown of the possible error responses — useful when you’re testing your link builder — lives in the deep-link signing reference.
What the user sees
Section titled “What the user sees”- Contact step — prefilled from
contactin the payload; user confirms or edits. - Payment step — the secure card-capture form. The card never touches Topiic — it’s tokenised by the payment gateway directly from the browser.
- Completion — brief “Activating your subscription…” then redirect to
ret.
If the user clicks Cancel, the session ends and a checkout.failed webhook fires.
Branding & UX
Section titled “Branding & UX”The hosted page uses Topiic’s brand colours and merchant name. Per-merchant theming (custom logo / accent colour) is on the roadmap but not in v1.
What you should never do
Section titled “What you should never do”- Don’t parse the
retURL’s?status=to decide whether the customer is subscribed. The webhook is the source of truth — the return URL is a UX cue and can be reached even when provisioning failed. - Don’t poll any Topiic endpoint waiting for the subscription to appear. Use the webhook.
- Don’t mint a deep link in browser JavaScript. The signing secret must stay server-side.
- Don’t reuse a
nonce. Generate a fresh random value (≥16 bytes) for every link.
- Signing deep links — payload schema + code.
- Handling the return URL — what to do after the user comes back.
- Webhooks overview — how the event reaches you.