· API Docs
Guide

Hosted pay page

The hosted pay page is a ready-made page you can redirect a payer to. They see the transfer instructions and upload their slip there — you build no UI and never handle the slip file yourself.

The flow

  • 1. Create a payin as usual (see Accept a payment) — the response now also carries pay_token and expires_at.
  • 2. Build the URL and redirect the payer to it.
  • 3. The payer transfers and uploads a slip on the page; finance then verifies it — the payin moves pending → success exactly like a normal manual_slip payin.
text
https://<pay-host>/pay/{pay_token}

Pay page themes

Set pay_theme when you create the payin to choose how the page looks. The theme is painted on the first server-rendered byte, so there is no colour flash on load. An absent or unrecognised value falls back to classic.

Append the theme= query param to the URL to override the stored theme for a single visit — handy for previewing a theme before committing to it.

text
https://<pay-host>/pay/{pay_token}?theme=neon
ParameterValuesDescription
themeany id in the catalog belowOverrides the payin’s stored pay_theme for that visit only. An unknown id falls back to classic.
modelight | darkForces the Modern layout into light or dark; without it, Modern follows the payer’s own toggle. Ignored by classic and the colour re-skins.

The catalog

classic is the standard palette and the only theme that still lets the payer toggle light/dark; light and dark are classic locked into one mode. The other colour themes re-skin the whole page and lock their own mode. Modern is a different page structure (direct-transfer + slip upload, no QR) that still follows the payer’s mode via mode=.

light / dark

Default — the standard look, with the in-page light/dark toggle (theme=classic)

light

Classic forced to light mode (theme=light)

dark

Classic forced to dark mode (theme=dark)

light

Cream → mint pastel gradient, emerald accent

light

Warm cream, terracotta accent

dark

Royal blue with white accent

dark

Dark navy, grid pattern + blue glow

light

Pink-orange gradient, pink accent

dark

Near-black with gold accent

dark

Dark navy, dot pattern + green glow

light

Warm cream, rust accent

light

White with green accent

dark

Very dark purple, grid + cyan-green accent

dark

Brand family — forest green

dark

Brand family — wine / burgundy

dark

Brand family — black + gold

dark

Brand family — pure black (silver card)

dark

Brand family — bright orange

light

Brand family — dark teal

light

Brand family — dark purple

light

Brand family — magenta / pink

light

Brand family — bright blue

light

Brand family — dark green

light

Brand family — bright sky

Payer endpoints (public, no auth)

These endpoints live on a separate pay-host and are reached with the pay_token alone — no API key, no cookie.

GET/pay-api/v1/pay/:tokenpublic
POST/pay-api/v1/pay/:token/disclosure-consentpublic
POST/pay-api/v1/pay/:token/slippublic

Read the payment details

bash
curl "https://pay.example.com/pay-api/v1/pay/pt_9b1c7f2a0c3d4e5f9a1b2c3d4e5f6a7b"

PayView returns amount / fee / net as exact integer-minor-unit strings with a bound currency_profile for formatting:

json
{
  "token": "pt_9b1c7f2a0c3d4e5f9a1b2c3d4e5f6a7b",
  "merchant_name": "ร้านสมชาย",
  "merchant_logo": null,
  "amount": "250000",
  "fee": "3750",
  "net": "246250",
  "currency": "THB",
  "currency_profile": {
    "code": "THB",
    "name": "Thai Baht",
    "symbol": "฿",
    "locale": "th-TH",
    "description": "Thai Baht",
    "scale": 2,
    "unit_step": 1
  },
  "status": "pending",
  "expires_at": "2026-08-19T12:30:00Z",
  "destination": {
    "bank_code": "KBANK",
    "account_no": "1234567890",
    "holder_name": "สมชาย ใจดี"
  },
  "payer": null,
  "promptpay": null,
  "order_ref": "INV-2026-000123",
  "redirect_url": null,
  "pay_theme": null
}

When a payin is directly matched to a P2P payout, call this after the payer accepts the conditions on the pay page. The server appends an immutable row to p2p_disclosure_events.

bash
curl -X POST "https://pay.example.com/pay-api/v1/pay/pt_9b1c7f2a0c3d4e5f9a1b2c3d4e5f6a7b/disclosure-consent"

Upload a slip

Send it as multipart under the field slip — png / jpeg / jfif up to 10MB.

bash
curl "https://pay.example.com/pay-api/v1/pay/pt_9b1c7f2a0c3d4e5f9a1b2c3d4e5f6a7b/slip" \
  -F "[email protected];type=image/jpeg"