<!-- canonical: https://matiforge.com/insights/multi-tenant-payments-architecture -->
# Payments architecture for multi-tenant platforms

*Why each tenant should settle on its own gateway account, and the provider-neutral core, webhook handling and reconciliation that this model requires.*

Design decisions · By T P Joshi · 2026-09-09 (updated 2026-09-22) · Payments · 5 min read

## Choosing the settlement model

A multi-tenant platform that takes payments must decide whose account receives the funds. The two common models differ in far more than integration effort.

**Platform-account model.** The platform collects every payment on its own merchant account and pays tenants out afterwards. This gives full control over pricing, payout timing and fee deduction. It also places the platform in the flow of funds: it holds money that belongs to others, carries refund and chargeback exposure, and can fall under payment-aggregation licensing and tax-collection duties that vary by jurisdiction (in India, for example, GST tax collection at source by e-commerce operators). Those questions need legal advice before launch, not after.

**Tenant-account model.** Each tenant connects a merchant account of its own, and funds settle directly to the tenant's bank account. The platform orchestrates checkout, records outcomes and reports on them, but never holds the money. The tenant remains the merchant of record, so refunds, disputes, settlements and tax treatment stay with the party that made the sale.

Where tenants are independent businesses, the second model keeps the platform out of the flow of funds and out of most of the liabilities attached to it. The remainder of this article assumes it.

## A provider-neutral payment core

Gateways differ in vocabulary, signature schemes, retry behaviour, refund semantics and settlement reports. If those differences reach the rest of the system, every new provider becomes a rewrite. The alternative is a core domain model that no gateway owns: an order, a payment attempt, a refund, a dispute and a settlement, with a small canonical state machine (created, pending, captured, failed, refunded, disputed).

Each provider then becomes an adapter behind one interface:

- create a checkout session or order;
- verify and parse an incoming webhook;
- fetch the current status of a payment;
- issue a full or partial refund;
- list and fetch disputes;
- fetch settlement records.

The adapter maps provider statuses onto the canonical states and keeps the raw provider payload alongside, so that events can be audited and replayed. Adding a provider means writing one adapter and passing the shared contract tests, without touching orders, reporting or the tenant interface.

Three practices belong in the core rather than in the adapters. Money is stored as integer minor units with an explicit currency. Every call that moves money carries an idempotency key. Checkout is hosted or tokenised by the gateway, so card data never enters the platform's systems and PCI DSS scope stays minimal.

## Credentials and tenant isolation

Each tenant supplies its own API credentials and webhook secret. They are encrypted at rest, never logged, and resolved only inside that tenant's request context. Test-mode and live-mode credentials are kept apart, and rotation is supported without downtime.

When a tenant switches providers or rotates keys, the previous credentials are archived, not deleted. A refund or dispute months after a purchase has to be issued against the account that took the payment.

A failing credential or a provider outage should degrade one tenant only. Per-tenant rate limits, health checks (a test call, the time of the last webhook received) and a visible connection status let a tenant find a broken setup before its customers do.

## Webhooks, polling and idempotent processing

Webhooks are the primary signal that a payment has changed state, and they are not reliable on their own. Delivery is typically at-least-once, events can arrive out of order, and an endpoint that is briefly unavailable can miss events altogether. A sound handler therefore:

1. verifies the signature the provider documents (typically an HMAC over the raw request body) with the tenant's own webhook secret, using a constant-time comparison, and rejects anything that fails;
2. stores the event under the provider's event identifier, with a uniqueness constraint, before acknowledging it;
3. acknowledges quickly and processes asynchronously, so that a slow downstream step does not trigger provider retries;
4. applies the state change idempotently and refuses transitions the state machine forbids, such as a payment returning from captured to pending.

A scheduled poller covers the remaining gap. It queries the gateway for payments that are still pending after a grace period, with backoff and an upper bound, so that a lost webhook never leaves a paid order unfulfilled. Payments that stay unresolved go to the exceptions queue described next.

## Reconciliation and the exceptions queue

Reconciliation compares the platform's ledger with each provider's settlement records on a schedule. Every break falls into one of a small number of classes:

| Break                                        | Typical cause                                                                    |
| -------------------------------------------- | -------------------------------------------------------------------------------- |
| Paid at the provider, absent from the ledger | Missed webhook, failed processing                                                |
| In the ledger, absent at the provider        | Payment marked paid from a client-side redirect, test and live credentials mixed |
| Amount, currency or status differs           | Partial refund, fee or tax adjustment, dispute opened after capture              |
| Duplicate                                    | Retried request without an idempotency key, event processed twice                |

Nothing is corrected silently. Each break enters an exceptions queue with the evidence attached (both records and the event history), an age and an owner, and with the actions that resolve it: match, refund, adjust or escalate. Queue age is tracked as an operating metric, because unresolved breaks accumulate into month-end problems.

The same discipline applies one level up. Provider payouts are checked against bank credits, and provider fees against the fees recorded in the ledger.

## Trade-offs to accept

The model is not free. Each tenant has to open and verify a merchant account with its gateway before its first sale, which adds onboarding friction. The platform cannot deduct a commission at the point of payment, so its own fees are billed separately, usually as a subscription or as invoiced usage. Gateway problems that originate on the tenant's side reach the platform's support queue and need tooling to diagnose. Providers also differ in capability (partial refunds, dispute APIs, settlement report formats), so the adapter interface should declare what each provider supports instead of assuming parity.

## Where to start

Design reconciliation first. Checkout is the straightforward part; the month-end close is where a payment system is tested. The exceptions queue should be a real screen with real actions, not a log file that someone searches during an audit.

---

Jversity, the education platform MatiForge builds and operates, follows this model: each institute connects its own gateway account. The [case study](/work/building-jversity) describes the platform.
