Review this generated checkout boundary before it handles payment requests.
Require a positive integer amount, avoid holding a database transaction during the gateway call, roll back on every Throwable after the transaction starts, log no secrets, and preserve the cause when translating failure.
php
<?php
final class PaymentGateway {
public function charge(int $cents, string $token): string {
return 'PAY-7';
}
}
function checkout(PDO $db, PaymentGateway $gateway, array $request): string
{
$db->beginTransaction();
try {
$amount = (int) ($request['amount_cents'] ?? 0);
$paymentId = $gateway->charge($amount, $request['token']);
$db->commit();
return $paymentId;
} catch (Exception $error) {
$db->rollBack();
error_log($error->getMessage() . ' token=' . $request['token']);
throw new RuntimeException('Checkout failed');
}
}
generated code is illustrative, not from any one model