Take card and wallet payments worldwide through Stripe Checkout. The shopper pays on a Stripe-hosted page. A signed webhook tells your site when the payment completes.
Before you start
- A Stripe account. Test mode is fine.
- Your secret key (
sk_test_…) and publishable key (pk_test_…) from Developers → API keys
Set up Stripe
1. Add the webhook in Stripe first. Stripe Gateway Settings won't save without the webhook signing secret. In Stripe, go to Developers → Webhooks → Add endpoint:
- URL:
https://your.site/api/v2/method/bwh_payments.bwh_payments.webhook.handle?gateway=Stripe - Events:
checkout.session.completed, and for refundsrefund.created,refund.updatedandrefund.failed
Copy the endpoint's signing secret (whsec_…).
2. Fill in Stripe Gateway Settings
| Field | Value |
|---|---|
| Publishable Key | pk_test_… or pk_live_… |
| Secret Key | sk_test_… or sk_live_…. The key decides whether payments are test or live. |
| Mode | Test or Live, for your own reference |
| Success URL | Your confirmation page. Stripe adds ?session_id=… to it. |
| Failure URL | Your payment-failed page, shown when the shopper cancels |
| Webhook Secret | The endpoint's signing secret (whsec_…) from step 1 |
3. Create a Payment Gateway Profile named Stripe, set Gateway Settings to Stripe Gateway Settings, and tick Enabled.
How it behaves
| Stripe says | Payment status |
|---|---|
Checkout Session payment_status is paid |
Paid |
Checkout Session status is expired |
Expired |
| Anything else | Pending |
- Amounts are sent in the currency's smallest unit (cents, fils, yen), using its correct number of decimals.
- Webhooks are verified with Stripe's own library, which also rejects old, replayed signatures. Stripe's event id makes sure each event is applied only once.
- Refunds go against the Checkout Session's payment. Partial refunds are supported. A
pendingrefund settles from a refund webhook, or fromsync_refunds. A refund made in the Stripe Dashboard is recorded too. - Cancelling an open checkout (
release_if_unpaid()) expires the Stripe session.
Good to know
- The Stripe Python SDK (12.5 or later) is installed with BWH Payments. Each settings instance uses its own
StripeClient, never the SDK's globalstripe.api_key. - A payment method that settles later, such as a bank debit, stays Pending when the checkout completes. It becomes Paid when your app next checks its status.
Next steps
- Webhooks and security: debug a delivery that isn't arriving
- Build a payment gateway: add a gateway that isn't listed
Last updated 17 hours ago
Was this helpful?