Stripe Customer Portal force retry charge on "past due" invoice immediately after updating payment method

Viewed 870

A customer signs up for a subscription with trial. After trial ends, customer's card is charged. If the charge fails, stripe retries 4 times to charge the card within following 3 weeks (default settings). Until a successful charge happens, customer's subscription is in "past due" state. I ask customers to update their card details.

The problem is that when they update their payment method through customer portal Stripe does not charge the updated card immediately to cover the "past due" invoice. It follows the schedule of the default "retries".

I could not find any setting nor API configuration for the customer portal which would prompt charging customer's card immediately after card details were updated.

I entertained the option to allow customers sign up for a new subscription without trial instead of updating their card details. The problem I face in this case, is that, if customer does indeed create a new subscription within the 3 weeks of retries, the previous "past due" invoices will still be charged to his card. In this case, I have to manually cancel their previous subscription.

Can someone suggest the best approach to handle this?

Update

As per Jonathan's suggestion, this is how I handle this:

            const customerId = event.data.object.customer;
            const subscriptions = await stripe.subscriptions.list({
              customer: customerId,
              status: "past_due",
              limit: 1,
            });
            if (subscriptions.data) {
              // retrieve and pay open invoice for overdue subscription
              const invoices = await stripe.invoices.list({
                customer: customerId,
                subscription: subscriptions.data[0].id,
                status: "open",
                limit: 1,
              });
              if (invoices.data) {
                await stripe.invoices.pay(invoices.data[0].id);
              }
            }
2 Answers

There's no way to immediately force a payment attempt on an unpaid invoice after a customer updates their payment details. You'd need to handle this yourself by subscribing to the payment_method.attached event. Then inside your webhook handler you can implement the logic required to pay the invoice.

I highly recommend to not use the payment_method.attached event for your this use case because it does not handle the case where the users already has a valid payment method attached but not set to default.

So, by listening only to payment_method.attached you will miss the case where the user sets to default an existing valid payment method.

Instead, listen to customer.updated and verify that previousAttributes->invoice_settings->default_payment_method has changed and after that you can verify if there is a past_due subscription and try to pay the pending invoice. By doing so you will handle both cases. Because the customer.updated is also triggered when attaching a new payment method as default.

Enjoy.

Related