Last active
May 28, 2026 13:38
-
-
Save nathaningram/9fb4dc79bdae5e28a1fa5d37b275ca72 to your computer and use it in GitHub Desktop.
PMPro + Stripe: trigger immediate open-invoice retry when a member updates their payment method after a failed renewal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Plugin Name: BWW PMPro Payment Updates | |
| * Description: After a member updates their billing in PMPro, immediately tell Stripe to pay the open invoice using the new default payment method instead of waiting for Smart Retries. Falls back to Smart Retries on any error. | |
| * Version: 2026.05 | |
| * Author: Brilliant Web Works | |
| */ | |
| add_action( 'pmpro_after_update_billing', 'bww_pmpro_retry_open_invoice_on_billing_update', 10, 2 ); | |
| function bww_pmpro_retry_open_invoice_on_billing_update( $user_id, $order ) { | |
| if ( empty( $order ) || $order->gateway !== 'stripe' || empty( $order->subscription_transaction_id ) ) { | |
| return; | |
| } | |
| if ( ! class_exists( '\Stripe\Invoice' ) ) { | |
| return; | |
| } | |
| try { | |
| $subscription = \Stripe\Subscription::retrieve( $order->subscription_transaction_id ); | |
| if ( empty( $subscription->latest_invoice ) ) { | |
| return; | |
| } | |
| $invoice = \Stripe\Invoice::retrieve( $subscription->latest_invoice ); | |
| if ( $invoice->status !== 'open' ) { | |
| return; | |
| } | |
| // Pay with the card the member just submitted. Passing it explicitly | |
| // avoids relying on Stripe having already propagated it as the | |
| // subscription default; falls back to the subscription default if the | |
| // order does not carry a payment method id. | |
| $pay_args = array(); | |
| if ( ! empty( $order->payment_method_id ) ) { | |
| $pay_args['payment_method'] = $order->payment_method_id; | |
| } | |
| $invoice->pay( $pay_args ); | |
| } catch ( \Throwable $e ) { | |
| error_log( sprintf( | |
| '[bww-pmp-payment-updates] retry failed: %s (code %s)', | |
| get_class( $e ), | |
| method_exists( $e, 'getCode' ) ? (string) $e->getCode() : 'n/a' | |
| ) ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment