Plugin Directory

Changeset 3486614


Ignore:
Timestamp:
03/19/2026 03:13:52 PM (9 days ago)
Author:
peachpay
Message:

1.120.22

Location:
peachpay-for-woocommerce
Files:
893 added
5 edited

Legend:

Unmodified
Added
Removed
  • peachpay-for-woocommerce/trunk/changelog.txt

    r3486515 r3486614  
    11*** PeachPay for WooCommerce Changelog ***
     2
     32026-03-19 - version 1.120.22
     4* **Fixed**:
     5  * **CPay**: Bug fix - Subscription order renewal was charging the card twice in some cases.
    26
    372026-03-19 - version 1.120.21
  • peachpay-for-woocommerce/trunk/core/payments/convesiopay/gateways/class-peachpay-convesiopay-card-gateway.php

    r3465731 r3486614  
    12481248    public function process_subscription_renewal( $parent_order, $renewal_order, $renewal_total ) {
    12491249        try {
     1250            // Idempotency: do not charge if this renewal order is already paid (prevents double charge from duplicate hooks or webhook + sync race).
     1251            if ( $renewal_order->has_status( array( 'processing', 'completed' ) ) ) {
     1252                peachpay_log( 'debug', 'ConvesioPay: Stored-card renewal skipped - order ' . $renewal_order->get_order_number() . ' already paid (status: ' . $renewal_order->get_status() . ').' );
     1253                return;
     1254            }
     1255            if ( ! empty( $renewal_order->get_meta( '_convesiopay_payment_id' ) ) ) {
     1256                peachpay_log( 'debug', 'ConvesioPay: Stored-card renewal skipped - order ' . $renewal_order->get_order_number() . ' already has ConvesioPay payment ID.' );
     1257                return;
     1258            }
     1259
     1260            // If subscription already has another completed renewal order created recently (e.g. duplicate scheduled action created two renewal orders), skip charging this one to avoid double charge.
     1261            if ( function_exists( 'wcs_get_subscriptions_for_renewal_order' ) ) {
     1262                $subscriptions = wcs_get_subscriptions_for_renewal_order( $renewal_order );
     1263                $subscription  = is_array( $subscriptions ) ? array_pop( $subscriptions ) : null;
     1264                if ( $subscription && is_callable( array( $subscription, 'get_related_orders' ) ) ) {
     1265                    $renewal_order_ids = $subscription->get_related_orders( 'ids', 'renewal' );
     1266                    $recent_cutoff     = strtotime( '-2 hours' );
     1267                    foreach ( (array) $renewal_order_ids as $other_id ) {
     1268                        if ( (int) $other_id === (int) $renewal_order->get_id() ) {
     1269                            continue;
     1270                        }
     1271                        $other_order = wc_get_order( $other_id );
     1272                        if ( ! $other_order || ! $other_order->has_status( array( 'processing', 'completed' ) ) ) {
     1273                            continue;
     1274                        }
     1275                        $created = $other_order->get_date_created();
     1276                        if ( $created && $created->getTimestamp() >= $recent_cutoff ) {
     1277                            peachpay_log( 'info', 'ConvesioPay: Stored-card renewal skipped - subscription already has completed renewal order #' . $other_order->get_order_number() . ' (possible duplicate scheduled action). Order ' . $renewal_order->get_order_number() . ' not charged.' );
     1278                            $renewal_order->add_order_note( sprintf(
     1279                                __( 'Renewal payment skipped: subscription already has a completed renewal order #%s. This may be a duplicate; no charge was made.', 'peachpay-for-woocommerce' ),
     1280                                $other_order->get_order_number()
     1281                            ) );
     1282                            return;
     1283                        }
     1284                    }
     1285                }
     1286            }
     1287
    12501288            // Get stored payment data from parent order
    12511289            $customer_id              = $parent_order->get_meta( '_convesiopay_customer_id' );
  • peachpay-for-woocommerce/trunk/core/payments/stripe/abstract/class-peachpay-stripe-payment-gateway.php

    r3485577 r3486614  
    377377    public function process_subscription_renewal( $parent_order, $renewal_order, $renewal_total ) {
    378378        try {
     379            // Idempotency: do not charge if this renewal order is already paid (prevents double charge from duplicate hooks or webhook + sync race).
     380            if ( $renewal_order->has_status( array( 'processing', 'completed' ) ) ) {
     381                peachpay_log( 'debug', 'Stripe: Subscription renewal skipped - order ' . $renewal_order->get_order_number() . ' already paid (status: ' . $renewal_order->get_status() . ').' );
     382                return null;
     383            }
     384            if ( ! empty( $renewal_order->get_transaction_id() ) ) {
     385                peachpay_log( 'debug', 'Stripe: Subscription renewal skipped - order ' . $renewal_order->get_order_number() . ' already has transaction ID.' );
     386                return null;
     387            }
     388
     389            // If subscription already has another completed renewal order created recently (e.g. duplicate scheduled action), skip to avoid double charge.
     390            if ( function_exists( 'wcs_get_subscriptions_for_renewal_order' ) ) {
     391                $subscriptions = wcs_get_subscriptions_for_renewal_order( $renewal_order );
     392                $subscription  = is_array( $subscriptions ) ? array_pop( $subscriptions ) : null;
     393                if ( $subscription && is_callable( array( $subscription, 'get_related_orders' ) ) ) {
     394                    $renewal_order_ids = $subscription->get_related_orders( 'ids', 'renewal' );
     395                    $recent_cutoff     = strtotime( '-2 hours' );
     396                    foreach ( (array) $renewal_order_ids as $other_id ) {
     397                        if ( (int) $other_id === (int) $renewal_order->get_id() ) {
     398                            continue;
     399                        }
     400                        $other_order = wc_get_order( $other_id );
     401                        if ( ! $other_order || ! $other_order->has_status( array( 'processing', 'completed' ) ) ) {
     402                            continue;
     403                        }
     404                        $created = $other_order->get_date_created();
     405                        if ( $created && $created->getTimestamp() >= $recent_cutoff ) {
     406                            peachpay_log( 'info', 'Stripe: Subscription renewal skipped - subscription already has completed renewal order #' . $other_order->get_order_number() . ' (possible duplicate scheduled action). Order ' . $renewal_order->get_order_number() . ' not charged.' );
     407                            $renewal_order->add_order_note( sprintf(
     408                                __( 'Renewal payment skipped: subscription already has a completed renewal order #%s. This may be a duplicate; no charge was made.', 'peachpay-for-woocommerce' ),
     409                                $other_order->get_order_number()
     410                            ) );
     411                            return null;
     412                        }
     413                    }
     414                }
     415            }
     416
    379417            $stripe_mode       = PeachPay_Stripe_Order_Data::get_peachpay( $parent_order, 'stripe_mode' );
    380418            $peachpay_mode     = PeachPay_Stripe_Order_Data::get_peachpay( $parent_order, 'peachpay_mode' );
  • peachpay-for-woocommerce/trunk/peachpay.php

    r3486515 r3486614  
    44 * Plugin URI: https://woocommerce.com/products/peachpay
    55 * Description: Connect and manage all your payment methods, offer shoppers a beautiful Express Checkout, and reduce cart abandonment.
    6  * Version: 1.120.21
     6 * Version: 1.120.22
    77 * Text Domain: peachpay-for-woocommerce
    88 * Domain Path: /languages
  • peachpay-for-woocommerce/trunk/readme.txt

    r3486515 r3486614  
    44Requires at least: 5.8
    55Tested up to: 6.9.1
    6 Stable tag: 1.120.21
     6Stable tag: 1.120.22
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    262262
    263263== Changelog ==
     264
     265= 1.120.22 =
     266* **Fixed**:
     267  * **CPay**: Bug fix - Subscription order renewal was charging the card twice in some cases.
    264268
    265269= 1.120.21 =
Note: See TracChangeset for help on using the changeset viewer.