Skip to main content

Online Transaction Service

Overview

gateway-online-txn owns the e-commerce edge plus merchant-operated payment entry points: checkout sessions, hosted payment flows, typed virtual-terminal sale/auth/force-auth, authenticated setup-intent confirmation, shopper payment submission, storefront resources, API-key records, webhook delivery attempts, and checkout-facing subscription actions. It delegates payment execution to the internal processing service.

Production traffic uses https://pay.peakgateway.co; staging uses https://staging-pay.peakgateway.co. Both hosts default to online-txn and also route /online-txn/* with the prefix removed.

AreaResponsibility
CheckoutCreate, read, cancel, expire, and pay checkout sessions
Virtual terminalValidate typed card/ACH credentials, enforce scope/App Check/impersonation and idempotency, canonicalize requests, and delegate sale/auth/force-auth
Setup intentsConfirm authenticated setup intents on the pay host; management retains PAN-free metadata and lifecycle operations
Shopper paymentValidate session credentials and submit card or wallet payment data
Hosted paymentsPayment links, buttons, iframe flows, and appearance configuration
StorefrontProducts, prices, coupons, promotion codes, shipping, and customers
API keysPersist merchant API keys and exchange them through auth for scoped OAuth tokens
WebhooksCreate delivery attempts, sign payloads, retry failures, and expose replay controls
Fraud controlsEndpoint rate limits and optional reCAPTCHA Enterprise assessment
SubscriptionsCheckout-facing create and lifecycle operations delegated to processing

Authentication Modes

CallerCredential
Server integrationOAuth2 Bearer token from the auth service
API-key integrationRaw key exchanged at /auth/oauth2/api-key/token; downstream calls use the returned Bearer token
Checkout shopperSession token/secret bound to one checkout session
Portal BFFFirebase-authenticated management call forwarded through an internal service client

A raw API key is not a long-lived Bearer credential for arbitrary online-txn routes. The auth service validates it and issues a short-lived, scoped OAuth token.

API Contracts

The public OpenAPI specification is the source of truth for checkout, wallet, subscription, storefront, and typed virtual-terminal request/response bodies:

  • Public API reference
  • websites/docs/openapi/public-api.yaml
  • services/online-txn/src/main/kotlin/.../controller/

The pay host owns the credential-bearing transaction and setup-intent confirmation routes:

  • POST /api/v1/transactions/sale
  • POST /api/v1/transactions/auth
  • POST /api/v1/transactions/force-auth
  • POST /api/v1/setup-intents/{setupIntentId}/confirm

Do not duplicate endpoint schemas in this page. The generated reference covers current fields such as line items, minor-unit amounts, Apple Pay and Google Pay payloads, session-token headers, idempotency headers, and subscription mutation responses.

Checkout Lifecycle

OPEN --pay approved--> COMPLETED
| |
| +--declined/validation failure--> OPEN (when retry remains allowed)
+--cancel-------------------------------> CANCELLED
+--expiry-------------------------------> EXPIRED

The persisted session is authoritative. Shopper redirects and browser state are presentation concerns and cannot mark a payment successful. A session moves to its terminal success state only after processing has returned a durable payment outcome and online-txn has persisted the corresponding session transition.

Fast repeated /pay calls are rate limited. Certification automation that receives 429 RATE_LIMITED must honor the retry window and resume the failed step rather than recreate the full run.

Wallet Payments

Apple Pay and Google Pay requests preserve provider payloads and merchant configuration through the checkout boundary. The service validates the session and wallet-specific request shape before delegating payment execution. Wallet certificates, merchant identifiers, and domain verification are documented in Digital Wallets.

Webhook Delivery

Webhook ownership is intentionally split:

  • management owns durable subscription/configuration records and operator actions;
  • online-txn owns per-destination delivery attempts, retries, and dispatch state;
  • domain services persist their transition before publishing an event.

Delivery uses HMAC-SHA256 over the exact timestamp and raw request body. SDK helpers are the preferred verification path. Consumers must verify against the raw bytes before JSON parsing and enforce an age window to limit replay.

Webhook delivery is downstream of the payment transition. Exhausted delivery retries enter DLQ/operator recovery; they never reverse an approved payment. See Event Log and Replay.

Data Ownership

Online-txn owns the tables for:

  • checkout sessions and shopper-session state
  • hosted-payment configuration
  • storefront catalog and promotion resources
  • merchant API-key records owned by this service
  • webhook delivery attempts and retry state

Processing owns transactions, customers/payment methods where designated by the processing contract, subscriptions, and monetary outcomes. Management owns merchant/operator configuration and tenant authorization. Cross-service writes to another service's single-owner tables are prohibited.

The SQLDelight definitions under libs/schema/src/main/sqldelight/ are the schema source of truth.

Reliability and Security

  • Resolve location ownership before reading or mutating a session.
  • Require OAuth scope and applicable Firebase App Check/impersonation checks on merchant-operated payment routes.
  • Require idempotency on externally retryable monetary actions.
  • Never log PAN, CVV, raw bank account data, raw wallet cryptograms, session secrets, API keys, or webhook secrets.
  • Persist delivery attempts and terminal payment outcomes independently.
  • Treat an unknown processing result as in-doubt, not as a safe retry.
  • Keep shopper routes narrowly scoped to the session credential.

Runtime

ComponentTechnology
LanguageKotlin 2.2 on Java 25
FrameworkSpring Boot 4.0.5
DatabaseCloud Spanner PostgreSQL dialect through SQLDelight/PGAdapter
MessagingCloud Pub/Sub
Payment executionInternal call to processing with Cloud Run IAM
Public hostpay.peakgateway.co / staging-pay.peakgateway.co

Health endpoint: GET /health on the service, publicly reachable as /online-txn/health on the payment host.