Stripe: Pending Updates
When something happens with your Subscriptions (most of the times) Stripe sends events for it and it makes certain changes to the status, to the dates like the trial_ends_at , ends_at and so forth.
For example when a subscription is created with a faulty payment method it goes to incomplete status and the payment should be confirmed in order to change the subscription status to active which is normal way a handling those situations because it gives the user the ability to resume the subscription when a proper payment method is added.
But not in every case you need that behavior to happen like this that's why Stripe provides the Pending Updates which allows postponing updates for your subscriptions, for example: A user has an active subscription, on the billing cycle something went wrong and no payment was made
Instead of changing the status to past_due Stripe can "wait" for a successful payment and then sent a web-hook event to your system to inform that the user has paid, which allows you to provide a better user experience and to spare your users of the confirm process and in the mean time to restrict their access to the your service.
Prerequisites
collection method of the subscriptions should be
charge_automaticallyThe payment method used should be one of those
Usage
You can use pending updates with:
How to use it with subscription update:
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
// Find your keys at https://dashboard.stripe.com/apikeys.
$stripe = new \Stripe\StripeClient('sk_test_51RRquARcy99RV4czPtcirlPrgNttCr026zIC57B3Y9ZsYW6LWUv0sZv2sOgizGtNGijy6sMFPubOpO1bqTuM2lRg00t5TbV7SG');
$subscription = $stripe->subscriptions->retrieve('sub_49ty4767H20z6a');
$stripe->subscriptions->update(
$subscription->id,
[
'payment_behavior' => 'pending_if_incomplete',
'proration_behavior' => 'always_invoice',
'items' => [
[
'id' => $subscription->items->data[0]->id,
'price' => 'price_CBb6IXqvTLXp3f',
],
],
]
);if the everything goes smooth and everything is well and good, the subscription is updated, if the things go sideways you will receive:
{
"id": "sub_49ty4767H20z6a",
"object": "subscription",
"application_fee_percent": null,
"pending_update": {
"expires_at": 1571194285,
"subscription_items": [
{
"id": "si_09IkI4u3ZypJUk5onGUZpe8O",
"price": "price_CBb6IXqvTLXp3f"
}
]
}
}Failed payments
As stated in the Stripe own documentation:
After making the update, check the
pending_updatehash on the subscription or listen for thecustomer.subscription.updatedevent in your webhook. A populatedpending_updatehash means the payment failed and your subscription update isnβt applied.
In other words: "we give you the heads up, the rest is up to you"
For these cases you need create custom logic that will handle:
For card declines, attach a new payment method to the customer. Then use the pay endpoint to pay the invoice that the update generates.
For customer authentication, follow the requires action flow.
there some things regarding the fields that can be upgraded, not all subscription fields can be upgraded a complete list can be found here
Expiration
If nothing happens the pending update can expire that's why you need to pay attention to the expired_at date when it passes Stripe will void the invoice and removes the update.
A pending updateβs
expired_attime matches the first occurrence of either the trial end or the earliest items.current period end. This applies if either time is within 23 hours of the update request. Otherwise, the expiration is 23 hours from the update request.
Webhook events
The are a few events fired in regards of the pending update:
Event | Purpose |
|---|---|
| Receive notifications for subscriptions, checking for the |
| Receive notifications when pending updates are applied so that you can take further actions like upgrading, downgrading, provisioning, or deprovisioning services. |
| Receive notifications when pending updates expire or are automatically voided, and if needed, try the update request again. |
Conclusion
Stripe provides a lot of powerful features and this is one of them, using such feature can make the UX for your customers much better and will allow you be more "flexible" in some cases. Well documented(as always), it easy to setup(depends on the project of course).
Share this post