meta['payment_method'] — see PaymentConfirmed's docblock for * why. This split is what makes an async/webhook-driven gateway (payment * confirmed in a request that has no synchronous caller waiting for an * Order at all) and a synchronous one (Stripe) work through the exact same * contract. See docs/checkout.md / docs/payments.md. */ interface PaymentDriver { /** * Whether this driver can actually be used right now — e.g. Stripe * checking its own API key is present, an offline-style driver always * returning true since it has no external dependency. Independent of * Modules\Core\Payment\Models\PaymentMethod::enabled (the admin * on/off toggle) — CheckoutService::getPaymentMethods() combines both: * a type is only offered to the storefront if it's administratively * enabled AND its driver reports itself configured. */ public function isConfigured(): bool; /** * $type is the payment type key being confirmed (e.g. 'cash-in-hand', * 'cash-on-delivery', 'stripe') — passed through even though most * drivers only ever serve one type, because a driver shared across * several types (e.g. one "no real confirmation" offline driver behind * both cash-in-hand and cash-on-delivery) needs it to look up that * type's own config (e.g. its 'authorized' status) rather than another * type's. * * $data carries whatever the gateway needs to confirm this specific * payment (Stripe: ['payment_intent' => $id], a redirect-based * provider: its callback payload) — passed explicitly by the caller * (a controller, a webhook job) rather than a driver reaching into the * global request(), so confirm() works the same whether it's called * from a synchronous HTTP request or an async webhook/job with no * active request at all. * * @param array $data * * @throws FingerprintMismatchException * @throws CartException */ public function confirm(Cart $cart, string $type, string $fingerprint, array $data): void; }