Skip to content

Stripe events

checkout.session.completed: what it means and what to email

Stripe sends checkout.session.completed when a customer finishes Checkout. What it means, the payment_status to check, who gets a receipt, and what to email.

Sent
When a customer finishes Checkout or pays through a Payment Link
Stripe emails
A receipt, once you turn on Stripe's email for successful payments
Kicklace
A purchase for the session total

What it means

A customer finished a Checkout Session, which is Stripe's hosted payment page, or a Payment Link, which uses Checkout too. It is the event Stripe tells you to build fulfillment on, because a customer can pay and then lose their connection before your success page loads.

Completed does not always mean paid, so read payment_status. paid means the funds are available, and for a subscription with a free trial it means the trial's $0 invoice went through. unpaid means the funds are not available yet, as with a payment method that settles later. no_payment_required is a Session that has nothing to collect yet. For the delayed methods Stripe also sends checkout.session.async_payment_succeeded when the money arrives and checkout.session.async_payment_failed when it does not.

When Stripe sends it

Once for each completed Checkout Session. If a webhook endpoint listens for this event and you set a success_url, Checkout waits up to 10 seconds for your server to answer before it sends the customer on, so return a 2xx quickly and do the work after.

Your fulfillment can run more than once for the same Session, once from the webhook and once from your landing page, and the same event can be delivered more than once as well. Make the work safe to repeat, and keep the ids of the events you have handled.

Does Stripe email the customer?

A receipt, if you turn it on. The Successful payments toggle under Payments in Stripe's Customer emails settings emails a receipt for a payment that succeeds. For a one-time payment, Stripe also sends an invoice summary if you create the Session with invoice_creation enabled. A subscription makes its own invoices, and the same receipt setting covers them.

Either way, what Stripe sends is a receipt, so the welcome and the first step are still yours to write.

The email to send

A thank-you the same minute, with the one first step. Let mode decide what it says: payment is a purchase, subscription is a plan that has started. If you also act on invoice.paid for subscriptions, send from one of the two, not both.

Subject: You're in, {{first_name}}

Hi {{first_name}},

Thanks for choosing [your app]. Your [plan] is active, and the best first step is [one step, with a link].

If anything is unclear, reply to this email and it comes to me.

[Your name]

Fields worth reading

  • customer_details.email and customer_details.name: who paid, as Checkout collected it. Either can be empty.
  • customer: the Stripe customer id. In subscription mode Checkout creates the customer unless you passed one.
  • mode: payment, subscription or setup.
  • payment_status: whether to fulfill, as above.
  • amount_total and currency: the total after discounts and tax, in the smallest unit of the currency.
  • subscription, invoice and payment_intent: the ids of what the Session made, depending on its mode.
  • client_reference_id and metadata: your own ids, for finding the order or the user.
  • recovered_from: set when the Session was opened from the recovery link of one that expired.
if (event.type === "checkout.session.completed") {
  const session = event.data.object;
  if (session.payment_status === "paid") {
    const to = session.customer_details?.email;
    const plan = session.mode === "subscription";
  }
}

To see a real payload, run stripe trigger checkout.session.completed in a sandbox and read the event it sends.

What Kicklace does

With Stripe connected, the event lands on the person as a purchase, purchase, for the session total, and the first one moves them to Paying on your Lifecycle map. Kicklace keeps the Session's mode with it and marks a subscription's payment as recurring, so a renewal is not read as credits somebody chose to buy.

The purchase's key is the Session's invoice when it has one, then its payment, then the event's own id, so a repeat delivery never lands twice. Kicklace finds the person by the email Checkout collected or by the Stripe customer id it already knows.

A sequence on the Paying stage answers a purchase, and the first-run setup puts a short thank-you there. Nothing sends until you switch it on, and Kicklace shows who would have got it over the last 30 days first.

Write yours from your URL. Paste your site's address into the welcome email generator and it writes the thank-you email in your site's voice, ready to copy, with no sign-up.

Sources

Checked against Stripe’s docs on .

Free up to 1,000 contacts.

Join the journey

We're building Kicklace so you can get back to building your own product. We'll email you when there's something new worth showing.