← marketplace
engineersapisha:7df285be245f284fmanual

stripe-api

Use when integrating Stripe payments in Node.js — creating PaymentIntents, Checkout Sessions, subscriptions, and verifying webhook signatures.

Install confidence
curl --create-dirs -fsSL https://skillmake.xyz/i/stripe-api -o ~/.claude/skills/stripe-api/SKILL.md
Pinned content
sha:7df285be245f284f
Generated with
manual
Source
docs.stripe.com

The file served at /api/marketplace/stripe-api-7df285be/raw matches this hash. Inspect before install, then copy the command.

5,353 chars · ~1,338 tokens
---
name: stripe-api
description: Use when integrating Stripe payments in Node.js — creating PaymentIntents, Checkout Sessions, subscriptions, and verifying webhook signatures.
source: https://docs.stripe.com/api
generated: 2026-07-02T18:43:28.584Z
category: api
audience: engineers
---

## When to use

- Accepting one-time card payments via PaymentIntents or Checkout
- Building subscriptions, customers, and recurring billing
- Verifying and handling Stripe webhook events securely
- Issuing refunds or managing products, prices, and invoices

## Key concepts

### PaymentIntent

Tracks the lifecycle of a single payment, including SCA/3DS. You create it server-side, then confirm it client-side with the returned client_secret.

### Checkout Session

A Stripe-hosted (or embedded) payment page. Create a Session server-side and redirect the customer; Stripe handles the UI and SCA.

### Customer + Subscription

A Customer stores payment methods and billing info; a Subscription attaches recurring Prices to a Customer and generates Invoices automatically.

### Idempotency keys

Pass an idempotencyKey on POST requests so retries don't create duplicate charges; Stripe returns the original result for 24 hours.

### Webhook signature verification

Stripe signs each webhook with your endpoint secret; verify with stripe.webhooks.constructEvent using the RAW request body and the Stripe-Signature header.

### Expandable objects & amounts

Many fields are IDs that can be expanded via `expand`; amounts are in the currency's smallest unit (e.g. cents for USD).

## API reference

```
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)
```

Initialize the Node SDK with your secret key.

```
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
```

```
stripe.paymentIntents.create(params, options?)
```

Create a PaymentIntent for an amount/currency; returns a client_secret to confirm on the client.

```
const pi = await stripe.paymentIntents.create({
  amount: 1999,
  currency: 'usd',
  automatic_payment_methods: { enabled: true },
}, { idempotencyKey: 'order_123' });
// send pi.client_secret to the browser
```

```
stripe.checkout.sessions.create(params)
```

Create a hosted Checkout Session and redirect the customer to session.url.

```
const session = await stripe.checkout.sessions.create({
  mode: 'payment',
  line_items: [{ price: 'price_123', quantity: 1 }],
  success_url: 'https://app.com/success?session_id={CHECKOUT_SESSION_ID}',
  cancel_url: 'https://app.com/cancel',
});
```

```
stripe.customers.create(params) / stripe.subscriptions.create(params)
```

Create a Customer and a recurring Subscription tied to one or more Prices.

```
const customer = await stripe.customers.create({ email: 'a@b.com' });
const sub = await stripe.subscriptions.create({
  customer: customer.id,
  items: [{ price: 'price_monthly' }],
});
```

```
stripe.refunds.create({ payment_intent })
```

Refund a captured payment fully or partially.

```
await stripe.refunds.create({ payment_intent: 'pi_123', amount: 500 });
```

```
stripe.webhooks.constructEvent(rawBody, sigHeader, endpointSecret)
```

Verify and parse an incoming webhook; throws if the signature is invalid.

```
let event;
try {
  event = stripe.webhooks.constructEvent(req.rawBody, req.headers['stripe-signature'], process.env.STRIPE_WEBHOOK_SECRET);
} catch (err) {
  return res.status(400).send(`Webhook Error: ${err.message}`);
}
if (event.type === 'payment_intent.succeeded') { /* ... */ }
```

```
stripe.prices.create / stripe.products.create / stripe.invoices.create
```

Define the catalog (Products and recurring/one-time Prices) and create Invoices for billing.

```
const product = await stripe.products.create({ name: 'Pro plan' });
const price = await stripe.prices.create({
  product: product.id,
  unit_amount: 1500,
  currency: 'usd',
  recurring: { interval: 'month' },
});
```

```
stripe.<resource>.list(params) with auto-pagination
```

List resources; use .autoPagingEach() / for-await to iterate beyond a single page.

```
for await (const customer of stripe.customers.list({ limit: 100 })) {
  console.log(customer.id);
}
```

## Gotchas

- Webhook verification needs the RAW request body — body-parsing middleware (express.json()) breaks the signature; use express.raw() on the route.
- Amounts are in the smallest currency unit (cents), and zero-decimal currencies like JPY are NOT multiplied by 100.
- Never use your secret key in client code; the client only ever sees the publishable key and a PaymentIntent client_secret.
- Webhooks can arrive out of order and more than once — make handlers idempotent and treat events as the source of truth, not the redirect.
- Always pass idempotency keys on payment-creating POSTs so network retries don't double-charge customers.
- Test mode and live mode use separate keys, objects, and webhook secrets — IDs are not interchangeable across modes.
- Pin the API version (Stripe-Version) explicitly; relying on the account default can cause silent behavior changes on upgrades.
- Confirming a PaymentIntent succeeds asynchronously for some payment methods — rely on the webhook, not the create() response, for fulfillment.

---
Generated by SkillMake from https://docs.stripe.com/api on 2026-07-02T18:43:28.584Z.
Verify against source before relying on details.

File: ~/.claude/skills/stripe-api/SKILL.md