SaaS / FaaSStripe

How to prefill credit card data on Stripe Checkout

Using Stripe checkout can provide a credit card form to customers. But by default, we have to fill in our own […]

広告ここから
広告ここまで

Using Stripe checkout can provide a credit card form to customers.

app.post('/products/:price_id/checkout', async function(req, res) {
  const priceId = req.params.price_id;
  const appUrl = req.headers.origin;

  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
  const checkoutSessionProps = {
    mode: 'payment',
    payment_method_types: ['card'],
    line_items: [{
      price: priceId,
      quantity: 1
    }],
    cancel_url: `${appUrl}/cancel`,
    success_url: `${appUrl}/success`,
  }

  const session = await stripe.checkout.sessions.create(checkoutSessionProps)

  res.json({
    session
  });
});

But by default, we have to fill in our own card information always.

Use customer prop to prefill card information

When we put customer attributes to checkout.sessions.create method, we can reuse their card information on the Checkout page.

app.post('/products/:price_id/checkout', async function(req, res) {
  const priceId = req.params.price_id;
  const appUrl = req.headers.origin;

  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
  const customer = await stripe.customers.create()

  const checkoutSessionProps = {
    mode: 'payment',
    payment_method_types: ['card'],
    line_items: [{
      price: priceId,
      quantity: 1
    }],
    cancel_url: `${appUrl}/cancel`,
    success_url: `${appUrl}/success`,
  }
  checkoutSessionProps['customer'] = customer.id
  checkoutSessionProps['payment_intent_data'] {
    setup_future_usage: 'on_session'
  }

  const session = await stripe.checkout.sessions.create(checkoutSessionProps)

  res.json({
    customer_id: customer.id,
    session
  });
});

Then, before calling the stripe.redirectToCheckout method on the frontend app, we have to save the created customer id into the user database like firebase or Cognito or Auth0, etc…

The following example, call REST API to get a new customer id and checkout session id. And save the customer id into Amazon Cognito User Pools and call the redirectToCheckout using stripe-js.

const redirectToStripeCheckout = async (priceId, type) => {
    const user = await Auth.currentAuthenticatedUser()
    const customerId = user.attributes['custom:StripeCustomerId'] || null;

    const checkout = await API.post('stripeapi', `/products/${priceId}/checkout`, {
        body: {
            type,
            customer_id: customerId
        }
    })
    if (!customerId || customerId !== checkout.customer_id) {
        await Auth.updateUserAttributes(user, {
            'custom:StripeCustomerId': checkout.customer_id
        })
    }


    const stripe = await loadStripe(process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY)
    const result = await stripe.redirectToCheckout({ sessionId: checkout.session.id })
    if (result.error) throw new Error(result.error.message)

    return;
}

Finally, the REST API creating checkout session-id will handle the customer id given from the frontend.

const createCustomerIfExists = async (customerId = null) => {
  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
  if ( customerId ) {
    const existsCustomer = await stripe.customers.retrieve(customerId)
    if (existsCustomer.deleted !== true) return existsCustomer
  }
  const newCustomer = await stripe.customers.create()
  return newCustomer
}

app.post('/products/:price_id/checkout', async function(req, res) {
  const priceId = req.params.price_id;
  const appUrl = req.headers.origin;
  const mode = req.body.type === 'recurring' ? 'subscription': 'payment'

  const customer = await createCustomerIfExists(req.body.customer_id)
  const customerId = customer.id || null;

  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
  const checkoutSessionProps = {
    mode,
    payment_method_types: ['card'],
    line_items: [{
      price: priceId,
      quantity: 1
    }],
    cancel_url: `${appUrl}/cancel`,
    success_url: `${appUrl}/success`,
  }
  if (customerId) {
    checkoutSessionProps['customer'] = customerId
    const paymentIntentData = mode === 'payment' ? {
      setup_future_usage: 'on_session'
    }: undefined
    if (paymentIntentData) checkoutSessionProps['payment_intent_data'] = paymentIntentData
  }
  const session = await stripe.checkout.sessions.create(checkoutSessionProps)
  // Add your code here
  res.json({
    customer_id: customerId,
    session
  });
});

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts