javascriptruby-on-railsstripe-payments

Use Stripe Express Checkout Element for Subscription


I want to know if I can use the stripe express checkout element for subscription?

I use ruby btw

Based on the document, one of the modes made it seem possible:

const elements = stripe.elements({
  mode: 'payment', // This can be `subscription`
  amount: 1099,
  currency: 'usd',
  appearance,
})

I have a lookup key for the subscription price. I was hoping to use it somewhere once the payment method is confirmed here:

const handleError = (error) => {
  const messageContainer = document.querySelector('#error-message');
  messageContainer.textContent = error.message;
}

expressCheckoutElement.on('confirm', async (event) => {
  const {error: submitError} = await elements.submit();
  if (submitError) {
    handleError(submitError);
    return;
  }

  // Create the PaymentIntent and obtain clientSecret
  const res = await fetch('/create-intent', {
    method: 'POST',
  });
  const {client_secret: clientSecret} = await res.json();

  const {error} = await stripe.confirmPayment({
    // `elements` instance used to create the Express Checkout Element
    elements,
    // `clientSecret` from the created PaymentIntent
    clientSecret,
    confirmParams: {
      return_url: 'https://example.com/order/123/complete',
    },
  });

  if (error) {
    // This point is only reached if there's an immediate error when
    // confirming the payment. Show the error to your customer (for example, payment details incomplete)
    handleError(error);
  } else {
    // The payment UI automatically closes with a success animation.
    // Your customer is redirected to your `return_url`.
  }
});

I want to create the subscription at the return_url. But based on the provided document, it's only for a one-time payment.

So if I did this (without using the subscription price id and just create the subscription of the customer at the return url). They will gonna be two charges, one for the one-time payment at express checkout and the second on when the subscription is created.

Any help?


Solution

  • I used pgs' answer as a hint for mine.

    const elements = stripe.elements({
      mode: 'setup'
      amount: 1099,
      currency: 'usd',
      setupFutureUsage: 'off_session',
      paymentMethodCreation: 'manual', 
      appearance,
    })
    

    This would set the express checkout button to be able to create the payment method using stripe.createPaymentMethod

    Now for the confirm of express checkout:

    expressCheckoutElement.on('confirm', async (event) => {
      const {error: submitError} = await elements.submit();
      if (submitError) {
        handleError(submitError);
        return;
      }
    
      // Create a Payment method
      const {error, paymentMethod} = await stripe.createPaymentMethod({
        // `elements` instance used to create the Express Checkout Element
        elements,
        params: {
          // Use billing details at payment method
          billing_details: event.billingDetails
        }
      });
    
      if (error) {
        // This point is only reached if there's an immediate error when
        // confirming the payment. Show the error to your customer (for example, payment details incomplete)
        handleError(error);
      } else {
       // Attach paymentMethod.id to customer
       // Set payment method as default
       // Create subscription 
      }
    });
    

    Attach paymentMethod.id to customer. I use Ruby for the backend

    Stripe::PaymentMethod.attach(
      payment_method_id,
      {customer: customer_id},
    )
    

    Set payment method as default:

    Stripe::Customer.update(customer_id, {invoice_settings: {default_payment_method: payment_method_id}})
    

    Now you should be able to create a subscription.