Kessai Payment Engine
Kessai is a flexible payment engine for Drupal that manages the financial aspects of transactions. It records payment details, supports various payment gateway integrations, and provides a robust state machine for managing payment processes like initiation, settlement, and refunds. The system allows other modules or custom code to react to payment events without being directly coupled to the payment gateway.
Kessai (Japanese 決済, settlement) is a lightweight, gateway-agnostic payment engine for Drupal. It owns the money side of a payment and leaves the domain decisions, what to charge and what a paid payment means, to the site.
What it provides
- A payment entity recording amount, currency, state, kind, gateway, the provider reference, the checkout session, an optional stored-card token and an optional subject of any entity type. Beside the amount it keeps what actually happened to it: how much has been claimed, how much of a hold has been released, and how much has gone back.
- A record per movement of money. A claim takes money off an authorization, a reversal releases a hold nobody collected, and a refund gives back money that was. Each is a row of its own carrying its amount, its state, the provider’s own reference for it and the caller’s word for what it was, so two endings that move the same total stay legible apart. Because each is recorded separately, all three can be partial: one guarantee can yield a fee now and a damage claim later.
- A gateway plugin type, with an offline manual gateway bundled. Optional operations live on capability interfaces a gateway opts into, so the engine asks whether an operation is supported instead of calling it and trusting the answer.
- A locked, idempotent state machine over pending, authorized, captured, cancelled, refunded, failed and expired. Every transition is a compare-and-set under a lock, so a duplicate provider callback is a no-op and two concurrent callers cannot both charge.
- Payment expiry. A payment carries a deadline the gateway itself declares, and a cron reaper sweeps the lapsed ones. A payment that reached a provider is asked about before it is written off, within a per-run budget, so a payer whose browser return and webhook both failed is not recorded expired for a payment they actually made.
- Checkout sessions in the engine. The provider session is modeled once, so one session per payment is reused while it is open and no gateway has to cache its own.
- Events for every outcome: initiated, authorized, captured, cancelled, failed, expired and refunded, plus partially cancelled and partially refunded for the cases that leave the payment where it was. Consumers react to those without the engine knowing anything about the domain.
Gateways report outcomes through a browser return, a server-to-server webhook, or an operator action. Whichever arrives first records the state change and announces it; the others are no-ops.
Submodules
- Kessai Worldline: the Worldline Direct gateway, hosted checkout and card on file.
- Kessai Simulator: a fake gateway for development and testing.
- Kessai Audit Trail: records payment events into an audit trail.
- Kessai Views: administration views for payments and for each kind of movement against them.
Requirements
Drupal 11.3 or newer, Drupal 12 included, and the bcmath PHP extension. The Worldline submodule additionally requires the Worldline Direct PHP SDK.
Status
Kessai is in alpha. There is no migration path between alpha releases, in either direction, and reinstall is the only supported path; migration paths will begin with the beta releases. While the module is in alpha it will keep breaking entities, base fields, config, routes and interfaces wherever that yields a better model.
Working with Orchestra
Kessai pairs with Orchestra: its orchestra_payment submodule turns a workflow wait node into a payment step, for a booking, an order or a membership.