What you get
Stripe Checkout as your card processor. When a client visits your public payment page and chooses "Card," RemixCRM creates a Stripe Checkout Session and redirects them to Stripe's hosted page. Stripe handles the card form, 3D Secure, Apple Pay, Google Pay, and Link automatically.
On successful payment, Stripe redirects back to RemixCRM, which:
- Verifies the session was paid via the Stripe API
- Marks the payment row
completed - Stores the Stripe receipt URL
- Tries to match the payment to an event (by client email + event date)
- Fires the
payment.recordedwebhook
No additional UI work is needed — the public pay page automatically uses Stripe when you select it as the provider.
Prerequisites
- A Stripe account at dashboard.stripe.com
- Your business verified in Stripe (required to take live payments — sandbox/test mode works immediately)
Setup
1. Get your API keys
In the Stripe Dashboard:
- Go to Developers → API keys
- You'll see two keys:
- Publishable key — starts with
pk_test_…(test mode) orpk_live_…(live mode) - Secret key — starts with
sk_test_…orsk_live_…. Click "Reveal" to see it.
- Publishable key — starts with
Keep these handy. The secret key is sensitive — don't paste it into chat or commit it to a repo.
2. Configure in RemixCRM
- Go to Settings
- Find the Card Processor section
- Select Stripe
- Scroll to Stripe Payments below
- Pick Environment:
- Test (sandbox) — use
pk_test_…/sk_test_…keys. No real charges. - Live (production) — use
pk_live_…/sk_live_…keys. Real money.
- Test (sandbox) — use
- Paste Publishable Key and Secret Key
- Click Save
3. Test the flow
- Visit your public pay page:
https://app.remixcrm.com/pay/<your-org-slug> - Fill in name, email, event date, amount
- Click Continue to Stripe Checkout
- You're redirected to Stripe — enter a test card:
4242 4242 4242 4242— succeeds4000 0000 0000 9995— insufficient funds- Any future expiry, any CVC, any ZIP
- After payment, Stripe sends you back to RemixCRM
- You should see a green "Payment received" confirmation
- Check Settings → Reports → Payments to see the row
4. Switch to live
Once tested:
- Settings → Card Processor → Stripe Payments
- Change Environment to Live
- Replace both keys with
pk_live_…andsk_live_… - Save
Tip: Use Stripe's Restricted Keys for the secret key in production — generate one with only
payment_intents.writeandcheckout.sessions.writepermissions. Less blast-radius if it ever leaks.
How RemixCRM uses Stripe
| Step | API call |
|---|---|
| Client clicks "Continue to Stripe Checkout" | POST /v1/checkout/sessions |
| Client completes payment on Stripe | (handled by Stripe-hosted page) |
Stripe redirects to /pay/<slug>?stripe_session_id=cs_…&paid=1 |
(handled by browser) |
| RemixCRM verifies | GET /v1/checkout/sessions/{id}?expand=payment_intent |
| RemixCRM fetches receipt URL | GET /v1/payment_intents/{id}?expand=latest_charge |
All calls run server-side using your secret key. The publishable key is exposed publicly (as it must be) but it can only create sessions, not query the account.
Idempotency: each click creates a new Checkout Session. Stripe rejects double charges on the same Session, so abandoned-then-resumed sessions don't double-charge.
Webhooks (optional)
The current implementation polls the session on return to verify payment, so inbound Stripe webhooks are not required. If you want richer events (refunds, disputes, recurring billing), you can wire Stripe webhooks later — but the baseline pay flow needs no webhook setup at all.
Troubleshooting
"Stripe is not configured for this business" on the pay page
The org's payment_provider is set to stripe but stripe_secret_key is
missing. Go to Settings → Card Processor → make sure all three Stripe fields
are filled and saved.
Payment succeeds in Stripe but the row stays "pending" in RemixCRM
This happens when the user closes the tab before Stripe redirects back. The charge is real but the confirm step never ran. Fix: open the event's Payments tab, find the pending row, and click "Confirm." Or query the session ID in Stripe to verify and manually update.
In a future release this gap will be closed by a Stripe webhook subscription —
filing this as payment.session_id_orphaned in your bug reports is helpful
data.
Receipt URL is missing after payment
We fetch it via latest_charge on the PaymentIntent. If your Stripe account
hasn't enabled receipts, the URL will be null. Enable receipts in Stripe
Dashboard → Settings → Customer emails → "Successful payments."
"Stripe error: No such payment_intent"
The session belongs to a different Stripe account than the one whose keys are in Settings. This usually means you copied test keys but Stripe ran the session in live mode (or vice versa). Match the environment.