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

# Stripe

> Process payments, manage subscriptions, and run a Stripe-hosted billing portal — all through Archie's auto-generated GraphQL API.

The Stripe integration handles payments, subscriptions, invoicing, and refunds in your Archie app. Once you connect it, Archie exposes a namespaced set of GraphQL queries and mutations (`stripe_*`) that your frontend, custom functions, and backend routes can call.

<Note>
  A typed TypeScript SDK for integrations is coming with the next archie-app release. This page documents the GraphQL operation surface available today.
</Note>

## Enable the integration

Open the **Integrations** module in the left sidebar and pick Stripe from the catalog.

You'll need from your [Stripe dashboard](https://dashboard.stripe.com/apikeys):

* **Secret Key** — starts with `sk_test_` (test mode) or `sk_live_` (production). Used by the backend to authenticate API calls.
* **Publishable Key** — starts with `pk_test_` or `pk_live_`. Safe to use in the frontend.
* **Environment** — pick `TEST` while building, `LIVE` when you're ready to take real payments.
* **Webhook Secret** *(optional)* — `whsec_...`. Required if you want Archie to verify Stripe webhook signatures.

Archie encrypts the secret key with AES-256-GCM before storing it. Keys are scoped per project per environment, so test credentials on a development branch never touch production.

## What you can do

The integration adds GraphQL operations for everything most apps need from Stripe:

* **Customers** — `stripe_customer`, `stripe_customers`, `stripe_createCustomer`, `stripe_updateCustomer`, `stripe_deleteCustomer`
* **Payment intents** — `stripe_paymentIntent`, `stripe_paymentIntents`, `stripe_createPaymentIntent`, `stripe_updatePaymentIntent`, `stripe_confirmPaymentIntent`, `stripe_cancelPaymentIntent`
* **Subscriptions** — `stripe_subscription`, `stripe_subscriptions`, `stripe_createSubscription`, `stripe_updateSubscription`, `stripe_cancelSubscription`
* **Products and prices** — `stripe_products`, `stripe_createProduct`, `stripe_prices`, `stripe_createPrice`
* **Invoices** — `stripe_invoice`, `stripe_invoices`, `stripe_payInvoice`
* **Refunds** — `stripe_refunds`, `stripe_createRefund`
* **Checkout sessions** — `stripe_createCheckoutSession` for Stripe-hosted checkout
* **Billing portal** — `stripe_createBillingPortalSession` for self-serve subscription management
* **Payment methods** — `stripe_paymentMethods`, `stripe_attachPaymentMethod`, `stripe_detachPaymentMethod`
* **Webhook events** — `stripe_webhookEvents` for inspecting signed events Archie has received

All list queries support cursor-based pagination via `first` and `after`.

## Calling Stripe from your app

### Create a customer

```graphql theme={null}
mutation {
  stripe_createCustomer(input: {
    name: "Ada Lovelace"
    email: "ada@example.com"
    phone: "+15551234567"
    metadata: { plan: "founder" }
  }) {
    id
    email
    createdAt
  }
}
```

### Create a Checkout session

For Stripe-hosted checkout (the easiest path for most builders):

```graphql theme={null}
mutation {
  stripe_createCheckoutSession(input: {
    mode: "subscription"
    customerEmail: "ada@example.com"
    successUrl: "https://yourapp.com/welcome"
    cancelUrl: "https://yourapp.com/pricing"
    lineItems: [{ priceId: "price_1ABC...", quantity: 1 }]
  }) {
    id
    url
  }
}
```

Redirect the user to the returned `url`. Stripe handles the payment and redirects to your `successUrl` when complete.

### Open the billing portal

Let customers manage their own subscription:

```graphql theme={null}
mutation {
  stripe_createBillingPortalSession(input: {
    customerId: "cus_..."
    returnUrl: "https://yourapp.com/account"
  }) {
    url
  }
}
```

### Create a payment intent (manual flow)

If you want to render a custom checkout with Stripe.js or Stripe Elements:

```graphql theme={null}
mutation {
  stripe_createPaymentIntent(input: {
    amount: 49.99
    currency: "usd"
    customerId: "cus_..."
    automaticPaymentMethods: true
  }) {
    id
    clientSecret
    status
  }
}
```

Pass the returned `clientSecret` to your frontend Stripe.js confirm step.

## Webhooks

When you save the integration, Archie generates a webhook URL specific to your project and environment. Add it in the Stripe dashboard under **Developers → Webhooks**, and provide the resulting signing secret in the integration config.

Archie verifies every incoming event before storing it. Query received events with `stripe_webhookEvents`, or react to them inside a custom function — see [Webhooks](/features/backend/integrations/webhooks).

Common events you'll likely care about:

* `payment_intent.succeeded`
* `payment_intent.payment_failed`
* `customer.subscription.created` / `updated` / `deleted`
* `invoice.paid` / `invoice.payment_failed`
* `checkout.session.completed`

## FAQ

<AccordionGroup>
  <Accordion title="Test mode vs. live mode — when does each apply?">
    Archie selects credentials based on the environment your app is running in. Development environments use the keys saved with `TEST`; production uses the ones saved with `LIVE`. Setting up both up front means you can swap stages without touching code.
  </Accordion>

  <Accordion title="Can I use Stripe.js or Stripe Elements on the frontend?">
    Yes. Use `stripe_createPaymentIntent` to get a `clientSecret`, then confirm it on the frontend with the publishable key. The publishable key is returned from the integration config and is safe to expose in client code.
  </Accordion>

  <Accordion title="How do I refund a payment?">
    Call `stripe_createRefund` with the `paymentIntentId`. Omit `amount` for a full refund or pass an amount for partial. Refunds start as `pending` and update to `succeeded` or `failed` once Stripe processes them.
  </Accordion>

  <Accordion title="What happens to webhook events if my app is down?">
    Stripe retries failed webhook deliveries with exponential backoff for up to three days. Once your app is reachable, Archie verifies and stores the event normally. You can also replay events from the Stripe dashboard.
  </Accordion>

  <Accordion title="Can I use a specific Stripe SDK version directly?">
    Yes. Add the `stripe` package to your custom function and call it with `ctx.integrations.stripe.config.secretKey`. The GraphQL operations cover most cases; the SDK is for anything they don't expose.
  </Accordion>
</AccordionGroup>
