guys! First time touched stripe got confused with such problem - Need to make flow for paying for combination PRODUCT + SUBSCRIPTION in one payment (with 3d secure flow if it is req) and to send one total invoice for customer. So I've made such a plan:
But when i started point 4 of my list i got confused because of subscription logic on stripe. As i got it from docs, subscription will create it's own payment intent, own invoice and will ask for own 3ds. So i'm rather confused, because it look like user will need to pass two 3ds for product and sub, will pay for both in two different payments and will get two invoices. What am i missing? Why subscription cannot be attach to "main" payment, be paid by it after 3ds passed and be activated after that? Why should i split them and make it more complex than one sigle payment/invoice?
how it is looking from code point of view (just mockup without any side operations):
const customer = await stripe.customers.create({
email,
address,
name,
});
const { paymentMethod } = await stripe.createPaymentMethod({
type: "card",
card: cardElement,
billing_details: {
address: {
city,
country,
line1: address1,
line2: address2,
postal_code: zip,
},
email,
name,
},
});
const paymentMethod = await stripe.paymentMethods.attach(paymentId, {
customer,
});
const order = await stripe.paymentIntents.create({
amount: sum * 100,
currency: unit,
description: "project name",
customer,
payment_method: paymentId,
setup_future_usage: "off_session",
confirm: true,
capture_method: "manual", // to hold money
receipt_email: email,
return_url: returnUrl, // to return after 3ds
});
const subs = await stripe.subscriptions.create({
customer: customerId,
items: subscriptions,
expand: ["latest_invoice.payment_intent"],
});
if (subs.status === "incomplete" && subs.latest_invoice.payment_intent) {
await stripe
.confirmCardPayment(
subs.latest_invoice.payment_intent.client_secret,
{
payment_method: {
card: cardElement,
},
}
)
}
/* the only way i found to pass 3ds on sub without getting "incomplete" status
but it provide second 3ds for subs */
const action = order.next_action;
if (action && action.type === "redirect_to_url") {
window.location = action.redirect_to_url.url;
}
await stripe.paymentIntents.capture(paymentId);
So final result is - i have two payments (one - for product which im counting is total basket - subscriptions price, second - subscriptions), two 3ds for each, 1 invoice created by subscription, totally miss product invoice logic, coz i don't understand how to handle double pay for invoice and intent and it's seems like crutch.
You can add additional items when creating the Subscription, which is likely what you want to be doing here instead: https://stripe.com/docs/billing/invoices/subscription#first-invoice-extra