Payment gateway
This page records what the brief asks for, how payments relate to points, and the integration shape we expect, as a basis for choosing a gateway.
What the brief asks for
Section titled “What the brief asks for”- FINNS credit: a closed-loop prepaid balance that guests buy in the app or on the website, by card or virtual account (bank transfer), and spend only at FINNS.
- Gateway: Airwallex.
- Regulation: single-merchant, closed-loop credit sits outside Bank Indonesia’s e-money licensing. Balances are deferred revenue for FINNS (IFRS 15), and unredeemed credit is breakage that finance must account for.
Today: payment stays with the booking engine
Section titled “Today: payment stays with the booking engine”flowchart LR classDef ext fill:#F3ECDF,stroke:#B9A88B,color:#12191B classDef ours fill:#13686C,stroke:#0B4A4D,color:#ffffff book["Booking engine<br/>takes the payment itself"]:::ext core["Core"]:::ours pg["Booking engine's<br/>own payment provider"]:::ext book --> pg book -- "booking X paid, total IDR Y" --> core core -- "points at the configured rate" --> core
Core never handles card data or payment state. It only hears that a booking was paid, and earns points on the total.
A likely shape for credit top-ups
Section titled “A likely shape for credit top-ups”For discussion. Credit is money, not points: it would need its own ledger with money-grade controls, kept apart from the points ledger.
sequenceDiagram
autonumber
actor G as Guest
box rgb(227,244,243) FINNS platform
participant APP as Guest app
participant CORE as Core (credit ledger)
end
box rgb(243,236,223) Third party
participant PG as Payment gateway
end
G->>APP: Top up IDR 1,000,000
APP->>CORE: Create top-up (amount, method)
CORE->>PG: Create payment request (external id = top-up id)
PG-->>CORE: Checkout URL / VA number
CORE-->>APP: Checkout details
APP->>G: Gateway checkout (card) or VA instructions
G->>PG: Pay
PG-)CORE: Webhook: payment succeeded (signed)
Note over CORE: nowrap:Verify signature, look up top-up by external id,<br/>credit the balance exactly once
CORE-->>PG: 200
APP->>CORE: Refresh balance
CORE-->>APP: Credit balance
Selection criteria
Section titled “Selection criteria”| Criterion | Why it matters here |
|---|---|
| Virtual accounts with low flat fees | The business case assumes ~30% of credit is funded by bank transfer to avoid the 2.5% card fee |
| Signed webhooks with retries and idempotent references | Exactly-once crediting, matching how core already handles points |
| Refunds and partial refunds through the API | Unused credit, disputes |
| Settlement reports by API | Reconciliation and breakage accounting in NetSuite |
| Tokenised cards | Faster repeat top-ups without FINNS ever touching card data (PCI scope stays with the gateway) |
Internal and confidential. Share partner sections only as partner builds (pnpm build:partner).

