# Stripe

> This page is about FlutterFlow (the app builder you use by describing your app), not FlutterFlow Studio.

URL: https://docs.flutterflow.io/ffx/stripe

Connect Stripe with a test key, ask for checkout or a subscription, and check the payment before you accept an order.

Use Stripe to add a hosted checkout or a subscription to your app. Start with a test key so you can test payments before you accept real money.

## Connect Stripe {#before-you-start}

Stripe checkout requires a connected Stripe account and prices for what you sell:

- A Stripe connection set up by an app owner. Only owners can connect services.
- For subscriptions, recurring prices in Stripe. Every price in a subscription checkout must be recurring.
- Either a default price on each active product in Stripe, or the exact price ID (starting with `price_`) to give the agent. The agent automatically sees only each active product's default price.

To connect a test key:

1. Open **Project Settings › Connections** and select **Stripe**.
2. Paste your Stripe test secret key into **Secret key**, and then select **Connect**.

See [Connect a service](https://docs.flutterflow.io/ffx/connect-a-service).

<Mock name="stripe-test-connection" alt="Stripe's Account card in Project Settings › Connections › Stripe, with the Stripe row reading Connected as Ledger test account." />

## What to ask

Ask the agent for the payment flow and how the app verifies the payment:

> Example request: "Add Stripe checkout for booking a visit. Use a price from my connected Stripe account. After checkout, read the payment back and confirm the amount, currency, and booking before marking it paid."

> Example request: "Add subscription checkout using a recurring Stripe price. Ask me which recurring price to use and where to send people after they pay or cancel."

> Example request: "Check the Stripe checkout session whose ID I provide. Tell me whether it was paid, the total and currency, and the order reference."

Creating a checkout returns a URL for the payment page. It doesn't confirm that the customer paid. To verify payment, your app reads the session back or checks Stripe's payment event.

When paying unlocks something, such as marking an order paid, the agent might do that check in your app's server code, using the payment record Stripe sends. If that code also calls Stripe itself, the agent asks you to save your Stripe key again as a server secret. If you ask it to react to other Stripe events, it can also ask for a webhook signing secret and give you an address to add in Stripe.

## Agent questions {#what-the-agent-may-ask-you}

If Stripe isn't connected, the agent shows a connection card. Connect Stripe through that card, or ask an owner to connect it. See [Answer the agent](https://docs.flutterflow.io/ffx/answer-the-agent).

## Review {#check-the-result}

After the agent finishes, read the turn's [**Summary**](https://docs.flutterflow.io/ffx/what-changed#summary) and review its [**Changes**](https://docs.flutterflow.io/ffx/what-changed#changes-tab). Check the affected screens in **Screens**, and try the change in **Preview**. If the change uses records or sign-in, test it with [the thread's own data in **Data**](https://docs.flutterflow.io/ffx/thread-data).

After you push a backend change, check the result in **Backend**.

A checkout counts as paid only when its payment status is `paid`. Before you accept an order, verify that the returned total, currency, and order reference match the order. Returning to your app from checkout doesn't prove payment on its own.

## Push {#push-it}

After you test the payment flow, [push the changes to your app](https://docs.flutterflow.io/ffx/push).

## Live payments {#switch-to-live-payments}

When you're ready to accept real payments, replace the test key with your live Stripe key: open the Stripe account's options menu and select **Replace key**.

If you also saved your Stripe key as a server secret, replace it with your live key too: in **Backend › Secrets**, under **Server secrets**, select **Rotate** on that secret. **Replace key** changes only the connection.

Previews and the agent in your threads share your app's connection to each service. When you use **Replace key** to swap a test key for a live key, previews and the agent switch to the live key too. Each connection belongs to the app where you added it; reusing a key from another app creates an independent copy, so replacing or disconnecting one leaves the other unchanged. See [Manage connections](https://docs.flutterflow.io/ffx/manage-connections).

## Store purchases {#store-purchases}

In-app purchases through the App Store and Google Play aren't available. Use Stripe for real-world goods and services, such as visits, deliveries, or tickets.

## Troubleshooting {#if-something-goes-wrong}

For a failed connection or service call, see [Troubleshoot connections](https://docs.flutterflow.io/ffx/troubleshoot-connections). If a subscription checkout fails, verify that its Stripe prices are recurring. If your app can't read a payment back, check that the session was created with the same connection: test keys can't read live payments, and live keys can't read test payments.
