How to pay for multiple subscriptions at once for the first time.
A customer can choose multiple subscriptions, some of them are with monthly payment and others with half-yearly payment.
When the customer chooses the subscriptions he adds them to the cart.
I do this on the server side for the creation of a customer (stripe.com/docs/billing/subscriptions/elements#create-customer)
$customer = $stripe->customers->create([
'email' => $this->getUser()->getEmail(),
]);
then I create the subscriptions (https://stripe.com/docs/billing/subscriptions/multiple)
$sub1 = $stripe->subscriptions->create([
'customer' => 'cus_4fdAW5ftNQow1b',
'items' => [['price' => 'price_CZB2krKbBDOkTe']],
'payment_behavior' => 'default_incomplete',
'expand' => ['latest_invoice.payment_intent'],
]);
$sub2 = $stripe->subscriptions->create([
'customer' => 'cus_4fdAW5ftNQow1b',
'items' => [['price' => 'price_CZB1AX3KOacNJb']],
'payment_behavior' => 'default_incomplete',
'expand' => ['latest_invoice.payment_intent'],
]);
However, in the doc cite:
"On the backend, create the subscription with status incomplete using payment_behavior=default_incomplete and returns the client_secret from the payment intent to the frontend to complete payment."
The problem I have is that I have one client_secret for each subscription. So, how to pay (for the first time, start of the subscriptions) in one credit card form.
In the front end I have this:
let stripePublicKey = "{{ stripePublicKey }}"
let stripe = Stripe(stripePublicKey);
let elements = stripe.elements();
//let clientSecret = {{clientSecret}} // the secret client is requested in the function stripe.confirmCardPayment below
//Create an instance of an Element and mount it to the Element container
let card = elements.create('card');
card.mount('#card-element');
function displayError(event) {
//changeLoadingStatePrices(false);
let displayError = document.getElementById('card-element-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
}
card.addEventListener('change', function (event) {
displayError(event);
});
const btn = document.querySelector('#submit-payment-btn');
btn.addEventListener('click', async (e) => {
e.preventDefault();
const nameInput = document.getElementById('name');
// Create payment method and confirm payment intent.
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: nameInput.value,
},
}
}).then((result) => {
if(result.error) {
alert(result.error.message);
} else {
// Successful subscription payment
}
});
});
Is this possible? If not what approach should I consider?
Thanks!
UPDATE
If I make a loop to pay, is it wrong?
const btn = document.querySelector('#submit-payment-btn');
btn.addEventListener('click', async (e) => {
e.preventDefault();
for(const [key, value] of Object.entries(clientSecrets)) {
// Create payment method and confirm payment intent.
await stripe.confirmCardPayment(value.secret, {
payment_method: {
card: card,
billing_details: {
name: '{{app.user.fullName}}'
},
}
}).then((result) => {
if (result.error) {
alert(result.error.message);
} else {
// Successful subscription payment
console.log('Successful subscription payment');
}
});
}
});
Can it cause problems?