Setting Stripe up

This package ships the payment provider. Nothing here needs a Stripe SDK, a build step or a redeploy — a portal that holds the keys sells, and a portal that does not says so.

1. The three keys

Key What it is Where it comes from
Commerce:Stripe:SecretKey the server-side API secret (sk_test_… / sk_live_…) Stripe dashboard → Developers → API keys
Commerce:Stripe:WebhookSecret the endpoint signing secret (whsec_…) Stripe dashboard → the endpoint you add in step 2
Commerce:BaseUrl this portal's public base URL the deployment

As environment variables they are Commerce__Stripe__SecretKey, Commerce__Stripe__WebhookSecret and Commerce__BaseUrl.

🚨 The key names are contract. They are read out of environment variables, Key Vault secret names and helm values on every portal that sells, so renaming one is a silent deletion: a renamed key reads as absent, and absent means "this portal does not sell".

🚨 A secret's VALUE never leaves configuration. Nothing logs it, renders it or stores it on a node. The only thing derived from the secret key is its prefix, which names test-vs-live mode.

2. The webhook endpoint

Add an endpoint in the Stripe dashboard pointing at:

{Commerce:BaseUrl}/api/hooks/Store/Payments

Subscribe it to exactly these four events:

🚨 The last two are what keeps a subscription alive. An endpoint not subscribed to invoice.paid grants each plan exactly one month while Stripe keeps charging the card; without customer.subscription.deleted a cancelled subscriber keeps access forever.

Then allowlist the target on the portal: WebhookInbox:Targets:0 = Store/Payments. The inbox is fail-closed — without the allowlist the endpoint answers 404 and stores nothing, however correct the Stripe side is.

3. Test and live are separate worlds

Test-mode and live-mode endpoints are configured separately at Stripe, so a live-mode endpoint never fires for an sk_test_… checkout and vice versa. A key lists only the endpoints of its own mode — which is what lets Store/MaintenancePaymentPathAudit tell "no endpoint registered" apart from "registered in the other mode".

What the module does, and deliberately does not

Reading further

Reconnecting…
The server was updated. Reloading the page to pick up the latest version.