Plugin Directory

Changeset 2326668


Ignore:
Timestamp:
06/18/2020 12:46:21 PM (5 years ago)
Author:
pensopay
Message:

Upgrade to 5.7.1

Location:
woo-pensopay
Files:
20 added
15 edited
71 copied

Legend:

Unmodified
Added
Removed
  • woo-pensopay/tags/5.7.1/README.txt

    r2240317 r2326668  
    2828
    2929== Changelog ==
     30= 5.7.1 =
     31* Fix: WC_Subscriptions error with zero checkout amount when using a 100% discount coupon.
     32* Fix: Viabill double tag in some cases on product page.
     33* Fix: Viabill logo show on order view.
     34* Fix: Mobilepay now moves the phone number to the payment window.
     35* Feature: Virtual Terminal added. Allows payments from admin now.
     36* Feature: Mass Capture
     37* Deprecation of iframe in favor of embedded window.
     38* Test against latest versions.
     39
     40= 5.7.0 =
     41* Feature: Add callback handler for recurring requests
     42* Fix: Stop using WC_Subscriptions_Manager::process_subscription_payment_failure_on_order as this is deprecated.
     43* Dev: Make synchronous recurring requests optional with the introduced filter: woocommerce_pensopay_set_synchronized_request
     44* Dev: Blocked callbacks for recurring requests are now optional. Can be disabled with the filter: woocommerce_pensopay_block_callback
     45
     46= 5.6.2 =
     47* Fix: Add missing order payment box in backend for fbg1886, ideal, paypal and swish
     48
     49= 5.6.1 =
     50* Fix: MobilePay Checkout not saving address data properly when no customer account was set on the order.
     51
     52= 5.6.0 =
     53* Feature: Add UI setting for enabling/disabling transaction caching
     54* Feature: Add UI setting for setting the transaction caching expiration time
     55* Feature: Update a cached transaction on accepted callbacks
     56* Feature: Add private key validation and success indicator next to the settings field - (requires permissions to read the private key via API)
     57* Feature: Add button to flush the transaction cache from inside the plugin settings
     58* Fix: Remove "Cancel" transaction on partially captured transactions as this action is not supported
     59* Fix: MobilePay Checkout is now only creating users if user registration is required. The behavior can be modified via the filter woocommerce_pensopay_mobilepay_checkout_create_user
     60* Fix: Stop performing capture logic on order completion when the orders is not paid with PensoPay
     61* Fix: Add permission check on ajax endpoint for clearing logs
     62* Fix: WC_PensoPay_Order::get_order_id_from_callback fallback now allows both prefixed and suffixed order numbers
     63* Fix: Recurring payments not being cancellable
     64* Improvement: Do not reuse cURL instances to avoid problems with some cPanel PHP upgrades where KeepAlive is disabled by default
     65* Developer: Add the possibility to hide buttons for clearing logs and transaction cache via filters.
     66
    3067= 5.5.3 =
    3168* Fix for embedded payments.
     
    67104* Fix: Fix missing shipping information on MobilePay Checkout orders if no shipping address is specified in the MobilePay app
    68105* Fix: Bump minimum PHP version to 5.4
     106
     107= 5.3.0 =
    69108* Fix: Make .is-loading in backend more specific.
    70109* Feature: Trustly as separate payment method instance
     
    77116* Enhancement: Updates helper texts on embedded window and text_on_statement on the settings page
    78117* Enhancement: Only load the backend javascripts on relevant pages
     118
     119= 5.2.0 =
    79120* Feature: Add support for embedded payments through overlay with Clearhaus
    80121* Developer: Add action 'woocommerce_pensopay_callback_subscription_authorized' and 'woocommerce_pensopay_callback_payment_authorized' for easier way of handling authorized callbacks for specific transaction types.
  • woo-pensopay/tags/5.7.1/assets/javascript/backend.js

    r2237549 r2326668  
    124124        new PensoPayPrivateKey().init();
    125125
     126        function wcppInsertAjaxResponseMessage(response) {
     127            if (response.hasOwnProperty('status') && response.status == 'success') {
     128                var message = $('<div id="message" class="updated"><p>' + response.message + '</p></div>');
     129                message.hide();
     130                message.insertBefore($('#wcpp_wiki'));
     131                message.fadeIn('fast', function () {
     132                    setTimeout(function () {
     133                        message.fadeOut('fast', function () {
     134                            message.remove();
     135                        });
     136                    },5000);
     137                });
     138            }
     139        }
     140
    126141        var emptyLogsButton = $('#wcpp_logs_clear');
    127142        emptyLogsButton.on('click', function(e) {
    128143            e.preventDefault();
     144            emptyLogsButton.prop('disabled', true);
    129145            $.getJSON(ajaxurl, { action: 'pensopay_empty_logs' }, function (response) {
    130                 if (response.hasOwnProperty('status') && response.status == 'success') {
    131                     var message = $('<div id="message" class="updated"><p>' + response.message + '</p></div>');
    132                     message.hide();
    133                     message.insertBefore($('#wcpp_wiki'));
    134                     message.fadeIn('fast', function () {
    135                         setTimeout(function () {
    136                             message.fadeOut('fast', function () {
    137                                 message.remove();
    138                             });
    139                         },5000);
    140                     });
    141                 }
     146                wcppInsertAjaxResponseMessage(response);
     147                emptyLogsButton.prop('disabled', false);
     148            });
     149        });
     150
     151        var flushCacheButton = $('#wcpp_flush_cache');
     152        flushCacheButton.on('click', function(e) {
     153            e.preventDefault();
     154            flushCacheButton.prop('disabled', true);
     155            $.getJSON(ajaxurl, { action: 'pensopay_flush_cache' }, function (response) {
     156                wcppInsertAjaxResponseMessage(response);
     157                flushCacheButton.prop('disabled', false);
    142158            });
    143159        });
     
    166182
    167183        this.refresh.on('click', function() {
    168             self.refresh.addClass('is-loading');
    169             $.post(ajaxurl + '?action=pensopay_fetch_private_key', { api_key: self.apiKeyField.val() }, function(response) {
    170                 if (response.status === 'success') {
    171                     self.field.val(response.data.private_key);
    172                 } else {
    173                     self.flashError(response.message);
    174                 }
    175 
    176                 self.refresh.removeClass('is-loading');
    177             }, 'json');
     184            if ( ! self.refresh.hasClass('ok')) {
     185                self.refresh.addClass('is-loading');
     186                $.post(ajaxurl + '?action=pensopay_fetch_private_key', { api_key: self.apiKeyField.val() }, function(response) {
     187                    if (response.status === 'success') {
     188                        self.field.val(response.data.private_key);
     189                        self.refresh.removeClass('refresh').addClass('ok');
     190                    } else {
     191                        self.flashError(response.message);
     192                    }
     193
     194                    self.refresh.removeClass('is-loading');
     195                }, 'json');
     196            }
    178197        });
    179     }
     198
     199        this.validatePrivateKey();
     200    }
     201
     202    PensoPayPrivateKey.prototype.validatePrivateKey = function() {
     203        var self = this;
     204        $.post(ajaxurl + '?action=pensopay_fetch_private_key', { api_key: self.apiKeyField.val() }, function(response) {
     205            if (response.status === 'success' && self.field.val() === response.data.private_key) {
     206                self.refresh.removeClass('refresh').addClass('ok');
     207            }
     208
     209            self.refresh.fadeIn();
     210        }, 'json');
     211    };
    180212
    181213    PensoPayPrivateKey.prototype.flashError = function (message) {
  • woo-pensopay/tags/5.7.1/assets/javascript/mobilepay.js

    r2135476 r2326668  
    7373        disableField: function ($field) {
    7474            if (  ! togglableCheckoutFields ) {
     75                return;
     76            }
     77
     78            if ($field.selector === '#billing_phone') {
    7579                return;
    7680            }
  • woo-pensopay/tags/5.7.1/assets/stylesheets/woocommerce-pensopay.css

    r2237549 r2326668  
    212212}
    213213
    214 #wcpp_wiki, #wcpp_logs {
     214
     215.button.wcpp-debug-button {
    215216    margin-right: 5px;
    216217}
  • woo-pensopay/tags/5.7.1/classes/api/woocommerce-pensopay-api-payment.php

    r2237549 r2326668  
    6666     * @throws PensoPay_API_Exception
    6767     * @throws PensoPay_Exception
     68     * @throws PensoPay_Capture_Exception
    6869     */
    6970    public function capture( $transaction_id, $order, $amount = null ) {
     
    8182
    8283        if ( $capture->qp_status_code > 20200 ) {
    83             throw new PensoPay_API_Exception( sprintf( 'Capturing payment on order #%s failed. Message: %s', $order->get_id(), $capture->qp_status_msg ) );
     84            throw new PensoPay_Capture_Exception( sprintf( 'Capturing payment on order #%s failed. Message: %s', $order->get_id(), $capture->qp_status_msg ) );
    8485        }
    8586
     
    165166        $remaining_balance = $this->get_remaining_balance();
    166167
     168
    167169        $allowed_states = [
    168170            'capture'          => [ 'authorize', 'recurring' ],
    169             'cancel'           => [ 'authorize' ],
     171            'cancel'           => [ 'authorize', 'recurring' ],
    170172            'refund'           => [ 'capture', 'refund' ],
    171173            'renew'            => [ 'authorize' ],
     
    176178
    177179        // We wants to still allow captures if there is a remaining balance.
    178         if ( 'capture' == $state && $remaining_balance > 0 ) {
     180        if ( 'capture' === $state && $remaining_balance > 0 && $action !== 'cancel' ) {
    179181            return true;
    180182        }
  • woo-pensopay/tags/5.7.1/classes/api/woocommerce-pensopay-api-subscription.php

    r2237549 r2326668  
    1313class WC_PensoPay_API_Subscription extends WC_PensoPay_API_Transaction
    1414{
    15     /**
    16     * __construct function.
    17     *
    18     * @access public
    19     * @return void
    20     */
    21     public function __construct( $resource_data = NULL )
    22     {
    23         // Run the parent construct
    24         parent::__construct();
     15    /**
     16     * __construct function.
     17     *
     18     * @access public
     19     * @return void
     20     */
     21    public function __construct( $resource_data = null ) {
     22        // Run the parent construct
     23        parent::__construct();
    2524
    26         // Set the resource data to an object passed in on object instantiation.
    27         // Usually done when we want to perform actions on an object returned from
    28         // the API sent to the plugin callback handler.
    29         if( is_object( $resource_data ) )
    30         {
    31             $this->resource_data = $resource_data;
    32         }
     25        // Set the resource data to an object passed in on object instantiation.
     26        // Usually done when we want to perform actions on an object returned from
     27        // the API sent to the plugin callback handler.
     28        if ( is_object( $resource_data ) ) {
     29            $this->resource_data = $resource_data;
     30        }
    3331
    34         // Append the main API url
    35         $this->api_url .= 'subscriptions/';
    36     }
     32        // Append the main API url
     33        $this->api_url .= 'subscriptions/';
     34    }
    3735
    3836
     
    5351
    5452
    55     /**
    56     * recurring function.
    57     *
    58     * Sends a 'recurring' request to the PensoPay API
    59     *
    60     * @access public
    61     * @param  int $transaction_id
    62     * @param  int $amount
    63     * @return $request
    64     * @throws PensoPay_API_Exception
    65     */
    66     public function recurring( $subscription_id, $order, $amount = NULL)
    67     {
    68         // Check if a custom amount ha been set
    69         if( $amount === NULL )
    70         {
    71             // No custom amount set. Default to the order total
    72             $amount = WC_Subscriptions_Order::get_recurring_total( $order );
    73         }
     53    /**
     54     * recurring function.
     55     *
     56     * Sends a 'recurring' request to the PensoPay API
     57     *
     58     * @access public
     59     *
     60     * @param int $transaction_id
     61     * @param int $amount
     62     *
     63     * @return $request
     64     * @throws PensoPay_API_Exception
     65     */
     66    public function recurring( $subscription_id, $order, $amount = null ) {
     67        // Check if a custom amount ha been set
     68        if ( $amount === null ) {
     69            // No custom amount set. Default to the order total
     70            $amount = WC_Subscriptions_Order::get_recurring_total( $order );
     71        }
    7472
    75         if( ! $order instanceof WC_PensoPay_Order ) {
     73        if ( ! $order instanceof WC_PensoPay_Order ) {
    7674            $order_id = $order->get_id();
    77             $order = new WC_PensoPay_Order( $order_id );
    78         }
     75            $order    = new WC_PensoPay_Order( $order_id );
     76        }
    7977
    80         $order_number = $order->get_order_number_for_api( $is_recurring = TRUE );
     78        $order_number = $order->get_order_number_for_api( $is_recurring = true );
    8179
    82         $request = $this->post( sprintf( '%d/%s?synchronized', $subscription_id, "recurring" ), [
    83             'amount' => WC_PensoPay_Helper::price_multiply( $amount ),
    84             'order_id' => sprintf('%s', $order_number ),
    85             'auto_capture' => $order->get_autocapture_setting(),
    86             'autofee' => WC_PensoPay_Helper::option_is_enabled( WC_PP()->s( 'pensopay_autofee' ) ),
    87             'text_on_statement' => WC_PP()->s('pensopay_text_on_statement'),
    88             'order_post_id' => $order->get_id(),
    89         ], TRUE );
     80        $is_synchronized = apply_filters( 'woocommerce_pensopay_set_synchronized_request', true, $subscription_id, $order, $amount );
    9081
    91         return $request;
    92     }
     82        $request_url = sprintf( '%d/%s?synchronized', $subscription_id, "recurring" );
     83        if ( $is_synchronized ) {
     84            $request_url .= '?synchronized';
     85        }
     86
     87        $request = $this->post( $request_url, [
     88            'amount'            => WC_PensoPay_Helper::price_multiply( $amount ),
     89            'order_id'          => sprintf( '%s', $order_number ),
     90            'auto_capture'      => $order->get_autocapture_setting(),
     91            'autofee'           => WC_PensoPay_Helper::option_is_enabled( WC_PP()->s( 'pensopay_autofee' ) ),
     92            'text_on_statement' => WC_PP()->s( 'pensopay_text_on_statement' ),
     93            'order_post_id'     => $order->get_id(),
     94        ], true );
     95
     96        return $request;
     97    }
    9398
    9499
  • woo-pensopay/tags/5.7.1/classes/api/woocommerce-pensopay-api-transaction.php

    r2237549 r2326668  
    301301
    302302        $authorized_operations = array_filter( $this->resource_data->operations, function ( $operation ) {
    303             return 'authorize' === $operation->type;
     303            return 'authorize' === $operation->type || 'recurring' === $operation->type;
    304304        } );
    305305
     
    415415     */
    416416    public static function is_transaction_caching_enabled() {
    417         return apply_filters( 'woocommerce_pensopay_transaction_cache_enabled', true );
     417        $is_enabled = strtolower( WC_PP()->s( 'pensopay_caching_enabled' ) ) === 'no' ? false : true;
     418
     419        return apply_filters( 'woocommerce_pensopay_transaction_cache_enabled', $is_enabled );
    418420    }
    419421
     
    433435        }
    434436
     437        $expiration = (int) WC_PP()->s( 'pensopay_caching_expiration' );
     438
     439        if ( ! $expiration ) {
     440            $expiration = 7 * DAY_IN_SECONDS;
     441        }
     442
    435443        // Cache expiration in seconds
    436         $expiration = apply_filters( 'woocommerce_pensopay_transaction_cache_expiration', 7 * DAY_IN_SECONDS );
     444        $expiration = apply_filters( 'woocommerce_pensopay_transaction_cache_expiration', $expiration );
    437445
    438446        return set_transient( 'wcpp_transaction_' . $this->resource_data->id, json_encode( $this->resource_data ), $expiration );
  • woo-pensopay/tags/5.7.1/classes/api/woocommerce-pensopay-api.php

    r2237549 r2326668  
    5151     */
    5252    public function __construct( $api_key = null ) {
    53         add_action( 'shutdown', [ $this, 'shutdown' ] );
    54 
    5553        if ( empty( $api_key ) ) {
    5654            $this->api_key = WC_PP()->s( 'pensopay_apikey' );
     
    254252        // Everything went well, return the resource data object.
    255253        if ( $return_array ) {
    256             return [
     254            $return_data = [
    257255                $this->resource_data,
    258256                $curl_request_url,
     
    261259                curl_getinfo( $this->ch ),
    262260            ];
    263         }
    264 
    265         return $this->resource_data;
     261        } else {
     262            $return_data = $this->resource_data;
     263        }
     264
     265        curl_close( $this->ch );
     266
     267        return $return_data;
    266268    }
    267269
     
    286288     *
    287289     * @access public
    288      * @return cURL object
     290     * @return false|resource
    289291     */
    290292    protected function remote_instance( $post_id = null ) {
    291         if ( $this->ch === null ) {
    292             $this->ch = curl_init();
    293             curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, true );
    294             curl_setopt( $this->ch, CURLOPT_SSL_VERIFYPEER, false );
    295             curl_setopt( $this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
    296             curl_setopt( $this->ch, CURLOPT_HTTPHEADER, [
    297                 'Authorization: Basic ' . base64_encode( ':' . $this->api_key ),
    298                 'Accept-Version: v10',
    299                 'Accept: application/json',
    300                 'PensoPay-Callback-Url: ' . ( ! $this->block_callback ) ? WC_PensoPay_Helper::get_callback_url( $post_id ) : null
    301             ] );
    302         }
     293        $this->ch = curl_init();
     294
     295        curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, true );
     296        curl_setopt( $this->ch, CURLOPT_SSL_VERIFYPEER, false );
     297        curl_setopt( $this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
     298
     299        curl_setopt( $this->ch, CURLINFO_HEADER_OUT, true );
     300
     301        $callback_url = ! apply_filters( 'woocommerce_pensopay_block_callback', $this->block_callback, $post_id ) ? WC_PensoPay_Helper::get_callback_url( $post_id ) : null;
     302
     303        curl_setopt( $this->ch, CURLOPT_HTTPHEADER, [
     304            'Authorization: Basic ' . base64_encode( ':' . $this->api_key ),
     305            'Accept-Version: v10',
     306            'Accept: application/json',
     307            "QuickPay-Callback-Url: {$callback_url}"
     308        ] );
    303309
    304310        return $this->ch;
    305     }
    306 
    307 
    308     /**
    309      * shutdown function.
    310      *
    311      * Closes the current cURL connection
    312      *
    313      * @access public
    314      * @return void
    315      */
    316     public function shutdown() {
    317         if ( ! empty( $this->ch ) ) {
    318             curl_close( $this->ch );
    319         }
    320311    }
    321312
  • woo-pensopay/tags/5.7.1/classes/instances/mobilepay-checkout.php

    r2237549 r2326668  
    175175            try {
    176176                $customer = null;
     177                $create_user = apply_filters( 'woocommerce_pensopay_mobilepay_checkout_create_user', wc()->checkout()->is_registration_required(), $order, $transaction );
    177178
    178179                if ( ! $order->get_customer_id() ) {
     
    181182                        $customer = new WC_Customer( $customer_id );
    182183                    }
    183                 } else if ( $this->s( 'mobilepay_checkout_update_existing_customer_data' ) ) {
     184                } else if ( $order->get_customer_id() && $this->s( 'mobilepay_checkout_update_existing_customer_data' ) ) {
    184185                    $customer = new WC_Customer( $order->get_customer_id() );
    185186                }
  • woo-pensopay/tags/5.7.1/classes/instances/viabill.php

    r2237549 r2326668  
    44
    55    public $main_settings = NULL;
     6
     7    protected $_isWdp = false;
    68
    79    public function __construct() {
     
    2426        add_filter('woocommerce_gateway_method_description', [ $this, 'viabill_payment_method' ], 10, 2);
    2527        add_action('woocommerce_checkout_order_review', [ $this, 'viabill_checkout_order_review'], 10, 0);
     28        $that = $this;
     29        add_action('wdp_price_display_init_hooks', static function() use($that) { $that->_isWdp = false; }, 10, 0);
     30        add_action('wdp_price_display_remove_hooks', static function() use($that) { $that->_isWdp = true; }, 10, 0);
    2631    }
    2732
     
    106111    {
    107112        global $woocommerce_loop;
     113
     114        //Do not show for advanced pricing
     115        if ($this->_isWdp) {
     116            return '';
     117        }
    108118
    109119        //Frontpage / shop page
  • woo-pensopay/tags/5.7.1/classes/woocommerce-pensopay-helper.php

    r2238251 r2326668  
    1818    const PENSOPAY_VAR_ORDERID = 'order_id';
    1919    const PENSOPAY_VAR_IFRAMESUCCESS = 'pensoPaySuccess';
     20
     21    protected static function get_recurring_total($order)
     22    {
     23        $recurring_total = 0;
     24
     25        foreach ( wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) ) as $subscription ) {
     26
     27            // Find the total for all recurring items
     28            if ( empty( $product_id ) ) {
     29                $recurring_total += $subscription->get_total() + $subscription->get_total_discount(); //This behavior changed
     30            } else {
     31                // We want the discount for a specific item (so we need to find if this subscription contains that item)
     32                foreach ( $subscription->get_items() as $line_item ) {
     33                    if ( wcs_get_canonical_product_id( $line_item ) == $product_id ) {
     34                        $recurring_total += $subscription->get_total() + $subscription->get_total_discount();
     35                        break;
     36                    }
     37                }
     38            }
     39        }
     40
     41        return $recurring_total;
     42    }
     43
     44    public static function order_needs_payment( $needs_payment, $order, $valid_order_statuses ) {
     45        /**
     46         * We need to add an extra step here because of a WC_Subscriptions bug
     47         * Basically, we emulate WC_Subscriptions' check with a fix for actual recurring total
     48         */
     49        if (
     50            false === $needs_payment
     51            && 0 == $order->get_total()
     52            && in_array($order->get_status(), $valid_order_statuses)
     53            && wcs_order_contains_subscription($order)
     54            && self::get_recurring_total($order) > 0
     55            && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')
     56        ) {
     57            $needs_payment = true;
     58        }
     59
     60        return $needs_payment;
     61    }
    2062
    2163    public static function viabill_header()
  • woo-pensopay/tags/5.7.1/classes/woocommerce-pensopay-log.php

    r2237549 r2326668  
    1111 */
    1212class WC_PensoPay_Log {
    13    
     13
    1414    /* The domain handler used to name the log */
    1515    private $_domain = 'woocommerce-pensopay';
    16    
    17    
     16
     17
    1818    /* The WC_Logger instance */
    1919    private $_logger;
    20    
    21    
     20
     21
    2222    /**
    2323    * __construct.
  • woo-pensopay/tags/5.7.1/classes/woocommerce-pensopay-order.php

    r2237549 r2326668  
    855855            'bitcoin',
    856856            'ideal',
     857            'fbg1886',
     858            'ideal',
    857859            'klarna',
    858860            'pensopay',
    859861            'mobilepay',
    860862            'mobilepay_checkout',
     863            'paypal',
    861864            'pensopay',
    862865            'pensopay-extra',
    863866            'resurs',
    864867            'sofort',
     868            'swish',
    865869            'trustly',
    866870            'viabill',
  • woo-pensopay/tags/5.7.1/classes/woocommerce-pensopay-settings.php

    r2237549 r2326668  
    115115                    'checkboxgroup'   => 'end'
    116116                ],
     117
     118                '_caching'                    => [
     119                    'type'  => 'title',
     120                    'title' => __( 'Transaction Cache', 'woo-pensopay' )
     121                ],
     122                'pensopay_caching_enabled'    => [
     123                    'title'       => __( 'Enable Caching', 'woo-pensopay' ),
     124                    'type'        => 'checkbox',
     125                    'description' => __( 'Caches transaction data to improve application and web-server performance. <strong>Recommended.</strong>', 'woo-pensopay' ),
     126                    'default'     => 'yes',
     127                    'desc_tip'    => false,
     128                ],
     129                'pensopay_caching_expiration' => [
     130                    'title'       => __( 'Cache Expiration', 'woo-pensopay' ),
     131                    'label'       => __( 'Cache Expiration', 'woo-pensopay' ),
     132                    'type'        => 'number',
     133                    'description' => __( '<strong>Time in seconds</strong> for how long a transaction should be cached. <strong>Default: 604800 (7 days).</strong>', 'woo-pensopay' ),
     134                    'default'     => 7 * DAY_IN_SECONDS,
     135                    'desc_tip'    => false,
     136                ],
     137
    117138                '_Extra_gateway_settings'            => [
    118139                    'type'  => 'title',
     
    134155                        'nl'        => 'Dutch',
    135156                        'pl'        => 'Polish',
    136                         'se'        => 'Swedish',
    137                         'automatic' => 'Detect Automatically'
     157                        'se'        => 'Swedish'
    138158                    ]
    139159                ],
    140                 'pensopay_currency'                  => [
     160                'pensopay_currency'       => [
    141161                    'title'       => __( 'Currency', 'woo-pensopay' ),
    142162                    'description' => __( 'Choose your currency. Please make sure to use the same currency as in your WooCommerce currency settings.', 'woo-pensopay' ),
     
    152172                    ]
    153173                ],
    154                 'pensopay_cardtypelock'              => [
     174                'pensopay_cardtypelock'   => [
    155175                    'title'       => __( 'Payment methods', 'woo-pensopay' ),
    156176                    'type'        => 'text',
     
    158178                    'default'     => 'creditcard',
    159179                ],
    160                 'pensopay_branding_id'               => [
     180                'pensopay_branding_id'    => [
    161181                    'title'       => __( 'Branding ID', 'woo-pensopay' ),
    162182                    'type'        => 'text',
     
    165185                    'desc_tip'    => true,
    166186                ],
    167                 'pensopay_sendaddresses'             => [
     187                'pensopay_sendaddresses'           => [
    168188                    'title'       => __( 'Send customer info to payment gateway', 'woo-pensopay' ),
    169189                    'type'        => 'checkbox',
     
    173193                    'desc_tip'    => true,
    174194                ],
    175                 'pensopay_iframe'           => [
    176                     'title'       => __( 'Enable IFrame', 'woo-pensopay' ),
    177                     'type'        => 'checkbox',
    178                     'label'       => __( 'Enable', 'woo-pensopay' ),
    179                     'description' => __( 'If enabled, payments are made in the shop using an iframe instead of a redirect to pensopay.', 'woo-pensopay' ),
    180                     'default'     => 'no',
    181                     'desc_tip'    => true,
    182                 ],
     195//              'pensopay_iframe'           => [
     196//                  'title'       => __( 'Enable IFrame', 'woo-pensopay' ),
     197//                  'type'        => 'checkbox',
     198//                  'label'       => __( 'Enable', 'woo-pensopay' ),
     199//                  'description' => __( 'If enabled, payments are made in the shop using an iframe instead of a redirect to pensopay.', 'woo-pensopay' ),
     200//                  'default'     => 'no',
     201//                  'desc_tip'    => true,
     202//              ],
    183203                'pensopay_autofee' => [
    184204                    'title'       => __( 'Enable autofee', 'woo-pensopay' ),
     
    200220                    'title'             => __( 'Text on statement', 'woo-pensopay' ),
    201221                    'type'              => 'text',
    202                     'description'       => __( 'Text that will be placed on cardholder’s bank statement (MAX 22 ASCII characters and only supported by Clearhaus currently).', 'woo-pensopay' ),
     222                    'description'       => __( '<b>Note: Only enter a value if required to do so.</b><br/>Text that will be placed on cardholder’s bank statement (MAX 22 ASCII characters and only supported by Clearhaus currently).', 'woo-pensopay' ),
    203223                    'default'           => '',
    204                     'desc_tip'          => true,
     224                    'desc_tip'          => false,
    205225                    'custom_attributes' => [
    206226                        'maxlength' => 22,
     
    396416        printf( '<a id="wcpp_logs" class="button" href="%s">%s</a>', WC_PP()->log->get_admin_link(), __( 'View debug logs', 'woo-pensopay' ) );
    397417        printf( '<button id="wcpp_logs_clear" class="button">%s</button>', __( 'Empty debug logs', 'woo-pensopay' ) );
    398         printf( '<br/>' );
    399         printf( '<h3 class="wc-settings-sub-title">%s</h3>', __( 'Enable', 'woo-pensopay' ) );
     418
     419        if ( woocommerce_pensopay_can_user_empty_logs() ) {
     420            printf( '<button role="button" id="wcpp_logs_clear" class="wcpp-debug-button button">%s</button>', __( 'Empty debug logs', 'woo-pensopay' ) );
     421        }
     422
     423        if ( woocommerce_pensopay_can_user_flush_cache() ) {
     424            printf( '<button role="button" id="wcpp_flush_cache" class="wcpp-debug-button button">%s</button>', __( 'Empty transaction cache', 'woo-pensopay' ) );
     425        }
     426
     427        printf( '<br/>' );
     428        printf( '<h3 class="wc-settings-sub-title">%s</h3>', __( 'Enable', 'woo-pensopay' ) );
    400429    }
    401430
  • woo-pensopay/tags/5.7.1/woocommerce-pensopay.php

    r2240317 r2326668  
    44 * Plugin URI: http://wordpress.org/plugins/pensopay/
    55 * Description: Integrates your PensoPay payment gateway into your WooCommerce installation.
    6  * Version: 5.5.3
     6 * Version: 5.7.1
    77 * Author: PensoPay
    88 * Text Domain: woo-pensopay
     
    6868    require_once WCPP_PATH . 'classes/modules/woocommerce-pensopay-checkout.php';
    6969    require_once WCPP_PATH . 'classes/modules/woocommerce-pensopay-admin-orders.php';
     70    require_once WCPP_PATH . 'classes/woocommerce-pensopay-statekeeper.php';
    7071    require_once WCPP_PATH . 'classes/woocommerce-pensopay-exceptions.php';
    7172    require_once WCPP_PATH . 'classes/woocommerce-pensopay-log.php';
     
    7879    require_once WCPP_PATH . 'classes/woocommerce-pensopay-views.php';
    7980    require_once WCPP_PATH . 'classes/woocommerce-pensopay-callbacks.php';
     81    require_once WCPP_PATH . 'helpers/permissions.php';
    8082    require_once WCPP_PATH . 'helpers/transactions.php';
    8183
     
    245247
    246248            if ( is_admin() ) {
    247                 add_action( 'admin_menu', 'WC_PensoPay_Helper::enqueue_stylesheet' );
    248                 add_action( 'admin_menu', 'WC_PensoPay_Helper::enqueue_javascript_backend' );
     249                add_action( 'admin_enqueue_scripts', 'WC_PensoPay_Helper::enqueue_stylesheet' );
     250                add_action( 'admin_enqueue_scripts', 'WC_PensoPay_Helper::enqueue_javascript_backend' );
    249251                add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ] );
    250252                add_action( 'wp_ajax_pensopay_manual_transaction_actions', [ $this, 'ajax_pensopay_manual_transaction_actions' ] );
    251253                add_action( 'wp_ajax_pensopay_empty_logs', [ $this, 'ajax_empty_logs' ] );
     254                add_action( 'wp_ajax_pensopay_flush_cache', [ $this, 'ajax_flush_cache' ] );
    252255                add_action( 'wp_ajax_pensopay_ping_api', [ $this, 'ajax_ping_api' ] );
    253256                add_action( 'wp_ajax_pensopay_fetch_private_key', [ $this, 'ajax_fetch_private_key' ] );
     
    277280            add_filter( 'qtranslate_language_detect_redirect', 'WC_PensoPay_Helper::qtranslate_prevent_redirect', 10, 3 );
    278281            add_filter( 'wpss_misc_form_spam_check_bypass', 'WC_PensoPay_Helper::spamshield_bypass_security_check', - 10, 1 );
     282
     283            //Needs Payment Subscription Fix
     284            add_filter( 'woocommerce_order_needs_payment', 'WC_PensoPay_Helper::order_needs_payment', 10, 3 );
    279285
    280286            add_action('wp_head', 'WC_PensoPay_Helper::viabill_header'); //Header JS
     
    499505
    500506                    // Subscription
    501                     if ( $order->contains_subscription() ) {
     507                    if ( WC_PensoPay_Subscription::is_subscription( $order ) ) {
    502508                        $payment = new WC_PensoPay_API_Subscription();
    503509                        $payment->get( $transaction_id );
     
    507513                        $payment->get( $transaction_id );
    508514                    }
    509 
    510515
    511516                    $payment->get( $transaction_id );
     
    553558         */
    554559        public function ajax_empty_logs() {
    555             $this->log->clear();
    556             echo json_encode( [ 'status' => 'success', 'message' => 'Logs successfully emptied' ] );
    557             exit;
     560            if ( woocommerce_pensopay_can_user_empty_logs() ) {
     561                $this->log->clear();
     562                echo json_encode( [ 'status' => 'success', 'message' => 'Logs successfully emptied' ] );
     563                exit;
     564            }
     565        }
     566
     567        /**
     568         * ajax_empty_logs function.
     569         *
     570         * Ajax method to empty the debug logs
     571         *
     572         * @access public
     573         * @return json
     574         */
     575        public function ajax_flush_cache() {
     576            global $wpdb;
     577            if ( woocommerce_pensopay_can_user_flush_cache() ) {
     578                $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_wcpp_transaction_%' OR option_name LIKE '_transient_timeout_wcpp_transaction_%'" );
     579                echo json_encode( [ 'status' => 'success', 'message' => 'The transaction cache has been cleared.' ] );
     580                exit;
     581            }
    558582        }
    559583
     
    615639            $order = new WC_PensoPay_Order( $post_id );
    616640
    617             // Only run logic on the correct instance to avoid multiple calls.
    618             //has_pensopay_payment handles this - kept for brevity
    619 //          if ( $this->id !== $order->get_payment_method() ) {
    620 //              return;
    621 //          }
     641            // Only run logic on the correct instance to avoid multiple calls, or if all extra instances has not been loaded.
     642            if ( ( WC_PensoPay_Statekeeper::$gateways_added && $this->id !== $order->get_payment_method() ) || ! $order->has_pensopay_payment() ) {
     643                return;
     644            }
    622645
    623646            // Check the gateway settings.
     
    896919
    897920            // Capture a recurring payment with fixed amount
    898             $response = $this->process_recurring_payment( $transaction, $transaction_id, $amount_to_charge, $renewal_order );
    899 
    900             return $response;
     921            return $this->process_recurring_payment( $transaction, $transaction_id, $amount_to_charge, $renewal_order );
    901922        }
    902923
     
    923944
    924945                // Capture a recurring payment with fixed amount
    925                 list( $response ) = $transaction->recurring( $subscription_transaction_id, $order, $amount_to_charge );
     946                list( $response, $request_url ) = $transaction->recurring( $subscription_transaction_id, $order, $amount_to_charge );
    926947
    927948                if ( ! $response->accepted ) {
    928                     throw new PensoPay_Exception( "Recurring payment not accepted by acquirer." );
     949                    if ( $response->state === 'pending' && strpos( $request_url, 'synchronized' ) === false ) {
     950                        // Payment is still pending and is not ready to be handled.. Wait for callback and skip processing on our end for now.
     951                        return $response;
     952                    } else {
     953                        throw new PensoPay_Exception( "Recurring payment not accepted by acquirer." );
     954                    }
    929955                }
    930956
     
    969995            $order_meta_query .= " AND `meta_key` NOT IN ('" . WC_PensoPay_Order::META_FAILED_PAYMENT_COUNT . "')";
    970996            $order_meta_query .= " AND `meta_key` NOT IN ('_pensopay_transaction_id')";
     997            $order_meta_query .= " AND `meta_key` NOT IN ('_transaction_id')";
    971998
    972999            return $order_meta_query;
     
    11471174                $transaction = end( $json->operations );
    11481175
    1149                 // Is the transaction accepted and approved by PP / Acquirer?
    1150                 if ( $json->accepted ) {
     1176                // Is the transaction accepted and approved by QP / Acquirer?
     1177                // Did we find an order?
     1178                if ( $json->accepted && $order ) {
     1179                    // Overwrite the order object to inherit specific PensoPay logic
     1180                    $order = new WC_PensoPay_Order( $order->get_id() );
    11511181
    11521182                    do_action( 'woocommerce_pensopay_accepted_callback_before_processing', $order, $json );
     
    11711201                            case 'refund' :
    11721202                                $order->note( sprintf( __( 'Refunded %s %s', 'woo-pensopay' ), WC_PensoPay_Helper::price_normalize( $transaction->amount ), $json->currency ) );
    1173                                 break;
     1203                                break;
     1204
     1205                            case 'recurring':
     1206                                WC_PensoPay_Callbacks::payment_authorized( $order, $json );
     1207                                break;
    11741208
    11751209                            case 'authorize' :
     
    12401274                    $this->log->separator();
    12411275
    1242                     if ( $transaction->type == 'recurring' ) {
    1243                         WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $order );
    1244                     }
     1276                    if ( $transaction->type == 'recurring' || 'rejected' !== $json->state ) {
     1277                        $order->update_status( 'failed', sprintf( 'Payment failed: <br />%s', $request_body ) );
     1278                    }
    12451279
    12461280                    if ( 'rejected' != $json->state ) {
     
    15891623                        }
    15901624
    1591                         WC_PensoPay_Views::get_view( 'html-order-table-transaction-data.php', array(
     1625                        WC_PensoPay_Views::get_view( 'html-order-table-transaction-data.php', [
    15921626                            'transaction_id'             => $transaction_id,
    15931627                            'transaction_order_id'       => $order->get_transaction_order_id(),
     
    15971631                            'transaction_is_test'        => $transaction->is_test(),
    15981632                            'is_cached'                  => $transaction->is_loaded_from_cached(),
    1599                         ) );
     1633                        ] );
    16001634                    }
    16011635                } catch ( PensoPay_API_Exception $e ) {
     
    18651899        $methods[] = 'WC_PensoPay';
    18661900
     1901        WC_PensoPay_Statekeeper::$gateways_added = true;
     1902
    18671903        return apply_filters( 'woocommerce_pensopay_load_instances', $methods );
    18681904    }
     
    18721908    add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'WC_PensoPay::add_action_links' );
    18731909}
     1910
     1911if (!class_exists( 'WC_PensoPay_VirtualTerminal_Payment' )) {
     1912    require_once WCPP_PATH . 'classes/woocommerce-pensopay-virtualterminal-payment.php';
     1913}
     1914
     1915add_action('admin_menu', function($t) {
     1916    if (is_admin() && current_user_can('manage_woocommerce')) {
     1917        add_submenu_page('woo-virtualterminal', __('New Payment', 'woo-pensopay'),
     1918            __('New Payment', 'woo-pensopay'), 'manage_woocommerce', 'pensopay-virtualterminal-payment', array(
     1919                WC_PensoPay_VirtualTerminal_Payment::get_instance(),
     1920                'render'
     1921            ));
     1922    }
     1923}, 90, 1);
     1924add_action('init', array(WC_PensoPay_VirtualTerminal_Payment::class, 'register_post_types'), 5);
     1925
     1926//add_filter('cron_schedules', 'add_penso_cron');
     1927//function add_penso_cron($schedules)
     1928//{
     1929//    $schedules['minute'] = array(
     1930//        'interval' => 1, //*60
     1931//        'display' => esc_html__('Every Minute'),
     1932//    );
     1933//    return $schedules;
     1934//}
     1935
     1936add_action('pensopay_virtualpayments_update', 'WC_PensoPay_VirtualTerminal_Payment::vterminal_update_payments');
     1937if (!wp_next_scheduled('pensopay_virtualpayments_update')) {
     1938    wp_schedule_event(time(), 'daily', 'pensopay_virtualpayments_update');
     1939}
     1940
     1941register_deactivation_hook(__FILE__, 'pensopay_virtualpayments_update_deactivate');
     1942function pensopay_virtualpayments_update_deactivate()
     1943{
     1944    $timestamp = wp_next_scheduled('pensopay_virtualpayments_update');
     1945    wp_unschedule_event($timestamp, 'pensopay_virtualpayments_update');
     1946}
     1947
    18741948
    18751949/**
  • woo-pensopay/trunk/README.txt

    r2240317 r2326668  
    2828
    2929== Changelog ==
     30= 5.7.1 =
     31* Fix: WC_Subscriptions error with zero checkout amount when using a 100% discount coupon.
     32* Fix: Viabill double tag in some cases on product page.
     33* Fix: Viabill logo show on order view.
     34* Fix: Mobilepay now moves the phone number to the payment window.
     35* Feature: Virtual Terminal added. Allows payments from admin now.
     36* Feature: Mass Capture
     37* Deprecation of iframe in favor of embedded window.
     38* Test against latest versions.
     39
     40= 5.7.0 =
     41* Feature: Add callback handler for recurring requests
     42* Fix: Stop using WC_Subscriptions_Manager::process_subscription_payment_failure_on_order as this is deprecated.
     43* Dev: Make synchronous recurring requests optional with the introduced filter: woocommerce_pensopay_set_synchronized_request
     44* Dev: Blocked callbacks for recurring requests are now optional. Can be disabled with the filter: woocommerce_pensopay_block_callback
     45
     46= 5.6.2 =
     47* Fix: Add missing order payment box in backend for fbg1886, ideal, paypal and swish
     48
     49= 5.6.1 =
     50* Fix: MobilePay Checkout not saving address data properly when no customer account was set on the order.
     51
     52= 5.6.0 =
     53* Feature: Add UI setting for enabling/disabling transaction caching
     54* Feature: Add UI setting for setting the transaction caching expiration time
     55* Feature: Update a cached transaction on accepted callbacks
     56* Feature: Add private key validation and success indicator next to the settings field - (requires permissions to read the private key via API)
     57* Feature: Add button to flush the transaction cache from inside the plugin settings
     58* Fix: Remove "Cancel" transaction on partially captured transactions as this action is not supported
     59* Fix: MobilePay Checkout is now only creating users if user registration is required. The behavior can be modified via the filter woocommerce_pensopay_mobilepay_checkout_create_user
     60* Fix: Stop performing capture logic on order completion when the orders is not paid with PensoPay
     61* Fix: Add permission check on ajax endpoint for clearing logs
     62* Fix: WC_PensoPay_Order::get_order_id_from_callback fallback now allows both prefixed and suffixed order numbers
     63* Fix: Recurring payments not being cancellable
     64* Improvement: Do not reuse cURL instances to avoid problems with some cPanel PHP upgrades where KeepAlive is disabled by default
     65* Developer: Add the possibility to hide buttons for clearing logs and transaction cache via filters.
     66
    3067= 5.5.3 =
    3168* Fix for embedded payments.
     
    67104* Fix: Fix missing shipping information on MobilePay Checkout orders if no shipping address is specified in the MobilePay app
    68105* Fix: Bump minimum PHP version to 5.4
     106
     107= 5.3.0 =
    69108* Fix: Make .is-loading in backend more specific.
    70109* Feature: Trustly as separate payment method instance
     
    77116* Enhancement: Updates helper texts on embedded window and text_on_statement on the settings page
    78117* Enhancement: Only load the backend javascripts on relevant pages
     118
     119= 5.2.0 =
    79120* Feature: Add support for embedded payments through overlay with Clearhaus
    80121* Developer: Add action 'woocommerce_pensopay_callback_subscription_authorized' and 'woocommerce_pensopay_callback_payment_authorized' for easier way of handling authorized callbacks for specific transaction types.
  • woo-pensopay/trunk/assets/javascript/backend.js

    r2237549 r2326668  
    124124        new PensoPayPrivateKey().init();
    125125
     126        function wcppInsertAjaxResponseMessage(response) {
     127            if (response.hasOwnProperty('status') && response.status == 'success') {
     128                var message = $('<div id="message" class="updated"><p>' + response.message + '</p></div>');
     129                message.hide();
     130                message.insertBefore($('#wcpp_wiki'));
     131                message.fadeIn('fast', function () {
     132                    setTimeout(function () {
     133                        message.fadeOut('fast', function () {
     134                            message.remove();
     135                        });
     136                    },5000);
     137                });
     138            }
     139        }
     140
    126141        var emptyLogsButton = $('#wcpp_logs_clear');
    127142        emptyLogsButton.on('click', function(e) {
    128143            e.preventDefault();
     144            emptyLogsButton.prop('disabled', true);
    129145            $.getJSON(ajaxurl, { action: 'pensopay_empty_logs' }, function (response) {
    130                 if (response.hasOwnProperty('status') && response.status == 'success') {
    131                     var message = $('<div id="message" class="updated"><p>' + response.message + '</p></div>');
    132                     message.hide();
    133                     message.insertBefore($('#wcpp_wiki'));
    134                     message.fadeIn('fast', function () {
    135                         setTimeout(function () {
    136                             message.fadeOut('fast', function () {
    137                                 message.remove();
    138                             });
    139                         },5000);
    140                     });
    141                 }
     146                wcppInsertAjaxResponseMessage(response);
     147                emptyLogsButton.prop('disabled', false);
     148            });
     149        });
     150
     151        var flushCacheButton = $('#wcpp_flush_cache');
     152        flushCacheButton.on('click', function(e) {
     153            e.preventDefault();
     154            flushCacheButton.prop('disabled', true);
     155            $.getJSON(ajaxurl, { action: 'pensopay_flush_cache' }, function (response) {
     156                wcppInsertAjaxResponseMessage(response);
     157                flushCacheButton.prop('disabled', false);
    142158            });
    143159        });
     
    166182
    167183        this.refresh.on('click', function() {
    168             self.refresh.addClass('is-loading');
    169             $.post(ajaxurl + '?action=pensopay_fetch_private_key', { api_key: self.apiKeyField.val() }, function(response) {
    170                 if (response.status === 'success') {
    171                     self.field.val(response.data.private_key);
    172                 } else {
    173                     self.flashError(response.message);
    174                 }
    175 
    176                 self.refresh.removeClass('is-loading');
    177             }, 'json');
     184            if ( ! self.refresh.hasClass('ok')) {
     185                self.refresh.addClass('is-loading');
     186                $.post(ajaxurl + '?action=pensopay_fetch_private_key', { api_key: self.apiKeyField.val() }, function(response) {
     187                    if (response.status === 'success') {
     188                        self.field.val(response.data.private_key);
     189                        self.refresh.removeClass('refresh').addClass('ok');
     190                    } else {
     191                        self.flashError(response.message);
     192                    }
     193
     194                    self.refresh.removeClass('is-loading');
     195                }, 'json');
     196            }
    178197        });
    179     }
     198
     199        this.validatePrivateKey();
     200    }
     201
     202    PensoPayPrivateKey.prototype.validatePrivateKey = function() {
     203        var self = this;
     204        $.post(ajaxurl + '?action=pensopay_fetch_private_key', { api_key: self.apiKeyField.val() }, function(response) {
     205            if (response.status === 'success' && self.field.val() === response.data.private_key) {
     206                self.refresh.removeClass('refresh').addClass('ok');
     207            }
     208
     209            self.refresh.fadeIn();
     210        }, 'json');
     211    };
    180212
    181213    PensoPayPrivateKey.prototype.flashError = function (message) {
  • woo-pensopay/trunk/assets/javascript/mobilepay.js

    r2135476 r2326668  
    7373        disableField: function ($field) {
    7474            if (  ! togglableCheckoutFields ) {
     75                return;
     76            }
     77
     78            if ($field.selector === '#billing_phone') {
    7579                return;
    7680            }
  • woo-pensopay/trunk/assets/stylesheets/woocommerce-pensopay.css

    r2237549 r2326668  
    212212}
    213213
    214 #wcpp_wiki, #wcpp_logs {
     214
     215.button.wcpp-debug-button {
    215216    margin-right: 5px;
    216217}
  • woo-pensopay/trunk/classes/api/woocommerce-pensopay-api-payment.php

    r2237549 r2326668  
    6666     * @throws PensoPay_API_Exception
    6767     * @throws PensoPay_Exception
     68     * @throws PensoPay_Capture_Exception
    6869     */
    6970    public function capture( $transaction_id, $order, $amount = null ) {
     
    8182
    8283        if ( $capture->qp_status_code > 20200 ) {
    83             throw new PensoPay_API_Exception( sprintf( 'Capturing payment on order #%s failed. Message: %s', $order->get_id(), $capture->qp_status_msg ) );
     84            throw new PensoPay_Capture_Exception( sprintf( 'Capturing payment on order #%s failed. Message: %s', $order->get_id(), $capture->qp_status_msg ) );
    8485        }
    8586
     
    165166        $remaining_balance = $this->get_remaining_balance();
    166167
     168
    167169        $allowed_states = [
    168170            'capture'          => [ 'authorize', 'recurring' ],
    169             'cancel'           => [ 'authorize' ],
     171            'cancel'           => [ 'authorize', 'recurring' ],
    170172            'refund'           => [ 'capture', 'refund' ],
    171173            'renew'            => [ 'authorize' ],
     
    176178
    177179        // We wants to still allow captures if there is a remaining balance.
    178         if ( 'capture' == $state && $remaining_balance > 0 ) {
     180        if ( 'capture' === $state && $remaining_balance > 0 && $action !== 'cancel' ) {
    179181            return true;
    180182        }
  • woo-pensopay/trunk/classes/api/woocommerce-pensopay-api-subscription.php

    r2237549 r2326668  
    1313class WC_PensoPay_API_Subscription extends WC_PensoPay_API_Transaction
    1414{
    15     /**
    16     * __construct function.
    17     *
    18     * @access public
    19     * @return void
    20     */
    21     public function __construct( $resource_data = NULL )
    22     {
    23         // Run the parent construct
    24         parent::__construct();
     15    /**
     16     * __construct function.
     17     *
     18     * @access public
     19     * @return void
     20     */
     21    public function __construct( $resource_data = null ) {
     22        // Run the parent construct
     23        parent::__construct();
    2524
    26         // Set the resource data to an object passed in on object instantiation.
    27         // Usually done when we want to perform actions on an object returned from
    28         // the API sent to the plugin callback handler.
    29         if( is_object( $resource_data ) )
    30         {
    31             $this->resource_data = $resource_data;
    32         }
     25        // Set the resource data to an object passed in on object instantiation.
     26        // Usually done when we want to perform actions on an object returned from
     27        // the API sent to the plugin callback handler.
     28        if ( is_object( $resource_data ) ) {
     29            $this->resource_data = $resource_data;
     30        }
    3331
    34         // Append the main API url
    35         $this->api_url .= 'subscriptions/';
    36     }
     32        // Append the main API url
     33        $this->api_url .= 'subscriptions/';
     34    }
    3735
    3836
     
    5351
    5452
    55     /**
    56     * recurring function.
    57     *
    58     * Sends a 'recurring' request to the PensoPay API
    59     *
    60     * @access public
    61     * @param  int $transaction_id
    62     * @param  int $amount
    63     * @return $request
    64     * @throws PensoPay_API_Exception
    65     */
    66     public function recurring( $subscription_id, $order, $amount = NULL)
    67     {
    68         // Check if a custom amount ha been set
    69         if( $amount === NULL )
    70         {
    71             // No custom amount set. Default to the order total
    72             $amount = WC_Subscriptions_Order::get_recurring_total( $order );
    73         }
     53    /**
     54     * recurring function.
     55     *
     56     * Sends a 'recurring' request to the PensoPay API
     57     *
     58     * @access public
     59     *
     60     * @param int $transaction_id
     61     * @param int $amount
     62     *
     63     * @return $request
     64     * @throws PensoPay_API_Exception
     65     */
     66    public function recurring( $subscription_id, $order, $amount = null ) {
     67        // Check if a custom amount ha been set
     68        if ( $amount === null ) {
     69            // No custom amount set. Default to the order total
     70            $amount = WC_Subscriptions_Order::get_recurring_total( $order );
     71        }
    7472
    75         if( ! $order instanceof WC_PensoPay_Order ) {
     73        if ( ! $order instanceof WC_PensoPay_Order ) {
    7674            $order_id = $order->get_id();
    77             $order = new WC_PensoPay_Order( $order_id );
    78         }
     75            $order    = new WC_PensoPay_Order( $order_id );
     76        }
    7977
    80         $order_number = $order->get_order_number_for_api( $is_recurring = TRUE );
     78        $order_number = $order->get_order_number_for_api( $is_recurring = true );
    8179
    82         $request = $this->post( sprintf( '%d/%s?synchronized', $subscription_id, "recurring" ), [
    83             'amount' => WC_PensoPay_Helper::price_multiply( $amount ),
    84             'order_id' => sprintf('%s', $order_number ),
    85             'auto_capture' => $order->get_autocapture_setting(),
    86             'autofee' => WC_PensoPay_Helper::option_is_enabled( WC_PP()->s( 'pensopay_autofee' ) ),
    87             'text_on_statement' => WC_PP()->s('pensopay_text_on_statement'),
    88             'order_post_id' => $order->get_id(),
    89         ], TRUE );
     80        $is_synchronized = apply_filters( 'woocommerce_pensopay_set_synchronized_request', true, $subscription_id, $order, $amount );
    9081
    91         return $request;
    92     }
     82        $request_url = sprintf( '%d/%s?synchronized', $subscription_id, "recurring" );
     83        if ( $is_synchronized ) {
     84            $request_url .= '?synchronized';
     85        }
     86
     87        $request = $this->post( $request_url, [
     88            'amount'            => WC_PensoPay_Helper::price_multiply( $amount ),
     89            'order_id'          => sprintf( '%s', $order_number ),
     90            'auto_capture'      => $order->get_autocapture_setting(),
     91            'autofee'           => WC_PensoPay_Helper::option_is_enabled( WC_PP()->s( 'pensopay_autofee' ) ),
     92            'text_on_statement' => WC_PP()->s( 'pensopay_text_on_statement' ),
     93            'order_post_id'     => $order->get_id(),
     94        ], true );
     95
     96        return $request;
     97    }
    9398
    9499
  • woo-pensopay/trunk/classes/api/woocommerce-pensopay-api-transaction.php

    r2237549 r2326668  
    301301
    302302        $authorized_operations = array_filter( $this->resource_data->operations, function ( $operation ) {
    303             return 'authorize' === $operation->type;
     303            return 'authorize' === $operation->type || 'recurring' === $operation->type;
    304304        } );
    305305
     
    415415     */
    416416    public static function is_transaction_caching_enabled() {
    417         return apply_filters( 'woocommerce_pensopay_transaction_cache_enabled', true );
     417        $is_enabled = strtolower( WC_PP()->s( 'pensopay_caching_enabled' ) ) === 'no' ? false : true;
     418
     419        return apply_filters( 'woocommerce_pensopay_transaction_cache_enabled', $is_enabled );
    418420    }
    419421
     
    433435        }
    434436
     437        $expiration = (int) WC_PP()->s( 'pensopay_caching_expiration' );
     438
     439        if ( ! $expiration ) {
     440            $expiration = 7 * DAY_IN_SECONDS;
     441        }
     442
    435443        // Cache expiration in seconds
    436         $expiration = apply_filters( 'woocommerce_pensopay_transaction_cache_expiration', 7 * DAY_IN_SECONDS );
     444        $expiration = apply_filters( 'woocommerce_pensopay_transaction_cache_expiration', $expiration );
    437445
    438446        return set_transient( 'wcpp_transaction_' . $this->resource_data->id, json_encode( $this->resource_data ), $expiration );
  • woo-pensopay/trunk/classes/api/woocommerce-pensopay-api.php

    r2237549 r2326668  
    5151     */
    5252    public function __construct( $api_key = null ) {
    53         add_action( 'shutdown', [ $this, 'shutdown' ] );
    54 
    5553        if ( empty( $api_key ) ) {
    5654            $this->api_key = WC_PP()->s( 'pensopay_apikey' );
     
    254252        // Everything went well, return the resource data object.
    255253        if ( $return_array ) {
    256             return [
     254            $return_data = [
    257255                $this->resource_data,
    258256                $curl_request_url,
     
    261259                curl_getinfo( $this->ch ),
    262260            ];
    263         }
    264 
    265         return $this->resource_data;
     261        } else {
     262            $return_data = $this->resource_data;
     263        }
     264
     265        curl_close( $this->ch );
     266
     267        return $return_data;
    266268    }
    267269
     
    286288     *
    287289     * @access public
    288      * @return cURL object
     290     * @return false|resource
    289291     */
    290292    protected function remote_instance( $post_id = null ) {
    291         if ( $this->ch === null ) {
    292             $this->ch = curl_init();
    293             curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, true );
    294             curl_setopt( $this->ch, CURLOPT_SSL_VERIFYPEER, false );
    295             curl_setopt( $this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
    296             curl_setopt( $this->ch, CURLOPT_HTTPHEADER, [
    297                 'Authorization: Basic ' . base64_encode( ':' . $this->api_key ),
    298                 'Accept-Version: v10',
    299                 'Accept: application/json',
    300                 'PensoPay-Callback-Url: ' . ( ! $this->block_callback ) ? WC_PensoPay_Helper::get_callback_url( $post_id ) : null
    301             ] );
    302         }
     293        $this->ch = curl_init();
     294
     295        curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, true );
     296        curl_setopt( $this->ch, CURLOPT_SSL_VERIFYPEER, false );
     297        curl_setopt( $this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
     298
     299        curl_setopt( $this->ch, CURLINFO_HEADER_OUT, true );
     300
     301        $callback_url = ! apply_filters( 'woocommerce_pensopay_block_callback', $this->block_callback, $post_id ) ? WC_PensoPay_Helper::get_callback_url( $post_id ) : null;
     302
     303        curl_setopt( $this->ch, CURLOPT_HTTPHEADER, [
     304            'Authorization: Basic ' . base64_encode( ':' . $this->api_key ),
     305            'Accept-Version: v10',
     306            'Accept: application/json',
     307            "QuickPay-Callback-Url: {$callback_url}"
     308        ] );
    303309
    304310        return $this->ch;
    305     }
    306 
    307 
    308     /**
    309      * shutdown function.
    310      *
    311      * Closes the current cURL connection
    312      *
    313      * @access public
    314      * @return void
    315      */
    316     public function shutdown() {
    317         if ( ! empty( $this->ch ) ) {
    318             curl_close( $this->ch );
    319         }
    320311    }
    321312
  • woo-pensopay/trunk/classes/instances/mobilepay-checkout.php

    r2237549 r2326668  
    175175            try {
    176176                $customer = null;
     177                $create_user = apply_filters( 'woocommerce_pensopay_mobilepay_checkout_create_user', wc()->checkout()->is_registration_required(), $order, $transaction );
    177178
    178179                if ( ! $order->get_customer_id() ) {
     
    181182                        $customer = new WC_Customer( $customer_id );
    182183                    }
    183                 } else if ( $this->s( 'mobilepay_checkout_update_existing_customer_data' ) ) {
     184                } else if ( $order->get_customer_id() && $this->s( 'mobilepay_checkout_update_existing_customer_data' ) ) {
    184185                    $customer = new WC_Customer( $order->get_customer_id() );
    185186                }
  • woo-pensopay/trunk/classes/instances/viabill.php

    r2237549 r2326668  
    44
    55    public $main_settings = NULL;
     6
     7    protected $_isWdp = false;
    68
    79    public function __construct() {
     
    2426        add_filter('woocommerce_gateway_method_description', [ $this, 'viabill_payment_method' ], 10, 2);
    2527        add_action('woocommerce_checkout_order_review', [ $this, 'viabill_checkout_order_review'], 10, 0);
     28        $that = $this;
     29        add_action('wdp_price_display_init_hooks', static function() use($that) { $that->_isWdp = false; }, 10, 0);
     30        add_action('wdp_price_display_remove_hooks', static function() use($that) { $that->_isWdp = true; }, 10, 0);
    2631    }
    2732
     
    106111    {
    107112        global $woocommerce_loop;
     113
     114        //Do not show for advanced pricing
     115        if ($this->_isWdp) {
     116            return '';
     117        }
    108118
    109119        //Frontpage / shop page
  • woo-pensopay/trunk/classes/woocommerce-pensopay-helper.php

    r2238251 r2326668  
    1818    const PENSOPAY_VAR_ORDERID = 'order_id';
    1919    const PENSOPAY_VAR_IFRAMESUCCESS = 'pensoPaySuccess';
     20
     21    protected static function get_recurring_total($order)
     22    {
     23        $recurring_total = 0;
     24
     25        foreach ( wcs_get_subscriptions_for_order( $order, array( 'order_type' => 'parent' ) ) as $subscription ) {
     26
     27            // Find the total for all recurring items
     28            if ( empty( $product_id ) ) {
     29                $recurring_total += $subscription->get_total() + $subscription->get_total_discount(); //This behavior changed
     30            } else {
     31                // We want the discount for a specific item (so we need to find if this subscription contains that item)
     32                foreach ( $subscription->get_items() as $line_item ) {
     33                    if ( wcs_get_canonical_product_id( $line_item ) == $product_id ) {
     34                        $recurring_total += $subscription->get_total() + $subscription->get_total_discount();
     35                        break;
     36                    }
     37                }
     38            }
     39        }
     40
     41        return $recurring_total;
     42    }
     43
     44    public static function order_needs_payment( $needs_payment, $order, $valid_order_statuses ) {
     45        /**
     46         * We need to add an extra step here because of a WC_Subscriptions bug
     47         * Basically, we emulate WC_Subscriptions' check with a fix for actual recurring total
     48         */
     49        if (
     50            false === $needs_payment
     51            && 0 == $order->get_total()
     52            && in_array($order->get_status(), $valid_order_statuses)
     53            && wcs_order_contains_subscription($order)
     54            && self::get_recurring_total($order) > 0
     55            && 'yes' !== get_option(WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'no')
     56        ) {
     57            $needs_payment = true;
     58        }
     59
     60        return $needs_payment;
     61    }
    2062
    2163    public static function viabill_header()
  • woo-pensopay/trunk/classes/woocommerce-pensopay-log.php

    r2237549 r2326668  
    1111 */
    1212class WC_PensoPay_Log {
    13    
     13
    1414    /* The domain handler used to name the log */
    1515    private $_domain = 'woocommerce-pensopay';
    16    
    17    
     16
     17
    1818    /* The WC_Logger instance */
    1919    private $_logger;
    20    
    21    
     20
     21
    2222    /**
    2323    * __construct.
  • woo-pensopay/trunk/classes/woocommerce-pensopay-order.php

    r2237549 r2326668  
    855855            'bitcoin',
    856856            'ideal',
     857            'fbg1886',
     858            'ideal',
    857859            'klarna',
    858860            'pensopay',
    859861            'mobilepay',
    860862            'mobilepay_checkout',
     863            'paypal',
    861864            'pensopay',
    862865            'pensopay-extra',
    863866            'resurs',
    864867            'sofort',
     868            'swish',
    865869            'trustly',
    866870            'viabill',
  • woo-pensopay/trunk/classes/woocommerce-pensopay-settings.php

    r2237549 r2326668  
    115115                    'checkboxgroup'   => 'end'
    116116                ],
     117
     118                '_caching'                    => [
     119                    'type'  => 'title',
     120                    'title' => __( 'Transaction Cache', 'woo-pensopay' )
     121                ],
     122                'pensopay_caching_enabled'    => [
     123                    'title'       => __( 'Enable Caching', 'woo-pensopay' ),
     124                    'type'        => 'checkbox',
     125                    'description' => __( 'Caches transaction data to improve application and web-server performance. <strong>Recommended.</strong>', 'woo-pensopay' ),
     126                    'default'     => 'yes',
     127                    'desc_tip'    => false,
     128                ],
     129                'pensopay_caching_expiration' => [
     130                    'title'       => __( 'Cache Expiration', 'woo-pensopay' ),
     131                    'label'       => __( 'Cache Expiration', 'woo-pensopay' ),
     132                    'type'        => 'number',
     133                    'description' => __( '<strong>Time in seconds</strong> for how long a transaction should be cached. <strong>Default: 604800 (7 days).</strong>', 'woo-pensopay' ),
     134                    'default'     => 7 * DAY_IN_SECONDS,
     135                    'desc_tip'    => false,
     136                ],
     137
    117138                '_Extra_gateway_settings'            => [
    118139                    'type'  => 'title',
     
    134155                        'nl'        => 'Dutch',
    135156                        'pl'        => 'Polish',
    136                         'se'        => 'Swedish',
    137                         'automatic' => 'Detect Automatically'
     157                        'se'        => 'Swedish'
    138158                    ]
    139159                ],
    140                 'pensopay_currency'                  => [
     160                'pensopay_currency'       => [
    141161                    'title'       => __( 'Currency', 'woo-pensopay' ),
    142162                    'description' => __( 'Choose your currency. Please make sure to use the same currency as in your WooCommerce currency settings.', 'woo-pensopay' ),
     
    152172                    ]
    153173                ],
    154                 'pensopay_cardtypelock'              => [
     174                'pensopay_cardtypelock'   => [
    155175                    'title'       => __( 'Payment methods', 'woo-pensopay' ),
    156176                    'type'        => 'text',
     
    158178                    'default'     => 'creditcard',
    159179                ],
    160                 'pensopay_branding_id'               => [
     180                'pensopay_branding_id'    => [
    161181                    'title'       => __( 'Branding ID', 'woo-pensopay' ),
    162182                    'type'        => 'text',
     
    165185                    'desc_tip'    => true,
    166186                ],
    167                 'pensopay_sendaddresses'             => [
     187                'pensopay_sendaddresses'           => [
    168188                    'title'       => __( 'Send customer info to payment gateway', 'woo-pensopay' ),
    169189                    'type'        => 'checkbox',
     
    173193                    'desc_tip'    => true,
    174194                ],
    175                 'pensopay_iframe'           => [
    176                     'title'       => __( 'Enable IFrame', 'woo-pensopay' ),
    177                     'type'        => 'checkbox',
    178                     'label'       => __( 'Enable', 'woo-pensopay' ),
    179                     'description' => __( 'If enabled, payments are made in the shop using an iframe instead of a redirect to pensopay.', 'woo-pensopay' ),
    180                     'default'     => 'no',
    181                     'desc_tip'    => true,
    182                 ],
     195//              'pensopay_iframe'           => [
     196//                  'title'       => __( 'Enable IFrame', 'woo-pensopay' ),
     197//                  'type'        => 'checkbox',
     198//                  'label'       => __( 'Enable', 'woo-pensopay' ),
     199//                  'description' => __( 'If enabled, payments are made in the shop using an iframe instead of a redirect to pensopay.', 'woo-pensopay' ),
     200//                  'default'     => 'no',
     201//                  'desc_tip'    => true,
     202//              ],
    183203                'pensopay_autofee' => [
    184204                    'title'       => __( 'Enable autofee', 'woo-pensopay' ),
     
    200220                    'title'             => __( 'Text on statement', 'woo-pensopay' ),
    201221                    'type'              => 'text',
    202                     'description'       => __( 'Text that will be placed on cardholder’s bank statement (MAX 22 ASCII characters and only supported by Clearhaus currently).', 'woo-pensopay' ),
     222                    'description'       => __( '<b>Note: Only enter a value if required to do so.</b><br/>Text that will be placed on cardholder’s bank statement (MAX 22 ASCII characters and only supported by Clearhaus currently).', 'woo-pensopay' ),
    203223                    'default'           => '',
    204                     'desc_tip'          => true,
     224                    'desc_tip'          => false,
    205225                    'custom_attributes' => [
    206226                        'maxlength' => 22,
     
    396416        printf( '<a id="wcpp_logs" class="button" href="%s">%s</a>', WC_PP()->log->get_admin_link(), __( 'View debug logs', 'woo-pensopay' ) );
    397417        printf( '<button id="wcpp_logs_clear" class="button">%s</button>', __( 'Empty debug logs', 'woo-pensopay' ) );
    398         printf( '<br/>' );
    399         printf( '<h3 class="wc-settings-sub-title">%s</h3>', __( 'Enable', 'woo-pensopay' ) );
     418
     419        if ( woocommerce_pensopay_can_user_empty_logs() ) {
     420            printf( '<button role="button" id="wcpp_logs_clear" class="wcpp-debug-button button">%s</button>', __( 'Empty debug logs', 'woo-pensopay' ) );
     421        }
     422
     423        if ( woocommerce_pensopay_can_user_flush_cache() ) {
     424            printf( '<button role="button" id="wcpp_flush_cache" class="wcpp-debug-button button">%s</button>', __( 'Empty transaction cache', 'woo-pensopay' ) );
     425        }
     426
     427        printf( '<br/>' );
     428        printf( '<h3 class="wc-settings-sub-title">%s</h3>', __( 'Enable', 'woo-pensopay' ) );
    400429    }
    401430
  • woo-pensopay/trunk/woocommerce-pensopay.php

    r2240317 r2326668  
    44 * Plugin URI: http://wordpress.org/plugins/pensopay/
    55 * Description: Integrates your PensoPay payment gateway into your WooCommerce installation.
    6  * Version: 5.5.3
     6 * Version: 5.7.1
    77 * Author: PensoPay
    88 * Text Domain: woo-pensopay
     
    6868    require_once WCPP_PATH . 'classes/modules/woocommerce-pensopay-checkout.php';
    6969    require_once WCPP_PATH . 'classes/modules/woocommerce-pensopay-admin-orders.php';
     70    require_once WCPP_PATH . 'classes/woocommerce-pensopay-statekeeper.php';
    7071    require_once WCPP_PATH . 'classes/woocommerce-pensopay-exceptions.php';
    7172    require_once WCPP_PATH . 'classes/woocommerce-pensopay-log.php';
     
    7879    require_once WCPP_PATH . 'classes/woocommerce-pensopay-views.php';
    7980    require_once WCPP_PATH . 'classes/woocommerce-pensopay-callbacks.php';
     81    require_once WCPP_PATH . 'helpers/permissions.php';
    8082    require_once WCPP_PATH . 'helpers/transactions.php';
    8183
     
    245247
    246248            if ( is_admin() ) {
    247                 add_action( 'admin_menu', 'WC_PensoPay_Helper::enqueue_stylesheet' );
    248                 add_action( 'admin_menu', 'WC_PensoPay_Helper::enqueue_javascript_backend' );
     249                add_action( 'admin_enqueue_scripts', 'WC_PensoPay_Helper::enqueue_stylesheet' );
     250                add_action( 'admin_enqueue_scripts', 'WC_PensoPay_Helper::enqueue_javascript_backend' );
    249251                add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, [ $this, 'process_admin_options' ] );
    250252                add_action( 'wp_ajax_pensopay_manual_transaction_actions', [ $this, 'ajax_pensopay_manual_transaction_actions' ] );
    251253                add_action( 'wp_ajax_pensopay_empty_logs', [ $this, 'ajax_empty_logs' ] );
     254                add_action( 'wp_ajax_pensopay_flush_cache', [ $this, 'ajax_flush_cache' ] );
    252255                add_action( 'wp_ajax_pensopay_ping_api', [ $this, 'ajax_ping_api' ] );
    253256                add_action( 'wp_ajax_pensopay_fetch_private_key', [ $this, 'ajax_fetch_private_key' ] );
     
    277280            add_filter( 'qtranslate_language_detect_redirect', 'WC_PensoPay_Helper::qtranslate_prevent_redirect', 10, 3 );
    278281            add_filter( 'wpss_misc_form_spam_check_bypass', 'WC_PensoPay_Helper::spamshield_bypass_security_check', - 10, 1 );
     282
     283            //Needs Payment Subscription Fix
     284            add_filter( 'woocommerce_order_needs_payment', 'WC_PensoPay_Helper::order_needs_payment', 10, 3 );
    279285
    280286            add_action('wp_head', 'WC_PensoPay_Helper::viabill_header'); //Header JS
     
    499505
    500506                    // Subscription
    501                     if ( $order->contains_subscription() ) {
     507                    if ( WC_PensoPay_Subscription::is_subscription( $order ) ) {
    502508                        $payment = new WC_PensoPay_API_Subscription();
    503509                        $payment->get( $transaction_id );
     
    507513                        $payment->get( $transaction_id );
    508514                    }
    509 
    510515
    511516                    $payment->get( $transaction_id );
     
    553558         */
    554559        public function ajax_empty_logs() {
    555             $this->log->clear();
    556             echo json_encode( [ 'status' => 'success', 'message' => 'Logs successfully emptied' ] );
    557             exit;
     560            if ( woocommerce_pensopay_can_user_empty_logs() ) {
     561                $this->log->clear();
     562                echo json_encode( [ 'status' => 'success', 'message' => 'Logs successfully emptied' ] );
     563                exit;
     564            }
     565        }
     566
     567        /**
     568         * ajax_empty_logs function.
     569         *
     570         * Ajax method to empty the debug logs
     571         *
     572         * @access public
     573         * @return json
     574         */
     575        public function ajax_flush_cache() {
     576            global $wpdb;
     577            if ( woocommerce_pensopay_can_user_flush_cache() ) {
     578                $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_wcpp_transaction_%' OR option_name LIKE '_transient_timeout_wcpp_transaction_%'" );
     579                echo json_encode( [ 'status' => 'success', 'message' => 'The transaction cache has been cleared.' ] );
     580                exit;
     581            }
    558582        }
    559583
     
    615639            $order = new WC_PensoPay_Order( $post_id );
    616640
    617             // Only run logic on the correct instance to avoid multiple calls.
    618             //has_pensopay_payment handles this - kept for brevity
    619 //          if ( $this->id !== $order->get_payment_method() ) {
    620 //              return;
    621 //          }
     641            // Only run logic on the correct instance to avoid multiple calls, or if all extra instances has not been loaded.
     642            if ( ( WC_PensoPay_Statekeeper::$gateways_added && $this->id !== $order->get_payment_method() ) || ! $order->has_pensopay_payment() ) {
     643                return;
     644            }
    622645
    623646            // Check the gateway settings.
     
    896919
    897920            // Capture a recurring payment with fixed amount
    898             $response = $this->process_recurring_payment( $transaction, $transaction_id, $amount_to_charge, $renewal_order );
    899 
    900             return $response;
     921            return $this->process_recurring_payment( $transaction, $transaction_id, $amount_to_charge, $renewal_order );
    901922        }
    902923
     
    923944
    924945                // Capture a recurring payment with fixed amount
    925                 list( $response ) = $transaction->recurring( $subscription_transaction_id, $order, $amount_to_charge );
     946                list( $response, $request_url ) = $transaction->recurring( $subscription_transaction_id, $order, $amount_to_charge );
    926947
    927948                if ( ! $response->accepted ) {
    928                     throw new PensoPay_Exception( "Recurring payment not accepted by acquirer." );
     949                    if ( $response->state === 'pending' && strpos( $request_url, 'synchronized' ) === false ) {
     950                        // Payment is still pending and is not ready to be handled.. Wait for callback and skip processing on our end for now.
     951                        return $response;
     952                    } else {
     953                        throw new PensoPay_Exception( "Recurring payment not accepted by acquirer." );
     954                    }
    929955                }
    930956
     
    969995            $order_meta_query .= " AND `meta_key` NOT IN ('" . WC_PensoPay_Order::META_FAILED_PAYMENT_COUNT . "')";
    970996            $order_meta_query .= " AND `meta_key` NOT IN ('_pensopay_transaction_id')";
     997            $order_meta_query .= " AND `meta_key` NOT IN ('_transaction_id')";
    971998
    972999            return $order_meta_query;
     
    11471174                $transaction = end( $json->operations );
    11481175
    1149                 // Is the transaction accepted and approved by PP / Acquirer?
    1150                 if ( $json->accepted ) {
     1176                // Is the transaction accepted and approved by QP / Acquirer?
     1177                // Did we find an order?
     1178                if ( $json->accepted && $order ) {
     1179                    // Overwrite the order object to inherit specific PensoPay logic
     1180                    $order = new WC_PensoPay_Order( $order->get_id() );
    11511181
    11521182                    do_action( 'woocommerce_pensopay_accepted_callback_before_processing', $order, $json );
     
    11711201                            case 'refund' :
    11721202                                $order->note( sprintf( __( 'Refunded %s %s', 'woo-pensopay' ), WC_PensoPay_Helper::price_normalize( $transaction->amount ), $json->currency ) );
    1173                                 break;
     1203                                break;
     1204
     1205                            case 'recurring':
     1206                                WC_PensoPay_Callbacks::payment_authorized( $order, $json );
     1207                                break;
    11741208
    11751209                            case 'authorize' :
     
    12401274                    $this->log->separator();
    12411275
    1242                     if ( $transaction->type == 'recurring' ) {
    1243                         WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $order );
    1244                     }
     1276                    if ( $transaction->type == 'recurring' || 'rejected' !== $json->state ) {
     1277                        $order->update_status( 'failed', sprintf( 'Payment failed: <br />%s', $request_body ) );
     1278                    }
    12451279
    12461280                    if ( 'rejected' != $json->state ) {
     
    15891623                        }
    15901624
    1591                         WC_PensoPay_Views::get_view( 'html-order-table-transaction-data.php', array(
     1625                        WC_PensoPay_Views::get_view( 'html-order-table-transaction-data.php', [
    15921626                            'transaction_id'             => $transaction_id,
    15931627                            'transaction_order_id'       => $order->get_transaction_order_id(),
     
    15971631                            'transaction_is_test'        => $transaction->is_test(),
    15981632                            'is_cached'                  => $transaction->is_loaded_from_cached(),
    1599                         ) );
     1633                        ] );
    16001634                    }
    16011635                } catch ( PensoPay_API_Exception $e ) {
     
    18651899        $methods[] = 'WC_PensoPay';
    18661900
     1901        WC_PensoPay_Statekeeper::$gateways_added = true;
     1902
    18671903        return apply_filters( 'woocommerce_pensopay_load_instances', $methods );
    18681904    }
     
    18721908    add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'WC_PensoPay::add_action_links' );
    18731909}
     1910
     1911if (!class_exists( 'WC_PensoPay_VirtualTerminal_Payment' )) {
     1912    require_once WCPP_PATH . 'classes/woocommerce-pensopay-virtualterminal-payment.php';
     1913}
     1914
     1915add_action('admin_menu', function($t) {
     1916    if (is_admin() && current_user_can('manage_woocommerce')) {
     1917        add_submenu_page('woo-virtualterminal', __('New Payment', 'woo-pensopay'),
     1918            __('New Payment', 'woo-pensopay'), 'manage_woocommerce', 'pensopay-virtualterminal-payment', array(
     1919                WC_PensoPay_VirtualTerminal_Payment::get_instance(),
     1920                'render'
     1921            ));
     1922    }
     1923}, 90, 1);
     1924add_action('init', array(WC_PensoPay_VirtualTerminal_Payment::class, 'register_post_types'), 5);
     1925
     1926//add_filter('cron_schedules', 'add_penso_cron');
     1927//function add_penso_cron($schedules)
     1928//{
     1929//    $schedules['minute'] = array(
     1930//        'interval' => 1, //*60
     1931//        'display' => esc_html__('Every Minute'),
     1932//    );
     1933//    return $schedules;
     1934//}
     1935
     1936add_action('pensopay_virtualpayments_update', 'WC_PensoPay_VirtualTerminal_Payment::vterminal_update_payments');
     1937if (!wp_next_scheduled('pensopay_virtualpayments_update')) {
     1938    wp_schedule_event(time(), 'daily', 'pensopay_virtualpayments_update');
     1939}
     1940
     1941register_deactivation_hook(__FILE__, 'pensopay_virtualpayments_update_deactivate');
     1942function pensopay_virtualpayments_update_deactivate()
     1943{
     1944    $timestamp = wp_next_scheduled('pensopay_virtualpayments_update');
     1945    wp_unschedule_event($timestamp, 'pensopay_virtualpayments_update');
     1946}
     1947
    18741948
    18751949/**
Note: See TracChangeset for help on using the changeset viewer.