Payments - Stripe setup
web2app connects directly to your own Stripe account. Every payment from your funnel goes straight to you. You set up the connection once in Settings, then attach a Price ID to each plan in the editor.
Payments are optional while you build
You do not need Stripe keys to create funnels, edit steps, or publish drafts. Keys are required only when visitors should complete a real payment at the Checkout step. Until then, you can design the full flow and add keys when you are ready to test or go live.
What each Stripe key does
| Key | Where it runs | What breaks without it |
|---|---|---|
| Secret Key | web2app server | Checkout cannot create a payment — you see "Stripe is not configured" |
| Publishable Key | Visitor browser | Payment form does not load even if the server created a payment |
| Webhook Signing Secret | web2app server | Payment may succeed in Stripe, but Subscribers will not update |
The Publishable Key is public by design (like in any Stripe integration). web2app stores it as-is, not encrypted. Only server-side secrets are encrypted at rest.
Prefer Paddle?
web2app also supports Paddle as an alternative processor. Paddle is a Merchant of Record - it handles VAT and global tax compliance for you. See Payments - Paddle setup.
Step 1 - Get your Stripe API keys
- Sign in at dashboard.stripe.com.
- Go to Developers -> API keys.
- Copy the Publishable key (
pk_live_...). - For the server key, prefer a Restricted key instead of a full Secret key when possible.
Recommended restricted key permissions
web2app only uses your Stripe key to create checkout payment objects and to read Stripe objects needed to reconcile webhooks. It does not create refunds, transfers, payouts, disputes, products, or prices.
| Stripe resource | Access | Why web2app needs it |
|---|---|---|
| PaymentIntents | Write | Creates one-time payments for One-time/Lifetime plans. |
| PaymentIntents | Read | Reads payment intent metadata during invoice/refund webhook handling. |
| Customers | Write | Creates a Stripe Customer before creating a subscription checkout. |
| Subscriptions | Write | Creates subscriptions for recurring plans. |
| Subscriptions | Read | Reads subscription metadata/status from invoice webhooks. |
| Invoices | Read | Subscription creation expands latest_invoice.payment_intent; paid invoice webhooks are used for renewals. |
| Prices | Read | Recurring plans reference your Stripe Price ID (price_...). |
| Products | Read | Price/Product metadata may be returned with subscription/price data. |
Leave unrelated resources at None, especially Refunds Write, Transfers, Payouts, Disputes, Files, and account/balance management resources. Refunds should be created manually in Stripe Dashboard; web2app only listens for refund events.
Use test mode first
Switch the Stripe Dashboard toggle to Test mode to get pk_test_... / restricted test keys while you're building. Replace them with live keys when you're ready to go live. Test cards: 4242 4242 4242 4242, any future date, any CVC.
Step 2 - Add keys in Settings
- In the dashboard sidebar, open Settings.
- In the Active payment processor toggle, select Stripe.
- Paste your Secret Key and Publishable Key -> click Save.
Both keys are required for checkout. You will add the Webhook Signing Secret in the next step after creating the endpoint in Stripe.
Step 3 - Create a webhook endpoint
Stripe uses webhooks to tell web2app when a payment succeeds, a subscription renews, a charge fails, or a refund happens.
- In the Stripe Dashboard go to Developers -> Webhooks -> Add endpoint.
- In web2app Settings, copy the Webhook endpoint URL shown under your Stripe fields. It is unique to your workspace; paste it exactly as displayed.
- Paste that URL into the Endpoint URL field in Stripe.
- Under Events to send, select:
payment_intent.succeededinvoice.payment_succeededinvoice.payment_failedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedcharge.refunded
- Click Add endpoint.
- On the endpoint detail page, click Reveal next to Signing secret and copy the
whsec_...value. - Back in Settings, paste it into Webhook Signing Secret -> Save again.
One webhook per workspace
Each workspace has its own webhook URL in Settings. Do not reuse another team's URL or share yours where it could be misused.
Step 4 - Create a Price in Stripe
For each paid plan in your funnel you need a Stripe Price ID.
- In Stripe Dashboard go to Product catalogue -> Add product.
- Fill in the product name, for example "Monthly Subscription".
- Under Pricing, choose:
- Recurring -> pick interval: Weekly, Monthly, Every 3 months (quarterly), or Yearly
- One-time -> for lifetime or single-charge plans
- Set the amount and currency.
- Click Save product.
- Copy the Price ID. It starts with
price_, for exampleprice_1AbCdEfGhIjKlMn.
Step 5 - Attach the Price ID to a plan
- Open your funnel in the editor.
- Click the Paywall step.
- Open the Pricing section and find the plan you want (Monthly, Yearly, etc.).
- Paste the Price ID into the Stripe Price ID field.
- Set Billing in the editor to match what you chose in Stripe (Weekly / Monthly / Quarterly / Yearly / One-time).
- Save the step.
Repeat for each plan that should charge through Stripe.
One-time and lifetime plans
For One-time and Lifetime billing periods, Stripe charges the amount you entered in the editor directly. A Price ID is still required for these plans.
Step 6 - Publish and test
- Publish the funnel.
- Use Preview from the editor for a quick checkout check, or use Copy link for a full live-link test.
- Complete the flow to the Checkout step.
- Pay with a test card:
4242 4242 4242 4242, any future date, any CVC. - Check Subscribers in the dashboard. The payment should appear within seconds.
Keep the full default link
If your funnel uses the default domain, the copied URL includes workspace details. Keep the full link when testing Stripe checkout.
Express checkout methods
Express checkout methods are configured in Stripe, not in web2app. Apple Pay, Google Pay, Link, PayPal, Klarna, and Amazon Pay appear only when Stripe can offer them for the visitor's browser, device, currency, domain, and account settings. Apple Pay requires HTTPS and a verified merchant domain in Stripe. If you use a custom funnel domain, verify that exact visitor-facing domain.
Billing periods reference
| Editor value | Stripe interval | Stripe creates |
|---|---|---|
| Weekly | Every 1 week | Subscription |
| Monthly | Every 1 month | Subscription |
| Quarterly | Every 3 months | Subscription |
| Yearly | Every 1 year | Subscription |
| One-time | - | PaymentIntent |
| Lifetime | - | PaymentIntent |
What happens after payment
- Subscriptions (weekly / monthly / quarterly / yearly): Stripe handles renewals automatically. Failures update the status in Subscribers to Past due. Cancellations set it to Canceled.
- One-time / Lifetime: a single charge; no renewal.
- The visitor is sent to your Success step.
Refunds and disputes
Process refunds and handle disputes directly in your Stripe Dashboard. Refund events (charge.refunded) sync back to web2app purchase access state and can trigger refund.created webhooks.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| "Stripe is not configured" on checkout | Secret Key missing, not saved, or Paddle is active | In Settings, select Stripe and save the Secret Key |
| Payment form empty / publishable key error | Publishable Key missing or not saved | In Settings, save the Publishable Key (pk_...) |
| "This plan has no Stripe Price ID" | Price ID missing on the plan | Edit the Paywall step, add price_... to the plan |
| Payment succeeds but Subscribers not updated | Webhook not set up, wrong secret, or missing event | Check webhook URL, signing secret, and selected events in Settings |
| Card declined | Test card used in live mode (or vice versa) | Use 4242... in test mode; use real card in live mode |