> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rocket.new/llms.txt
> Use this file to discover all available pages before exploring further.

# Add payments to your app

> Step-by-step Rocket.new guide to adding Stripe payments.

export const LlmsDirective = () => <blockquote className="llms-directive">
    For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
    For a lightweight markdown version of this page, append .md to the URL.
  </blockquote>;

<LlmsDirective />

Stripe is the fastest way to accept payments in your Rocket app. This tutorial walks you through connecting Stripe, creating a pricing page, setting up checkout, handling webhooks, and testing the full payment flow.

<Info>
  You'll need a [Stripe account](https://stripe.com) to follow this tutorial. Free to create - no charges until you process real payments.
</Info>

## What you'll set up

By the end of this tutorial, your app will have:

* A pricing page with plan options
* A Stripe Checkout flow for processing payments
* Webhook handling for payment events (successful charges, subscription changes)
* Test mode verification before going live

## Connect Stripe

<Steps>
  <Step title="Get your Stripe API keys">
    Log into your [Stripe Dashboard](https://dashboard.stripe.com/apikeys) and copy your **publishable key** and **secret key**. Make sure you're in **test mode** (toggle in the top-right of the Stripe dashboard).

    You'll have two pairs of keys:

    * **Test keys** - for development and testing (start with `pk_test_` and `sk_test_`)
    * **Live keys** - for real payments (start with `pk_live_` and `sk_live_`)
  </Step>

  <Step title="Add keys to your Rocket app">
    Ask Rocket to set up Stripe integration with your keys:

    ```plaintext wrap theme={null}
    Set up Stripe integration. My publishable key is pk_test_xxxxx and my secret key is sk_test_xxxxx. Store the secret key as a server-side environment variable.
    ```

    Rocket will store your secret key securely as an environment variable and configure the Stripe SDK in your app.

    <Warning>
      Never paste your **live** secret key directly into a prompt. Use test keys during development. Add live keys through Rocket's environment variable settings when you're ready to go live.
    </Warning>
  </Step>

  <Step title="Create products in Stripe">
    In your Stripe Dashboard, go to **Products** and create the plans you want to offer. For example:

    * **Free** - \$0/month
    * **Pro** - \$29/month
    * **Enterprise** - \$99/month

    Copy the **price ID** for each plan (starts with `price_`). You'll reference these when building your pricing page.
  </Step>
</Steps>

## Build a pricing page

Ask Rocket to create a pricing page that displays your plans and links to Stripe Checkout.

```plaintext wrap theme={null}
Create a pricing page with three plans: Free ($0/month), Pro ($29/month), and Enterprise ($99/month). The Pro plan should be highlighted as "Most Popular." Each plan should list 4-5 features and have a "Get Started" button that initiates Stripe Checkout for the corresponding plan. Use price IDs: price_free_xxx, price_pro_xxx, price_enterprise_xxx.
```

Rocket will generate a responsive pricing page with plan cards, feature lists, and checkout buttons.

## Set up Stripe Checkout

Stripe Checkout is a hosted payment page that handles card input, validation, and compliance for you. Ask Rocket to wire up the checkout flow:

```plaintext wrap theme={null}
Create a server-side API route that creates a Stripe Checkout session. When a user clicks a pricing plan's "Get Started" button, redirect them to Stripe Checkout for that plan. After successful payment, redirect to a /success page. After cancellation, redirect back to the pricing page.
```

The checkout flow works like this:

1. User clicks a plan on your pricing page
2. Your app creates a Stripe Checkout session on the server
3. User is redirected to Stripe's hosted payment page
4. After payment, user returns to your success page

<Info>
  Stripe Checkout handles PCI compliance, card validation, 3D Secure, and local payment methods automatically. You don't need to build a custom payment form.
</Info>

## Handle webhooks

Webhooks let Stripe notify your app when payment events happen - a charge succeeds, a subscription renews, or a payment fails.

<Steps>
  <Step title="Create a webhook endpoint">
    Ask Rocket to add a webhook handler:

    ```plaintext wrap theme={null}
    Create a webhook endpoint at /api/webhooks/stripe that handles these Stripe events: checkout.session.completed (activate the user's subscription), invoice.payment_succeeded (renew access), and customer.subscription.deleted (revoke access). Verify the webhook signature using the Stripe webhook secret.
    ```
  </Step>

  <Step title="Get your webhook secret">
    In the Stripe Dashboard, go to **Developers → Webhooks** and add an endpoint pointing to your app's webhook URL. Stripe will give you a **webhook signing secret** (starts with `whsec_`).

    Add this secret as an environment variable in your Rocket app.
  </Step>

  <Step title="Configure events">
    Select the events you want Stripe to send to your webhook:

    * `checkout.session.completed` - a customer completed payment
    * `invoice.payment_succeeded` - a subscription renewed
    * `invoice.payment_failed` - a payment attempt failed
    * `customer.subscription.deleted` - a subscription was cancelled
  </Step>
</Steps>

## Test your payment flow

Before going live, test everything end-to-end in Stripe's test mode.

<Steps>
  <Step title="Use test card numbers">
    Stripe provides test card numbers for different scenarios:

    | Card number           | Scenario                          |
    | --------------------- | --------------------------------- |
    | `4242 4242 4242 4242` | Successful payment                |
    | `4000 0000 0000 3220` | Requires 3D Secure authentication |
    | `4000 0000 0000 9995` | Payment declined                  |

    Use any future expiration date, any 3-digit CVC, and any billing zip code.
  </Step>

  <Step title="Test the full flow">
    Walk through the complete payment path:

    1. Go to your pricing page
    2. Click a plan's checkout button
    3. Complete payment with a test card
    4. Verify you land on the success page
    5. Check the Stripe Dashboard to confirm the payment appears
  </Step>

  <Step title="Test webhooks locally">
    Use the [Stripe CLI](https://stripe.com/docs/stripe-cli) to forward webhook events to your staging environment for testing:

    ```plaintext wrap theme={null}
    stripe listen --forward-to localhost:3000/api/webhooks/stripe
    ```

    Trigger a test event and verify your webhook handler processes it correctly.
  </Step>

  <Step title="Go live">
    When everything works in test mode:

    1. Switch your Stripe Dashboard to **live mode**
    2. Replace test API keys with live keys in Rocket's environment variables
    3. Update your webhook endpoint to use the live webhook secret
    4. Click **Launch** to deploy your app to production
  </Step>
</Steps>

<Warning>
  Double-check that your live secret key is stored as a server-side environment variable, not exposed in client-side code. Run the [security checklist](/learn/tutorials/security-checklist) before accepting real payments.
</Warning>

## What's next?

<CardGroup cols={2}>
  <Card title="Security checklist" icon="shield-check" href="/learn/tutorials/security-checklist">
    Ensure API keys and payment flows are locked down.
  </Card>

  <Card title="Launch your site" icon="rocket" href="/build/launch-web/launch-your-site">
    Test payment flows in staging before going live.
  </Card>

  <Card title="Deploy to the web" icon="globe" href="/build/launch-web/launch-your-site">
    Launch your app with payments to a live URL.
  </Card>

  <Card title="Prompting for Build" icon="hammer" href="/learn/guides/for-build">
    Write better prompts for app features and integrations.
  </Card>
</CardGroup>
