The Stripe Payments gateway in Blesta works on the modern PaymentIntents API, so it handles 3DS, off-session charging, and SCA out of the box. The catch is the webhook configuration. Subscribe to too many event types and the gateway processes the same charge multiple times — each subsequent event arrives without the full intent context and gets recorded as a small rounding-error transaction.
This guide installs the gateway, configures it with live keys, and sets the webhook to the exact event list that avoids the duplicate-charge bug. Doing the WHMCS-to-Blesta move first? Run through the migration checklist before connecting live gateways.
Install the gateway
In Blesta admin go to Settings → Company → Payment Gateways → Available, find Stripe Payments, and click Install. The gateway ships with core Blesta — no separate plugin download needed.
Open Manage on the newly installed gateway and enter:
- Publishable Key —
pk_live_...from dashboard.stripe.com/apikeys - Secret Key —
sk_live_...from the same page
Use live keys, not test keys. Blesta does not have a sandbox mode flag on this gateway — test mode is implied by using pk_test/sk_test. Mixing test keys with a live Stripe webhook is the second most common cause of "payments succeed but invoices stay unpaid".
Tick the currencies this gateway should accept. Stripe processes whatever the customer's invoice is denominated in, but Blesta only routes invoices in the listed currencies through this gateway.
Configure the webhook
Stripe needs to call back into Blesta to confirm payment status. The callback URL pattern is:
https://billing.example.com/callback/gw/<company_id>/stripe_payments/
<company_id> is 1 on a single-company install. Find it in Settings → System → Companies if you run multi-company.
In the Stripe dashboard go to Developers → Webhooks → Add endpoint. Paste the URL. Then — and this is the part everyone gets wrong — select events to listen for, not "all events".
The four events you need
payment_intent.succeeded
payment_intent.payment_failed
charge.refunded
charge.dispute.created
That is the complete list. Save the endpoint.
Test before going live
Stripe ships a one-click test card for the dashboard. Create a $1 invoice on a test client, pay it from the client area with 4242 4242 4242 4242, then verify three things:
- The Blesta invoice shows Paid within ~5 seconds (the webhook is faster than polling).
- The Stripe dashboard shows exactly one Payment Intent and one Charge for $1.00 — no $0.01 stragglers.
- The Blesta transaction log (Billing → Transactions) lists one approved transaction tied to the invoice.
If you see two transactions or any amount other than $1.00, the webhook subscription is too broad. Edit it down to the four events above and replay the test.
Handle off-session renewals
Stripe Payments stores the customer's payment method as a reusable pm_... token on first successful charge. Blesta's renewal cron uses that token to charge invoices automatically without user interaction. For 3DS-required cards this triggers an off-session authentication challenge; the gateway emails the customer a link to complete it. No additional config needed — it works as long as the webhook list above is correct.
Refunds and disputes
Process refunds from the Blesta invoice screen (Billing → Invoices → Refund). The gateway calls Stripe's refund API directly; the charge.refunded webhook then confirms back into Blesta and updates the transaction state.
Disputes initiated in Stripe (chargebacks) flow in through charge.dispute.created and mark the transaction as disputed. Blesta does not automatically void the related service — handle that in your fraud workflow.
Why does Blesta record an extra $0.01 transaction for every Stripe payment?+
What is the correct Stripe webhook URL for Blesta?+
Does Blesta's Stripe gateway support 3D Secure and SCA?+
Can I use both test and live Stripe keys in Blesta?+
Next steps
- Add PayPal alongside Stripe with Blesta PayPal Payments Standard setup.
- Coming from another billing platform? Read the WHMCS to Blesta migration checklist.
- Activate a production Blesta license before flipping live keys on.