Skip to content

Accept a Payment Fresh

Build a payment form or use a prebuilt checkout page to start accepting online payments.

Integration options

Choose the integration that fits your needs:

OptionHostingCustomizationComplexity
Stripe-hosted CheckoutStripe's domainLimitedLowest
Embedded CheckoutYour domainModerate (Appearance API)Low
Payment Element (custom UI)Your domainFull CSS controlMedium

Stripe-hosted Checkout

Redirect customers to a Stripe-hosted payment page. Stripe handles the entire payment flow.

Pros: No UI code needed, Stripe handles 3DS, all payment methods included
Cons: Customers leave your domain during checkout

javascript
// Server: create a Checkout Session
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const session = await stripe.checkout.sessions.create({
  payment_method_types: ['card'],
  line_items: [
    {
      price_data: {
        currency: 'usd',
        product_data: { name: 'T-shirt' },
        unit_amount: 2000, // $20.00
      },
      quantity: 1,
    },
  ],
  mode: 'payment',
  success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
  cancel_url: 'https://example.com/cancel',
});

// Redirect to session.url
html
<!-- Client: simple checkout button -->
<form action="/create-checkout-session" method="POST">
  <button type="submit">Checkout</button>
</form>

A Checkout Session represents what your customer sees when redirected to the payment form. Configure it with:

  • Line items with pricing
  • Supported payment methods
  • Success and cancel redirect URLs
  • Optional: customer email, tax ID collection, shipping addresses

Checkout Session with existing price

If you have a pre-created Price in the Dashboard or API:

javascript
const session = await stripe.checkout.sessions.create({
  line_items: [{ price: 'price_1234', quantity: 1 }],
  mode: 'payment',
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
});

Handle the success redirect

After payment, Stripe redirects to your success_url. Retrieve the session to get order details:

javascript
// GET /success?session_id=cs_...
const session = await stripe.checkout.sessions.retrieve(req.query.session_id);
console.log(session.payment_status); // 'paid'
console.log(session.customer_details.email);

Handle fulfillment with webhooks

Don't rely solely on the redirect URL — customers may close the browser. Use the checkout.session.completed webhook for reliable fulfillment:

javascript
app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
  const event = stripe.webhooks.constructEvent(
    req.body,
    req.headers['stripe-signature'],
    process.env.STRIPE_WEBHOOK_SECRET
  );

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    await fulfillOrder(session);
  }

  res.json({ received: true });
});

Payment Element (custom UI)

Build your own checkout form using Stripe's Payment Element component. Customers stay on your domain.

javascript
// 1. Server: create a PaymentIntent
const paymentIntent = await stripe.paymentIntents.create({
  amount: 2000,
  currency: 'usd',
});
// Return paymentIntent.client_secret to client
javascript
// 2. Client: initialize Stripe and mount Payment Element
const stripe = Stripe('pk_test_YOUR_KEY');
const elements = stripe.elements({ clientSecret });

const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');

// 3. Handle form submission
const { error } = await stripe.confirmPayment({
  elements,
  confirmParams: { return_url: 'https://example.com/success' },
});

Existing customers

Pre-fill checkout fields for known customers:

javascript
const session = await stripe.checkout.sessions.create({
  customer: 'cus_existing_id', // existing Customer ID
  // OR
  customer_email: 'customer@example.com',
  line_items: [{ price: 'price_1234', quantity: 1 }],
  mode: 'payment',
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
});

Testing

Use test card 4242 4242 4242 4242 with any future expiry and any CVC to test a successful payment. See Test Cards for decline scenarios and 3DS testing.

Stripe API Reference - Self-contained docs reference, refreshed 2026-05-18