From a41f97ca9d13ab835e52f443e8b5f1872cc24438 Mon Sep 17 00:00:00 2001 From: SenthilKumar Date: Wed, 12 May 2021 16:30:56 +0530 Subject: [PATCH] Changes from PR https://github.com/slogsdon/globalpayments-gateway-provider-for-woocommerce/pull/9 (AVS CVV decline conditions added) --- README.md | 2 +- .../globalpayments-secure-payment-fields.css | 18 - .../globalpayments-secure-payment-fields.js | 311 ++++-------------- composer.json | 38 +++ ...ments-gateway-provider-for-woocommerce.php | 9 +- phpcs.xml | 34 ++ phpunit.xml.dist | 22 ++ readme.txt | 45 +-- src/Gateways/AbstractGateway.php | 117 +++---- src/Gateways/Clients/SdkClient.php | 61 ++-- src/Gateways/GeniusGateway.php | 6 + src/Gateways/GpApiGateway.php | 147 +-------- src/Gateways/HeartlandGateway.php | 78 ++++- .../HeartlandGiftGateway.php | 6 +- src/Gateways/Requests/AbstractRequest.php | 8 +- .../Requests/AuthorizationRequest.php | 8 +- .../Requests/GetAccessTokenRequest.php | 6 +- src/Gateways/Requests/RefundRequest.php | 2 +- src/Gateways/Requests/RequestArg.php | 3 - src/Gateways/Requests/VerifyRequest.php | 10 - src/Gateways/TransitGateway.php | 6 + tests/Bootstrap.php | 34 ++ tests/Unit/SampleTest.php | 13 + tests/bin/install-wp-tests.sh | 118 +++++++ 24 files changed, 502 insertions(+), 600 deletions(-) create mode 100644 composer.json create mode 100644 phpcs.xml create mode 100644 phpunit.xml.dist create mode 100644 tests/Bootstrap.php create mode 100644 tests/Unit/SampleTest.php create mode 100644 tests/bin/install-wp-tests.sh diff --git a/README.md b/README.md index 3d25dcf..64c6917 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# GlobalPayments WooCommerce +# Global Payments Gateway Provider for WooCommerce This extension allows WooCommerce to use the available Global Payments payment gateways. All card data is tokenized using the respective gateway's tokenization service. diff --git a/assets/frontend/css/globalpayments-secure-payment-fields.css b/assets/frontend/css/globalpayments-secure-payment-fields.css index c7d7b20..0a4ce6a 100644 --- a/assets/frontend/css/globalpayments-secure-payment-fields.css +++ b/assets/frontend/css/globalpayments-secure-payment-fields.css @@ -1,21 +1,3 @@ .globalpayments iframe { min-height: 3.6rem; - width: 100%; } - -div[id^="GlobalPayments-overlay-"] { - z-index: 1001 !important; -} - -.woocommerce-globalpayments-validation-error { - margin-bottom:2.617924em; - background-color:#e2401c; - margin-left:0; - border-radius:2px; - color:#fff; - clear:both; - border-left:.6180469716em solid rgba(0,0,0,.15); - padding:1em 2em 1em 3.5em; - position:relative; - list-style:none outside -} \ No newline at end of file diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index 5e4e7d7..6697a99 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -4,16 +4,14 @@ $, wc_checkout_params, GlobalPayments, - GlobalPayments3DS, - globalpayments_secure_payment_fields_params, - globalpayments_secure_payment_threedsecure_params + globalpayments_secure_payment_fields_params ) { /** * Frontend code for Global Payments in WooCommerce * * @param {object} options */ - function GlobalPaymentsWooCommerce( options, threeDSecureOptions ) { + function GlobalPaymentsWooCommerce(options) { /** * Card form instance @@ -28,37 +26,18 @@ * @type {string} */ this.id = options.id; - /** * Payment field options * * @type {object} */ this.fieldOptions = options.field_options; - /** * Payment gateway options * * @type {object} */ this.gatewayOptions = options.gateway_options; - - /** - * 3DS endpoints - */ - this.threedsecure = threeDSecureOptions.threedsecure; - - /** - * Order info - */ - this.order = threeDSecureOptions.order; - - /** - * - * @type {null} - */ - this.tokenResponse = null; - this.attachEventHandlers(); }; @@ -82,27 +61,15 @@ } ); - // Checkout - if ( 1 == wc_checkout_params.is_checkout ) { - $( document.body ).on( 'updated_checkout', this.renderPaymentFields.bind( this ) ); - if ( 'globalpayments_gpapi' === this.id) { - $( document.body ).on( 'updated_checkout', this.threeDSSecure.bind( this ) ); - } - return; - } - - // Order Pay - if ( $( document.body ).hasClass( 'woocommerce-order-pay' ) ) { + // Order Pay + Add payment method + if ( $( document.body ).hasClass( 'woocommerce-order-pay' ) || $( 'form#add_payment_method' ).length > 0 ) { $( document ).ready( this.renderPaymentFields.bind( this ) ); - if ( 'globalpayments_gpapi' === this.id) { - $( document ).ready( this.threeDSSecure.bind( this ) ); - } return; } - // Add payment method - if ( $( 'form#add_payment_method' ).length > 0 ) { - $( document ).ready( this.renderPaymentFields.bind( this ) ); + // Checkout + if ( wc_checkout_params.is_checkout ) { + $( document.body ).on( 'updated_checkout', this.renderPaymentFields.bind( this ) ); return; } }, @@ -200,14 +167,11 @@ */ toggleSubmitButtons: function () { var paymentGatewaySelected = $( this.getPaymentMethodRadioSelector() ).is( ':checked' ); - if ( ! paymentGatewaySelected ) { - return; - } - var savedCardsAvailable = $( this.getStoredPaymentMethodsRadioSelector() + '[value!="new"]' ).length > 0; var newSavedCardSelected = 'new' === $( this.getStoredPaymentMethodsRadioSelector() + ':checked' ).val(); - var shouldBeVisible = ( ! savedCardsAvailable ) || ( savedCardsAvailable && newSavedCardSelected ); + var shouldBeVisible = (paymentGatewaySelected && ! savedCardsAvailable) || (savedCardsAvailable && newSavedCardSelected); + if (shouldBeVisible) { // our gateway was selected $( this.getSubmitButtonTargetSelector() ).show(); @@ -234,7 +198,7 @@ return; } - this.tokenResponse = JSON.stringify(response); + console.log(response); var that = this; @@ -268,134 +232,6 @@ }); }, - /** - * Validate mandatory checkout fields - * - * @returns {boolean} - */ - validateFields: function() { - if ( ! $( '#billing_first_name' ).val() - || ! $( '#billing_last_name' ).val() - || ! $( '#billing_address_1' ).val() - || ! $( '#billing_city' ).val() - || ! $( '#billing_phone' ).val() - || ! $( '#billing_email' ).val() ) { - - return false; - } - - return true; - }, - - /** - * 3DS Process - */ - threeDSSecure: function () { - var checkVersionButton = $( this.getPlaceOrderButtonSelector() ); - if ( ! checkVersionButton ) { - console.error( 'Warning! Place Order button cannot be loaded' ); - return; - } - - //handle 3DS 2.0 workflow - var start3DS = async (e) => { - this.blockOnSubmit(); - e.preventDefault(); - if ( 1 === wc_checkout_params.is_checkout && ! this.validateFields() ) { - this.showPaymentError( 'Please fill in the required fields.' ); - e.stopPropagation(); - return; - } - - var _that = this; - - GlobalPayments.ThreeDSecure.checkVersion( this.threedsecure.checkEnrollmentUrl, { - tokenResponse: this.tokenResponse, - wcTokenId: $( 'input[name="wc-' + this.id + '-payment-token"]:checked', this.getForm() ).val(), - amount: this.order.amount, - currency: this.order.currency, - challengeWindow: { - windowSize: GlobalPayments.ThreeDSecure.ChallengeWindowSize.Windowed500x600, - displayMode: 'lightbox', - hide: false, - }, - }) - .then( function( versionCheckData ) { - // Card holder not enrolled in 3D Secure, continue the WooCommerce flow. - if ( versionCheckData.enrolled === "NOT_ENROLLED" ) { - $( _that.getForm() ).submit(); - return; - } - - if ( "ONE" === versionCheckData.version ) { - _that.createInputElement( 'serverTransId', versionCheckData.challenge.response.data.MD ); - _that.createInputElement( 'PaRes', versionCheckData.challenge.response.data.PaRes ); - $( _that.getForm() ).submit(); - return; - } - - if ( versionCheckData.error ) { - _that.showPaymentError( versionCheckData.message ); - return; - } - - GlobalPayments.ThreeDSecure.initiateAuthentication( _that.threedsecure.initiateAuthenticationUrl, { - tokenResponse: _that.tokenResponse, - wcTokenId: $( 'input[name="wc-' + _that.id + '-payment-token"]:checked', _that.getForm() ).val(), - versionCheckData: versionCheckData, - challengeWindow: { - windowSize: GlobalPayments.ThreeDSecure.ChallengeWindowSize.Windowed500x600, - displayMode: 'lightbox', - }, - order: _that.order, - }) - .then( function ( authenticationData ) { - if ( authenticationData.error ) { - _that.showPaymentError( authenticationData.message ); - return; - } - _that.createInputElement( 'serverTransId', versionCheckData.serverTransactionId ); - $( _that.getForm() ).submit(); - - }); - - }) - .catch( function( e ) { - console.error( e ); - _that.showPaymentError( e.reasons[0].message ); - return; - }); - - - - - return false; - }; - - checkVersionButton.off( 'click' ).on('click', start3DS ); - - $( document ).on("click",'img[id^="GlobalPayments-frame-close-"]', this.cancelTransaction.bind( this ) ); - - }, - - cancelTransaction: function () { - this.showPaymentError( 'Transaction canceled' ); - }, - - createInputElement: function ( name, value ) { - var inputElement = (document.getElementById( this.id + '-' + name )); - - if ( ! inputElement) { - inputElement = document.createElement( 'input' ); - inputElement.id = this.id + '-' + name; - inputElement.name = this.id + '[' + name + ']'; - inputElement.type = 'hidden'; - this.getForm().appendChild( inputElement ); - } - - inputElement.value = value; - }, - /** * Places/submits the order to WooCommerce * @@ -457,7 +293,7 @@ * @returns */ resetValidationErrors: function () { - $( '.' + this.id + ' .woocommerce-globalpayments-validation-error' ).hide(); + $( '.' + this.id + ' .validation-error' ).hide(); }, /** @@ -468,29 +304,7 @@ * @returns */ showValidationError: function (fieldType) { - $( '.' + this.id + '.' + fieldType + ' .woocommerce-globalpayments-validation-error' ).show(); - }, - - /** - * Shows payment error and scrolls to it - * - * @param {string} message Error message - * - * @returns - */ - showPaymentError: function ( message ) { - var $form = $( this.getForm() ); - - this.unblockOnError(); - - // Remove notices from all sources - $( '.woocommerce-NoticeGroup, .woocommerce-NoticeGroup-checkout, .woocommerce-error, .woocommerce-globalpayments-checkout-error' ).remove(); - - $form.prepend( '
' + message + '
' ); - - $( 'html, body' ).animate( { - scrollTop: ( $form.offset().top - 100 ) - }, 1000 ); + $( '.' + this.id + '.' + fieldType + ' .validation-error' ).show(); }, /** @@ -509,6 +323,7 @@ } var numberOfReasons = error.reasons.length; + for ( var i = 0; i < numberOfReasons; i++ ) { var reason = error.reasons[i]; switch ( reason.code ) { @@ -552,7 +367,7 @@ alert(reason.message); break; default: - this.showPaymentError( reason.message ); + break; } } }, @@ -592,62 +407,78 @@ var imageBase = 'https://api2.heartlandportico.com/securesubmit.v1/token/gp-1.6.0/assets'; return { 'html': { - 'font-size': '100%', - '-webkit-text-size-adjust': '100%', + 'font-size': '62.5%' }, - 'body': { - 'font-size': '14px', + 'font-size': '1.4rem' }, '#secure-payment-field-wrapper': { - 'position': 'relative' + 'postition': 'relative' }, '#secure-payment-field': { + '-o-transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s', + '-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)', + '-webkit-transition': 'border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s', 'background-color': '#fff', - 'border': '1px solid #ccc', - 'border-radius': '4px', + 'border': '1px solid #cecece', + 'border-radius': '2px', + 'box-shadow': 'none', + 'box-sizing': 'border-box', 'display': 'block', - - 'font-size': '14px', + 'font-family': '"Roboto", sans-serif', + 'font-size': '11px', + 'font-smoothing': 'antialiased', 'height': '35px', - 'padding': '6px 12px', - 'width': '100%', + 'margin': '5px 0 10px 0', + 'max-width': '100%', + 'outline': '0', + 'padding': '0 10px', + 'transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s', + 'vertical-align': 'baseline', + 'width': '100%' }, '#secure-payment-field:focus': { 'border': '1px solid lightblue', 'box-shadow': '0 1px 3px 0 #cecece', 'outline': 'none' }, - '#secure-payment-field[type=button]': { + '#secure-payment-field[type=button]': { + 'text-align': 'center', + 'text-transform': 'none', + 'white-space': 'nowrap', + + 'background-image': 'none', + 'background': '#1979c3', + 'border': '1px solid #1979c3', + 'color': '#ffffff', 'cursor': 'pointer', - 'border': '0', - 'border-radius': '0', - 'background': 'none', - 'background-color': '#333333', - 'border-color': '#333333', - 'color': '#fff', - 'padding': '.6180469716em 1.41575em', - 'text-decoration': 'none', - 'text-shadow': 'none', 'display': 'inline-block', + 'font-family': '"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif', + 'font-weight': '500', + 'padding': '14px 17px', + 'font-size': '1.8rem', + 'line-height': '2.2rem', + 'box-sizing': 'border-box', + 'vertical-align': 'middle', + 'margin': '0', 'height': 'initial', - 'width': '100%', + 'width': 'initial', 'flex': 'initial', - 'position': 'relative', - 'margin': '0', - '-webkit-appearance': 'none', - 'white-space': 'pre-wrap', - 'margin-bottom': '0', - 'float': 'none', - 'font': '600 1.41575em Source Sans Pro,HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif !important' + 'position': 'absolute', + 'right': '0' }, '#secure-payment-field[type=button]:focus': { - 'color': '#fff', - 'background': '#000000', + 'outline': 'none', + + 'box-shadow': 'none', + 'background': '#006bb4', + 'border': '1px solid #006bb4', + 'color': '#ffffff' }, '#secure-payment-field[type=button]:hover': { - 'color': '#fff', - 'background': '#000000', + 'background': '#006bb4', + 'border': '1px solid #006bb4', + 'color': '#ffffff' }, '.card-cvv': { 'background': 'transparent url(' + imageBase + '/cvv.png) no-repeat right', @@ -782,7 +613,7 @@ } }; - new GlobalPaymentsWooCommerce( globalpayments_secure_payment_fields_params, globalpayments_secure_payment_threedsecure_params ); + new GlobalPaymentsWooCommerce( globalpayments_secure_payment_fields_params ); }( /** * Global `jQuery` reference @@ -802,22 +633,10 @@ * @type {any} */ (window).GlobalPayments, - /** - * Global `GlobalPayments` reference - * - * @type {any} - */ - (window).GlobalPayments.ThreeDSecure, /** * Global `globalpayments_secure_payment_fields_params` reference * * @type {any} */ - (window).globalpayments_secure_payment_fields_params, - /** - * Global `globalpayments_secure_payment_threedsecure_params` reference - * - * @type {any} - */ - (window).globalpayments_secure_payment_threedsecure_params || {} + (window).globalpayments_secure_payment_fields_params )); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..2fd9b08 --- /dev/null +++ b/composer.json @@ -0,0 +1,38 @@ +{ + "name": "globalpayments/globalpayments-gateway-provider-for-woocommerce", + "description": "This extension allows WooCommerce to use the available Global Payments payment gateways. All card data is tokenized using the respective gateway's tokenization service.", + "homepage": "https://github.com/globalpayments/globalpayments-gateway-provider-for-woocommerce", + "license": "MIT", + "type": "wordpress-plugin", + "require": { + "composer/installers": "^1.7", + "globalpayments/php-sdk": "^2.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^7.5", + "squizlabs/php_codesniffer": "^3.5", + "wp-coding-standards/wpcs": "^2.1", + "woocommerce/woocommerce": "^3.8" + }, + "autoload": { + "psr-4": { + "GlobalPayments\\WooCommercePaymentGatewayProvider\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "GlobalPayments\\WooCommercePaymentGatewayProvider\\Tests\\": "tests" + } + }, + "scripts": { + "fix": [ "phpcbf" ], + "test": [ + "phpcs", + "WP_TESTS_DIR='./tests/fixtures/wordpress-tests-lib' phpunit" + ] + }, + "scripts-descriptions": { + "test": "Analyze code against the WordPress coding standards with PHP_CodeSniffer, and Run unit tests", + "fix": "Fix coding standards warnings/errors automatically with PHP Code Beautifier" + } +} diff --git a/globalpayments-gateway-provider-for-woocommerce.php b/globalpayments-gateway-provider-for-woocommerce.php index 0083c40..80c6308 100644 --- a/globalpayments-gateway-provider-for-woocommerce.php +++ b/globalpayments-gateway-provider-for-woocommerce.php @@ -1,12 +1,13 @@ + + + + + + . + + + tests/ + */vendor/* + */wp-content/* + + + + + + + + + + + + + + + + + + + * + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..07a29ed --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + ./tests/Unit + + + + diff --git a/readme.txt b/readme.txt index d67d716..00fadfb 100644 --- a/readme.txt +++ b/readme.txt @@ -1,42 +1,9 @@ -=== GlobalPayments WooCommerce === -Contributors: globalpayments -Tags: woocommerce, woo, commerce, global, payments, heartland, payment, systems, tsys, genius, gpapi, gp-api, 3DS, gateway, token, tokenize, save cards -Requires at least: 5.4 -Tested up to: 5.7 -Stable tag: 1.0.0-b.1 +=== Global Payments Gateway Provider for WooCommerce === +Contributors: markhagan, Mark Smedal Jr +Tags: woocommerce, woo, commerce, global, payments, heartland, payment, systems, tsys, genius,gateway, token, tokenize, save cards +Tested up to: 5.2 +Stable tag: trunk License: MIT -License URI: https://github.com/globalpayments/globalpayments-woocommerce/blob/main/LICENSE +License URI: https://github.com/globalpayments/globalpayments-gateway-provider-for-woocommerce/blob/master/LICENSE -== Description == This extension allows WooCommerce to use the available Global Payments payment gateways. All card data is tokenized using the respective gateway's tokenization service. - -= Features = -- Heartland Portico gateway -- TSYS Genius gateway -- TSYS TransIT gateway with TSEP -- Global Payments API (GP-API) gateway -- Credit Cards -- Integrates with Woocommerce -- Sale transactions (automatic capture or separate capture action later) -- Refund transactions from a previous Sale -- Verify payment method -- Stored payment methods -- 3D Secure 2 & SCA -- 3D Secure 1 - -= Support = -For more information or questions, please email developers@globalpay.com . - -= Developer Docs = -Discover our developer portal powered by Heartland, a Global Payments Company (https://developer.heartlandpaymentsystems.com/) or our portal for companies located outside the US (https://developer.globalpay.com/). - -== Installation == -After you have installed and configured the main WooCommerce plugin use the following steps to install the GlobalPayments WooCommerce: -1. In your WordPress admin, go to Plugins > Add New and search for "GlobalPayments WooCommerce" -2. Click Install, once installed click Activate -3. Configure and Enable gateways in WooCommerce by adding your public and secret Api Keys - -== Changelog == - -= 1.0.0-b.1 = -* Initial release. diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 129c032..8df6c46 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -5,7 +5,6 @@ defined( 'ABSPATH' ) || exit; use Exception; -use GlobalPayments\Api\Entities\Enums\GatewayProvider; use GlobalPayments\Api\Entities\Exceptions\ApiException; use GlobalPayments\Api\Entities\Reporting\TransactionSummary; use WC_Payment_Gateway_CC; @@ -49,10 +48,6 @@ abstract class AbstractGateway extends WC_Payment_Gateway_Cc { //gp-api requests const TXN_TYPE_GET_ACCESS_TOKEN = 'getAccessToken'; - //3DS requests - const TXN_TYPE_CHECK_ENROLLMENT = 'checkEnrollment'; - const TXN_TYPE_INITIATE_AUTHENTICATION = 'initiateAuthentication'; - /** * Gateway provider. Should be overriden by individual gateway implementations * @@ -110,6 +105,28 @@ abstract class AbstractGateway extends WC_Payment_Gateway_Cc { * @var Clients\ClientInterface */ protected $client; + + /** + * AVS CVN auto reverse condition + * + * @var bool + */ + public $check_avs_cvv; + + /** + * AVS result codes + * + * @var array + */ + public $avs_reject_conditions; + + /** + * CVN result codes + * + * @var array + */ + public $cvn_reject_conditions; + public function __construct() { $this->client = new Clients\SdkClient(); @@ -173,6 +190,20 @@ abstract public function get_gateway_form_fields(); * @return string */ abstract public function get_first_line_support_email(); + + /** + * Avs Rejection Conditions + * + * @return string + */ + abstract public function avs_rejection_conditions(); + + /** + * CVV Rejection Conditions + * + * @return string + */ + abstract public function cvn_rejection_conditions(); /** * Get the current gateway provider @@ -251,23 +282,16 @@ public function tokenization_script() { parent::tokenization_script(); // Global Payments styles for client-side tokenization - $css_style = Plugin::get_url( '/assets/frontend/css/globalpayments-secure-payment-fields.css' ); - /** - * Allow iframe styling according to theme - * - * @param $css_style CSS stylesheet - */ - $css_style = apply_filters( 'globalpayments_secure_payment_fields', $css_style ); wp_enqueue_style( 'globalpayments-secure-payment-fields', - $css_style, + Plugin::get_url( '/assets/frontend/css/globalpayments-secure-payment-fields.css' ), array(), WC()->version ); // Global Payments scripts for handling client-side tokenization wp_enqueue_script( 'globalpayments-secure-payment-fields-lib', - 'https://js.globalpay.com/v1/globalpayments' + 'https://api2.heartlandportico.com/securesubmit.v1/token/gp-1.6.0/globalpayments' . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js', array(), WC()->version, @@ -289,39 +313,6 @@ public function tokenization_script() { 'field_options' => $this->secure_payment_fields(), ) ); - - // Global Payments scripts for handling 3DS - if ( GatewayProvider::GP_API !== $this->gateway_provider ) { - return; - } - - wp_enqueue_script( - 'globalpayments-threedsecure-lib', - Plugin::get_url( '/assets/frontend/js/globalpayments-3ds' ) - . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js', - array( 'globalpayments-secure-payment-fields-lib' ), - WC()->version, - true - ); - wp_localize_script( - 'globalpayments-secure-payment-fields', - 'globalpayments_secure_payment_threedsecure_params', - array( - 'threedsecure' => array( - 'methodNotificationUrl' => WC()->api_request_url( 'globalpayments_threedsecure_methodnotification' ), - 'challengeNotificationUrl' => WC()->api_request_url( 'globalpayments_threedsecure_challengenotification' ), - 'checkEnrollmentUrl' => WC()->api_request_url( 'globalpayments_threedsecure_checkenrollment' ), - 'initiateAuthenticationUrl' => WC()->api_request_url( 'globalpayments_threedsecure_initiateauthentication' ), - ), - 'order' => array ( - 'amount' => $this->get_session_amount(), - 'currency' => get_woocommerce_currency(), - 'billingAddress' => $this->get_billing_address(), - 'shippingAddress' => $this->get_shipping_address(), - 'customerEmail' => $this->get_customer_email(), - ), - ) - ); } /** @@ -449,7 +440,7 @@ protected function secure_payment_field_html_format() { '
-
' @@ -473,7 +464,6 @@ protected function add_hooks() { if ( is_add_payment_method_page() ) { add_action( 'wp_enqueue_scripts', array( $this, 'tokenization_script' ) ); - add_filter( 'woocommerce_available_payment_gateways', array( $this, 'woocommerce_available_payment_gateways') ); } } @@ -507,7 +497,6 @@ public function add_payment_method() { try { $response = $this->submit_request( $request ); - $is_successful = $this->handle_response( $request, $response ); } catch ( Exception $e ) { return array( 'result' => 'failure', @@ -515,6 +504,8 @@ public function add_payment_method() { ); } + $is_successful = $this->handle_response( $request, $response ); + return array( 'result' => $is_successful ? 'success' : 'failure', 'redirect' => $redirect, @@ -572,7 +563,7 @@ public static function capture_credit_card_authorization( $order_id ) { case "globalpayments_genius": $gateway = new GeniusGateway(); break; - case GpApiGateway::GATEWAY_ID: + case "globalpayments_gpapi": $gateway = new GpApiGateway(); break; }; @@ -636,8 +627,6 @@ protected function prepare_request( $txn_type, WC_Order $order = null ) { self::TXN_TYPE_REPORT_TXN_DETAILS => Requests\TransactionDetailRequest::class, self::TXN_TYPE_CAPTURE => Requests\CaptureAuthorizationRequest::class, self::TXN_TYPE_GET_ACCESS_TOKEN => Requests\GetAccessTokenRequest::class, - self::TXN_TYPE_CHECK_ENROLLMENT => Requests\ThreeDSecure\CheckEnrollmentRequest::class, - self::TXN_TYPE_INITIATE_AUTHENTICATION => Requests\ThreeDSecure\InitiateAuthenticationRequest::class, ); if ( ! isset( $map[ $txn_type ] ) ) { @@ -672,7 +661,7 @@ protected function submit_request( Requests\RequestInterface $request ) { * @return bool */ protected function handle_response( Requests\RequestInterface $request, Transaction $response ) { - if ($response->responseCode !== '00' && 'SUCCESS' !== $response->responseCode || $response->responseMessage === 'Partially Approved') { + if ($response->responseCode !== '00' && 'SUCCESS' !== $response->responseCode || $response->responseMessage === 'Partially Approved') { if ($response->responseCode === '10' || $response->responseMessage === 'Partially Approved') { try { $response->void()->withDescription('POST_AUTH_USER_DECLINE')->execute(); @@ -739,27 +728,7 @@ public function get_decline_message( string $response_code ) { */ public static function addCaptureOrderAction( $actions ) { - global $theorder; - - if ( AbstractGateway::TXN_TYPE_AUTHORIZE !== $theorder->get_meta('_globalpayments_payment_action') ) { - return $actions; - } $actions['capture_credit_card_authorization'] = 'Capture credit card authorization'; return $actions; } - - /** - * Disable adding new cards via 'My Account', if "Allow Card Saving" option not checked in admin. - * - * @param array $available_gateways - * @return array - */ - public function woocommerce_available_payment_gateways( $available_gateways ) { - if ( 'no' === $this->get_option( 'allow_card_saving' ) ) { - unset( $available_gateways[ $this->id ]); - } - - return $available_gateways; - } - } diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 1d0229b..79f9501 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -4,7 +4,7 @@ use GlobalPayments\Api\Builders\TransactionBuilder; use GlobalPayments\Api\Entities\Address; -use GlobalPayments\Api\Entities\Exceptions\ApiException; +use GlobalPayments\Api\Entities\Enums\GpApi\Channels; use GlobalPayments\Api\Entities\Transaction; use GlobalPayments\Api\Entities\Enums\AddressType; use GlobalPayments\Api\Entities\Enums\CardType; @@ -19,7 +19,6 @@ use GlobalPayments\Api\ServiceConfigs\Gateways\PorticoConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\TransitConfig; use GlobalPayments\Api\Services\ReportingService; -use GlobalPayments\Api\Services\Secure3dService; use GlobalPayments\Api\ServicesContainer; use GlobalPayments\WooCommercePaymentGatewayProvider\Data\PaymentTokenData; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\AbstractGateway; @@ -78,7 +77,10 @@ class SdkClient implements ClientInterface { protected $previous_transaction = null; public function set_request( RequestInterface $request ) { - $this->prepare_request_args( $request ); + $this->args = array_merge( + $request->get_default_args(), + $request->get_args() + ); $this->prepare_request_objects(); return $this; @@ -96,9 +98,6 @@ public function execute() { } $this->prepare_builder( $builder ); - if ( $this->threedsecure_is_enabled() ) { - $this->set_threedsecure_data(); - } $response = $builder->execute(); if ( ! is_null( $this->card_data ) && $response instanceof Transaction && $response->token ) { $this->card_data->token = $response->token; @@ -108,13 +107,6 @@ public function execute() { return $response; } - public function submit_request( RequestInterface $request ) { - $this->prepare_request_args( $request ); - $this->configure_sdk(); - - $request->do_request(); - } - protected function prepare_builder( TransactionBuilder $builder ) { foreach ( $this->builder_args as $name => $args ) { $method = 'with' . ucfirst( $name ); @@ -157,13 +149,6 @@ protected function get_transaction_builder() { return $subject->{$this->get_arg( RequestArg::TXN_TYPE )}(); } - protected function prepare_request_args( RequestInterface $request ) { - $this->args = array_merge( - $request->get_default_args(), - $request->get_args() - ); - } - protected function prepare_request_objects() { if ( $this->has_arg( RequestArg::AMOUNT ) ) { $this->builder_args['amount'] = array( $this->get_arg( RequestArg::AMOUNT ) ); @@ -274,22 +259,6 @@ protected function prepare_card_data( WC_Payment_Token_CC $token = null ) { } } - protected function threedsecure_is_enabled() { - return $this->has_arg( RequestArg::SERVER_TRANS_ID ); - } - - protected function set_threedsecure_data() { - $threeDSecureData = Secure3dService::getAuthenticationData() - ->withServerTransactionId( $this->get_arg( RequestArg::SERVER_TRANS_ID ) ) - ->withPayerAuthenticationResponse( $this->get_arg( RequestArg::PARES ) ) - ->execute(); - - if ( ! in_array( $threeDSecureData->eci, ["01", "02", "05", "06"] ) ) { - throw new ApiException( __( '3DS authentication failed' ) ); - } - $this->card_data->threeDSecure = $threeDSecureData; - } - protected function prepare_address( $address_type, array $data ) { $address = new Address(); $address->type = $address_type; @@ -314,25 +283,33 @@ protected function configure_sdk() { case GatewayProvider::TRANSIT: $gatewayConfig = new TransitConfig(); $gatewayConfig->acceptorConfig = new AcceptorConfig(); // defaults should work here - if ( $this->get_arg( RequestArg::TXN_TYPE ) === AbstractGateway::TXN_TYPE_CREATE_MANIFEST ) { - $gatewayConfig->deviceId = $this->args[ RequestArg::SERVICES_CONFIG ]['tsepDeviceId']; - } break; case GatewayProvider::GENIUS: $gatewayConfig = new GeniusConfig(); break; case GatewayProvider::GP_API: $gatewayConfig = new GpApiConfig(); - if ( $this->has_arg( RequestArg::PERMISSIONS ) ) { - $gatewayConfig->permissions = $this->get_arg( RequestArg::PERMISSIONS ); - } + $servicesConfig = $this->args[ RequestArg::SERVICES_CONFIG ]; + $gatewayConfig->setAppId( $servicesConfig['AppId'] ); + $gatewayConfig->setAppKey( $servicesConfig['AppKey'] ); + $gatewayConfig->setChannel( Channels::CardNotPresent ); + + unset( $this->args[ RequestArg::SERVICES_CONFIG ]['gatewayProvider'] ); break; } + $config = $this->set_object_data( $gatewayConfig, $this->args[ RequestArg::SERVICES_CONFIG ] ); + if ( + $this->args['SERVICES_CONFIG']['gatewayProvider'] === GatewayProvider::TRANSIT && + $this->get_arg( RequestArg::TXN_TYPE ) === AbstractGateway::TXN_TYPE_CREATE_MANIFEST + ) { + $config->deviceId = $this->args[ RequestArg::SERVICES_CONFIG ]['tsepDeviceId']; + } + ServicesContainer::configureService( $config ); } diff --git a/src/Gateways/GeniusGateway.php b/src/Gateways/GeniusGateway.php index e1cc1e6..2216913 100644 --- a/src/Gateways/GeniusGateway.php +++ b/src/Gateways/GeniusGateway.php @@ -102,4 +102,10 @@ public function get_backend_gateway_options() { 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, ); } + public function cvn_rejection_conditions() + {} + + public function avs_rejection_conditions() + {} + } diff --git a/src/Gateways/GpApiGateway.php b/src/Gateways/GpApiGateway.php index c79d5f1..dbf7d55 100644 --- a/src/Gateways/GpApiGateway.php +++ b/src/Gateways/GpApiGateway.php @@ -4,16 +4,10 @@ use GlobalPayments\Api\Entities\Enums\Environment; use GlobalPayments\Api\Entities\Enums\GatewayProvider; -use GlobalPayments\Api\Entities\Enums\GpApi\Channels; -use GlobalPayments\WooCommercePaymentGatewayProvider\Plugin; defined( 'ABSPATH' ) || exit; class GpApiGateway extends AbstractGateway { - /** - * Gateway ID - */ - const GATEWAY_ID = 'globalpayments_gpapi'; /** * SDK gateway provider * @@ -51,7 +45,7 @@ class GpApiGateway extends AbstractGateway { public $developer_id = ''; public function configure_method_settings() { - $this->id = self::GATEWAY_ID; + $this->id = 'globalpayments_gpapi'; $this->method_title = __( 'GP-API', 'globalpayments-gateway-provider-for-woocommerce' ); $this->method_description = __( 'Connect to the Global Payments API (GP-API) gateway', 'globalpayments-gateway-provider-for-woocommerce' ); } @@ -97,14 +91,10 @@ public function get_frontend_gateway_options() { public function get_backend_gateway_options() { return array( - 'appId' => $this->app_id, - 'appKey' => $this->app_key, - 'channel' => Channels::CardNotPresent, - 'country' => wc_get_base_location()['country'], - 'developerId' => '', - 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, - 'methodNotificationUrl' => WC()->api_request_url('globalpayments_threedsecure_methodnotification'), - 'challengeNotificationUrl' => WC()->api_request_url('globalpayments_threedsecure_challengenotification'), + 'AppId' => $this->app_id, + 'AppKey' => $this->app_key, + 'developerId' => '', + 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, ); } @@ -115,19 +105,6 @@ protected function get_access_token() { return $response->token; } - protected function add_hooks() { - parent::add_hooks(); - - /** - * The WooCommerce API allows plugins make a callback to a special URL that will then load the specified class (if it exists) - * and run an action. This is also useful for gateways that are not initialized. - */ - add_action( 'woocommerce_api_globalpayments_threedsecure_checkenrollment', array( $this, 'process_threeDSecure_checkEnrollment' ) ); - add_action( 'woocommerce_api_globalpayments_threedsecure_methodnotification', array( $this, 'process_threeDSecure_methodNotification' ) ); - add_action( 'woocommerce_api_globalpayments_threedsecure_initiateauthentication', array( $this, 'process_threeDSecure_initiateAuthentication' ) ); - add_action( 'woocommerce_api_globalpayments_threedsecure_challengenotification', array( $this, 'process_threeDSecure_challengeNotification' ) ); - } - public function mapResponseCodeToFriendlyMessage( $responseCode ) { if ( 'DECLINED' === $responseCode ) { return __( 'Your card has been declined by the bank.', 'globalpayments-gateway-provider-for-woocommerce' ); @@ -135,116 +112,10 @@ public function mapResponseCodeToFriendlyMessage( $responseCode ) { return __( 'An error occurred while processing the card.', 'globalpayments-gateway-provider-for-woocommerce' ); } + public function cvn_rejection_conditions() + {} - public function process_threeDSecure_checkEnrollment() - { - $request = $this->prepare_request( parent::TXN_TYPE_CHECK_ENROLLMENT ); - $this->client->submit_request( $request ); - } - - public function process_threeDSecure_initiateAuthentication() - { - $request = $this->prepare_request( parent::TXN_TYPE_INITIATE_AUTHENTICATION ); - $this->client->submit_request( $request ); - } - - public function process_threeDSecure_methodNotification() - { - if ( ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) ) { - return; - } - if ( 'application/x-www-form-urlencoded' !== $_SERVER['CONTENT_TYPE'] ) { - return; - } - - $convertedThreeDSMethodData = wc_clean( json_decode( base64_decode( $_POST['threeDSMethodData'] ) ) ); - $response = json_encode([ - 'threeDSServerTransID' => $convertedThreeDSMethodData->threeDSServerTransID, - ]); - - wp_enqueue_script( - 'globalpayments-threedsecure-lib', - Plugin::get_url( '/assets/frontend/js/globalpayments-3ds' ) - . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js' - ); - wp_add_inline_script( 'globalpayments-threedsecure-lib', 'GlobalPayments.ThreeDSecure.handleMethodNotification(' . $response . ');' ); - wp_print_scripts(); - exit(); - } + public function avs_rejection_conditions() + {} - public function process_threeDSecure_challengeNotification() - { - if ( ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) ) { - return; - } - if ( 'application/x-www-form-urlencoded' !== $_SERVER['CONTENT_TYPE'] ) { - return; - } - - try { - $response = new \stdClass(); - - if ( isset( $_POST['cres'] ) ) { - $convertedCRes = wc_clean( json_decode( base64_decode( $_POST['cres'] ) ) ); - - $response = json_encode([ - 'threeDSServerTransID' => $convertedCRes->threeDSServerTransID, - 'transStatus' => $convertedCRes->transStatus ?? '', - ]); - } - - if ( isset( $_POST['PaRes'] ) ) { - $response = json_encode( [ - 'MD' => wc_clean( $_POST['MD'] ), - 'PaRes' => wc_clean( $_POST['PaRes'] ), - ], JSON_UNESCAPED_SLASHES ); - } - wp_enqueue_script( - 'globalpayments-threedsecure-lib', - Plugin::get_url( '/assets/frontend/js/globalpayments-3ds' ) - . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js' - ); - wp_add_inline_script( 'globalpayments-threedsecure-lib', 'GlobalPayments.ThreeDSecure.handleChallengeNotification(' . $response . ');' ); - wp_print_scripts(); - exit(); - - } catch (Exception $e) { - $response = array('error' => TRUE, 'message' => $e->getMessage()); - } - } - - protected function get_session_amount() { - $cart_totals = WC()->session->get('cart_totals'); - return round($cart_totals['total'], 2); - } - - protected function get_customer_email() { - return WC()->customer->get_billing_email(); - } - - protected function get_billing_address() - { - return [ - 'streetAddress1' => WC()->customer->get_billing_address_1(), - 'streetAddress2' => WC()->customer->get_billing_address_2(), - 'city' => WC()->customer->get_billing_city(), - 'state' => WC()->customer->get_billing_state(), - 'postalCode' => WC()->customer->get_billing_postcode(), - 'country' => WC()->customer->get_billing_country(), - 'countryCode' => '', - ]; - } - - protected function get_shipping_address() - { - return [ - 'streetAddress1' => WC()->customer->get_shipping_address_1(), - 'streetAddress2' => WC()->customer->get_shipping_address_2(), - 'city' => WC()->customer->get_shipping_city(), - 'state' => WC()->customer->get_shipping_state(), - 'postalCode' => WC()->customer->get_shipping_postcode(), - 'country' => WC()->customer->get_shipping_country(), - 'countryCode' => '', - ]; - } } diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index 486299a..e10d7c2 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -36,8 +36,8 @@ class HeartlandGateway extends AbstractGateway { * * @var bool */ - public $allow_gift_cards; - + public $allow_gift_cards; + public function configure_method_settings() { $this->id = 'globalpayments_heartland'; $this->method_title = __( 'Heartland', 'globalpayments-gateway-provider-for-woocommerce' ); @@ -49,6 +49,7 @@ public function get_first_line_support_email() { } public function get_gateway_form_fields() { + return array( 'public_key' => array( 'title' => __( 'Public Key', 'globalpayments-gateway-provider-for-woocommerce' ), @@ -71,6 +72,27 @@ public function get_gateway_form_fields() { ), 'default' => 'no' ), + 'check_avs_cvv' => array( + 'title' => __( 'Check AVS CVN', 'globalpayments-gateway-provider-for-woocommerce' ), + 'label' => __( 'Check AVS/CVN result codes and reverse transaction.', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'checkbox', + 'description' => sprintf( + __( 'This will check AVS/CVN result codes and reverse transaction.' ) + ), + 'default' => 'no' + ), + 'avs_reject_conditions' => array( + 'title' => __( 'AVS Reject Conditions', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'multiselect', + 'description' => __( 'Choose for which AVS result codes, the transaction must be auto reveresed.'), + 'options' => $this->avs_rejection_conditions(), + ), + 'cvn_reject_conditions' => array( + 'title' => __( 'CVN Reject Conditions', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'multiselect', + 'description' => __( 'Choose for which CVN result codes, the transaction must be auto reveresed.'), + 'options' => $this->cvn_rejection_conditions(), + ), ); } @@ -181,11 +203,26 @@ public function payment_fields() { * @return array * */ public function process_payment( $order_id ) { - $order = new WC_Order( $order_id ); + $order = new WC_Order( $order_id ); $request = $this->prepare_request( $this->payment_action, $order ); $response = $this->submit_request( $request ); $is_successful = $this->handle_response( $request, $response ); - + + //reverse incase of AVS/CVN failure + if(!empty($response->transactionReference->transactionId) && !empty($this->check_avs_cvv)){ + if(!empty($response->avsResponseCode) || !empty($response->cvnResponseCode)){ + //check admin selected decline condtions + if(in_array($response->avsResponseCode, $this->avs_reject_conditions) || + in_array($response->cvnResponseCode, $this->cvn_reject_conditions)){ + Transaction::fromId( $response->transactionReference->transactionId ) + ->reverse( $request->order->data[ 'total' ] ) + ->execute(); + + $is_successful = false; + } + } + } + // Charge HPS gift cards if CC trans succeeds if ( $is_successful && !empty( WC()->session->get( 'heartland_gift_card_applied' ) ) ) { $gift_card_order_placement = new HeartlandGiftCardOrder(); @@ -210,4 +247,37 @@ public function process_payment( $order_id ) { 'redirect' => $is_successful ? $this->get_return_url( $order ) : false, ); } + + public function avs_rejection_conditions() + { + return array( + 'A' => 'Address matches, zip No Match', + 'N' => 'Neither address or zip code match', + 'R' => 'Retry - system unable to respond', + 'U' => 'Visa / Discover card AVS not supported', + 'S' => 'Master / Amex card AVS not supported', + 'Z' => 'Visa / Discover card 9-digit zip code match, address no match', + 'W' => 'Master / Amex card 9-digit zip code match, address no match', + 'Y' => 'Visa / Discover card 5-digit zip code and address match', + 'X' => 'Master / Amex card 5-digit zip code and address match', + 'G' => 'Address not verified for International transaction', + 'B' => 'Address match, Zip not verified', + 'C' => 'Address and zip mismatch', + 'D' => 'Address and zip match', + 'I' => 'AVS not verified for International transaction', + 'M' => 'Street address and postal code matches', + 'P' => 'Address and Zip not verified' + ); + } + + public function cvn_rejection_conditions() + { + return array( + 'N' => 'Not Matching', + 'P' => 'Not Processed', + 'S' => 'Result not present', + 'U' => 'Issuer not certified', + '?' => 'CVV unrecognized' + ); + } } diff --git a/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php index 8ae4eb4..6f93161 100644 --- a/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php +++ b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php @@ -36,8 +36,8 @@ protected function configureServiceContainer() public function applyGiftCard() { $gift_card_balance = $this->giftCardBalance( - wc_clean( $_POST['gift_card_number'] ), - wc_clean( $_POST['gift_card_pin'] ) + $_POST['gift_card_number'], + $_POST['gift_card_pin'] ); if ($gift_card_balance['error']) { @@ -330,7 +330,7 @@ public function removeAllGiftCardsFromSession() public function removeGiftCard($removed_card = null) { if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { - $removed_card = wc_clean( $_POST['securesubmit_card_id'] ); + $removed_card = $_POST['securesubmit_card_id']; } $applied_cards = WC()->session->get('heartland_gift_card_applied'); diff --git a/src/Gateways/Requests/AbstractRequest.php b/src/Gateways/Requests/AbstractRequest.php index 1b9e3fe..52ce27b 100644 --- a/src/Gateways/Requests/AbstractRequest.php +++ b/src/Gateways/Requests/AbstractRequest.php @@ -67,15 +67,9 @@ public function get_default_args() { public function get_request_data( $key = null ) { if ( null === $key ) { - if ( ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) ) { - return null; - } - if ( 'application/json' === $_SERVER['CONTENT_TYPE'] ) { - return json_decode( file_get_contents( 'php://input' ) ); - } // WooCommerce should verify nonce during its checkout handling // phpcs:ignore WordPress.Security.NonceVerification - return wc_clean( $_POST ); + return $_POST; } if ( ! isset( $this->data[ $key ] ) ) { diff --git a/src/Gateways/Requests/AuthorizationRequest.php b/src/Gateways/Requests/AuthorizationRequest.php index b784143..0da07ac 100644 --- a/src/Gateways/Requests/AuthorizationRequest.php +++ b/src/Gateways/Requests/AuthorizationRequest.php @@ -16,11 +16,9 @@ public function get_args() { $token = ( new PaymentTokenData( $this ) )->get_token(); return array( - RequestArg::AMOUNT => null !== $this->order ? $this->order->get_total() : null, - RequestArg::CURRENCY => null !== $this->order ? $this->order->get_currency() : null, - RequestArg::CARD_DATA => $token, - RequestArg::SERVER_TRANS_ID => $this->data[ $this->gateway_id ]['serverTransId'] ?? null, - RequestArg::PARES => $this->data[ $this->gateway_id ]['PaRes'] ?? null, + RequestArg::AMOUNT => null !== $this->order ? $this->order->get_total() : null, + RequestArg::CURRENCY => null !== $this->order ? $this->order->get_currency() : null, + RequestArg::CARD_DATA => $token, ); } } diff --git a/src/Gateways/Requests/GetAccessTokenRequest.php b/src/Gateways/Requests/GetAccessTokenRequest.php index c79c7db..043d025 100644 --- a/src/Gateways/Requests/GetAccessTokenRequest.php +++ b/src/Gateways/Requests/GetAccessTokenRequest.php @@ -12,10 +12,6 @@ public function get_transaction_type() { } public function get_args() { - return array( - RequestArg::PERMISSIONS => array( - 'PMT_POST_Create_Single', - ) - ); + return array(); } } diff --git a/src/Gateways/Requests/RefundRequest.php b/src/Gateways/Requests/RefundRequest.php index df030df..11f8ec4 100644 --- a/src/Gateways/Requests/RefundRequest.php +++ b/src/Gateways/Requests/RefundRequest.php @@ -15,7 +15,7 @@ public function get_transaction_type() { public function get_args() { $gateway_id = $this->order->get_transaction_id(); $description = $this->data['refund_reason']; - $refund_amount = wc_format_decimal( $this->data['refund_amount'] ); + $refund_amount = $this->data['refund_amount']; return array( RequestArg::CURRENCY => $this->order->get_currency(), diff --git a/src/Gateways/Requests/RequestArg.php b/src/Gateways/Requests/RequestArg.php index 2b6a30c..592a15f 100644 --- a/src/Gateways/Requests/RequestArg.php +++ b/src/Gateways/Requests/RequestArg.php @@ -8,9 +8,6 @@ abstract class RequestArg { const CARD_DATA = 'CARD_DATA'; const CARD_HOLDER_NAME = 'CARD_HOLDER_NAME'; const CURRENCY = 'CURRENCY'; - const PARES = 'PARES'; - const PERMISSIONS = 'PERMISSIONS'; - const SERVER_TRANS_ID = 'SERVER_TRANS_ID'; const SERVICES_CONFIG = 'SERVICES_CONFIG'; const SHIPPING_ADDRESS = 'SHIPPING_ADDRESS'; const TXN_TYPE = 'TXN_TYPE'; diff --git a/src/Gateways/Requests/VerifyRequest.php b/src/Gateways/Requests/VerifyRequest.php index 37949c7..6fb2063 100644 --- a/src/Gateways/Requests/VerifyRequest.php +++ b/src/Gateways/Requests/VerifyRequest.php @@ -4,7 +4,6 @@ use GlobalPayments\WooCommercePaymentGatewayProvider\Data\PaymentTokenData; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\AbstractGateway; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\GpApiGateway; defined( 'ABSPATH' ) || exit; @@ -16,15 +15,6 @@ public function get_transaction_type() { public function get_args() { $token = ( new PaymentTokenData( $this ) )->get_token(); - if ( GpApiGateway::GATEWAY_ID === $this->gateway_id ) { - return array( - RequestArg::CARD_DATA => $token, - RequestArg::CURRENCY => null !== $this->order ? $this->order->get_currency() : get_woocommerce_currency(), - RequestArg::SERVER_TRANS_ID => $this->data[ $this->gateway_id ]['serverTransId'] ?? null, - RequestArg::PARES => $this->data[ $this->gateway_id ]['PaRes'] ?? null, - ); - } - return array( RequestArg::CARD_DATA => $token, ); diff --git a/src/Gateways/TransitGateway.php b/src/Gateways/TransitGateway.php index 3c89203..262167b 100644 --- a/src/Gateways/TransitGateway.php +++ b/src/Gateways/TransitGateway.php @@ -211,4 +211,10 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { return $is_successful; } + public function cvn_rejection_conditions() + {} + + public function avs_rejection_conditions() + {} + } diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php new file mode 100644 index 0000000..ee4e8e6 --- /dev/null +++ b/tests/Bootstrap.php @@ -0,0 +1,34 @@ +assertNotNull(new \GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGateway()); + } +} diff --git a/tests/bin/install-wp-tests.sh b/tests/bin/install-wp-tests.sh new file mode 100644 index 0000000..2795af3 --- /dev/null +++ b/tests/bin/install-wp-tests.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +if [ $# -lt 3 ]; then + echo "usage: $0 [db-host] [wp-version]" + exit 1 +fi + +DB_NAME=$1 +DB_USER=$2 +DB_PASS=$3 +DB_HOST=${4-localhost} +WP_VERSION=${5-latest} + +WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} +WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} + +download() { + if [ `which curl` ]; then + curl -s "$1" > "$2"; + elif [ `which wget` ]; then + wget -nv -O "$2" "$1" + fi +} + +if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then + WP_TESTS_TAG="tags/$WP_VERSION" +elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + WP_TESTS_TAG="trunk" +else + # http serves a single offer, whereas https serves multiple. we only want one + download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json + grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json + LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') + if [[ -z "$LATEST_VERSION" ]]; then + echo "Latest WordPress version could not be found" + exit 1 + fi + WP_TESTS_TAG="tags/$LATEST_VERSION" +fi + +set -ex + +install_wp() { + + if [ -d $WP_CORE_DIR ]; then + return; + fi + + mkdir -p $WP_CORE_DIR + + if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then + mkdir -p /tmp/wordpress-nightly + download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip + unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ + mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR + else + if [ $WP_VERSION == 'latest' ]; then + local ARCHIVE_NAME='latest' + else + local ARCHIVE_NAME="wordpress-$WP_VERSION" + fi + download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz + tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR + fi + + download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php +} + +install_test_suite() { + # portable in-place argument for both GNU sed and Mac OSX sed + if [[ $(uname -s) == 'Darwin' ]]; then + local ioption='-i .bak' + else + local ioption='-i' + fi + + # set up testing suite if it doesn't yet exist + if [ ! -d $WP_TESTS_DIR ]; then + # set up testing suite + mkdir -p $WP_TESTS_DIR + svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + fi + + if [ ! -f wp-tests-config.php ]; then + download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR':" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php + sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php + fi + +} + +install_db() { + # parse DB_HOST for port or socket references + local PARTS=(${DB_HOST//\:/ }) + local DB_HOSTNAME=${PARTS[0]}; + local DB_SOCK_OR_PORT=${PARTS[1]}; + local EXTRA="" + + if ! [ -z $DB_HOSTNAME ] ; then + if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then + EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" + elif ! [ -z $DB_SOCK_OR_PORT ] ; then + EXTRA=" --socket=$DB_SOCK_OR_PORT" + elif ! [ -z $DB_HOSTNAME ] ; then + EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" + fi + fi + + # create database + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} + +install_wp +install_test_suite +install_db