When visitors cannot pay or an entry does not jump to "Paid", the cause is usually the connection to the payment provider, the amount, or a message from the provider that does not arrive. This article shows how to find the cause and fix it.
Requirements
- Funnelforms Pro. This feature is not included in Funnelforms Free.
- The right to see entries, to see the payment status and errors in the entry.
- To change connections, the right to change settings.
- A payment is set up in the form (section Payment in the Settings workspace).
Funnelforms Free does not show forms with a payment on the website; no entries with a payment come in there.
Where to find it
Funnelforms → Entries → open an entry → section Payment (with Check status).
Settings: Funnelforms → Forms → open a form → workspace Settings → section Payment.
Features at a glance
- The Payment section of the entry shows Status, Amount, Provider, Paid on, Coupon, Subscription, Reference and, if there are problems, Error.
- The badge Test payment marks payments made with test keys.
- Check status asks the provider for the current state right away.
- Funnelforms checks open payments with the provider every hour.
- With Edit you change the keys of a connection.
- Visitors can start a new attempt with Pay now.
Step by step
- Open Funnelforms → Entries and the affected entry.
- In the Payment section, read the Status and, if present, the Error.
- Click Check status. The message "Payment status updated." confirms the query.
- Compare the status with your account at the provider. With Stripe and Mollie, the Reference leads directly to the payment in the dashboard.
- If needed, adjust the connection, the amount or the webhook. You change keys in the Payment section at the connection with Edit.
- Publish the form if you changed settings.
- Check with a test payment. Use the test keys or the PayPal sandbox for it.
How it works
What do the error codes in the entry mean?
Under Error, the entry shows the code with which the last attempt at the provider ended. The word permanent: in front means that another attempt with the same data would change nothing.
| Code | Meaning |
|---|---|
permanent:connection_incomplete | The key is missing or does not have the expected format |
permanent:connection_missing | The connection was deleted or is gone |
permanent:http_401, permanent:http_403 | The provider rejected the credentials or rights |
permanent:http_400, permanent:http_404, permanent:http_422 | The provider rejected the request, for example because of the amount or currency |
http_429, http_500 to http_503 | The provider is overloaded or disrupted right now. A new attempt can work |
http_error | The provider could not be reached |
invalid_response | The provider answered without a payment page |
What happens if the payment cannot be started?
- If the connection is missing or the calculation of the amount fails, Funnelforms does not accept the entry at all. There is then no entry. The visitor sees "The payment could not be started. Please try again later."
- If the provider does not answer, the entry stays. The visitor sees the same message with the Pay now button and can try again. The entry shows the error.
When does the status jump to "Paid"?
Funnelforms asks the provider when the visitor returns, when a webhook arrives from Stripe, when you click Check status and during the hourly check. The check runs one hour after a payment starts and then every hour while payments are open. It covers payments of the last 7 days with Not paid yet or Payment pending. A call from outside cannot mark anything as paid; Funnelforms always asks the provider itself.
Which Stripe events does the webhook need?
checkout.session.* for payments, customer.subscription.* for subscriptions, charge.refunded for refunds and charge.dispute.created for disputes. With every event, Funnelforms asks for the current state itself. After a chargeback the entry shows "Payment disputed" as long as Stripe reports the payment as disputed and it is not refunded. How the dispute ends, you see in the Stripe dashboard.
Why does a SEPA entry stay on "Payment pending"?
For payment methods with a waiting time, the bank confirms later. Until then the entry stays on "Payment pending". Funnelforms learns the result through the Stripe webhook, the hourly check or at the next Check status. After 7 days the check stops; then Check status helps.
Why does the entry show "Test payment"?
The connection used test keys when the payment started: Stripe sk_test_… or rk_test_…, Mollie test_… or a PayPal sandbox app. Nobody was charged. The form's Payment section then shows Test mode.
Why do I have to publish the form after a change?
Visitors see the published version. Changes to the amount, connection, coupons or charging only apply after Publish. Entries already being paid keep their settings. New keys of a connection, however, apply right away to all forms that use it.
Best practices
- Test with a test entry after every change.
- With Stripe, set up the webhook with all four event groups.
- Check unpaid entries regularly, especially those older than 7 days, and click Check status if needed.
- Keep keys up to date. If a key expires or is revoked, new payments fail with
permanent:http_401. Then enter the new key with Edit.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Visitors see "The payment could not be started. Please try again later." and there is no entry | The connection is missing, or the calculation of the amount failed | In the Payment section, choose an existing connection. Check the calculation and its fields |
| The same message, but the entry exists | The provider did not answer or answered with an error | Read the Error in the entry and use the table above. The visitor can click Pay now |
| The entry stays on "Not paid yet" although it was paid | The provider's message did not arrive, or the visitor did not come back | Click Check status or wait for the hourly check. Set up the webhook for Stripe |
| Stripe: the webhook does not work | Wrong address, wrong signing secret or missing events. Funnelforms rejects calls with an invalid signature (HTTP 400) | Add the address shown as an endpoint in Stripe, choose checkout.session.*, customer.subscription.*, charge.refunded and charge.dispute.created, and enter the signing secret through Enter signing secret |
| Stripe: the signature is rejected although the secret is correct | The calls are older than five minutes, or the server clock is wrong | Check the date and time of the server |
| Stripe: subscription status or refund missing in the entry | The webhook only reports checkout.session.* | Add customer.subscription.* and charge.refunded in Stripe, then Check status |
| Mollie: the status does not change right away | The website is not reachable for Mollie, for example a local test site | Use a publicly reachable website, wait for the check or click Check status |
| PayPal: the payment shows "Not paid yet" | The visitor did not confirm the payment at PayPal or did not return | Click Check status or ask the visitor to click Pay now |
| Entries carry Test payment | The connection uses test keys | Enter the live keys at the connection with Edit, or choose a live connection |
permanent:http_401 after changing a key at the provider | The stored key is no longer valid | Click Edit at the connection and enter only the new key; empty fields keep the stored values |
| The amount is wrong | The calculation gives a different result, a coupon applied or a deposit is set | Check the calculation, Coupon in the entry and Deposit in percent. The entry shows "charged / total" |
| A coupon has no effect | No field or another field is chosen under Coupon code from the field, the code is not created or the form is not published | Check field and code and publish the form |
| Nothing is charged and the form ends normally | The amount is 0 or less, for example because of a 100 percent coupon | Check the calculation, the fixed amount and the coupons |
| The confirmation mail does not arrive | The action waits for Once the payment went through | Check the status. The action runs as soon as the payment has come in for the first time |
| A subscription cannot be set | Subscriptions only exist with Stripe | Use a Stripe connection |
| Stripe: the entry shows "Payment disputed" | The visitor disputed the payment with their bank | Respond to the dispute in the Stripe dashboard. Then click Check status |
| A partial refund does not show "Refunded" | The status "Refunded" only applies to full refunds | Check partial refunds in your account at the provider |
| The form no longer appears on the website | The website uses Funnelforms Free, which has no payments | Use Funnelforms Pro, or turn off Take a payment after the contact step under Settings → Payment and publish the form again |
Tips
- The error in the entry is a technical code. Quote it when you contact support, but never keys.
- Funnelforms stores keys encrypted and never shows them again, not even with Edit.
- Funnelforms writes status changes to a log of the website.
- New attempts through Pay now are limited: at most ten in ten minutes per visitor address and form. After that, "The payment could not be started. Please try again later." appears again.
FAQ
How do I see whether a payment has arrived? Open the entry. The status is in the Payment section. Click Check status to ask the provider for the current state.
What can a visitor do if the payment does not work? They can click Pay now and try again, possibly with another payment method. Their answers stay saved.
Can anyone mark an entry as paid without paying? No. Funnelforms always asks the provider. The visitor's browser and calls from outside cannot set the status.
Can I change the keys of a connection? Yes, with Edit at the connection ("Edit connection"). Fill in only what changes.