5

I'm using Stripe Subscription running under node.

I want to create a new checkout prefilling the email address. So I tried to do in the client:

// Setup event handler to create a Checkout Session when button is clicked
document
  .getElementById("basic-plan-btn")
  .addEventListener("click", function(evt) {
    createCheckoutSession(basicPlanId).then(function(data) {
      // Call Stripe.js method to redirect to the new Checkout page
      stripe
        .redirectToCheckout({
              sessionId: data.sessionId,
        })
        .then(handleResult);
    });
  });

The email here is directly in the code just to test it. In createCheckoutSession I added the customerEmail:

var createCheckoutSession = function(planId) {
  return fetch("https://example.com:4343/create-checkout-session", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      planId: planId,
      customerEmail: 'mario.rossi@gmail.com'
    })
  }).then(function(result) {
    return result.json();
  });
};

Then on the server I try to catch and forward the email but how can I do it?

app.post("/create-checkout-session", async (req, res) => {
  const domainURL = process.env.DOMAIN;
  const { planId } = req.body;

  // Create new Checkout Session for the order
  // Other optional params include:
  // [billing_address_collection] - to display billing address details on the page
  // [customer] - if you have an existing Stripe Customer ID
  // [customer_email] - lets you prefill the email input in the form
  // For full details see https://stripe.com/docs/api/checkout/sessions/create
  const session = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    subscription_data: { items: [{ plan: planId }] },
    // ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param
    success_url: `${domainURL}/success.html?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${domainURL}/canceled.html` 
  });

  res.send({
    sessionId: session.id
  });
});

I also tried to pass the email directly to the server using:

subscription_data: { items: [{ plan: planId, customer_email: 'a.b@gmail.com' }] },

But this doesn't populate the field in the checkout page

How do I fix it?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Lelio Faieta
  • 6,457
  • 7
  • 40
  • 74

2 Answers2

10

It is not part of subscription_data; it is its own field titled customer_email.

  const session = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    // THIS LINE, HERE:
    customer_email: 'a.b@gmail.com',
    subscription_data: { items: [{ plan: planId }] },
    // ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param
    success_url: `${domainURL}/success.html?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${domainURL}/canceled.html` 
  });
ceejayoz
  • 176,543
  • 40
  • 303
  • 368
  • got it! how do I get it from my createCheckoutSession? I want to pass it from the client to the server – Lelio Faieta Oct 01 '20 at 13:57
  • @LelioFaieta Same way you get the plan ID currently in `const { planId } = req.body;`. I'm not a Python guy, but I'd guess something like `const { planId, customerEmail } = req.body;`? – ceejayoz Oct 01 '20 at 13:59
  • so it will be const { customerEmail } = req.body? Sorry but I am still learning node :-) – Lelio Faieta Oct 01 '20 at 14:00
  • So `req.body` contains both the plan ID and customer email values from your `fetch` call. I'm not a Node guy either, whoops, so I'm not certain on syntax here. – ceejayoz Oct 01 '20 at 14:21
  • Yea, you'd use `const { planId, customerEmail } = req.body;` to destructure both parameters from the `body` at once, that's right. – Nolan H Oct 01 '20 at 14:38
  • 1
    And @ceejayoz is exactly right about using `customer_email` at the top level of the Checkout session create request. – Nolan H Oct 01 '20 at 14:38
  • Note that it seems the email address can't be changed if you specify a `customer_email`. Stripe will pre-fill it, but it can't be edited – Jon May 04 '22 at 00:05
2

Use "customer_email" parameter as shown below and this is the example in Node.js:

const session = await stripe.checkout.sessions.create({
    customer_email: 'example@gmail.com', // Here
    line_items=[
        {
            'price_data': {
                'currency': 'jpy',
                'unit_amount': 1000,
                'product_data': {
                    'name': 'Honey',
                    'description': 'Good honey',
                },
            },
            'quantity': 1,
        },
    ],
    mode: 'payment',
    success_url: 'https://example.com/success',
    cancel_url: 'https://example.com/cancel',
});

And because you use "customer_email" parameter so the email field is readonly as shown below:

enter image description here

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129