Letting the payer select an account¶
A payment step can offer several payment accounts. The payer selects one on the payment page. For example, a card account and an offline account for bank transfers:
Amount due: 120.00 EUR
[ Pay with Card ] [ Pay with Bank transfer ] [ Back to the form ]
The payer clicks "Pay with Bank transfer", and the step creates the payment through the offline account. The other buttons are the outcomes configured on the step.
Offering accounts from a resolver¶
The payable resolver says which accounts are on
offer. It passes them to the Payable as a list, in the order the page shows
them. The first account is selected by default:
public function resolve(ProcessInstanceInterface $instance, TokenInterface $token): ?Payable {
$order = $this->loadOrder($instance);
$account_uuids = [
$this->getCardAccountUuid($order),
$this->getTransferAccountUuid($order),
];
$amount = new Money('120.00', 'EUR');
return new Payable($amount, $amount, $account_uuids);
}
To select another account by default, name it. It must be one of the list:
return new Payable($amount, $amount, $account_uuids, default_account_uuid: $transfer_uuid);
A resolver with one account passes a list of one.
The accounts come from the resolver because they can depend on what it prices. A booking module, for example, offers the accounts of the order's tenant. A list on the step would send every tenant to the same accounts.
A resolver that overrides preview() passes the same accounts to the
PayablePreview, so the page shows them:
public function preview(ProcessInstanceInterface $instance, TokenInterface $token): ?PayablePreview {
$payable = $this->deriveFromResolve($instance, $token);
if ($payable === NULL) {
return NULL;
}
$summary = $this->buildOrderSummary($instance);
return new PayablePreview(
$payable->authorizeAmount,
$summary,
$payable->accountUuids,
$payable->defaultAccountUuid,
);
}
A resolver that does not override preview() needs nothing more: the base
class copies the accounts from resolve().
Offering accounts from process variables¶
The bundled orchestra_payment_variable resolver reads the account variable
(default payment_account_uuid). The variable holds one account uuid, or a
list of them. With a list, the first account is selected by default:
payment_amount: '120.00'
payment_account_uuid:
- 3f2b6c1e-8a4d-4f7e-9b1a-2c5d8e7f6a90 # Card, selected by default
- 9d4e2a7b-1c3f-4e8d-a6b5-0f1e2d3c4b5a # Bank transfer
What the page shows¶
- One account on offer: one "Go to payment" button, as with any step.
- Several accounts: one "Pay with …" button for each account. The label is the account label in Kessai. Kessai documents that label as the site owner's own words, so name each account for the payer ("Card", "Bank transfer").
- The account selected by default gets the primary button.
- An account that Kessai has disabled gets no button. With one account left, the page shows the one "Go to payment" button.
- An account that can no longer be paid in the time left gets no button either: see Deadlines per account. When no account can, the page says there is not enough time left.
How the step settings apply¶
- Account override: forces one account. The step then offers that account alone, whatever the resolver returns.
- Go straight to the gateway: the step skips the payment page and charges the account selected by default. A failed or canceled attempt returns to the payment page, where the payer can select another account.
What the click checks¶
The click carries the selected account. The step charges it only when the priced instance still offers it. Otherwise nothing is charged, and the page comes back with a notice so the payer selects again.
A payer can go back and select another account. The step then cancels the pending payment through the first account and creates a new one, because reusing it sends the payer to a provider they did not select. A payer who is already at the provider's checkout is not sent to a second one: the page says that the payment is being processed.
A bank transfer is not a checkout at a provider: the payer gets the transfer details, and an operator records the money when it arrives. So a payer who selected the bank transfer can come back and select the card. The pending transfer payment is then canceled. If the payer had already sent the money, an operator refunds it by hand.
Deadlines per account¶
Each payment keeps the deadline of its own account: for example, 20 minutes for a card and 3 days for a bank transfer. To let the step wait as long as the selected account allows, give the step the payment window deadline: see Payment window.
Switching never gives the payer more time. The step's payment timeout is counted from its first payment, and every payment ends by then, whichever account it goes through. A payer who selects the transfer on day 1, the card on day 4 and the transfer again on day 5 of a 5-day timeout gets one day for that last transfer, not three. See How long the payer gets.
On a step that lets the payer try again when a payment expires, an expired payment does not end the step either: the payer can select another account, or the same one again, until the step's time runs out. Each new payment is just another attempt inside the same window.