Skip to content

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.

  • 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.

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
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).