> For the complete documentation index, see [llms.txt](https://kb.craftformswp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kb.craftformswp.com/documentation/ecommerce/online-payments/setup-stripe.md).

# How to Accept Online Payments with CraftForms and Stripe

Collecting payments through a WordPress form used to mean installing a dedicated e-commerce plugin, building a product catalogue, and wiring up a checkout page — even if all you needed was a simple order form or deposit request. CraftForms takes a different approach: payment is just another field. You build your form, drop in a Payment block, and your customers pay as part of filling it in.

Under the hood, CraftForms uses **Stripe** to handle the financial plumbing — card processing, security, receipts. Stripe is free to sign up for and charges no monthly fee; you pay only when you collect money (a small percentage per successful transaction).

This guide walks you through the full setup: creating your Stripe account, connecting it to CraftForms, wiring it into a form, and taking your first real payment.

**What you'll need:**

* A CraftForms Pro licence (payments are a Pro feature)
* A Stripe account (free — we'll create one below)
* A WordPress page to use as your payment success/confirmation page

{% hint style="info" %}
**Prefer video?** Watch the [Stripe setup walkthrough](https://www.youtube.com/watch?v=8J58ZmvzsHA) — it covers the same steps as this guide, screen-recorded end to end.
{% endhint %}

***

#### Step 1: Create a Stripe Account

If you already have a Stripe account, skip to Step 2.

Go to **stripe.com** and click **Start now**. Enter your email address, choose a password, and verify your email when Stripe sends you a confirmation link.

After logging in for the first time, Stripe will ask you to activate your account before you can accept real payments. Click **Activate account** in the top banner and complete the business details form. You'll need:

* Your country and business type (individual, company, etc.)
* Your legal name (or business name)
* A brief description of what you sell
* Your bank account details for payouts

Activation usually takes a few minutes for individuals and up to a couple of days for companies requiring additional verification. You can configure CraftForms and test everything while you wait — test mode doesn't require a fully activated account.

***

#### Step 2: Get Your Stripe API Keys

Stripe gives you two sets of API keys: one for **test mode** (safe for development, no real money moves) and one for **live mode** (real transactions). You'll start with test keys.

In your Stripe Dashboard:

1. Click **Settings** (the cog icon) → **Developers** (or find it in the top-right menu on newer Stripe layouts).
2. Open **API keys** → **Manage API keys**.
3. You'll see two keys under **Standard keys**:
   * **Publishable key** — starts with `pk_test_`. This one is safe to expose in the browser.
   * **Secret key** — starts with `sk_test_`. Keep this private; it gives full API access to your account.
4. Click **Reveal test key** next to the secret key to see its full value.
5. Copy both keys — you'll paste them into CraftForms in the next step.

![Stripe API keys page with the publishable and secret test keys](https://97821998-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FM2yV1foUgoGHBC66VBDw%2Fuploads%2FaPxreakFa5YsXzOLw7UO%2FSCR-20260527-kiqb.png?alt=media\&token=6328f8fe-a00e-4efa-a851-60f3194db535)

***

#### Step 3: Add a Stripe Connection in CraftForms

CraftForms keeps each payment account as a named **payment connection**. One connection holds exactly one set of keys, so your test keys and your live keys become two connections. See [Payment Connections](https://kb.craftformswp.com/documentation/ecommerce/online-payments/payment-connections) for how connections work.

1. In your WordPress admin, go to **CraftForms → Settings** and open the **Payments** tab. (Only users who can manage site settings see it — usually admins.)
2. Under **Payment Connections**, click **Add New**.
3. Fill in the window:
   * **Name** — something you'll recognise in the form editor, e.g. `Stripe — Test`.
   * **Gateway** — **Stripe**. It can't be changed once the connection is saved.
   * **Mode** — **Test**.
   * **Publishable key** — paste your `pk_test_...` key.
   * **Secret key** — paste your `sk_test_...` key. The eye icon shows what you pasted.

![The Add Payment Connection window with Stripe in Test mode](https://97821998-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FM2yV1foUgoGHBC66VBDw%2Fuploads%2FxRCNJaWDaM3TZuFkfxTL%2FSCR-20260924-ljxr.png?alt=media\&token=c7bdce7d-683a-4d76-8bef-c4f10317d396)

{% hint style="info" %}
**Using Embedded Payment only** (card fields inside your form)? The keys are enough: click **Save** and go to [Step 6](#step-6-set-your-redirect-urls).

**Using Hosted Checkout** (customers pay on Stripe's page)? Keep the window open and continue with Steps 4 and 5 — Hosted Checkout needs the webhook.
{% endhint %}

***

#### Step 4: Set Up a Stripe Webhook

A webhook is how Stripe tells CraftForms that a payment was completed (or failed). Without it, CraftForms has no reliable way to know whether your customer actually paid — they could close the browser right after checkout and the submission would never be recorded as paid.

**First, copy your Webhook URL from CraftForms.**

Lower in the same connection window, the **Webhook** section shows a **Webhook URL** with a **Copy** button, and the events Stripe should send. The URL is unique to your site; every Stripe connection on the site uses the same one.

**Now set up the endpoint in Stripe.**

Back in the Stripe Dashboard:

1. Go to **Developers → Webhooks**.
2. Click **Add endpoint**.
3. Paste your CraftForms Webhook URL into the **Endpoint URL** field.
4. Under **Listen to**, choose **Events on your account**.
5. Click **Select events** and add these four:
   * `checkout.session.completed` — the customer paid through Stripe Checkout
   * `checkout.session.expired` — a checkout session timed out without payment
   * `payment_intent.succeeded` — the underlying payment settled
   * `payment_intent.payment_failed` — a payment attempt failed
6. Click **Add endpoint** to save.

After saving, Stripe takes you to the endpoint's detail page.

***

#### Step 5: Add the Webhook Signing Secret

On the endpoint's detail page, find **Signing secret** and click **Reveal**. It starts with `whsec_`.

Copy it and paste it into **Webhook signing secret** in the CraftForms connection window. Then click **Save**.

This secret lets CraftForms verify that incoming webhook calls are genuinely from Stripe and not from someone trying to fake a payment confirmation. If it's missing or wrong, CraftForms rejects the webhook outright — so don't skip this.

***

#### Testing Locally with the Stripe CLI

Stripe's servers need a publicly reachable URL to deliver webhook events to — if you're developing on `localhost` or a site behind a firewall/VPN, Stripe can't reach it. The **Stripe CLI** solves this by forwarding webhook events from Stripe straight to your machine, so you can test the full payment-and-webhook flow without deploying first.

1. **Install the CLI.**

   ```
   brew install stripe/stripe-cli/stripe
   ```

   (or download a binary for your OS from Stripe's CLI docs).
2. **Authenticate it against your Stripe account:**

   ```
   stripe login
   ```

   This opens your browser to authorise the CLI — no keys to copy by hand.
3. **Forward events to your local site**, using the webhook path from Step 4 on your local domain:

   ```
   stripe listen --forward-to https://your-site.test/wp-json/craftforms/v1/stripe/webhook
   ```
4. The CLI prints a signing secret starting with `whsec_`, valid for this `stripe listen` session only. While testing locally, paste it into your test connection's **Webhook signing secret** instead of the one from your real Stripe endpoint. Put the real one back before you deploy.
5. Leave `stripe listen` running, then test a payment through your form as usual (Step 8). Every event shows up in the CLI output and is forwarded to CraftForms, just as in production.
6. To fire a specific event without a full checkout:

   ```
   stripe trigger payment_intent.succeeded
   ```

Your test keys (`pk_test_...` / `sk_test_...`) work as normal with the CLI — only the webhook signing secret changes, since each `stripe listen` session mints its own.

***

#### Step 6: Set Your Redirect URLs

On the same **Payments** tab, below the connections, the **Redirect URLs** section tells the gateway where to send your customer after they finish (or abandon) checkout. They're shared by every payment connection, so you set them once.

**Payment success URL**

The page a customer lands on after a successful payment. Create a dedicated page for it — something like `/order-confirmation` or `/thank-you` — and add the **CraftForms Order Summary** block to it. The block shows the order details by itself: CraftForms adds an order reference to the URL, so there's nothing to configure on the block. See [Order Summary](/documentation/ecommerce/orders/order-summary.md).

Paste the full URL of that page into **Payment success URL** (e.g. `https://yoursite.com/order-confirmation`).

**Payment cancel URL**

The page a customer returns to if they click **Cancel** or **Back** during Stripe Checkout. Set it to the page with your payment form, so they can try again.

Click **Save settings**. You should see "Settings saved".

***

#### Step 7: Add a Payment Block to Your Form

Open (or create) the form you want to take payments on in the block editor, and insert a [**CraftForms Payment** block](https://kb.craftformswp.com/documentation/form-building/create-form/blocks/payment-block).

With the block selected, open its settings in the right-hand sidebar:

* **Payment Gateways** — pick an account for each gateway you want to offer. Choose your Stripe connection under **Stripe account**. If you pick accounts for several gateways (Stripe and PayPal, say), the customer chooses which to pay with on the form. If you have no connections yet, the panel links back to Payment Settings.
* **Payment Mode** — choose how the customer pays:
  * **Hosted Checkout (redirect to gateway)** — the customer goes to Stripe's own Checkout page to enter card details, then returns to your success or cancel page.
  * **Embedded Payment (inline on the form)** — Stripe's card fields appear right inside your form.
* **Customer Data** — map your form's email and name fields to **Customer Email** and **Customer Name**. Stripe then sends its own receipt email and shows a readable customer in its dashboard.

The **Setup Checklist** panel reminds you to set the redirect URLs, to change your Submit Button label (e.g. "Pay & Submit"), and that **currency is set globally** under **Settings → Ecommerce**, not per block.

***

#### Step 8: Test a Payment

1. Open the page on your site that contains your payment form.
2. Fill in the form and pay.
3. Use one of Stripe's test cards. The connection window lists them too while the connection is in Test mode.

   | Card number           | What it simulates                 |
   | --------------------- | --------------------------------- |
   | `4242 4242 4242 4242` | Payment succeeds                  |
   | `4000 0025 0000 3155` | Asks for 3D Secure authentication |
   | `4000 0000 0000 0002` | Card is declined                  |

   Use any future expiry date (e.g. `12/29`), any 3-digit CVC, and any postal code.
4. Complete the payment.

If everything is configured correctly:

* You're redirected to your **Payment success URL**, and the Order Summary block shows the order.
* In WordPress, **CraftForms → Submissions** shows the submission as paid.
* In the Stripe Dashboard under **Payments**, the test payment appears.

**If the redirect doesn't happen or the submission isn't marked paid**, check your webhook. In Stripe, go to **Developers → Webhooks → your endpoint** and open **Recent deliveries** — failed attempts are listed there with what went wrong.

Common causes:

* The webhook URL wasn't copied correctly (copy it again from the connection window and update the Stripe endpoint)
* The signing secret doesn't match (copy the `whsec_` value from the endpoint page again and save the connection)
* Your site is on localhost or behind a firewall Stripe can't reach (use the Stripe CLI above, or test on a public staging site)

***

#### Step 9: Go Live

Once test payments work end to end, you're ready to accept real money. Going live means a second connection with your live keys; the test one can stay for later testing.

**Get your live API keys from Stripe.** In the Stripe Dashboard, switch from **Test mode** to **Live mode** (top right), go to **Developers → API keys**, and copy the keys starting with `pk_live_` and `sk_live_`.

**Create a live webhook endpoint.** Your test endpoint only receives test-mode events. Still in Live mode, go to **Developers → Webhooks → Add endpoint** and repeat Step 4 with the same Webhook URL and the same four events. Copy the new endpoint's `whsec_` signing secret.

**Add a live connection in CraftForms.** Under **Settings → Payments → Payment Connections**, click **Add New**: name it e.g. `Stripe — Live`, choose **Stripe**, set **Mode** to **Live**, paste the live publishable and secret keys and the live signing secret, and click **Save**.

**Switch your forms to it.** In each form's Payment block, change **Stripe account** to the live connection and update the form.

> **A word of caution:** Once a form uses a live connection, every payment on it charges a real card. Run one real payment yourself (you can refund it straight away from the Stripe Dashboard) to confirm the flow works in production.

***

#### Troubleshooting

**Webhook signature mismatch error** The signing secret in the connection doesn't match the one on the Stripe endpoint. Open the endpoint in Stripe → Developers → Webhooks, click **Reveal** on the signing secret, and paste it again into the connection. Test and live endpoints have different secrets.

**Form submits but payment isn't recorded** The webhook probably isn't reaching your server. Check Stripe → Developers → Webhooks → your endpoint → Recent deliveries; the error details there point to the cause (wrong URL, server returning an error, etc.).

**Wrong keys for the connection's mode** A Stripe error like "No such customer" or "Invalid API key" often means live keys in a Test connection, or the other way round. A Test connection needs `pk_test_` / `sk_test_` keys; a Live connection needs `pk_live_` / `sk_live_`.

**Success page shows a blank Order Summary** Make sure the Order Summary block is on the page set as your Payment success URL, and that the URL in settings matches the page's actual address.

**"No account selected — the payment block will not render on the frontend"** The Payment block has no account picked for any gateway. Choose your Stripe connection under **Stripe account**.

***

#### You're All Set

Here's a recap of what you configured, and where to find it again:

| Setting                                        | Where                                                                        |
| ---------------------------------------------- | ---------------------------------------------------------------------------- |
| Connection name, mode (Test/Live) and API keys | CraftForms → Settings → Payments → Payment Connections → Edit                |
| Webhook URL                                    | Shown in the connection window; pasted into Stripe → Developers → Webhooks   |
| Webhook signing secret (`whsec_`)              | Copied from Stripe, pasted into the connection window                        |
| Payment success URL / Payment cancel URL       | CraftForms → Settings → Payments → Redirect URLs (shared by all connections) |
| Currency & number format                       | CraftForms → Settings → Ecommerce                                            |
| Which account, checkout mode, customer data    | The Payment block's settings, per form                                       |

From here, add a Payment block to any CraftForms form, pick your Stripe account, and set your price — your customers pay as part of submitting the form.
