Architecture
A form may contain at most one Stripe Payment block.
Connect Stripe (global)
1
Open Stripe API keys
Use Stripe Dashboard → API keys. Start in Test mode.
2
Paste keys in Flex Forms
Integrations → Stripe → enable → Mode Test → paste
pk_test_… and sk_test_… → Save. Flex Forms verifies the secret against Stripe’s Balance API and marks the connection Ready when it succeeds.3
Optional webhook (recommended)
In Stripe → Developers → Webhooks, add your endpoint:
https://your-domain.com/flex-forms/integrations/stripe/webhook(Named route: flex-forms.stripe.webhook.)Subscribe to all of these events:Paste the
whsec_… signing secret into Stripe integration settings.4
Go Live
Switch Mode to Live, paste live keys, save, and restrict the publishable key by domain in Stripe. Use a separate Live webhook endpoint (or dual endpoints) with the Live signing secret.
Payment block settings (Studio)
After Stripe is Ready, insert Stripe Payment from Payments (see also the block page). Configure on the block (not in Form Integrations):- Required — when off, respondents may submit without paying (optional payment / donation-style forms)
- Payment type
- Fixed amount — one charge amount
- Product options (choice cards) — labeled options with prices (Studio canvas: Add option → name + price). On fill, respondents pick a radio card.
- Customer enters amount — free amount field; optional minimum / maximum toggles with amounts below each toggle
- From a form field — pick a Number, Number stepper, or Currency field from a dropdown (Amount field)
- Also allow custom amount — when using Product options, let respondents type their own amount instead
- Currency — one currency for the whole Payment block
- Charge description
- Capture — Automatic or Manual authorize
- Payment methods
- Automatic (Dynamic payment methods) — Stripe shows relevant methods for the currency and your Dashboard (cards, BLIK, Przelewy24, Klarna, Apple Pay / Google Pay when eligible)
- Cards only — card Payment Element only
- Stripe receipt email — Stripe’s API supports
PaymentIntent.receipt_emailand emails a receipt on successful capture. Flex Forms options:- Do not send
- Primary email on the form
- Specific email field
- Email collected in Stripe Payment Element — uses the billing email typed in the payment UI (ConfirmationToken → patch PI → confirm)
- Collect billing name, email, phone, address — Stripe’s Payment Element collects these when the selected payment method needs them
- Collect shipping address — when on, Stripe can collect a shipping address in the payment form
- Show amount summary
- Save payment method (
setup_future_usage) - Statement descriptor suffix
Poland / wallets checklist (Dynamic payment methods)
Use Payment methods → Automatic and complete these in Stripe (not inside Flex Forms):- Payment methods — enable BLIK, Przelewy24, Klarna, cards, wallets as needed
- Charge currency on the block (e.g. PLN for BLIK)
- Public fill URL over HTTPS (required for wallets)
- Register your domain for Apple Pay in the Stripe Dashboard
- Test with Stripe test cards / test BLIK codes before switching to Live
Fill runtime
- Stripe.js loads only on fill/embed when the form includes the Payment block.
- Respondents see fixed amount, product choice cards, and/or a custom amount field — depending on Payment type.
- Payment Element mounts in accordion layout (radios always visible) with your publishable key.
- On submit (when Required is on), Stripe confirms the PaymentIntent.
- When Required is off, submit can succeed without a payment.
- Flex Forms verifies amount, currency, form metadata, and mode — then saves the submission and writes the Transactions ledger.
- The submit button stays disabled with a sending label until the AJAX request finishes (no full page reload).
Preview vs published
Transactions hub
Open Transactions in the Flex Forms left rail (next to Contacts). You’ll see cursor-paginated payments with provider, status, amount, payer, and form. From the hub you can:- Export CSV (respects filters)
- Refund (full remaining balance) or Partial… refund for Stripe payments that are succeeded or partially refunded
charge.refunded events (including refunds started in the Stripe Dashboard).
Permissions (optional Spatie): viewTransactions, exportTransactions, refundTransactions — see Studio permissions.
Troubleshooting
Form shows thank-you but no payment / empty Transactions
Form shows thank-you but no payment / empty Transactions
Most often the form is still a draft or you opened Preview. Publish the form, use the public fill URL, and confirm Stripe mode (Test vs Live) matches the keys you pasted.
Payment Element does not mount
Payment Element does not mount
Stripe must be Ready in Integrations, the Payment block must be on the form, and the fill page must load over HTTPS in production. Check the browser console for Stripe.js errors and that the publishable key matches the mode.
Webhook signature errors
Webhook signature errors
Paste the exact
whsec_… for that endpoint. Test and Live secrets differ. Endpoint path must be /flex-forms/integrations/stripe/webhook on the same host that serves Flex Forms.