Plugin Directory

Changeset 3321344


Ignore:
Timestamp:
07/02/2025 03:41:08 PM (8 months ago)
Author:
gocardless
Message:

Update to version 2.9.6 from GitHub

Location:
woocommerce-gateway-gocardless
Files:
6 deleted
22 edited
1 copied

Legend:

Unmodified
Added
Removed
  • woocommerce-gateway-gocardless/tags/2.9.6/assets/css/admin.css

    r3239558 r3321344  
    4040    margin-top: 6px;
    4141}
     42
     43.wcgc-sandbox-mode-notice {
     44    margin-top: 12px;
     45    align-items: center;
     46    background-color: #fff2d7;
     47    color: #4d3716;
     48    display: flex;
     49    font-size: 13px;
     50    padding: 12px;
     51    width: max-content;
     52}
  • woocommerce-gateway-gocardless/tags/2.9.6/build/index.asset.php

    r3242739 r3321344  
    1 <?php return array('dependencies' => array('react', 'wc-blocks-registry', 'wc-settings', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => '494e4afed799f2cde0fa');
     1<?php return array('dependencies' => array('react', 'wc-blocks-registry', 'wc-settings', 'wp-html-entities', 'wp-i18n'), 'version' => '70c5c2023330429d40bb');
  • woocommerce-gateway-gocardless/tags/2.9.6/build/index.js

    r3242739 r3321344  
    1 (()=>{"use strict";var e={20:(e,t,o)=>{var s=o(609),r=Symbol.for("react.element"),n=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),i=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,a={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,o){var s,l={},c=null,d=null;for(s in void 0!==o&&(c=""+o),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)n.call(t,s)&&!a.hasOwnProperty(s)&&(l[s]=t[s]);if(e&&e.defaultProps)for(s in t=e.defaultProps)void 0===l[s]&&(l[s]=t[s]);return{$$typeof:r,type:e,key:c,ref:d,props:l,_owner:i.current}}},848:(e,t,o)=>{e.exports=o(20)},609:e=>{e.exports=window.React}},t={};const o=window.wp.htmlEntities,s=window.wp.i18n,r=window.wc.wcBlocksRegistry,n=window.wp.element,i=window.wc.wcSettings,a=()=>{const e=(0,i.getSetting)("gocardless_data",null);if(!e)throw new Error((0,s.__)("GoCardless initialization data is not available","woocommerce-gateway-gocardless"));return e};var l,c,d,u=function o(s){var r=t[s];if(void 0!==r)return r.exports;var n=t[s]={exports:{}};return e[s](n,n.exports,o),n.exports}(848);const{description:p,logo_url:w,title:g,isTest:m,billingRequestNonce:_}=a(),f=e=>{const{eventRegistration:t,emitResponse:r,shouldSavePayment:i}=e,{onCheckoutSuccess:l}=t;return(0,n.useEffect)((()=>l((e=>{let t;return new Promise(((o,n)=>{const l={type:"error",messageContext:r.noticeContexts.PAYMENTS},{GoCardlessDropin:c}=window;if(!c)return void o({...l,message:(0,s.__)("GoCardless Drop-in is not available","woocommerce-gateway-gocardless")});const d=e?.processingResponse?.paymentDetails?.billing_request_flow_id,u=e?.processingResponse?.paymentDetails?.billing_request_nonce||_;if(!d)return void o({...l,message:(0,s.__)("Invalid billing request flow ID","woocommerce-gateway-gocardless")});const p={billingRequestFlowID:d,environment:m?"sandbox":"live",onSuccess:(t,r)=>{w(),t&&["fulfilling","fulfilled"].includes(t.status)?(e=>{const{wcAjaxUrl:t}=a(),o=new FormData;for(const t in e)o.append(t,e[t]);const s=t.replace("%%endpoint%%","gocardless_complete_billing_request_flow");return fetch(s,{method:"POST",body:o}).then((e=>e.json()))})({security:u,order_id:e.orderId,billing_request_id:t.id,save_customer_token:i?"yes":"no"}).then((e=>{e&&e.success?o({type:"success",redirectUrl:e.data.redirect_url}):o({...l,message:e.data?.message})})).catch((e=>{o({...l,message:e.message})})):o({...l,message:(0,s.__)("Billing request is not fulfulling or fulfilled yet, please try again later.","woocommerce-gateway-gocardless")})},onExit:(t,o)=>{t&&console.error(t),window.location.href=e.redirectUrl}};t=c.create(p),t.open();const w=()=>{t?.exit()}}))}))),[l,i,r.noticeContexts.PAYMENTS]),(0,o.decodeEntities)(p||"")},y=()=>(0,u.jsx)("img",{src:w,alt:(0,o.decodeEntities)(g),style:{marginRight:"12px",marginBottom:"4px"}}),v=e=>{const{PaymentMethodLabel:t}=e.components;return(0,u.jsx)(t,{text:(0,o.decodeEntities)(g),icon:(0,u.jsx)(y,{})})};(0,r.registerPaymentMethod)({name:"gocardless",label:(0,u.jsx)(v,{}),ariaLabel:(0,s.__)("GoCardless payment method","woocommerce-gateway-gocardless"),canMakePayment:({billingData:e,cartTotals:t})=>{const o=t?.currency_code,s=a()?.supportedCountries||[],r=a()?.supportedCurrencies||[];return s.includes(e?.country)&&r.includes(o)},content:(0,u.jsx)(f,{}),edit:(0,u.jsx)(f,{}),supports:{showSavedCards:null!==(l=a().showSavedCards)&&void 0!==l&&l,showSaveOption:null!==(c=a().showSaveOption)&&void 0!==c&&c,features:null!==(d=a()?.supports)&&void 0!==d?d:[]}})})();
     1(()=>{"use strict";var e={20:(e,t,o)=>{var r=o(609),n=Symbol.for("react.element"),s=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,o){var r,c={},l=null,d=null;for(r in void 0!==o&&(l=""+o),void 0!==t.key&&(l=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,r)&&!i.hasOwnProperty(r)&&(c[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===c[r]&&(c[r]=t[r]);return{$$typeof:n,type:e,key:l,ref:d,props:c,_owner:a.current}}},848:(e,t,o)=>{e.exports=o(20)},609:e=>{e.exports=window.React}},t={};const o=window.wp.htmlEntities,r=window.wp.i18n,n=window.wc.wcBlocksRegistry,s=window.wc.wcSettings,a=()=>{const e=(0,s.getSetting)("gocardless_data",null);if(!e)throw new Error((0,r.__)("GoCardless initialization data is not available","woocommerce-gateway-gocardless"));return e};var i,c,l,d=function o(r){var n=t[r];if(void 0!==n)return n.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,o),s.exports}(848);const{description:p,logo_url:u,title:w}=a(),_=e=>(0,o.decodeEntities)(p||""),y=()=>(0,d.jsx)("img",{src:u,alt:(0,o.decodeEntities)(w),style:{marginRight:"12px",marginBottom:"4px"}}),m=e=>{const{PaymentMethodLabel:t}=e.components;return(0,d.jsx)(t,{text:(0,o.decodeEntities)(w),icon:(0,d.jsx)(y,{})})};(0,n.registerPaymentMethod)({name:"gocardless",label:(0,d.jsx)(m,{}),ariaLabel:(0,r.__)("GoCardless payment method","woocommerce-gateway-gocardless"),canMakePayment:({billingData:e,cartTotals:t})=>{const o=t?.currency_code,r=a()?.supportedCountries||[],n=a()?.supportedCurrencies||[];return r.includes(e?.country)&&n.includes(o)},content:(0,d.jsx)(_,{}),edit:(0,d.jsx)(_,{}),supports:{showSavedCards:null!==(i=a().showSavedCards)&&void 0!==i&&i,showSaveOption:null!==(c=a().showSaveOption)&&void 0!==c&&c,features:null!==(l=a()?.supports)&&void 0!==l?l:[]}})})();
  • woocommerce-gateway-gocardless/tags/2.9.6/changelog.txt

    r3294262 r3321344  
    11*** GoCardless for WooCommerce Changelog ***
     2
     32025-07-02 - version 2.9.6
     4* Add - Respond with an error to the GoCardless webhook call if the scheduling action fails.
     5* Add - A notice indicating that GoCardless is connected in sandbox mode if the merchant is connected to a sandbox account.
     6* Update - Replaced JavaScript Drop-in with the redirect-to-GoCardless approach for the transaction/direct debit setup.
     7* Dev - Bump WooCommerce "tested up to" version 10.0.
     8* Dev - Bump WooCommerce minimum supported version to 9.8.
    29
    3102025-05-15 - version 2.9.5
  • woocommerce-gateway-gocardless/tags/2.9.6/client/blocks/gocardless-utils.js

    r3239558 r3321344  
    2020    return goCardlessServerData;
    2121};
    22 
    23 /**
    24  * Call the server to complete a billing request flow.
    25  *
    26  * @param {Object} data Data to send to the server.
    27  * @return {Promise<Object>} Response from the server.
    28  */
    29 export const completeBillingRequestFlow = (data) => {
    30     const { wcAjaxUrl } = getGoCardlessServerData();
    31     const formData = new FormData();
    32     for (const key in data) {
    33         formData.append(key, data[key]);
    34     }
    35     const ajaxUrl = wcAjaxUrl.replace(
    36         '%%endpoint%%',
    37         'gocardless_complete_billing_request_flow'
    38     );
    39 
    40     return fetch(ajaxUrl, {
    41         method: 'POST',
    42         body: formData,
    43     }).then((response) => response.json());
    44 };
  • woocommerce-gateway-gocardless/tags/2.9.6/client/blocks/index.js

    r3239558 r3321344  
    55import { __ } from '@wordpress/i18n';
    66import { registerPaymentMethod } from '@woocommerce/blocks-registry';
    7 import { useEffect } from '@wordpress/element';
    87
    98/**
     
    1110 */
    1211import { PAYMENT_METHOD_NAME } from './constants';
    13 import {
    14     completeBillingRequestFlow,
    15     getGoCardlessServerData,
    16 } from './gocardless-utils';
     12import { getGoCardlessServerData } from './gocardless-utils';
    1713
    1814const {
     
    2016    logo_url: logoUrl,
    2117    title,
    22     isTest,
    23     billingRequestNonce,
    2418} = getGoCardlessServerData();
    2519
    2620const Content = (props) => {
    27     const { eventRegistration, emitResponse, shouldSavePayment } = props;
    28     const { onCheckoutSuccess } = eventRegistration;
    29 
    30     // Handle the checkout success event.
    31     useEffect(() => {
    32         const unsubscribe = onCheckoutSuccess((data) => {
    33             let handler;
    34             // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    35             return new Promise((resolve, reject) => {
    36                 const errorOptions = {
    37                     type: 'error',
    38                     messageContext: emitResponse.noticeContexts.PAYMENTS,
    39                 };
    40 
    41                 const { GoCardlessDropin } = window;
    42                 if (!GoCardlessDropin) {
    43                     resolve({
    44                         ...errorOptions,
    45                         message: __(
    46                             'GoCardless Drop-in is not available',
    47                             'woocommerce-gateway-gocardless'
    48                         ),
    49                     });
    50                     return;
    51                 }
    52 
    53                 const billingRequestFlowId =
    54                     data?.processingResponse?.paymentDetails
    55                         ?.billing_request_flow_id;
    56                 const securityNonce = data?.processingResponse?.paymentDetails?.billing_request_nonce || billingRequestNonce;
    57                 if (!billingRequestFlowId) {
    58                     resolve({
    59                         ...errorOptions,
    60                         message: __(
    61                             'Invalid billing request flow ID',
    62                             'woocommerce-gateway-gocardless'
    63                         ),
    64                     });
    65                     return;
    66                 }
    67 
    68                 const options = {
    69                     billingRequestFlowID: billingRequestFlowId,
    70                     environment: isTest ? 'sandbox' : 'live',
    71                     // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    72                     onSuccess: (billingRequest, billingRequestFlow) => {
    73                         closeDropIn();
    74                         if (
    75                             billingRequest &&
    76                             ['fulfilling', 'fulfilled'].includes(
    77                                 billingRequest.status
    78                             )
    79                         ) {
    80                             const params = {
    81                                 security: securityNonce,
    82                                 order_id: data.orderId,
    83                                 billing_request_id: billingRequest.id,
    84                                 save_customer_token: shouldSavePayment
    85                                     ? 'yes'
    86                                     : 'no',
    87                             };
    88 
    89                             completeBillingRequestFlow(params)
    90                                 .then((res) => {
    91                                     if (res && res.success) {
    92                                         resolve({
    93                                             type: 'success',
    94                                             redirectUrl: res.data.redirect_url,
    95                                         });
    96                                     } else {
    97                                         resolve({
    98                                             ...errorOptions,
    99                                             message: res.data?.message,
    100                                         });
    101                                     }
    102                                 })
    103                                 .catch((error) => {
    104                                     resolve({
    105                                         ...errorOptions,
    106                                         message: error.message,
    107                                     });
    108                                 });
    109                         } else {
    110                             resolve({
    111                                 ...errorOptions,
    112                                 message: __(
    113                                     'Billing request is not fulfulling or fulfilled yet, please try again later.',
    114                                     'woocommerce-gateway-gocardless'
    115                                 ),
    116                             });
    117                         }
    118                     },
    119                     // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    120                     onExit: (error, metadata) => {
    121                         if (error) {
    122                             console.error(error); // eslint-disable-line no-console
    123                         }
    124                         window.location.href = data.redirectUrl;
    125                     },
    126                 };
    127                 handler = GoCardlessDropin.create(options);
    128                 handler.open();
    129                 const closeDropIn = () => {
    130                     handler?.exit();
    131                 };
    132             });
    133         });
    134         return unsubscribe;
    135     }, [
    136         onCheckoutSuccess,
    137         shouldSavePayment,
    138         emitResponse.noticeContexts.PAYMENTS,
    139     ]);
    140 
    14121    return decodeEntities(description || '');
    14222};
  • woocommerce-gateway-gocardless/tags/2.9.6/includes/class-wc-gocardless-ajax.php

    r3239558 r3321344  
    3232     */
    3333    public function init() {
    34         // Ajax handler for billing request flow.
    35         add_action( 'wc_ajax_gocardless_create_billing_request_flow', array( $this, 'ajax_create_billing_request_flow' ) );
    36         add_action( 'wc_ajax_gocardless_complete_billing_request_flow', array( $this, 'ajax_complete_billing_request_flow' ) );
    3734        add_action( 'wc_ajax_gocardless_regenerate_webhook_secret', array( $this, 'ajax_regenerate_webhook_secret' ) );
    3835    }
     
    5148
    5249        return $this->gateway;
    53     }
    54 
    55 
    56     /**
    57      * Create a billing request and billing request flow to process the payment.
    58      *
    59      * This method creates a billing request and billing request flow to process the payment.
    60      *
    61      * @see https://developer.gocardless.com/api-reference/#billing-requests-billing-requests
    62      * @see https://developer.gocardless.com/api-reference/#billing-requests-billing-request-flows
    63      *
    64      * @since 2.7.0
    65      */
    66     public function ajax_create_billing_request_flow() {
    67         check_ajax_referer( 'wc_gocardless_create_billing_request_flow', 'security' );
    68 
    69         $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
    70 
    71         $order = wc_get_order( $order_id );
    72         if ( ! $order ) {
    73             wp_send_json_error( array( 'message' => esc_html__( 'Invalid order.', 'woocommerce-gateway-gocardless' ) ) );
    74         }
    75 
    76         $gateway              = $this->get_gateway();
    77         $billing_request_flow = $gateway->create_billing_request_flow( $order );
    78         if ( 'success' === $billing_request_flow['result'] ) {
    79             $billing_request_flow_id = $billing_request_flow['billing_request_flow_id'];
    80             wp_send_json_success( array( 'billing_request_flow_id' => $billing_request_flow_id ) );
    81         } else {
    82             $message = $billing_request_flow['message'] ?? esc_html__( 'Failed to create billing request flow.', 'woocommerce-gateway-gocardless' );
    83             wp_send_json_error( array( 'message' => $message ) );
    84         }
    85     }
    86 
    87     /**
    88      * Complete the billing request flow.
    89      *
    90      * @since 2.7.0
    91      */
    92     public function ajax_complete_billing_request_flow() {
    93         check_ajax_referer( 'wc_gocardless_complete_billing_request_flow', 'security' );
    94         $order_id           = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
    95         $billing_request_id = isset( $_POST['billing_request_id'] ) ? wc_clean( wp_unslash( $_POST['billing_request_id'] ) ) : '';
    96 
    97         // Maybe save customer token.
    98         $gateway             = $this->get_gateway();
    99         $save_bank_accounts  = 'yes' === $gateway->get_option( 'saved_bank_accounts', 'yes' );
    100         $save_customer_token = (
    101             ! empty( $_POST['save_customer_token'] ) &&
    102             'yes' === wc_clean( wp_unslash( $_POST['save_customer_token'] ) ) &&
    103             get_current_user_id() &&
    104             $save_bank_accounts
    105         );
    106 
    107         if ( ! $order_id || ! $billing_request_id ) {
    108             wp_send_json_error( array( 'message' => esc_html__( 'Invalid request.', 'woocommerce-gateway-gocardless' ) ) );
    109         }
    110 
    111         $order = wc_get_order( $order_id );
    112         if ( ! $order ) {
    113             wp_send_json_error( array( 'message' => esc_html__( 'Order not found.', 'woocommerce-gateway-gocardless' ) ) );
    114         }
    115 
    116         wc_gocardless()->log( sprintf( '%s - GoCardless billing request fulfilled ajax call: "%s" and order ID %s', __METHOD__, $billing_request_id, $order_id ) );
    117 
    118         $response = $gateway->handle_billing_request_complete( $order, $billing_request_id, $save_customer_token );
    119         if ( 'success' === $response['result'] ) {
    120             wp_send_json_success( array( 'redirect_url' => $response['redirect'] ) );
    121         } else {
    122             $message = ! empty( $response['message'] ) ? $response['message'] : esc_html__( 'Failed to process billing request.', 'woocommerce-gateway-gocardless' );
    123             wp_send_json_error( array( 'message' => $message ) );
    124         }
    12550    }
    12651
  • woocommerce-gateway-gocardless/tags/2.9.6/includes/class-wc-gocardless-gateway-blocks-support.php

    r3239558 r3321344  
    6161        }
    6262
    63         // Register GoCardless Drop-in script.
    64         wp_register_script(
    65             'gocardless-dropin',
    66             'https://pay.gocardless.com/billing/static/dropin/v2/initialise.js',
    67             array(),
    68             $version,
    69             true
    70         );
    71 
    7263        wp_register_script(
    7364            'wc-gocardless-blocks-integration',
     
    8273        );
    8374
    84         return array( 'gocardless-dropin', 'wc-gocardless-blocks-integration' );
     75        return array( 'wc-gocardless-blocks-integration' );
    8576    }
    8677
     
    10091            'supportedCountries'  => WC_GoCardless_API::get_supported_countries(),
    10192            'supportedCurrencies' => WC_GoCardless_API::get_supported_currencies(),
    102             'isTest'              => 'yes' === $this->settings['testmode'],
    103             'wcAjaxUrl'           => WC_AJAX::get_endpoint( '%%endpoint%%' ),
    104             'billingRequestNonce' => wp_create_nonce( 'wc_gocardless_complete_billing_request_flow' ),
    10593        );
    10694    }
  • woocommerce-gateway-gocardless/tags/2.9.6/includes/class-wc-gocardless-gateway.php

    r3283451 r3321344  
    116116        add_filter( 'woocommerce_payment_methods_list_item', array( $this, 'saved_payment_methods_list_item' ), 99, 2 );
    117117        add_action( 'woocommerce_account_payment_methods_column_method', array( $this, 'saved_payment_methods_column_method' ) );
    118 
    119         // Order Pay (Receipt) page handling for complete billing request flow.
    120         add_filter( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
    121 
    122         // Update the logged_in cookie in current request, after a guest user is created to avoid nonce inconsistencies.
    123         add_action( 'set_logged_in_cookie', array( $this, 'set_cookie_on_current_request' ) );
    124118    }
    125119
     
    231225                <?php if ( ! empty( $access_token ) ) : ?>
    232226                    <span class="gocardless-connected"><span style="color: #00a32a">&#9679;</span>&nbsp;<?php esc_html_e( 'Connected', 'woocommerce-gateway-gocardless' ); ?></span>
     227
     228                    <?php if ( $this->testmode ) : ?>
     229                        <div class="wcgc-sandbox-mode-notice">
     230                            <span>
     231                                <?php
     232                                printf(
     233                                    '<strong>%1$s</strong> %2$s',
     234                                    esc_html__( 'GoCardless is connected in sandbox mode.', 'woocommerce-gateway-gocardless' ),
     235                                    esc_html__( 'You need to connect a live GoCardless account before you can accept real bank payments.', 'woocommerce-gateway-gocardless' )
     236                                );
     237                                ?>
     238                            </span>
     239                        </div>
     240                    <?php endif; ?>
    233241                <?php endif; ?>
    234242
     
    702710            $this->save_payment_method_checkbox();
    703711        }
    704         if ( is_wc_endpoint_url( 'order-pay' ) ) {
    705             ?>
    706             <div id="wc-gocardless-hidden-fields">
    707                 <input name="wc-gocardless-billing-request-id" type="hidden" value="" />
    708             </div>
    709             <?php
    710         }
    711         ?>
    712         <noscript>
    713             <?php esc_html_e( 'Since your browser does not support or has disabled JavaScript, you will not be able to use the GoCardless payment method. To proceed with your payment, please enable JavaScript in your current browser or switch to a browser that supports JavaScript.', 'woocommerce-gateway-gocardless' ); ?>
    714         </noscript>
    715         <?php
    716712    }
    717713
     
    931927            ),
    932928            'links'              => array( 'billing_request' => $billing_request_id ),
     929            'redirect_uri'       => $this->get_success_redirect_url( $order ),
     930            'exit_uri'           => $order->get_checkout_payment_url(),
    933931        );
    934932
     
    951949            );
    952950        }
    953         if ( empty( $billing_request_flow['billing_request_flows']['id'] ) ) {
     951        if ( empty( $billing_request_flow['billing_request_flows']['id'] ) || empty( $billing_request_flow['billing_request_flows']['authorisation_url'] ) ) {
    954952            return array(
    955953                'result'  => 'failure',
     
    962960
    963961        $response = array(
    964             'result'                  => 'success',
    965             'redirect'                => $order->get_checkout_payment_url(),
    966             'billing_request_flow_id' => $billing_request_flow['billing_request_flows']['id'],
     962            'result'   => 'success',
     963            'redirect' => esc_url_raw( $billing_request_flow['billing_request_flows']['authorisation_url'] ),
    967964        );
    968965
    969         // Update nonce if the customer is created.
    970         if ( did_action( 'woocommerce_created_customer' ) > 0 ) {
    971             $response['billing_request_nonce'] = wp_create_nonce( 'wc_gocardless_complete_billing_request_flow' );
    972         }
    973 
    974         return $response;
    975     }
    976 
    977     /**
    978      * Process payment for pay page.
    979      *
    980      * @param WC_Order $order Order object.
    981      * @return array Returns array with redirect url succeed, otherwise array with error message is returned.
    982      */
    983     public function process_payment_for_pay_page( WC_Order $order ) {
    984         $billing_request_id = isset( $_POST['wc-gocardless-billing-request-id'] ) ? sanitize_text_field( wp_unslash( $_POST['wc-gocardless-billing-request-id'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is already handled on the WooCommerce side.
    985         if ( empty( $billing_request_id ) ) {
    986             wc_add_notice( esc_html__( 'Billing request ID is required.', 'woocommerce-gateway-gocardless' ), 'error' );
    987             return array(
    988                 'result'  => 'failure',
    989                 'message' => esc_html__( 'Billing request ID is required.', 'woocommerce-gateway-gocardless' ),
    990             );
    991         }
    992 
    993         $save_token = (
    994             ! empty( $_POST['wc-gocardless-new-payment-method'] ) //phpcs:ignore WordPress.Security.NonceVerification -- Nonce verification is already handled on the WooCommerce side.
    995             && $this->saved_bank_accounts
    996             && get_current_user_id()
    997         );
    998 
    999         $response = $this->handle_billing_request_complete( $order, $billing_request_id, $save_token );
    1000         if ( 'failure' === $response['result'] ) {
    1001             wc_add_notice( $response['message'], 'error' );
    1002         }
    1003966        return $response;
    1004967    }
     
    11301093
    11311094    /**
    1132      * Set logged_in cookie with current request using new login session (to ensure consistent nonce).
    1133      * Only apply during the checkout process with the account creation.
    1134      *
    1135      * @param string $cookie Cookie value.
    1136      */
    1137     public function set_cookie_on_current_request( $cookie ) {
    1138         if ( defined( 'WOOCOMMERCE_CHECKOUT' ) && WOOCOMMERCE_CHECKOUT && did_action( 'woocommerce_created_customer' ) > 0 ) {
    1139             if ( ! defined( 'LOGGED_IN_COOKIE' ) ) {
    1140                 return;
    1141             }
    1142 
    1143             $_COOKIE[ LOGGED_IN_COOKIE ] = $cookie;
    1144         }
    1145     }
    1146 
    1147     /**
    11481095     * Process the payment and return the result
    11491096     *
     
    11571104        if ( $this->_is_processing_payment_with_saved_token() ) {
    11581105            return $this->_process_payment_with_saved_token( $order );
    1159         }
    1160 
    1161         if ( isset( $_GET['pay_for_order'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is already handled on the WooCommerce side.
    1162             // Pay for order page.
    1163             return $this->process_payment_for_pay_page( $order );
    11641106        }
    11651107
     
    12501192    /**
    12511193     * Get success redirect URL.
    1252      *
    1253      * @since 2.4.0
    1254      * @deprecated 2.7.0
     1194     * URL to redirect after successfull GoCardless transcation.
     1195     *
     1196     * @since 2.4.0
    12551197     *
    12561198     * @param WC_Order|int $order Order object or ID.
     
    12591201     */
    12601202    public function get_success_redirect_url( $order ) {
    1261         wc_deprecated_function( __METHOD__, '2.7.0' );
    1262 
    1263         $order    = wc_get_order( $order );
    1264         $order_id = wc_gocardless_get_order_prop( $order, 'id' );
    1265         $params   = array(
    1266             'request'  => 'redirect_flow',
    1267             'order_id' => $order_id,
     1203        $order              = wc_get_order( $order );
     1204        $order_id           = wc_gocardless_get_order_prop( $order, 'id' );
     1205        $billing_request_id = $this->get_order_resource( $order_id, 'billing_request', 'id' );
     1206        $params             = array(
     1207            'request'            => 'billing_request_flow',
     1208            'order_id'           => $order_id,
     1209            'billing_request_id' => $billing_request_id,
    12681210        );
    12691211
     
    12751217
    12761218        if ( $save_token ) {
    1277             $params['save_customer_token'] = 'true';
    1278         }
    1279 
    1280         $url = add_query_arg( $params, WC()->api_request_url( __CLASS__, true ) );
     1219            $params['save_customer_token'] = 'yes';
     1220        }
     1221
     1222        $url = add_query_arg( $params, WC()->api_request_url( 'WC_Gateway_GoCardless', true ) );
    12811223
    12821224        return $url;
     
    13171259
    13181260            switch ( $_GET['request'] ) { //phpcs:ignore WordPress.Security.NonceVerification
     1261                case 'billing_request_flow':
     1262                    $this->handle_billing_request_flow();
     1263                    break;
    13191264                case 'webhook':
    13201265                    $this->_handle_webhook();
     
    13271272            header( 'HTTP/1.1 400 Bad request' );
    13281273            wp_send_json_error( array( 'message' => $e->getMessage() ) );
     1274        }
     1275    }
     1276
     1277    /**
     1278     * Handle redirect back from GoCardless for billing request flow.
     1279     *
     1280     * @since 2.9.6
     1281     *
     1282     * @return void
     1283     */
     1284    protected function handle_billing_request_flow() {
     1285        try {
     1286            if ( empty( $_GET['billing_request_id'] ) || empty( $_GET['order_id'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification
     1287                throw new Exception( esc_html__( 'Invalid billing request flow request.', 'woocommerce-gateway-gocardless' ) );
     1288            }
     1289            $order_id           = absint( $_GET['order_id'] ); //phpcs:ignore WordPress.Security.NonceVerification
     1290            $billing_request_id = sanitize_text_field( wp_unslash( $_GET['billing_request_id'] ) ); //phpcs:ignore WordPress.Security.NonceVerification
     1291            $order              = wc_get_order( $order_id );
     1292
     1293            if ( ! $order ) {
     1294                throw new Exception( esc_html__( 'Order not found.', 'woocommerce-gateway-gocardless' ) );
     1295            }
     1296
     1297            wc_gocardless()->log( sprintf( '%s - Maybe redirected from GoCardless with billing_request_id "%s" and order ID %s', __METHOD__, $billing_request_id, $order_id ) );
     1298
     1299            $save_bank_accounts  = 'yes' === $this->get_option( 'saved_bank_accounts', 'no' );
     1300            $save_customer_token = (
     1301                ! empty( $_GET['save_customer_token'] ) && //phpcs:ignore WordPress.Security.NonceVerification
     1302                'yes' === wc_clean( wp_unslash( $_GET['save_customer_token'] ) ) && //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     1303                get_current_user_id() &&
     1304                $save_bank_accounts
     1305            );
     1306
     1307            $response = $this->handle_billing_request_complete( $order, $billing_request_id, $save_customer_token );
     1308            if ( 'success' === $response['result'] ) {
     1309                wp_safe_redirect( $response['redirect'] );
     1310                exit;
     1311            } else {
     1312                wc_add_notice( $response['message'], 'error' );
     1313                wp_safe_redirect( wc_get_page_permalink( 'checkout' ) );
     1314                exit;
     1315            }
     1316        } catch ( Exception $e ) {
     1317            wc_gocardless()->log( sprintf( '%s - Error when handling billing request flow request: %s', __METHOD__, $e->getMessage() ) );
     1318
     1319            $order           = wc_get_order( $order_id );
     1320            $current_user_id = get_current_user_id();
     1321
     1322            $error_message = __( 'We were unable to process your order.', 'woocommerce-gateway-gocardless' );
     1323
     1324            // Only include the "Cancel order" URL for users that own the order.
     1325            if ( $current_user_id && $current_user_id === $order->get_customer_id() ) {
     1326                /* translators: Link to retry cancel order */
     1327                $error_message = sprintf( __( 'We were unable to process your order, <a href="%s">click here to try again</a>.', 'woocommerce-gateway-gocardless' ), $order->get_cancel_order_url() );
     1328            }
     1329
     1330            $error_message = sprintf(
     1331                '%1$s %2$s<br><br>%3$s',
     1332                $error_message,
     1333                __( 'If the problem still persists please contact us with the details below.', 'woocommerce-gateway-gocardless' ),
     1334                $e->getMessage()
     1335            );
     1336
     1337            wc_add_notice( $error_message, 'error' );
     1338
     1339            wp_safe_redirect( wc_get_page_permalink( 'checkout' ) );
    13291340        }
    13301341    }
     
    16201631            }
    16211632
     1633            wc_gocardless()->log( sprintf( '%s - Handling webhook. Payload: %s', __METHOD__, print_r( $payload, true ) ) );
     1634
    16221635            $args = array( $payload );
    16231636
    16241637            // Process the webhook payload asynchronously.
    1625             WC()->queue()->schedule_single(
     1638            $action_id = WC()->queue()->schedule_single(
    16261639                WC()->call_function( 'time' ) + 1,
    16271640                'woocommerce_gocardless_process_webhook_payload_async',
     
    16301643            );
    16311644
     1645            // If the action is not scheduled, return error to GoCardless, to get a retry.
     1646            if ( empty( $action_id ) ) {
     1647                wc_gocardless()->log( sprintf( '%s - Failed to schedule action to process webhook.', __METHOD__ ) );
     1648                header( 'HTTP/1.1 500 Internal Server Error' );
     1649                throw new Exception( esc_html__( 'Failed to schedule action to process webhook.', 'woocommerce-gateway-gocardless' ) );
     1650            }
     1651
     1652            wc_gocardless()->log( sprintf( '%s - Action scheduled with ID %d, to process webhook.', __METHOD__, $action_id ) );
    16321653        } catch ( Exception $e ) {
     1654            wc_gocardless()->log( sprintf( '%s - Error when handling webhook: %s', __METHOD__, $e->getMessage() ) );
    16331655            wp_send_json_error( array( 'message' => $e->getMessage() ) );
    16341656        }
     
    25632585     * @since 2.4.0
    25642586     *
    2565      * @param array            $item          Item of payment method.
    2566      * @param WC_Payment_Token $payment_token The payment token associated with
    2567      *                                        this method entry.
     2587     * @param array                                    $item          Item of payment method.
     2588     * @param WC_GoCardless_Payment_Token_Direct_Debit $payment_token The payment token associated with this method entry.
    25682589     *
    25692590     * @return array Filtered item for direct debit.
     
    26562677            );
    26572678        }
    2658     }
    2659 
    2660     /**
    2661      * Enqueue scripts on order page for payment dropin.
    2662      *
    2663      * @return void
    2664      */
    2665     public function enqueue_scripts() {
    2666         // Only load scripts on checkout page, if access token is available and gateway is enabled.
    2667         if ( ! is_checkout() || ! $this->access_token || 'yes' !== $this->enabled ) {
    2668             return;
    2669         }
    2670 
    2671         $asset_path   = wc_gocardless()->plugin_path . '/build/wc-gocardless-checkout.asset.php';
    2672         $version      = wc_gocardless()->version;
    2673         $dependencies = array();
    2674         if ( file_exists( $asset_path ) ) {
    2675             $asset        = require $asset_path;
    2676             $version      = is_array( $asset ) && isset( $asset['version'] )
    2677                 ? $asset['version']
    2678                 : $version;
    2679             $dependencies = is_array( $asset ) && isset( $asset['dependencies'] )
    2680                 ? $asset['dependencies']
    2681                 : $dependencies;
    2682         }
    2683 
    2684         wp_enqueue_script(
    2685             'gocardless-dropin',
    2686             'https://pay.gocardless.com/billing/static/dropin/v2/initialise.js',
    2687             array(),
    2688             $version,
    2689             true
    2690         );
    2691 
    2692         wp_enqueue_script(
    2693             'wc-gocardless-checkout-js',
    2694             wc_gocardless()->plugin_url . '/build/wc-gocardless-checkout.js',
    2695             $dependencies,
    2696             $version,
    2697             true
    2698         );
    2699 
    2700         wp_localize_script(
    2701             'wc-gocardless-checkout-js',
    2702             'wc_gocardless_checkout_params',
    2703             array(
    2704                 'is_test'                        => $this->testmode,
    2705                 'ajax_url'                       => WC_AJAX::get_endpoint( '%%endpoint%%' ),
    2706                 'create_billing_request_nonce'   => wp_create_nonce( 'wc_gocardless_create_billing_request_flow' ),
    2707                 'complete_billing_request_nonce' => wp_create_nonce( 'wc_gocardless_complete_billing_request_flow' ),
    2708                 'is_order_pay_page'              => is_checkout() && is_wc_endpoint_url( 'order-pay' ),
    2709                 'order_id'                       => absint( get_query_var( 'order-pay' ) ),
    2710                 'generic_error'                  => __( 'An error occurred while processing the payment.', 'woocommerce-gateway-gocardless' ),
    2711             )
    2712         );
    27132679    }
    27142680
  • woocommerce-gateway-gocardless/tags/2.9.6/readme.txt

    r3294262 r3321344  
    33Tags:         gocardless, woocommerce, direct debit, instant bank pay
    44Tested up to: 6.8
    5 Stable tag:   2.9.5
     5Stable tag:   2.9.6
    66License:      GPL-3.0-or-later
    77License URI:  https://spdx.org/licenses/GPL-3.0-or-later.html
     
    140140
    141141== Changelog ==
     142
     143= 2.9.6 - 2025-07-02 =
     144* Add - Respond with an error to the GoCardless webhook call if the scheduling action fails.
     145* Add - A notice indicating that GoCardless is connected in sandbox mode if the merchant is connected to a sandbox account.
     146* Update - Replaced JavaScript Drop-in with the redirect-to-GoCardless approach for the transaction/direct debit setup.
     147* Dev - Bump WooCommerce "tested up to" version 10.0.
     148* Dev - Bump WooCommerce minimum supported version to 9.8.
    142149
    143150= 2.9.5 - 2025-05-15 =
     
    236243* Tweak - Update the payment method title to "Pay by bank" and change the logo to the GoCardless logo.
    237244
    238 = 2.6.4 - 2024-04-01 =
    239 * Dev - Bump WooCommerce "tested up to" version 8.7.
    240 * Dev - Bump WooCommerce minimum supported version to 8.4.
    241 * Dev - Bump WordPress "tested up to" version 6.5.
    242 
    243 = 2.6.3 - 2024-02-05 =
    244 * Fix - Allow customers to update subscription payment methods via Woo Subscriptions.
    245 * Dev - Bump WooCommerce "tested up to" version 8.5.
    246 * Dev - Bump WooCommerce minimum supported version to 8.3.
    247 * Dev - Bump WordPress minimum supported version to 6.3.
    248 
    249 = 2.6.2 - 2024-01-08 =
    250 * Tweak - Bump PHP "tested up to" version 8.3.
    251 * Dev - Declare compatibility with Product Editor.
    252 * Dev - Bump WooCommerce "tested up to" version 8.4.
    253 * Dev - Bump WooCommerce minimum supported version to 8.2.
    254 * Dev - Bump PHP minimum supported version to 7.4.
    255 
    256245[See changelog details prior to 2024 here](https://github.com/gocardless/woocommerce-gateway-gocardless/blob/trunk/changelog.txt).
  • woocommerce-gateway-gocardless/tags/2.9.6/woocommerce-gateway-gocardless.php

    r3294262 r3321344  
    44 * Plugin URI:           https://www.woocommerce.com/products/gocardless/
    55 * Description:          Extends both WooCommerce and WooCommerce Subscriptions with the GoCardless Payment Gateway. A GoCardless merchant account is required.
    6  * Version:              2.9.5
     6 * Version:              2.9.6
    77 * Requires at least:    6.6
    88 * Requires PHP:         7.4
     
    1313 * License URI:          https://spdx.org/licenses/GPL-3.0-or-later.html
    1414 * Requires Plugins:     woocommerce
    15  * WC requires at least: 9.6
    16  * WC tested up to:      9.8
     15 * WC requires at least: 9.8
     16 * WC tested up to:      10.0
    1717 *
    1818 * Copyright: © 2023-2025 WooCommerce
     
    3939     * @var string
    4040     */
    41     public $version = '2.9.5'; // WRCS: DEFINED_VERSION.
     41    public $version = '2.9.6'; // WRCS: DEFINED_VERSION.
    4242
    4343    /**
  • woocommerce-gateway-gocardless/trunk/assets/css/admin.css

    r3239558 r3321344  
    4040    margin-top: 6px;
    4141}
     42
     43.wcgc-sandbox-mode-notice {
     44    margin-top: 12px;
     45    align-items: center;
     46    background-color: #fff2d7;
     47    color: #4d3716;
     48    display: flex;
     49    font-size: 13px;
     50    padding: 12px;
     51    width: max-content;
     52}
  • woocommerce-gateway-gocardless/trunk/build/index.asset.php

    r3242739 r3321344  
    1 <?php return array('dependencies' => array('react', 'wc-blocks-registry', 'wc-settings', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => '494e4afed799f2cde0fa');
     1<?php return array('dependencies' => array('react', 'wc-blocks-registry', 'wc-settings', 'wp-html-entities', 'wp-i18n'), 'version' => '70c5c2023330429d40bb');
  • woocommerce-gateway-gocardless/trunk/build/index.js

    r3242739 r3321344  
    1 (()=>{"use strict";var e={20:(e,t,o)=>{var s=o(609),r=Symbol.for("react.element"),n=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),i=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,a={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,o){var s,l={},c=null,d=null;for(s in void 0!==o&&(c=""+o),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)n.call(t,s)&&!a.hasOwnProperty(s)&&(l[s]=t[s]);if(e&&e.defaultProps)for(s in t=e.defaultProps)void 0===l[s]&&(l[s]=t[s]);return{$$typeof:r,type:e,key:c,ref:d,props:l,_owner:i.current}}},848:(e,t,o)=>{e.exports=o(20)},609:e=>{e.exports=window.React}},t={};const o=window.wp.htmlEntities,s=window.wp.i18n,r=window.wc.wcBlocksRegistry,n=window.wp.element,i=window.wc.wcSettings,a=()=>{const e=(0,i.getSetting)("gocardless_data",null);if(!e)throw new Error((0,s.__)("GoCardless initialization data is not available","woocommerce-gateway-gocardless"));return e};var l,c,d,u=function o(s){var r=t[s];if(void 0!==r)return r.exports;var n=t[s]={exports:{}};return e[s](n,n.exports,o),n.exports}(848);const{description:p,logo_url:w,title:g,isTest:m,billingRequestNonce:_}=a(),f=e=>{const{eventRegistration:t,emitResponse:r,shouldSavePayment:i}=e,{onCheckoutSuccess:l}=t;return(0,n.useEffect)((()=>l((e=>{let t;return new Promise(((o,n)=>{const l={type:"error",messageContext:r.noticeContexts.PAYMENTS},{GoCardlessDropin:c}=window;if(!c)return void o({...l,message:(0,s.__)("GoCardless Drop-in is not available","woocommerce-gateway-gocardless")});const d=e?.processingResponse?.paymentDetails?.billing_request_flow_id,u=e?.processingResponse?.paymentDetails?.billing_request_nonce||_;if(!d)return void o({...l,message:(0,s.__)("Invalid billing request flow ID","woocommerce-gateway-gocardless")});const p={billingRequestFlowID:d,environment:m?"sandbox":"live",onSuccess:(t,r)=>{w(),t&&["fulfilling","fulfilled"].includes(t.status)?(e=>{const{wcAjaxUrl:t}=a(),o=new FormData;for(const t in e)o.append(t,e[t]);const s=t.replace("%%endpoint%%","gocardless_complete_billing_request_flow");return fetch(s,{method:"POST",body:o}).then((e=>e.json()))})({security:u,order_id:e.orderId,billing_request_id:t.id,save_customer_token:i?"yes":"no"}).then((e=>{e&&e.success?o({type:"success",redirectUrl:e.data.redirect_url}):o({...l,message:e.data?.message})})).catch((e=>{o({...l,message:e.message})})):o({...l,message:(0,s.__)("Billing request is not fulfulling or fulfilled yet, please try again later.","woocommerce-gateway-gocardless")})},onExit:(t,o)=>{t&&console.error(t),window.location.href=e.redirectUrl}};t=c.create(p),t.open();const w=()=>{t?.exit()}}))}))),[l,i,r.noticeContexts.PAYMENTS]),(0,o.decodeEntities)(p||"")},y=()=>(0,u.jsx)("img",{src:w,alt:(0,o.decodeEntities)(g),style:{marginRight:"12px",marginBottom:"4px"}}),v=e=>{const{PaymentMethodLabel:t}=e.components;return(0,u.jsx)(t,{text:(0,o.decodeEntities)(g),icon:(0,u.jsx)(y,{})})};(0,r.registerPaymentMethod)({name:"gocardless",label:(0,u.jsx)(v,{}),ariaLabel:(0,s.__)("GoCardless payment method","woocommerce-gateway-gocardless"),canMakePayment:({billingData:e,cartTotals:t})=>{const o=t?.currency_code,s=a()?.supportedCountries||[],r=a()?.supportedCurrencies||[];return s.includes(e?.country)&&r.includes(o)},content:(0,u.jsx)(f,{}),edit:(0,u.jsx)(f,{}),supports:{showSavedCards:null!==(l=a().showSavedCards)&&void 0!==l&&l,showSaveOption:null!==(c=a().showSaveOption)&&void 0!==c&&c,features:null!==(d=a()?.supports)&&void 0!==d?d:[]}})})();
     1(()=>{"use strict";var e={20:(e,t,o)=>{var r=o(609),n=Symbol.for("react.element"),s=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};t.jsx=function(e,t,o){var r,c={},l=null,d=null;for(r in void 0!==o&&(l=""+o),void 0!==t.key&&(l=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,r)&&!i.hasOwnProperty(r)&&(c[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===c[r]&&(c[r]=t[r]);return{$$typeof:n,type:e,key:l,ref:d,props:c,_owner:a.current}}},848:(e,t,o)=>{e.exports=o(20)},609:e=>{e.exports=window.React}},t={};const o=window.wp.htmlEntities,r=window.wp.i18n,n=window.wc.wcBlocksRegistry,s=window.wc.wcSettings,a=()=>{const e=(0,s.getSetting)("gocardless_data",null);if(!e)throw new Error((0,r.__)("GoCardless initialization data is not available","woocommerce-gateway-gocardless"));return e};var i,c,l,d=function o(r){var n=t[r];if(void 0!==n)return n.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,o),s.exports}(848);const{description:p,logo_url:u,title:w}=a(),_=e=>(0,o.decodeEntities)(p||""),y=()=>(0,d.jsx)("img",{src:u,alt:(0,o.decodeEntities)(w),style:{marginRight:"12px",marginBottom:"4px"}}),m=e=>{const{PaymentMethodLabel:t}=e.components;return(0,d.jsx)(t,{text:(0,o.decodeEntities)(w),icon:(0,d.jsx)(y,{})})};(0,n.registerPaymentMethod)({name:"gocardless",label:(0,d.jsx)(m,{}),ariaLabel:(0,r.__)("GoCardless payment method","woocommerce-gateway-gocardless"),canMakePayment:({billingData:e,cartTotals:t})=>{const o=t?.currency_code,r=a()?.supportedCountries||[],n=a()?.supportedCurrencies||[];return r.includes(e?.country)&&n.includes(o)},content:(0,d.jsx)(_,{}),edit:(0,d.jsx)(_,{}),supports:{showSavedCards:null!==(i=a().showSavedCards)&&void 0!==i&&i,showSaveOption:null!==(c=a().showSaveOption)&&void 0!==c&&c,features:null!==(l=a()?.supports)&&void 0!==l?l:[]}})})();
  • woocommerce-gateway-gocardless/trunk/changelog.txt

    r3294262 r3321344  
    11*** GoCardless for WooCommerce Changelog ***
     2
     32025-07-02 - version 2.9.6
     4* Add - Respond with an error to the GoCardless webhook call if the scheduling action fails.
     5* Add - A notice indicating that GoCardless is connected in sandbox mode if the merchant is connected to a sandbox account.
     6* Update - Replaced JavaScript Drop-in with the redirect-to-GoCardless approach for the transaction/direct debit setup.
     7* Dev - Bump WooCommerce "tested up to" version 10.0.
     8* Dev - Bump WooCommerce minimum supported version to 9.8.
    29
    3102025-05-15 - version 2.9.5
  • woocommerce-gateway-gocardless/trunk/client/blocks/gocardless-utils.js

    r3239558 r3321344  
    2020    return goCardlessServerData;
    2121};
    22 
    23 /**
    24  * Call the server to complete a billing request flow.
    25  *
    26  * @param {Object} data Data to send to the server.
    27  * @return {Promise<Object>} Response from the server.
    28  */
    29 export const completeBillingRequestFlow = (data) => {
    30     const { wcAjaxUrl } = getGoCardlessServerData();
    31     const formData = new FormData();
    32     for (const key in data) {
    33         formData.append(key, data[key]);
    34     }
    35     const ajaxUrl = wcAjaxUrl.replace(
    36         '%%endpoint%%',
    37         'gocardless_complete_billing_request_flow'
    38     );
    39 
    40     return fetch(ajaxUrl, {
    41         method: 'POST',
    42         body: formData,
    43     }).then((response) => response.json());
    44 };
  • woocommerce-gateway-gocardless/trunk/client/blocks/index.js

    r3239558 r3321344  
    55import { __ } from '@wordpress/i18n';
    66import { registerPaymentMethod } from '@woocommerce/blocks-registry';
    7 import { useEffect } from '@wordpress/element';
    87
    98/**
     
    1110 */
    1211import { PAYMENT_METHOD_NAME } from './constants';
    13 import {
    14     completeBillingRequestFlow,
    15     getGoCardlessServerData,
    16 } from './gocardless-utils';
     12import { getGoCardlessServerData } from './gocardless-utils';
    1713
    1814const {
     
    2016    logo_url: logoUrl,
    2117    title,
    22     isTest,
    23     billingRequestNonce,
    2418} = getGoCardlessServerData();
    2519
    2620const Content = (props) => {
    27     const { eventRegistration, emitResponse, shouldSavePayment } = props;
    28     const { onCheckoutSuccess } = eventRegistration;
    29 
    30     // Handle the checkout success event.
    31     useEffect(() => {
    32         const unsubscribe = onCheckoutSuccess((data) => {
    33             let handler;
    34             // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    35             return new Promise((resolve, reject) => {
    36                 const errorOptions = {
    37                     type: 'error',
    38                     messageContext: emitResponse.noticeContexts.PAYMENTS,
    39                 };
    40 
    41                 const { GoCardlessDropin } = window;
    42                 if (!GoCardlessDropin) {
    43                     resolve({
    44                         ...errorOptions,
    45                         message: __(
    46                             'GoCardless Drop-in is not available',
    47                             'woocommerce-gateway-gocardless'
    48                         ),
    49                     });
    50                     return;
    51                 }
    52 
    53                 const billingRequestFlowId =
    54                     data?.processingResponse?.paymentDetails
    55                         ?.billing_request_flow_id;
    56                 const securityNonce = data?.processingResponse?.paymentDetails?.billing_request_nonce || billingRequestNonce;
    57                 if (!billingRequestFlowId) {
    58                     resolve({
    59                         ...errorOptions,
    60                         message: __(
    61                             'Invalid billing request flow ID',
    62                             'woocommerce-gateway-gocardless'
    63                         ),
    64                     });
    65                     return;
    66                 }
    67 
    68                 const options = {
    69                     billingRequestFlowID: billingRequestFlowId,
    70                     environment: isTest ? 'sandbox' : 'live',
    71                     // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    72                     onSuccess: (billingRequest, billingRequestFlow) => {
    73                         closeDropIn();
    74                         if (
    75                             billingRequest &&
    76                             ['fulfilling', 'fulfilled'].includes(
    77                                 billingRequest.status
    78                             )
    79                         ) {
    80                             const params = {
    81                                 security: securityNonce,
    82                                 order_id: data.orderId,
    83                                 billing_request_id: billingRequest.id,
    84                                 save_customer_token: shouldSavePayment
    85                                     ? 'yes'
    86                                     : 'no',
    87                             };
    88 
    89                             completeBillingRequestFlow(params)
    90                                 .then((res) => {
    91                                     if (res && res.success) {
    92                                         resolve({
    93                                             type: 'success',
    94                                             redirectUrl: res.data.redirect_url,
    95                                         });
    96                                     } else {
    97                                         resolve({
    98                                             ...errorOptions,
    99                                             message: res.data?.message,
    100                                         });
    101                                     }
    102                                 })
    103                                 .catch((error) => {
    104                                     resolve({
    105                                         ...errorOptions,
    106                                         message: error.message,
    107                                     });
    108                                 });
    109                         } else {
    110                             resolve({
    111                                 ...errorOptions,
    112                                 message: __(
    113                                     'Billing request is not fulfulling or fulfilled yet, please try again later.',
    114                                     'woocommerce-gateway-gocardless'
    115                                 ),
    116                             });
    117                         }
    118                     },
    119                     // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
    120                     onExit: (error, metadata) => {
    121                         if (error) {
    122                             console.error(error); // eslint-disable-line no-console
    123                         }
    124                         window.location.href = data.redirectUrl;
    125                     },
    126                 };
    127                 handler = GoCardlessDropin.create(options);
    128                 handler.open();
    129                 const closeDropIn = () => {
    130                     handler?.exit();
    131                 };
    132             });
    133         });
    134         return unsubscribe;
    135     }, [
    136         onCheckoutSuccess,
    137         shouldSavePayment,
    138         emitResponse.noticeContexts.PAYMENTS,
    139     ]);
    140 
    14121    return decodeEntities(description || '');
    14222};
  • woocommerce-gateway-gocardless/trunk/includes/class-wc-gocardless-ajax.php

    r3239558 r3321344  
    3232     */
    3333    public function init() {
    34         // Ajax handler for billing request flow.
    35         add_action( 'wc_ajax_gocardless_create_billing_request_flow', array( $this, 'ajax_create_billing_request_flow' ) );
    36         add_action( 'wc_ajax_gocardless_complete_billing_request_flow', array( $this, 'ajax_complete_billing_request_flow' ) );
    3734        add_action( 'wc_ajax_gocardless_regenerate_webhook_secret', array( $this, 'ajax_regenerate_webhook_secret' ) );
    3835    }
     
    5148
    5249        return $this->gateway;
    53     }
    54 
    55 
    56     /**
    57      * Create a billing request and billing request flow to process the payment.
    58      *
    59      * This method creates a billing request and billing request flow to process the payment.
    60      *
    61      * @see https://developer.gocardless.com/api-reference/#billing-requests-billing-requests
    62      * @see https://developer.gocardless.com/api-reference/#billing-requests-billing-request-flows
    63      *
    64      * @since 2.7.0
    65      */
    66     public function ajax_create_billing_request_flow() {
    67         check_ajax_referer( 'wc_gocardless_create_billing_request_flow', 'security' );
    68 
    69         $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
    70 
    71         $order = wc_get_order( $order_id );
    72         if ( ! $order ) {
    73             wp_send_json_error( array( 'message' => esc_html__( 'Invalid order.', 'woocommerce-gateway-gocardless' ) ) );
    74         }
    75 
    76         $gateway              = $this->get_gateway();
    77         $billing_request_flow = $gateway->create_billing_request_flow( $order );
    78         if ( 'success' === $billing_request_flow['result'] ) {
    79             $billing_request_flow_id = $billing_request_flow['billing_request_flow_id'];
    80             wp_send_json_success( array( 'billing_request_flow_id' => $billing_request_flow_id ) );
    81         } else {
    82             $message = $billing_request_flow['message'] ?? esc_html__( 'Failed to create billing request flow.', 'woocommerce-gateway-gocardless' );
    83             wp_send_json_error( array( 'message' => $message ) );
    84         }
    85     }
    86 
    87     /**
    88      * Complete the billing request flow.
    89      *
    90      * @since 2.7.0
    91      */
    92     public function ajax_complete_billing_request_flow() {
    93         check_ajax_referer( 'wc_gocardless_complete_billing_request_flow', 'security' );
    94         $order_id           = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
    95         $billing_request_id = isset( $_POST['billing_request_id'] ) ? wc_clean( wp_unslash( $_POST['billing_request_id'] ) ) : '';
    96 
    97         // Maybe save customer token.
    98         $gateway             = $this->get_gateway();
    99         $save_bank_accounts  = 'yes' === $gateway->get_option( 'saved_bank_accounts', 'yes' );
    100         $save_customer_token = (
    101             ! empty( $_POST['save_customer_token'] ) &&
    102             'yes' === wc_clean( wp_unslash( $_POST['save_customer_token'] ) ) &&
    103             get_current_user_id() &&
    104             $save_bank_accounts
    105         );
    106 
    107         if ( ! $order_id || ! $billing_request_id ) {
    108             wp_send_json_error( array( 'message' => esc_html__( 'Invalid request.', 'woocommerce-gateway-gocardless' ) ) );
    109         }
    110 
    111         $order = wc_get_order( $order_id );
    112         if ( ! $order ) {
    113             wp_send_json_error( array( 'message' => esc_html__( 'Order not found.', 'woocommerce-gateway-gocardless' ) ) );
    114         }
    115 
    116         wc_gocardless()->log( sprintf( '%s - GoCardless billing request fulfilled ajax call: "%s" and order ID %s', __METHOD__, $billing_request_id, $order_id ) );
    117 
    118         $response = $gateway->handle_billing_request_complete( $order, $billing_request_id, $save_customer_token );
    119         if ( 'success' === $response['result'] ) {
    120             wp_send_json_success( array( 'redirect_url' => $response['redirect'] ) );
    121         } else {
    122             $message = ! empty( $response['message'] ) ? $response['message'] : esc_html__( 'Failed to process billing request.', 'woocommerce-gateway-gocardless' );
    123             wp_send_json_error( array( 'message' => $message ) );
    124         }
    12550    }
    12651
  • woocommerce-gateway-gocardless/trunk/includes/class-wc-gocardless-gateway-blocks-support.php

    r3239558 r3321344  
    6161        }
    6262
    63         // Register GoCardless Drop-in script.
    64         wp_register_script(
    65             'gocardless-dropin',
    66             'https://pay.gocardless.com/billing/static/dropin/v2/initialise.js',
    67             array(),
    68             $version,
    69             true
    70         );
    71 
    7263        wp_register_script(
    7364            'wc-gocardless-blocks-integration',
     
    8273        );
    8374
    84         return array( 'gocardless-dropin', 'wc-gocardless-blocks-integration' );
     75        return array( 'wc-gocardless-blocks-integration' );
    8576    }
    8677
     
    10091            'supportedCountries'  => WC_GoCardless_API::get_supported_countries(),
    10192            'supportedCurrencies' => WC_GoCardless_API::get_supported_currencies(),
    102             'isTest'              => 'yes' === $this->settings['testmode'],
    103             'wcAjaxUrl'           => WC_AJAX::get_endpoint( '%%endpoint%%' ),
    104             'billingRequestNonce' => wp_create_nonce( 'wc_gocardless_complete_billing_request_flow' ),
    10593        );
    10694    }
  • woocommerce-gateway-gocardless/trunk/includes/class-wc-gocardless-gateway.php

    r3283451 r3321344  
    116116        add_filter( 'woocommerce_payment_methods_list_item', array( $this, 'saved_payment_methods_list_item' ), 99, 2 );
    117117        add_action( 'woocommerce_account_payment_methods_column_method', array( $this, 'saved_payment_methods_column_method' ) );
    118 
    119         // Order Pay (Receipt) page handling for complete billing request flow.
    120         add_filter( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
    121 
    122         // Update the logged_in cookie in current request, after a guest user is created to avoid nonce inconsistencies.
    123         add_action( 'set_logged_in_cookie', array( $this, 'set_cookie_on_current_request' ) );
    124118    }
    125119
     
    231225                <?php if ( ! empty( $access_token ) ) : ?>
    232226                    <span class="gocardless-connected"><span style="color: #00a32a">&#9679;</span>&nbsp;<?php esc_html_e( 'Connected', 'woocommerce-gateway-gocardless' ); ?></span>
     227
     228                    <?php if ( $this->testmode ) : ?>
     229                        <div class="wcgc-sandbox-mode-notice">
     230                            <span>
     231                                <?php
     232                                printf(
     233                                    '<strong>%1$s</strong> %2$s',
     234                                    esc_html__( 'GoCardless is connected in sandbox mode.', 'woocommerce-gateway-gocardless' ),
     235                                    esc_html__( 'You need to connect a live GoCardless account before you can accept real bank payments.', 'woocommerce-gateway-gocardless' )
     236                                );
     237                                ?>
     238                            </span>
     239                        </div>
     240                    <?php endif; ?>
    233241                <?php endif; ?>
    234242
     
    702710            $this->save_payment_method_checkbox();
    703711        }
    704         if ( is_wc_endpoint_url( 'order-pay' ) ) {
    705             ?>
    706             <div id="wc-gocardless-hidden-fields">
    707                 <input name="wc-gocardless-billing-request-id" type="hidden" value="" />
    708             </div>
    709             <?php
    710         }
    711         ?>
    712         <noscript>
    713             <?php esc_html_e( 'Since your browser does not support or has disabled JavaScript, you will not be able to use the GoCardless payment method. To proceed with your payment, please enable JavaScript in your current browser or switch to a browser that supports JavaScript.', 'woocommerce-gateway-gocardless' ); ?>
    714         </noscript>
    715         <?php
    716712    }
    717713
     
    931927            ),
    932928            'links'              => array( 'billing_request' => $billing_request_id ),
     929            'redirect_uri'       => $this->get_success_redirect_url( $order ),
     930            'exit_uri'           => $order->get_checkout_payment_url(),
    933931        );
    934932
     
    951949            );
    952950        }
    953         if ( empty( $billing_request_flow['billing_request_flows']['id'] ) ) {
     951        if ( empty( $billing_request_flow['billing_request_flows']['id'] ) || empty( $billing_request_flow['billing_request_flows']['authorisation_url'] ) ) {
    954952            return array(
    955953                'result'  => 'failure',
     
    962960
    963961        $response = array(
    964             'result'                  => 'success',
    965             'redirect'                => $order->get_checkout_payment_url(),
    966             'billing_request_flow_id' => $billing_request_flow['billing_request_flows']['id'],
     962            'result'   => 'success',
     963            'redirect' => esc_url_raw( $billing_request_flow['billing_request_flows']['authorisation_url'] ),
    967964        );
    968965
    969         // Update nonce if the customer is created.
    970         if ( did_action( 'woocommerce_created_customer' ) > 0 ) {
    971             $response['billing_request_nonce'] = wp_create_nonce( 'wc_gocardless_complete_billing_request_flow' );
    972         }
    973 
    974         return $response;
    975     }
    976 
    977     /**
    978      * Process payment for pay page.
    979      *
    980      * @param WC_Order $order Order object.
    981      * @return array Returns array with redirect url succeed, otherwise array with error message is returned.
    982      */
    983     public function process_payment_for_pay_page( WC_Order $order ) {
    984         $billing_request_id = isset( $_POST['wc-gocardless-billing-request-id'] ) ? sanitize_text_field( wp_unslash( $_POST['wc-gocardless-billing-request-id'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is already handled on the WooCommerce side.
    985         if ( empty( $billing_request_id ) ) {
    986             wc_add_notice( esc_html__( 'Billing request ID is required.', 'woocommerce-gateway-gocardless' ), 'error' );
    987             return array(
    988                 'result'  => 'failure',
    989                 'message' => esc_html__( 'Billing request ID is required.', 'woocommerce-gateway-gocardless' ),
    990             );
    991         }
    992 
    993         $save_token = (
    994             ! empty( $_POST['wc-gocardless-new-payment-method'] ) //phpcs:ignore WordPress.Security.NonceVerification -- Nonce verification is already handled on the WooCommerce side.
    995             && $this->saved_bank_accounts
    996             && get_current_user_id()
    997         );
    998 
    999         $response = $this->handle_billing_request_complete( $order, $billing_request_id, $save_token );
    1000         if ( 'failure' === $response['result'] ) {
    1001             wc_add_notice( $response['message'], 'error' );
    1002         }
    1003966        return $response;
    1004967    }
     
    11301093
    11311094    /**
    1132      * Set logged_in cookie with current request using new login session (to ensure consistent nonce).
    1133      * Only apply during the checkout process with the account creation.
    1134      *
    1135      * @param string $cookie Cookie value.
    1136      */
    1137     public function set_cookie_on_current_request( $cookie ) {
    1138         if ( defined( 'WOOCOMMERCE_CHECKOUT' ) && WOOCOMMERCE_CHECKOUT && did_action( 'woocommerce_created_customer' ) > 0 ) {
    1139             if ( ! defined( 'LOGGED_IN_COOKIE' ) ) {
    1140                 return;
    1141             }
    1142 
    1143             $_COOKIE[ LOGGED_IN_COOKIE ] = $cookie;
    1144         }
    1145     }
    1146 
    1147     /**
    11481095     * Process the payment and return the result
    11491096     *
     
    11571104        if ( $this->_is_processing_payment_with_saved_token() ) {
    11581105            return $this->_process_payment_with_saved_token( $order );
    1159         }
    1160 
    1161         if ( isset( $_GET['pay_for_order'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is already handled on the WooCommerce side.
    1162             // Pay for order page.
    1163             return $this->process_payment_for_pay_page( $order );
    11641106        }
    11651107
     
    12501192    /**
    12511193     * Get success redirect URL.
    1252      *
    1253      * @since 2.4.0
    1254      * @deprecated 2.7.0
     1194     * URL to redirect after successfull GoCardless transcation.
     1195     *
     1196     * @since 2.4.0
    12551197     *
    12561198     * @param WC_Order|int $order Order object or ID.
     
    12591201     */
    12601202    public function get_success_redirect_url( $order ) {
    1261         wc_deprecated_function( __METHOD__, '2.7.0' );
    1262 
    1263         $order    = wc_get_order( $order );
    1264         $order_id = wc_gocardless_get_order_prop( $order, 'id' );
    1265         $params   = array(
    1266             'request'  => 'redirect_flow',
    1267             'order_id' => $order_id,
     1203        $order              = wc_get_order( $order );
     1204        $order_id           = wc_gocardless_get_order_prop( $order, 'id' );
     1205        $billing_request_id = $this->get_order_resource( $order_id, 'billing_request', 'id' );
     1206        $params             = array(
     1207            'request'            => 'billing_request_flow',
     1208            'order_id'           => $order_id,
     1209            'billing_request_id' => $billing_request_id,
    12681210        );
    12691211
     
    12751217
    12761218        if ( $save_token ) {
    1277             $params['save_customer_token'] = 'true';
    1278         }
    1279 
    1280         $url = add_query_arg( $params, WC()->api_request_url( __CLASS__, true ) );
     1219            $params['save_customer_token'] = 'yes';
     1220        }
     1221
     1222        $url = add_query_arg( $params, WC()->api_request_url( 'WC_Gateway_GoCardless', true ) );
    12811223
    12821224        return $url;
     
    13171259
    13181260            switch ( $_GET['request'] ) { //phpcs:ignore WordPress.Security.NonceVerification
     1261                case 'billing_request_flow':
     1262                    $this->handle_billing_request_flow();
     1263                    break;
    13191264                case 'webhook':
    13201265                    $this->_handle_webhook();
     
    13271272            header( 'HTTP/1.1 400 Bad request' );
    13281273            wp_send_json_error( array( 'message' => $e->getMessage() ) );
     1274        }
     1275    }
     1276
     1277    /**
     1278     * Handle redirect back from GoCardless for billing request flow.
     1279     *
     1280     * @since 2.9.6
     1281     *
     1282     * @return void
     1283     */
     1284    protected function handle_billing_request_flow() {
     1285        try {
     1286            if ( empty( $_GET['billing_request_id'] ) || empty( $_GET['order_id'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification
     1287                throw new Exception( esc_html__( 'Invalid billing request flow request.', 'woocommerce-gateway-gocardless' ) );
     1288            }
     1289            $order_id           = absint( $_GET['order_id'] ); //phpcs:ignore WordPress.Security.NonceVerification
     1290            $billing_request_id = sanitize_text_field( wp_unslash( $_GET['billing_request_id'] ) ); //phpcs:ignore WordPress.Security.NonceVerification
     1291            $order              = wc_get_order( $order_id );
     1292
     1293            if ( ! $order ) {
     1294                throw new Exception( esc_html__( 'Order not found.', 'woocommerce-gateway-gocardless' ) );
     1295            }
     1296
     1297            wc_gocardless()->log( sprintf( '%s - Maybe redirected from GoCardless with billing_request_id "%s" and order ID %s', __METHOD__, $billing_request_id, $order_id ) );
     1298
     1299            $save_bank_accounts  = 'yes' === $this->get_option( 'saved_bank_accounts', 'no' );
     1300            $save_customer_token = (
     1301                ! empty( $_GET['save_customer_token'] ) && //phpcs:ignore WordPress.Security.NonceVerification
     1302                'yes' === wc_clean( wp_unslash( $_GET['save_customer_token'] ) ) && //phpcs:ignore WordPress.Security.NonceVerification.Recommended
     1303                get_current_user_id() &&
     1304                $save_bank_accounts
     1305            );
     1306
     1307            $response = $this->handle_billing_request_complete( $order, $billing_request_id, $save_customer_token );
     1308            if ( 'success' === $response['result'] ) {
     1309                wp_safe_redirect( $response['redirect'] );
     1310                exit;
     1311            } else {
     1312                wc_add_notice( $response['message'], 'error' );
     1313                wp_safe_redirect( wc_get_page_permalink( 'checkout' ) );
     1314                exit;
     1315            }
     1316        } catch ( Exception $e ) {
     1317            wc_gocardless()->log( sprintf( '%s - Error when handling billing request flow request: %s', __METHOD__, $e->getMessage() ) );
     1318
     1319            $order           = wc_get_order( $order_id );
     1320            $current_user_id = get_current_user_id();
     1321
     1322            $error_message = __( 'We were unable to process your order.', 'woocommerce-gateway-gocardless' );
     1323
     1324            // Only include the "Cancel order" URL for users that own the order.
     1325            if ( $current_user_id && $current_user_id === $order->get_customer_id() ) {
     1326                /* translators: Link to retry cancel order */
     1327                $error_message = sprintf( __( 'We were unable to process your order, <a href="%s">click here to try again</a>.', 'woocommerce-gateway-gocardless' ), $order->get_cancel_order_url() );
     1328            }
     1329
     1330            $error_message = sprintf(
     1331                '%1$s %2$s<br><br>%3$s',
     1332                $error_message,
     1333                __( 'If the problem still persists please contact us with the details below.', 'woocommerce-gateway-gocardless' ),
     1334                $e->getMessage()
     1335            );
     1336
     1337            wc_add_notice( $error_message, 'error' );
     1338
     1339            wp_safe_redirect( wc_get_page_permalink( 'checkout' ) );
    13291340        }
    13301341    }
     
    16201631            }
    16211632
     1633            wc_gocardless()->log( sprintf( '%s - Handling webhook. Payload: %s', __METHOD__, print_r( $payload, true ) ) );
     1634
    16221635            $args = array( $payload );
    16231636
    16241637            // Process the webhook payload asynchronously.
    1625             WC()->queue()->schedule_single(
     1638            $action_id = WC()->queue()->schedule_single(
    16261639                WC()->call_function( 'time' ) + 1,
    16271640                'woocommerce_gocardless_process_webhook_payload_async',
     
    16301643            );
    16311644
     1645            // If the action is not scheduled, return error to GoCardless, to get a retry.
     1646            if ( empty( $action_id ) ) {
     1647                wc_gocardless()->log( sprintf( '%s - Failed to schedule action to process webhook.', __METHOD__ ) );
     1648                header( 'HTTP/1.1 500 Internal Server Error' );
     1649                throw new Exception( esc_html__( 'Failed to schedule action to process webhook.', 'woocommerce-gateway-gocardless' ) );
     1650            }
     1651
     1652            wc_gocardless()->log( sprintf( '%s - Action scheduled with ID %d, to process webhook.', __METHOD__, $action_id ) );
    16321653        } catch ( Exception $e ) {
     1654            wc_gocardless()->log( sprintf( '%s - Error when handling webhook: %s', __METHOD__, $e->getMessage() ) );
    16331655            wp_send_json_error( array( 'message' => $e->getMessage() ) );
    16341656        }
     
    25632585     * @since 2.4.0
    25642586     *
    2565      * @param array            $item          Item of payment method.
    2566      * @param WC_Payment_Token $payment_token The payment token associated with
    2567      *                                        this method entry.
     2587     * @param array                                    $item          Item of payment method.
     2588     * @param WC_GoCardless_Payment_Token_Direct_Debit $payment_token The payment token associated with this method entry.
    25682589     *
    25692590     * @return array Filtered item for direct debit.
     
    26562677            );
    26572678        }
    2658     }
    2659 
    2660     /**
    2661      * Enqueue scripts on order page for payment dropin.
    2662      *
    2663      * @return void
    2664      */
    2665     public function enqueue_scripts() {
    2666         // Only load scripts on checkout page, if access token is available and gateway is enabled.
    2667         if ( ! is_checkout() || ! $this->access_token || 'yes' !== $this->enabled ) {
    2668             return;
    2669         }
    2670 
    2671         $asset_path   = wc_gocardless()->plugin_path . '/build/wc-gocardless-checkout.asset.php';
    2672         $version      = wc_gocardless()->version;
    2673         $dependencies = array();
    2674         if ( file_exists( $asset_path ) ) {
    2675             $asset        = require $asset_path;
    2676             $version      = is_array( $asset ) && isset( $asset['version'] )
    2677                 ? $asset['version']
    2678                 : $version;
    2679             $dependencies = is_array( $asset ) && isset( $asset['dependencies'] )
    2680                 ? $asset['dependencies']
    2681                 : $dependencies;
    2682         }
    2683 
    2684         wp_enqueue_script(
    2685             'gocardless-dropin',
    2686             'https://pay.gocardless.com/billing/static/dropin/v2/initialise.js',
    2687             array(),
    2688             $version,
    2689             true
    2690         );
    2691 
    2692         wp_enqueue_script(
    2693             'wc-gocardless-checkout-js',
    2694             wc_gocardless()->plugin_url . '/build/wc-gocardless-checkout.js',
    2695             $dependencies,
    2696             $version,
    2697             true
    2698         );
    2699 
    2700         wp_localize_script(
    2701             'wc-gocardless-checkout-js',
    2702             'wc_gocardless_checkout_params',
    2703             array(
    2704                 'is_test'                        => $this->testmode,
    2705                 'ajax_url'                       => WC_AJAX::get_endpoint( '%%endpoint%%' ),
    2706                 'create_billing_request_nonce'   => wp_create_nonce( 'wc_gocardless_create_billing_request_flow' ),
    2707                 'complete_billing_request_nonce' => wp_create_nonce( 'wc_gocardless_complete_billing_request_flow' ),
    2708                 'is_order_pay_page'              => is_checkout() && is_wc_endpoint_url( 'order-pay' ),
    2709                 'order_id'                       => absint( get_query_var( 'order-pay' ) ),
    2710                 'generic_error'                  => __( 'An error occurred while processing the payment.', 'woocommerce-gateway-gocardless' ),
    2711             )
    2712         );
    27132679    }
    27142680
  • woocommerce-gateway-gocardless/trunk/readme.txt

    r3294262 r3321344  
    33Tags:         gocardless, woocommerce, direct debit, instant bank pay
    44Tested up to: 6.8
    5 Stable tag:   2.9.5
     5Stable tag:   2.9.6
    66License:      GPL-3.0-or-later
    77License URI:  https://spdx.org/licenses/GPL-3.0-or-later.html
     
    140140
    141141== Changelog ==
     142
     143= 2.9.6 - 2025-07-02 =
     144* Add - Respond with an error to the GoCardless webhook call if the scheduling action fails.
     145* Add - A notice indicating that GoCardless is connected in sandbox mode if the merchant is connected to a sandbox account.
     146* Update - Replaced JavaScript Drop-in with the redirect-to-GoCardless approach for the transaction/direct debit setup.
     147* Dev - Bump WooCommerce "tested up to" version 10.0.
     148* Dev - Bump WooCommerce minimum supported version to 9.8.
    142149
    143150= 2.9.5 - 2025-05-15 =
     
    236243* Tweak - Update the payment method title to "Pay by bank" and change the logo to the GoCardless logo.
    237244
    238 = 2.6.4 - 2024-04-01 =
    239 * Dev - Bump WooCommerce "tested up to" version 8.7.
    240 * Dev - Bump WooCommerce minimum supported version to 8.4.
    241 * Dev - Bump WordPress "tested up to" version 6.5.
    242 
    243 = 2.6.3 - 2024-02-05 =
    244 * Fix - Allow customers to update subscription payment methods via Woo Subscriptions.
    245 * Dev - Bump WooCommerce "tested up to" version 8.5.
    246 * Dev - Bump WooCommerce minimum supported version to 8.3.
    247 * Dev - Bump WordPress minimum supported version to 6.3.
    248 
    249 = 2.6.2 - 2024-01-08 =
    250 * Tweak - Bump PHP "tested up to" version 8.3.
    251 * Dev - Declare compatibility with Product Editor.
    252 * Dev - Bump WooCommerce "tested up to" version 8.4.
    253 * Dev - Bump WooCommerce minimum supported version to 8.2.
    254 * Dev - Bump PHP minimum supported version to 7.4.
    255 
    256245[See changelog details prior to 2024 here](https://github.com/gocardless/woocommerce-gateway-gocardless/blob/trunk/changelog.txt).
  • woocommerce-gateway-gocardless/trunk/woocommerce-gateway-gocardless.php

    r3294262 r3321344  
    44 * Plugin URI:           https://www.woocommerce.com/products/gocardless/
    55 * Description:          Extends both WooCommerce and WooCommerce Subscriptions with the GoCardless Payment Gateway. A GoCardless merchant account is required.
    6  * Version:              2.9.5
     6 * Version:              2.9.6
    77 * Requires at least:    6.6
    88 * Requires PHP:         7.4
     
    1313 * License URI:          https://spdx.org/licenses/GPL-3.0-or-later.html
    1414 * Requires Plugins:     woocommerce
    15  * WC requires at least: 9.6
    16  * WC tested up to:      9.8
     15 * WC requires at least: 9.8
     16 * WC tested up to:      10.0
    1717 *
    1818 * Copyright: © 2023-2025 WooCommerce
     
    3939     * @var string
    4040     */
    41     public $version = '2.9.5'; // WRCS: DEFINED_VERSION.
     41    public $version = '2.9.6'; // WRCS: DEFINED_VERSION.
    4242
    4343    /**
Note: See TracChangeset for help on using the changeset viewer.