This recipe walks you through the complete Stripe integration from initial account setup through test mode, live mode, webhook configuration, and common troubleshooting.
Step 1: Create Your Stripe Account
- Go to stripe.com and click Start now
- Enter your email, full name, and create a password
- Verify your email address
- Complete the onboarding to activate your account (business details, bank account for payouts, etc.)
If you want to test first before completing onboarding, Stripe lets you use Test mode immediately.
Step 2: Get Your Test Mode API Keys
- In the Stripe Dashboard, make sure the Test mode toggle is on (top right)
- Go to Developers > API Keys
- You will see two keys:
pk_test_
– Secret key: starts with sk_test_ (click to reveal)
- Copy both keys
Step 3: Connect Stripe to Fillin Forge
- In WordPress, go to Fillin Forge > Settings (the Stripe Payments card)
- Paste the Publishable Key and Secret Key
- Make sure the mode is set to Test
- Save settings
Step 4: Set Up the Stripe Webhook
Webhooks let Stripe notify Fillin Forge about payment events (successful charges, refunds, failures).
- In the Stripe Dashboard, go to Developers > Webhooks
- Click Add endpoint
- Enter the webhook URL shown in your Fillin Forge Stripe settings page (it looks like
https://yoursite.com/wp-json/formforge/v1/stripe/webhook) - Under Events to send, select
payment_intent.succeeded,payment_intent.payment_failed, andcharge.refunded - Click Add endpoint
- On the next screen, click to reveal the Signing Secret (starts with
whsec_) - Copy this Signing Secret
- Back in Fillin Forge, paste it into the Webhook Signing Secret field
- Save settings
Step 5: Create a Payment Form
- Go to Fillin Forge > New Form
- Add your regular fields (Name, Email, etc.)
- If you need dynamic pricing, add a Calculation field with a formula (e.g.,
{quantity} * 25) - Drag the Payment (Stripe) field into the form
- Configure the payment:
– Currency: Select your currency (USD, EUR, GBP, etc.)
- Save the form
Step 6: Test in Test Mode
- Embed the form on a test page
- Fill out the form and use Stripe’s test card:
4242 4242 4242 4242 - Enter any future expiration date (e.g., 12/30) and any 3-digit CVC (e.g., 123)
- Click Submit
- Verify:
– The payment appears in your Stripe Test Dashboard under Payments
Test other scenarios:| Test Card Number | Result |
|---|---|
| 4242 4242 4242 4242 | Successful payment |
| 4000 0000 0000 0002 | Card declined |
| 4000 0000 0000 9995 | Insufficient funds |
| 4000 0025 0000 3155 | Requires 3D Secure authentication |
Step 7: Switch to Live Mode
Once you are confident everything works:
- In Stripe Dashboard, turn off the Test mode toggle
- Go to Developers > API Keys and copy the Live keys (
pk_live_andsk_live_) - In Fillin Forge Settings, replace the test keys with live keys
- Change the mode to Live
- Create a new webhook endpoint for live mode (repeat Step 4 with live keys)
- Update the Webhook Signing Secret
- Save settings
Troubleshooting Common Payment Issues
| Problem | Cause | Solution |
|---|---|---|
| “Your card was declined” | Using a test card in live mode, or a real card in test mode | Verify you are in the correct mode |
| Payment field not appearing | Stripe keys are missing or invalid | Check Fillin Forge > Settings (Stripe Payments card) |
| Visitor reads “Payment could not be verified. If you were charged, please contact us before trying again.” | Stripe does not confirm the payment for this form: it is not paid, it was made for another form or field, in another currency, or in test mode on a live site, or it already belongs to another submission | The submission is not saved. Find the payment in your Stripe Dashboard, in the mode the form uses, and check it there |
| Submission shows “Payment not confirmed” | Stripe could not be asked when the form was sent | Wait: Fillin Forge asks again by itself through WP-Cron, for roughly the first three days after the submission. Or open the submission and press Check payment in Stripe |
| Submission shows “Not paid” | A later check found no completed payment in Stripe for this submission | Look for the payment in Stripe; press Check payment in Stripe in the submission to ask again |
| Submission shows “Paid amount differs” | The payment is for another amount than the values of the submission come to | Compare the two amounts in Stripe before you fulfil the order. The Check payment in Stripe button is not offered for this status |
| “Invalid API key” error | Keys are from the wrong mode or account | Re-copy keys from the correct mode |
| 3D Secure not completing | Popup blocked or network issue | Ensure popups are not blocked; test on another browser |
| Refund needed | Customer requested refund | Process refunds directly in the Stripe Dashboard; the charge.refunded webhook updates the saved submission status to refunded |
Payment submissions hide internal metadata keys such as _payment and __payment from emails, Slack, Discord, Telegram, the submission modal, CSV, and PDF. User-facing surfaces show readable payment rows instead: Payment status, Payment amount, and Payment date (and, beside the status, a Payment note when the payment is not confirmed, not paid, or paid for another amount). The normal Payment (Stripe) field can still show the PaymentIntent ID when it is useful for reconciliation.
—