Manual payments¶
A payment made in cash, by cheque or by bank transfer goes through the bundled
manual gateway. Kessai sends the payer nowhere and hears nothing back: the
payment stays pending until someone at the site records that the money
arrived.
A manual account can also give its payments a deadline, in seconds. A payment still pending when it passes is recorded expired, and can no longer be recorded as received here: money that arrives late goes on a new payment. With no deadline, the default, a manual payment waits as long as it takes. See Gateways.
Each account also has a minimum time to pay: the least time a payer needs before the deadline. An instant transfer needs minutes, a standard transfer a day, a cheque by post several days. When a site bounds a checkout, an account with too little time left is not offered and takes no payment. A manual account can also let a site extend its deadline, so one booking can be given five days instead of the account's three. See Bounding a checkout.
Recording a payment received¶
- Give the operator's role two permissions:
- "Administer Kessai payments", to reach the payments list;
- "Record manual payments as received", to record the money.
- The operator opens Administration > Payments > Payments
(
/admin/payments/payments). That list comes with thekessai_viewsmodule. - They tick the payments that were paid, choose Record payment received and apply it.
Each payment is recorded captured, for its whole amount. Kessai announces
kessai.captured, as for any other capture, so the consumer that took the
payment hears it the usual way. With kessai_audit_trail enabled, the audit
trail records who recorded it and when.
The action only applies to a payment that is:
- pending: a payment already authorized, captured, released, failed, canceled or expired is refused;
- of a gateway an operator settles: a card payment is refused, because only its provider can say it was paid.
A refused payment is left as it was, and the list says which ones were refused.
Always the whole amount
A pending payment holds nothing, so there is no part of it to claim:
recordPaymentReceived() records a pending payment captured in full. A payer who paid
less is a matter for the consumer, for example a new payment for the rest.
Doing it from code¶
On a pending payment, the action is a shortcut for one call, which a module can make itself:
$payment_client = \Drupal::service(\Drupal\kessai\PaymentClientInterface::class);
if ($payment_client->isAccountManuallySettled($payment->getAccountUuid())) {
$payment_client->recordPaymentReceived($payment);
}
On a payment that is not pending it records nothing. Ask
isAccountManuallySettled() before offering it: on a site whose payments are
settled on another host, the host refuses it for a payment whose provider
settles it, since only that provider says the payment was paid. It answers on
either kind of site, from the last handshake on the second.
A site's own offline gateway¶
The action does not ask for the manual plugin id. It asks whether the
gateway implements ManuallySettledGatewayInterface, which has no methods. A
site's own offline gateway gets the same action by implementing it:
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\kessai_engine\Attribute\PaymentGateway;
use Drupal\kessai_engine\ManuallySettledGatewayInterface;
use Drupal\kessai_engine\PaymentGatewayBase;
#[PaymentGateway(
id: 'my_counter',
label: new TranslatableMarkup('Paid at the counter'),
)]
final class CounterGateway extends PaymentGatewayBase implements ManuallySettledGatewayInterface {
// ...
}
See Gateways.