Skip to content

Hosted checkout

import { Steps } from ‘@astrojs/starlight/components’;

Hosted checkout is the path you’ll use for real customers. You create a session server-side; Trile hosts a page where the customer verifies their phone, tops up their wallet (eSewa/Khalti), and authorizes the subscription. You get back a subscription.created event.

It exists because the customer needs to do things your server can’t do for them — verify a phone via OTP, complete KYC, and pay a provider. Hosted checkout wraps all of that.

Terminal window
curl -s "$TRILE_API/v1/checkout/sessions" \
-H "x-api-key: $TRILE_KEY" -H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"priceId": "price_01ARZ3NDEKTSV4RRFFQ69G5FAY",
"successUrl": "https://yourapp.com/welcome",
"cancelUrl": "https://yourapp.com/pricing"
}'

Response:

{
"success": true,
"data": {
"id": "cs_01ARZ3NDEKTSV4RRFFQ69G5FB9",
"token": "one-time-token",
"publicUrl": "https://checkout.trile.app/cs_..."
},
"meta": { "requestId": "req_..." }
}

Redirect the customer to publicUrl. Optionally pre-bind an existing customer with customerId.

  1. Enters their phone; Trile sends an OTP (/otp/send) and verifies it (/otp/verify), binding the customer to the session.
  2. Sees the plan and the first-cycle amount vs. their current wallet balance (/balance).
  3. If short, tops up via eSewa/Khalti (/topup → provider → /topup/return, settled server-side).
  4. Confirms — Trile authorizes and creates the subscription (/complete), then redirects to your successUrl.

These /v1/checkout/sessions/:token/* endpoints power Trile’s own checkout UI. You normally don’t call them yourself unless you’re building a fully custom checkout (see below).

The redirect to successUrl is a UX convenience — don’t grant access based on it alone. A user can close the tab, and redirects can be spoofed. Instead:

  1. Register a webhook for subscription.created.
  2. Grant access when you receive (and verify) that event.
  3. Optionally reconcile via the event log.

For an evergreen “subscribe” button, a checkout link (clink_…) resolves to a fresh session each visit via GET /v1/checkout/links/:linkId — handy to embed in marketing pages without minting a session per visitor server-side.

If you must own the UI end to end, the per-session endpoints are public (anonymous + a per-session bearer issued at OTP verify): balance, otp/send, otp/verify, topup, topup/return, and complete. Treat the bearer as a short-lived session credential and follow the same order as the hosted flow above. This is significantly more work — prefer the hosted page unless you have a strong reason.