Plugin Directory

Changeset 3486327


Ignore:
Timestamp:
03/19/2026 10:13:17 AM (2 weeks ago)
Author:
easypayment
Message:

tags/9.0.58

Location:
woo-paypal-gateway
Files:
1068 added
13 edited

Legend:

Unmodified
Added
Removed
  • woo-paypal-gateway/trunk/languages/woo-paypal-gateway.pot

    r3473539 r3486327  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Payment Gateway for PayPal on WooCommerce 9.0.57\n"
     5"Project-Id-Version: Payment Gateway for PayPal on WooCommerce 9.0.58\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woo-paypal-gateway\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  • woo-paypal-gateway/trunk/ppcp/admin/js/ppcp-paypal-checkout-for-woocommerce-admin.js

    r3434048 r3486327  
    2020        this.setupCollapsibles();
    2121        this.setupAppleGooglePay();
     22        this.setupPaymentActionFields();
    2223        this.enforceReadonlySelect2Option('woocommerce_wpg_paypal_checkout_paypal_button_pages', ['checkout']);
     24    }
     25
     26    setupPaymentActionFields() {
     27        const $paymentAction = jQuery('#woocommerce_wpg_paypal_checkout_paymentaction');
     28        const $authorizedOrderStatus = jQuery('#woocommerce_wpg_paypal_checkout_authorized_order_status').closest('tr');
     29        const $captureOrderStatuses = jQuery('#woocommerce_wpg_paypal_checkout_capture_order_statuses').closest('tr');
     30
     31        if (!$paymentAction.length) {
     32            return;
     33        }
     34
     35        const toggleFields = () => {
     36            const isAuthorize = $paymentAction.val() === 'authorize';
     37            $authorizedOrderStatus.toggle(isAuthorize);
     38            $captureOrderStatuses.toggle(isAuthorize);
     39        };
     40
     41        $paymentAction.on('change', toggleFields);
     42        toggleFields();
    2343    }
    2444
  • woo-paypal-gateway/trunk/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-funnelkit-compat.php

    r3473539 r3486327  
    3333        }
    3434
     35        $gateways['wpg_paypal_checkout'] = 'PPCP_Paypal_Checkout_For_Woocommerce_FunnelKit_Upsell_PayPal';
    3536        $gateways['wpg_paypal_checkout_cc'] = 'PPCP_Paypal_Checkout_For_Woocommerce_FunnelKit_Upsell';
    36         $gateways['wpg_paypal_checkout'] = 'PPCP_Paypal_Checkout_For_Woocommerce_FunnelKit_Upsell_PayPal';
    3737
    3838        return $gateways;
     
    4848     */
    4949    public static function ensure_tokenization_support_for_funnelkit($supports, $feature, $gateway) {
    50        
    51         if (!$gateway instanceof WC_Payment_Gateway) {
     50        if ('tokenization' !== $feature) {
    5251            return $supports;
    5352        }
    5453
    55         if (!in_array($gateway->id, ['wpg_paypal_checkout_cc', 'wpg_paypal_checkout'], true)) {
     54        if (!in_array($gateway->id, ['wpg_paypal_checkout', 'wpg_paypal_checkout_cc'], true)) {
    5655            return $supports;
    5756        }
     
    9594
    9695        if (!in_array($order->get_payment_method(), ['wpg_paypal_checkout', 'wpg_paypal_checkout_cc'], true)) {
    97             $order->set_payment_method('wpg_paypal_checkout_cc');
     96            $order->set_payment_method($parent_order->get_payment_method());
    9897        }
    9998
     
    133132                public function get_supported_gateways() {
    134133                    $filtered = parent::get_supported_gateways();
     134                    unset($filtered['wpg_paypal_checkout']);
    135135                    unset($filtered['wpg_paypal_checkout_cc']);
    136                     unset($filtered['wpg_paypal_checkout']);
    137136
    138137                    return array_merge(
    139138                        [
     139                            'wpg_paypal_checkout' => 'PPCP_Paypal_Checkout_For_Woocommerce_FunnelKit_Upsell_PayPal',
    140140                            'wpg_paypal_checkout_cc' => 'PPCP_Paypal_Checkout_For_Woocommerce_FunnelKit_Upsell',
    141                             'wpg_paypal_checkout' => 'PPCP_Paypal_Checkout_For_Woocommerce_FunnelKit_Upsell_PayPal',
     141
    142142                        ],
    143143                        $filtered
  • woo-paypal-gateway/trunk/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-funnelkit-upsell.php

    r3473539 r3486327  
    5050    public function has_token($order) {
    5151        if (!$order instanceof WC_Order) {
    52             $order = wc_get_order($order);
    53         }
    54 
    55         if (!$order instanceof WC_Order) {
    5652            return false;
    5753        }
    5854
    59         $meta_key = '_payment_tokens_id';
    60 
    61         // Prevent stale meta cache issue
    62         $order->read_meta_data(true);
    63 
    64         $token = (string) $order->get_meta($meta_key, true);
    65 
    66         // Fallback (in case FunnelKit or other helper stored it differently)
    67         if ('' === $token && class_exists('WFOCU_Common')) {
    68             $token = (string) WFOCU_Common::get_order_meta($order, $meta_key);
     55        if (!empty($order->get_meta('_payment_tokens_id', true))) {
     56            return true;
    6957        }
    7058
    71         return '' !== trim($token);
     59        $parent_id = (int) $order->get_parent_id();
     60        if ($parent_id <= 0) {
     61            return false;
     62        }
     63
     64        $parent_order = wc_get_order($parent_id);
     65        if (!$parent_order instanceof WC_Order) {
     66            return false;
     67        }
     68
     69        return !empty($parent_order->get_meta('_payment_tokens_id', true));
     70
    7271    }
    7372
     
    7675     *
    7776     * @param WC_Order $order
    78      * @param array    $args
    7977     * @return array
    8078     */
  • woo-paypal-gateway/trunk/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-gateway-cc.php

    r3473539 r3486327  
    219219            $this->request->ppcp_create_order_request($woo_order_id);
    220220            exit;
    221         } elseif ($paypal_order_id = ppcp_get_session('ppcp_paypal_order_id')) {
     221        } elseif ($paypal_order_id = ppcp_get_paypal_order_id_from_session()) {
    222222            $is_success = ($this->paymentaction === 'capture') ? $this->request->ppcp_order_capture_request($woo_order_id) : $this->request->ppcp_order_auth_request($woo_order_id);
    223223            $order->update_meta_data('_payment_action', $this->paymentaction);
  • woo-paypal-gateway/trunk/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-gateway.php

    r3434048 r3486327  
    637637            exit();
    638638        } else {
    639             $ppcp_paypal_order_id = ppcp_get_session('ppcp_paypal_order_id');
     639            $ppcp_paypal_order_id = ppcp_get_paypal_order_id_from_session();
    640640            if (!empty($ppcp_paypal_order_id)) {
    641641                include_once WPG_PLUGIN_DIR . '/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-request.php';
  • woo-paypal-gateway/trunk/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-request.php

    r3473539 r3486327  
    3636    public $client_token;
    3737    public $paymentaction;
     38    public $authorized_order_status;
    3839    public $payee_preferred;
    3940    public $invoice_id_prefix;
     
    122123            }
    123124            $this->paymentaction = $this->get_option('paymentaction', 'capture');
     125            $this->authorized_order_status = $this->get_option('authorized_order_status', 'on-hold');
    124126            $this->payee_preferred = 'yes' === $this->get_option('payee_preferred', 'no');
    125127            $this->invoice_id_prefix = $this->get_option('invoice_id_prefix', 'WC-PPCP');
     
    167169    public function localize_button_text() {
    168170        $this->order_button_text = __('Continue to payment', 'woo-paypal-gateway');
     171    }
     172
     173    private function ppcp_set_order_session_data($paypal_order_id, $status, $woo_order_id = 0) {
     174        if (empty($paypal_order_id) || empty($status)) {
     175            return;
     176        }
     177
     178        ppcp_set_paypal_order_session_data($paypal_order_id, $status, $woo_order_id);
     179    }
     180
     181    private function ppcp_get_order_session_data() {
     182        return ppcp_get_paypal_order_session_data();
     183    }
     184
     185
     186    private function ppcp_get_paypal_order_id_from_session() {
     187        return ppcp_get_paypal_order_id_from_session();
     188    }
     189
     190    private function ppcp_validate_order_for_capture($paypal_order_id, $woo_order_id = 0) {
     191        $order_details = $this->ppcp_get_checkout_details($paypal_order_id);
     192        $paypal_status = is_object($order_details) && !empty($order_details->status) ? strtoupper($order_details->status) : '';
     193
     194        if ($paypal_status !== 'APPROVED') {
     195            $this->ppcp_log('Capture skipped. PayPal order is not approved. Current status: ' . $paypal_status);
     196            if (function_exists('wc_add_notice')) {
     197                wc_add_notice(__('PayPal order is not approved yet. Please approve the payment before capture.', 'woo-paypal-gateway'), 'error');
     198            }
     199            return false;
     200        }
     201
     202        $this->ppcp_set_order_session_data($paypal_order_id, 'approved', $woo_order_id);
     203        return true;
    169204    }
    170205
     
    605640                    }
    606641                    $return_response['orderID'] = $api_response['id'];
    607                     ppcp_set_session('ppcp_paypal_order_id', $api_response['id']);
     642                    $this->ppcp_set_order_session_data($api_response['id'], 'created', $woo_order_id);
    608643                    if (!empty(isset($woo_order_id) && !empty($woo_order_id))) {
    609                         $order->update_meta_data('_paypal_order_id', $api_response['id']);
    610                         $order->save_meta_data();
    611644                        ppcp_set_session('ppcp_paypal_transaction_details', $api_response);
    612645                    }
     
    706739                $this->ppcp_update_order($order);
    707740            }
    708             $paypal_order_id = ppcp_get_session('ppcp_paypal_order_id');
     741            $session_order_data = $this->ppcp_get_order_session_data();
     742            $paypal_order_id = !empty($session_order_data['id']) ? $session_order_data['id'] : $this->ppcp_get_paypal_order_id_from_session();
     743            if (empty($paypal_order_id)) {
     744                return false;
     745            }
     746            if (!$this->ppcp_validate_order_for_capture($paypal_order_id, $woo_order_id)) {
     747                return false;
     748            }
    709749            $this->ppcp_add_log_details('Capture payment for order');
    710750            $this->ppcp_log('Request : ' . wc_print_r($this->paypal_order_api . $paypal_order_id . '/capture', true));
     
    732772                    $this->ppcp_update_order_address_from_paypal_capture($woo_order_id, $api_response);
    733773                    $return_response['paypal_order_id'] = $api_response['id'];
    734                     $order->update_meta_data('_paypal_order_id', $api_response['id']);
    735                     $order->save_meta_data();
     774                    $this->ppcp_set_order_session_data($api_response['id'], 'capture', $woo_order_id);
    736775                    if ($api_response['status'] == 'COMPLETED') {
    737776                        do_action('wpg_ppcp_save_payment_method_details', $woo_order_id, $api_response);
     
    902941                $this->ppcp_update_order($order);
    903942            }
    904             $paypal_order_id = ppcp_get_session('ppcp_paypal_order_id');
     943            $session_order_data = $this->ppcp_get_order_session_data();
     944            $paypal_order_id = !empty($session_order_data['id']) ? $session_order_data['id'] : $this->ppcp_get_paypal_order_id_from_session();
    905945            $this->ppcp_add_log_details('Authorize payment for order');
    906946            $this->ppcp_log('Request : ' . wc_print_r($this->paypal_order_api . $paypal_order_id . '/authorize', true));
     
    927967                    $this->ppcp_update_order_address_from_paypal_capture($woo_order_id, $api_response);
    928968                    $return_response['paypal_order_id'] = $api_response['id'];
    929                     if (isset($woo_order_id) && !empty($woo_order_id)) {
    930                         $order->update_meta_data('_paypal_order_id', $api_response['id']);
    931                         $order->save_meta_data();
    932                     }
     969                    $this->ppcp_set_order_session_data($api_response['id'], 'approved', $woo_order_id);
    933970                    if ($api_response['status'] == 'COMPLETED') {
    934971                        $transaction_id = isset($api_response['purchase_units']['0']['payments']['authorizations']['0']['id']) ? $api_response['purchase_units']['0']['payments']['authorizations']['0']['id'] : '';
    935972                        $seller_protection = isset($api_response['purchase_units']['0']['payments']['authorizations']['0']['seller_protection']['status']) ? $api_response['purchase_units']['0']['payments']['authorizations']['0']['seller_protection']['status'] : '';
    936973                        $payment_status = isset($api_response['purchase_units']['0']['payments']['authorizations']['0']['status']) ? $api_response['purchase_units']['0']['payments']['authorizations']['0']['status'] : '';
    937                         $order->update_meta_data('_transaction_id', $transaction_id);
     974                        $order->set_transaction_id($transaction_id);
    938975                        $order->update_meta_data('_payment_status', $payment_status);
    939976                        $order->update_meta_data('_auth_transaction_id', $transaction_id);
     
    943980                        $order->add_order_note(sprintf(__('%1$s Transaction ID: %2$s', 'woo-paypal-gateway'), $order->get_payment_method_title(), $transaction_id));
    944981                        $order->add_order_note('Seller Protection Status: ' . ppcp_readable($seller_protection));
    945                         $order->update_status('on-hold');
    946                         $order->add_order_note(__('Payment authorized. Change payment status to processing or complete to capture funds.', 'woo-paypal-gateway'));
     982                        $order->update_status($this->authorized_order_status);
     983                        $order->add_order_note($this->get_payment_authorized_note());
    947984                    }
    948985                    wpg_clear_ppcp_session_and_cart();
     
    9661003                return;
    9671004            }
    968             $cached_id = ppcp_get_session('ppcp_paypal_order_id');
     1005            $cached_id = $this->ppcp_get_paypal_order_id_from_session();
    9691006            $cached_details = ppcp_get_session('ppcp_paypal_transaction_details');
    9701007            if ($cached_id === $paypal_order_id && !empty($cached_details)) {
     
    9971034            $this->ppcp_log('Response Message: ' . $message);
    9981035            $this->ppcp_log('Response Body: ' . wc_print_r($body, true));
    999             ppcp_set_session('ppcp_paypal_order_id', $paypal_order_id);
     1036            $normalized_status = isset($body->status) ? strtolower($body->status) : 'created';
     1037            if ($normalized_status === 'completed') {
     1038                $normalized_status = 'capture';
     1039            } elseif ($normalized_status === 'approved') {
     1040                $normalized_status = 'approved';
     1041            } else {
     1042                $normalized_status = 'created';
     1043            }
     1044            $this->ppcp_set_order_session_data($paypal_order_id, $normalized_status);
    10001045            ppcp_set_session('ppcp_paypal_transaction_details', $body);
    10011046            return $body;
     
    14491494
    14501495            // Retrieve the PayPal order ID and send the patch request to update the order
    1451             $paypal_order_id = ppcp_get_session('ppcp_paypal_order_id');
     1496            $paypal_order_id = $this->ppcp_get_paypal_order_id_from_session();
    14521497            $this->ppcp_add_log_details('Update order');
    14531498            $this->ppcp_log('Endpoint: ' . $this->paypal_order_api . $paypal_order_id);
     
    15731618                if (!empty($api_response['id'])) {
    15741619                    $return_response['paypal_order_id'] = $api_response['id'];
    1575                     $order->update_meta_data('_paypal_order_id', $api_response['id']);
    1576                     $order->save_meta_data();
     1620                    $this->ppcp_set_order_session_data($api_response['id'], 'capture', $woo_order_id);
    15771621                    $payment_source = isset($api_response['payment_source']) ? $api_response['payment_source'] : '';
    15781622                    if (!empty($payment_source['card'])) {
     
    19441988                switch ($posted['event_type']) {
    19451989                    case 'PAYMENT.AUTHORIZATION.CREATED' :
    1946                         $this->payment_status_on_hold($order, $posted);
     1990                        $this->payment_status_authorized($order);
    19471991                        break;
    19481992                    case 'PAYMENT.AUTHORIZATION.VOIDED' :
     
    19752019        } else {
    19762020            if ('created' === $posted['resource']['status']) {
    1977                 $this->payment_on_hold($order, __('Payment authorized. Change payment status to processing or complete to capture funds.', 'woo-paypal-gateway'));
     2021                $this->payment_on_hold($order, $this->get_payment_authorized_note());
    19782022            } else {
    19792023                if (!empty($posted['pending_reason'])) {
     
    19832027            }
    19842028        }
     2029    }
     2030
     2031    private function get_payment_authorized_note() {
     2032        $capture_statuses = $this->get_capture_order_statuses();
     2033
     2034        if (empty($capture_statuses)) {
     2035            return __('Payment authorized. Capture statuses are not configured.', 'woo-paypal-gateway');
     2036        }
     2037
     2038        $status_labels = array();
     2039        $order_statuses = wc_get_order_statuses();
     2040
     2041        foreach ($capture_statuses as $status) {
     2042            $status_key = 'wc-' . $status;
     2043            if (isset($order_statuses[$status_key])) {
     2044                $status_labels[] = $order_statuses[$status_key];
     2045            } else {
     2046                $status_labels[] = ucfirst(str_replace('-', ' ', $status));
     2047            }
     2048        }
     2049
     2050        // translators: %s is a comma-separated list of WooCommerce order status labels.
     2051        return sprintf(__('Payment authorized. Change the order to one of your configured capture statuses (%s) to capture funds.', 'woo-paypal-gateway'), implode(', ', $status_labels));
     2052    }
     2053
     2054    private function get_capture_order_statuses() {
     2055        $capture_statuses = $this->get_option('capture_order_statuses', array('processing', 'completed'));
     2056
     2057        if (!is_array($capture_statuses)) {
     2058            $capture_statuses = array('processing', 'completed');
     2059        }
     2060
     2061        $capture_statuses = array_values(array_filter(array_map('sanitize_key', $capture_statuses)));
     2062
     2063        return empty($capture_statuses) ? array('processing', 'completed') : $capture_statuses;
    19852064    }
    19862065
     
    20512130                );
    20522131            }
     2132        }
     2133    }
     2134
     2135    public function payment_status_authorized($order) {
     2136        if ($order->has_status(array('pending'))) {
     2137            $order->update_status($this->authorized_order_status, $this->get_payment_authorized_note());
    20532138        }
    20542139    }
     
    23642449                $this->api_response = json_decode(wp_remote_retrieve_body($this->api_response), true);
    23652450                if (!empty($this->api_response['status'])) {
    2366                     if (!empty(isset($woo_order_id) && !empty($woo_order_id))) {
    2367                         $order->update_meta_data('_paypal_order_id', $this->api_response['id']);
    2368                         $order->save();
    2369                     }
    2370                     ppcp_set_session('ppcp_paypal_order_id', $this->api_response['id']);
     2451                    $this->ppcp_set_order_session_data($this->api_response['id'], 'created', $woo_order_id);
    23712452                    if (!empty($this->api_response['links'])) {
    23722453                        foreach ($this->api_response['links'] as $key => $link_result) {
     
    24432524    public function ppcp_regular_capture() {
    24442525        if (isset($_GET['token']) && !empty($_GET['token'])) {
    2445             ppcp_set_session('ppcp_paypal_order_id', wc_clean($_GET['token']));
     2526            $paypal_order_id = wc_clean($_GET['token']);
     2527            $this->ppcp_set_order_session_data($paypal_order_id, 'approved');
    24462528        } else {
    24472529            wp_safe_redirect(wc_get_checkout_url());
     
    32393321            // Check if we have the necessary session data
    32403322            $reference_id    = ppcp_get_session('ppcp_reference_id');
    3241             $paypal_order_id = ppcp_get_session('ppcp_paypal_order_id');
     3323            $paypal_order_id = $this->ppcp_get_paypal_order_id_from_session();
    32423324
    32433325            if (empty($reference_id) || empty($paypal_order_id)) {
  • woo-paypal-gateway/trunk/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-settings.php

    r3473539 r3486327  
    18751875
    18761876        public function wpg_advanced_settings() {
     1877            $order_status_options = $this->ppcp_get_order_status_options();
     1878
    18771879            $advanced_settings = array(
    18781880                'paymentaction' => array(
     
    18871889                        'authorize' => __('Authorize', 'woo-paypal-gateway'),
    18881890                    ),
     1891                ),
     1892                'authorized_order_status' => array(
     1893                    'title' => __('Authorized Order Status', 'woo-paypal-gateway'),
     1894                    'type' => 'select',
     1895                    'class' => 'wc-enhanced-select',
     1896                    'description' => __('If the transaction is authorized, this status will be applied to the order.', 'woo-paypal-gateway'),
     1897                    'default' => 'on-hold',
     1898                    'desc_tip' => true,
     1899                    'options' => $order_status_options,
     1900                ),
     1901                'capture_order_statuses' => array(
     1902                    'title' => __('Capture Order Statuses', 'woo-paypal-gateway'),
     1903                    'type' => 'multiselect',
     1904                    'class' => 'wc-enhanced-select',
     1905                    'description' => __('Authorized payments will be captured when the order moves to one of these statuses.', 'woo-paypal-gateway'),
     1906                    'default' => array('processing', 'completed'),
     1907                    'desc_tip' => true,
     1908                    'options' => $order_status_options,
     1909                    'custom_attributes' => array('data-placeholder' => __('Select order statuses', 'woo-paypal-gateway')),
    18891910                ),
    18901911                'brand_name' => array(
     
    19802001            }
    19812002            return $advanced_settings;
     2003        }
     2004
     2005        private function ppcp_get_order_status_options() {
     2006            $order_statuses = wc_get_order_statuses();
     2007            $formatted_statuses = array();
     2008
     2009            foreach ($order_statuses as $status_key => $status_label) {
     2010                $formatted_statuses[str_replace('wc-', '', $status_key)] = $status_label;
     2011            }
     2012
     2013            return $formatted_statuses;
    19822014        }
    19832015
  • woo-paypal-gateway/trunk/ppcp/includes/ppcp-paypal-checkout-for-woocommerce-function.php

    r3473539 r3486327  
    5858    }
    5959
    60 }
     60
     61}
     62
     63if (!function_exists('ppcp_set_paypal_order_session_data')) {
     64
     65    function ppcp_set_paypal_order_session_data($paypal_order_id, $status = 'created', $woo_order_id = 0) {
     66        if (empty($paypal_order_id)) {
     67            return;
     68        }
     69
     70        ppcp_set_session('ppcp_paypal_order_data', array(
     71            'id' => $paypal_order_id,
     72            'status' => strtolower($status),
     73            'woo_order_id' => absint($woo_order_id),
     74        ));
     75    }
     76
     77}
     78
     79if (!function_exists('ppcp_get_paypal_order_session_data')) {
     80
     81    function ppcp_get_paypal_order_session_data() {
     82        $session_data = ppcp_get_session('ppcp_paypal_order_data');
     83        return is_array($session_data) ? $session_data : array();
     84    }
     85
     86}
     87
     88if (!function_exists('ppcp_get_paypal_order_id_from_session')) {
     89
     90    function ppcp_get_paypal_order_id_from_session() {
     91        $session_data = ppcp_get_paypal_order_session_data();
     92        $status = isset($session_data['status']) ? strtolower($session_data['status']) : '';
     93
     94        if ($status !== 'approved') {
     95            return '';
     96        }
     97
     98        return !empty($session_data['id']) ? $session_data['id'] : '';
     99    }
     100
     101}
     102
    61103if (!function_exists('ppcp_has_active_session')) {
    62104
    63105    function ppcp_has_active_session() {
    64106        $checkout_details = ppcp_get_session('ppcp_paypal_transaction_details');
    65         $ppcp_paypal_order_id = ppcp_get_session('ppcp_paypal_order_id');
     107        $ppcp_paypal_order_id = ppcp_get_paypal_order_id_from_session();
    66108        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only check for query var, no state change.
    67109        $has_paypal_order_id = isset($_GET['paypal_order_id']);
  • woo-paypal-gateway/trunk/ppcp/public/class-ppcp-paypal-checkout-for-woocommerce-button-manager.php

    r3473539 r3486327  
    3333    public $order_review_page_description;
    3434    public $paymentaction;
     35    public $authorized_order_status;
     36    public $capture_order_statuses;
    3537    public $advanced_card_payments;
    3638    public $threed_secure_contingency;
     
    169171        $this->device_class = $this->is_mobile ? 'mobile' : 'desktop';
    170172        $this->paymentaction = $this->ppcp_get_settings('paymentaction', 'capture');
     173        $this->authorized_order_status = $this->ppcp_get_settings('authorized_order_status', 'on-hold');
     174        $this->capture_order_statuses = $this->get_capture_order_statuses();
    171175        $this->advanced_card_payments = 'yes' === $this->ppcp_get_settings('enable_advanced_card_payments', 'no');
    172176        $this->threed_secure_contingency = $this->ppcp_get_settings('3d_secure_contingency', 'SCA_WHEN_REQUIRED');
     
    201205        }
    202206        $this->auto_complete = $this->ppcp_get_settings( 'auto_complete', 'no' );
     207        $this->authorized_order_status = $this->get_authorized_order_status();
    203208        $this->AVSCodes = array("A" => "Address Matches Only (No ZIP)",
    204209            "B" => "Address Matches Only (No ZIP)",
     
    256261        add_filter('body_class', array($this, 'ppcp_add_class_order_review_page'));
    257262        add_action('woocommerce_before_checkout_form', array($this, 'ppcp_order_review_page_description'), 9);
    258         add_action('woocommerce_order_status_processing', array($this, 'ppcp_capture_payment'));
    259         add_action('woocommerce_order_status_completed', array($this, 'ppcp_capture_payment'));
     263        foreach ($this->capture_order_statuses as $capture_status) {
     264            add_action('woocommerce_order_status_' . $capture_status, array($this, 'ppcp_capture_payment'));
     265        }
    260266        add_action('woocommerce_order_status_cancelled', array($this, 'ppcp_cancel_authorization'));
    261267        add_action('woocommerce_order_status_refunded', array($this, 'ppcp_cancel_authorization'));
     
    296302    }
    297303
    298     /**
     304     /**
    299305     * Register FunnelKit checkout/upsell/post-purchase smart button hooks.
    300306     */
     
    862868            echo '<div data-context="express_checkout" class="apple-pay-container express_checkout ' . esc_attr( $this->device_class . ' ' . $shape_class ) . '" style="--button-height: ' . (int) $button_height . 'px; --button-radius: ' . (int) $button_radius . 'px; height: ' . (int) $button_height . 'px;"></div>';
    863869        }
     870        do_action( 'wpg_ppcp_checkout_top_express_buttons', $this );
    864871        echo '</div>';
    865872        echo '</div>';
     
    10061013                case "cc_capture":
    10071014                    wc_clear_notices();
    1008                     ppcp_set_session('ppcp_paypal_order_id', wc_clean($_GET['paypal_order_id']));
     1015                    ppcp_set_paypal_order_session_data(wc_clean($_GET['paypal_order_id']), 'approved');
    10091016                    $this->ppcp_cc_capture();
    10101017                    break;
     
    15591566                    }
    15601567                }
    1561                 ppcp_set_session('ppcp_paypal_order_id', wc_clean($_GET['paypal_order_id']));
     1568                ppcp_set_paypal_order_session_data(wc_clean($_GET['paypal_order_id']), 'approved');
    15621569                if (empty($this->checkout_details)) {
    15631570                    $this->checkout_details = ppcp_get_session('ppcp_paypal_transaction_details', false);
     
    16551662            }
    16561663            apply_filters('woocommerce_payment_successful_result', array('result' => 'success'), $order_id);
    1657             $order->update_meta_data('_transaction_id', $transaction_id);
     1664            $order->set_transaction_id($transaction_id);
    16581665            $order->update_meta_data('_payment_status', $payment_status);
    16591666            $order->update_meta_data('_auth_transaction_id', $transaction_id);
     
    16631670            $order->add_order_note(sprintf(__('Payment via %1$s. Transaction ID: %2$s', 'woo-paypal-gateway'), $this->title, $transaction_id));
    16641671            $order->add_order_note('Seller Protection Status: ' . ppcp_readable($seller_protection));
    1665             $order->update_status('on-hold');
    1666             $order->add_order_note(__('Payment authorized. Change payment status to processing or complete to capture funds.', 'woo-paypal-gateway'));
     1672            $order->update_status($this->authorized_order_status);
     1673            $order->add_order_note($this->get_payment_authorized_note());
    16671674        }
    16681675        wpg_clear_ppcp_session_and_cart();
     
    18631870    }
    18641871
     1872    private function get_capture_order_statuses() {
     1873        $capture_statuses = $this->ppcp_get_settings('capture_order_statuses', array('processing', 'completed'));
     1874
     1875        if (!is_array($capture_statuses)) {
     1876            $capture_statuses = array('processing', 'completed');
     1877        }
     1878
     1879        $capture_statuses = array_values(array_filter(array_map(array($this, 'ppcp_sanitize_order_status_name'), $capture_statuses)));
     1880
     1881        return empty($capture_statuses) ? array('processing', 'completed') : $capture_statuses;
     1882    }
     1883
     1884    private function ppcp_sanitize_order_status_name($status) {
     1885        if (function_exists('wc_sanitize_order_status_name')) {
     1886            return wc_sanitize_order_status_name($status);
     1887        }
     1888
     1889        $status = sanitize_key($status);
     1890
     1891        if (strpos($status, 'wc-') === 0) {
     1892            $status = substr($status, 3);
     1893        }
     1894
     1895        return $status;
     1896    }
     1897
     1898    private function get_payment_authorized_note() {
     1899        if (empty($this->capture_order_statuses)) {
     1900            return __('Payment authorized. Capture statuses are not configured.', 'woo-paypal-gateway');
     1901        }
     1902
     1903        $status_labels = array();
     1904        $order_statuses = wc_get_order_statuses();
     1905
     1906        foreach ($this->capture_order_statuses as $status) {
     1907            $status_key = 'wc-' . $status;
     1908            if (isset($order_statuses[$status_key])) {
     1909                $status_labels[] = $order_statuses[$status_key];
     1910            } else {
     1911                $status_labels[] = ucfirst(str_replace('-', ' ', $status));
     1912            }
     1913        }
     1914
     1915        // translators: %s is a comma-separated list of WooCommerce order status labels.
     1916        return sprintf(__('Payment authorized. Change the order to one of your configured capture statuses (%s) to capture funds.', 'woo-paypal-gateway'), implode(', ', $status_labels));
     1917    }
     1918
    18651919    public function ppcp_capture_payment($order_id) {
    18661920        $order = wc_get_order($order_id);
     
    19341988        }
    19351989        return false;
     1990    }
     1991
     1992    protected function get_authorize_capture_statuses() {
     1993        $capture_statuses = $this->ppcp_get_settings('authorize_capture_statuses', array('processing', 'completed'));
     1994
     1995        if (!is_array($capture_statuses)) {
     1996            $capture_statuses = array_filter(array_map('trim', explode(',', (string) $capture_statuses)));
     1997        }
     1998
     1999        $capture_statuses = array_values(array_unique(array_map(array($this, 'ppcp_sanitize_order_status_name'), $capture_statuses)));
     2000        $capture_statuses = array_filter($capture_statuses);
     2001
     2002        if (empty($capture_statuses)) {
     2003            return array('processing', 'completed');
     2004        }
     2005
     2006        return apply_filters('wpg_ppcp_authorize_capture_statuses', $capture_statuses, $this);
     2007    }
     2008
     2009    protected function get_authorized_order_status() {
     2010        $authorized_order_status = $this->ppcp_sanitize_order_status_name($this->ppcp_get_settings('authorized_order_status', 'on-hold'));
     2011
     2012        if (empty($authorized_order_status)) {
     2013            $authorized_order_status = 'on-hold';
     2014        }
     2015
     2016        return apply_filters('wpg_ppcp_authorized_order_status', $authorized_order_status, $this);
     2017    }
     2018
     2019    protected function get_authorize_capture_statuses_label() {
     2020        $order_statuses = wc_get_order_statuses();
     2021        $capture_status_labels = array();
     2022
     2023        foreach ($this->authorize_capture_statuses as $capture_status) {
     2024            $status_key = 'wc-' . $capture_status;
     2025            if (isset($order_statuses[$status_key])) {
     2026                $capture_status_labels[] = $order_statuses[$status_key];
     2027            }
     2028        }
     2029
     2030        if (empty($capture_status_labels)) {
     2031            $capture_status_labels = array(__('Processing', 'woo-paypal-gateway'), __('Completed', 'woo-paypal-gateway'));
     2032        }
     2033
     2034        return implode(', ', $capture_status_labels);
    19362035    }
    19372036
     
    21462245    public function ppcp_cc_capture() {
    21472246        try {
    2148             $ppcp_paypal_order_id = ppcp_get_session('ppcp_paypal_order_id');
     2247            $ppcp_paypal_order_id = ppcp_get_paypal_order_id_from_session();
    21492248            if (!empty($ppcp_paypal_order_id)) {
    21502249                include_once WPG_PLUGIN_DIR . '/ppcp/includes/class-ppcp-paypal-checkout-for-woocommerce-request.php';
     
    24522551            $this->checkout_details = ppcp_get_session('ppcp_paypal_transaction_details', false);
    24532552            if (empty($this->checkout_details)) {
    2454                 $ppcp_order_id = ppcp_get_session('ppcp_paypal_order_id');
     2553                $ppcp_order_id = ppcp_get_paypal_order_id_from_session();
    24552554                if (!empty($ppcp_order_id)) {
    24562555                    $this->checkout_details = $this->request->ppcp_get_checkout_details($ppcp_order_id);
     
    32593358   
    32603359    public function store_polylang_in_wc_session() {
     3360        // Only run on pages where PayPal buttons are relevant
     3361        if ( ! is_cart() && ! is_checkout() && ! is_checkout_pay_page() ) {
     3362            return;
     3363        }
     3364
    32613365        if ( ! function_exists( 'WC' ) || ! WC()->session ) {
    32623366            return;
     
    32853389
    32863390        $locale = sanitize_text_field( $locale );
     3391
     3392        // Skip if cookie already exists with the same value — prevents Set-Cookie
     3393        // on every request which would bypass Cloudflare and other reverse-proxy caches
     3394        if ( isset( $_COOKIE[ self::PPCP_LANG_COOKIE_KEY ] ) && $_COOKIE[ self::PPCP_LANG_COOKIE_KEY ] === $locale ) {
     3395            return;
     3396        }
    32873397
    32883398        $secure   = is_ssl();
  • woo-paypal-gateway/trunk/ppcp/public/js/ppcp-paypal-checkout-for-woocommerce-public.js

    r3473539 r3486327  
    22    class PPCPManager {
    33        constructor(ppcp_manager) {
    4             // 9.0.57
     4            // 9.0.58
    55            this.ppcp_manager = ppcp_manager;
    66            this.productAddToCart = true;
  • woo-paypal-gateway/trunk/readme.txt

    r3473539 r3486327  
    33Tags: PayPal, PayPal Checkout, Credit Cards, Venmo 
    44Requires at least: 3.3 
    5 Tested up to: 6.9.1
    6 Stable tag: 9.0.57
     5Tested up to: 6.9.4
     6Stable tag: 9.0.58
    77Requires PHP: 7.4 
    88License: GPLv3 
     
    102102== Changelog ==
    103103
     104= 9.0.58 - 2026-03-19 =
     105* Added - Settings to configure Authorized Order Status and Capture Order Statuses for better control over PayPal payment flow.
     106* Improved - Enhanced locale cookie handling to avoid repeated cookie resets and improve performance with caching systems.
     107
    104108= 9.0.57 - 2026-03-03 =
    105109 * Added - Auto-complete paid orders option to automatically mark orders as Completed after successful payment.
  • woo-paypal-gateway/trunk/woo-paypal-gateway.php

    r3473539 r3486327  
    66 * Plugin URI:        https://profiles.wordpress.org/easypayment
    77 * Description:       PayPal, Credit/Debit Cards, Google Pay, Apple Pay, Pay Later, Venmo, SEPA, iDEAL, Mercado Pago, Sofort, Bancontact & more - by an official PayPal Partner
    8  * Version:           9.0.57
     8 * Version:           9.0.58
    99 * Author:            easypayment
    1010 * Author URI:        https://profiles.wordpress.org/easypayment/
     
    1616 * Requires PHP: 7.4
    1717 * Requires Plugins: woocommerce
    18  * Tested up to: 6.9.1
     18 * Tested up to: 6.9.4
    1919 * WC requires at least: 3.4
    20  * WC tested up to: 10.5.2
     20 * WC tested up to: 10.6.1
    2121 */
    2222if (!defined('WPINC')) {
     
    2626
    2727if (!defined('WPG_PLUGIN_VERSION')) {
    28     define('WPG_PLUGIN_VERSION', '9.0.57');
     28    define('WPG_PLUGIN_VERSION', '9.0.58');
    2929}
    3030if (!defined('WPG_PLUGIN_PATH')) {
Note: See TracChangeset for help on using the changeset viewer.