From 2c5054c85243b66c92b282e04d5f52544b9a4468 Mon Sep 17 00:00:00 2001 From: securesubmit-buildmaster Date: Mon, 17 Feb 2020 14:08:59 -0500 Subject: [PATCH 01/57] decline-messages-work --- src/Gateways/AbstractGateway.php | 71 +++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 10caf96..205f277 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -544,7 +544,16 @@ protected function submit_request( Requests\RequestInterface $request ) { */ protected function handle_response( Requests\RequestInterface $request, Transaction $response ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName - if ( '00' !== $response->responseCode ) { + if ( '00' !== $response->responseCode ) { + global $woocommerce; + $decline_message = $this->decline_message[$response->responseCode]; + + if (function_exists('wc_add_notice')) { + wc_add_notice($decline_message, 'error'); + } else if (isset($woocommerce) && property_exists($woocommerce, 'add_error')) { + $woocommerce->add_error($decline_message); + } + return false; } @@ -571,4 +580,64 @@ protected function handle_response( Requests\RequestInterface $request, Transact protected function is_transaction_active( TransactionSummary $details ) { return false; } + + /** + * string Key = gateway response codes for declined transaction attempts; + * string Value = customer-facing messages for each decline code + */ + public $decline_message = array( + '02' => "The card was declined.", + '03' => "The card was declined.", + '04' => "The card was declined.", + '05' => "The card was declined.", + '41' => "The card was declined.", + '43' => "The card was declined.", + '44' => "The card was declined.", + '51' => "The card was declined.", + '56' => "The card was declined.", + '61' => "The card was declined.", + '62' => "The card was declined.", + '63' => "The card was declined.", + '65' => "The card was declined.", + '78' => "The card was declined.", + '06' => "An error occurred while processing the card.", + '07' => "An error occurred while processing the card.", + '12' => "An error occurred while processing the card.", + '15' => "An error occurred while processing the card.", + '19' => "An error occurred while processing the card.", + '52' => "An error occurred while processing the card.", + '53' => "An error occurred while processing the card.", + '57' => "An error occurred while processing the card.", + '58' => "An error occurred while processing the card.", + '76' => "An error occurred while processing the card.", + '77' => "An error occurred while processing the card.", + '96' => "An error occurred while processing the card.", + 'EC' => "An error occurred while processing the card.", + '13' => "Must be greater than or equal 0.", + '14' => "The card number is incorrect.", + '54' => "The card has expired.", + '55' => "The pin is invalid.", + '75' => "Maximum number of pin retries exceeded.", + '80' => "Card expiration date is invalid.", + '86' => "Can't verify card pin number.", + '91' => "The card issuer timed-out.", + 'EB' => "The card's security code is incorrect.", + 'N7' => "The card's security code is incorrect.", + 'FR' => "Possible fraud detected", + // gift card declines + '1' => "An unknown gift error has occurred.", + '2' => "An unknown gift error has occurred.", + '11' => "An unknown gift error has occurred.", + '3' => "The card data is invalid.", + '8' => "The card data is invalid.", + '4' => "The card has expired.", + '5' => "The card was declined.", + '12' => "The card was declined.", + '6' => "An error occurred while processing the card.", + '7' => "An error occurred while processing the card.", + '10' => "An error occurred while processing the card.", + '9' => "Must be greater than or equal 0.", + '13' => "The amount was partially approved.", + '14' => "The pin is invalid.", + ); } From a6eab219117e961adf1a8ed766869d2b6686a073 Mon Sep 17 00:00:00 2001 From: securesubmit-buildmaster Date: Mon, 17 Feb 2020 15:52:00 -0500 Subject: [PATCH 02/57] change-decline-handling --- src/Gateways/AbstractGateway.php | 64 +------------------ src/Gateways/HeartlandGateway.php | 101 ++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 62 deletions(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 205f277..1d4c7a7 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -545,8 +545,8 @@ protected function submit_request( Requests\RequestInterface $request ) { protected function handle_response( Requests\RequestInterface $request, Transaction $response ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName if ( '00' !== $response->responseCode ) { - global $woocommerce; - $decline_message = $this->decline_message[$response->responseCode]; + $woocommerce = WC(); + $decline_message = $this->get_decline_message($response->responseCode); if (function_exists('wc_add_notice')) { wc_add_notice($decline_message, 'error'); @@ -580,64 +580,4 @@ protected function handle_response( Requests\RequestInterface $request, Transact protected function is_transaction_active( TransactionSummary $details ) { return false; } - - /** - * string Key = gateway response codes for declined transaction attempts; - * string Value = customer-facing messages for each decline code - */ - public $decline_message = array( - '02' => "The card was declined.", - '03' => "The card was declined.", - '04' => "The card was declined.", - '05' => "The card was declined.", - '41' => "The card was declined.", - '43' => "The card was declined.", - '44' => "The card was declined.", - '51' => "The card was declined.", - '56' => "The card was declined.", - '61' => "The card was declined.", - '62' => "The card was declined.", - '63' => "The card was declined.", - '65' => "The card was declined.", - '78' => "The card was declined.", - '06' => "An error occurred while processing the card.", - '07' => "An error occurred while processing the card.", - '12' => "An error occurred while processing the card.", - '15' => "An error occurred while processing the card.", - '19' => "An error occurred while processing the card.", - '52' => "An error occurred while processing the card.", - '53' => "An error occurred while processing the card.", - '57' => "An error occurred while processing the card.", - '58' => "An error occurred while processing the card.", - '76' => "An error occurred while processing the card.", - '77' => "An error occurred while processing the card.", - '96' => "An error occurred while processing the card.", - 'EC' => "An error occurred while processing the card.", - '13' => "Must be greater than or equal 0.", - '14' => "The card number is incorrect.", - '54' => "The card has expired.", - '55' => "The pin is invalid.", - '75' => "Maximum number of pin retries exceeded.", - '80' => "Card expiration date is invalid.", - '86' => "Can't verify card pin number.", - '91' => "The card issuer timed-out.", - 'EB' => "The card's security code is incorrect.", - 'N7' => "The card's security code is incorrect.", - 'FR' => "Possible fraud detected", - // gift card declines - '1' => "An unknown gift error has occurred.", - '2' => "An unknown gift error has occurred.", - '11' => "An unknown gift error has occurred.", - '3' => "The card data is invalid.", - '8' => "The card data is invalid.", - '4' => "The card has expired.", - '5' => "The card was declined.", - '12' => "The card was declined.", - '6' => "An error occurred while processing the card.", - '7' => "An error occurred while processing the card.", - '10' => "An error occurred while processing the card.", - '9' => "Must be greater than or equal 0.", - '13' => "The amount was partially approved.", - '14' => "The pin is invalid.", - ); } diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index 4d62935..e5bedb1 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -71,4 +71,105 @@ protected function is_transaction_active( TransactionSummary $details ) { // @phpcs:ignore WordPress.NamingConventions.ValidVariableName return 'A' === $details->transactionStatus; } + + /** + * returns decline message for display to customer + * + * @param string $response_code + * + * @return string + */ + public function get_decline_message( string $response_code ) { + switch ($response_code) { + case '02': + case '03': + case '04': + case '05': + case '41': + case '43': + case '44': + case '51': + case '56': + case '61': + case '62': + case '62': + case '63': + case '65': + case '78': + return 'The card was declined.'; + case '06': + case '07': + case '12': + case '15': + case '19': + case '52': + case '53': + case '57': + case '58': + case '76': + case '77': + case '96': + case 'EC': + return 'An error occured while processing the card.'; + case '13': + return 'Must be greater than or equal 0.'; + case '14': + return 'The card number is incorrect.'; + case '54': + return 'The card has expired.'; + case '55': + return 'The pin is invalid.'; + case '75': + return 'Maximum number of pin retries exceeded.'; + case '80': + return 'Card expiration date is invalid.'; + case '86': + return 'Can\'t verify card pin number.'; + case '91': + return 'The card issuer timed-out.'; + case 'EB': + case 'N7': + return 'The card\'s security code is incorrect.'; + case 'FR': + return 'Possible fraud detected.'; + default: + return 'An error occurred while processing the card.'; + } + } + + /** + * returns gift-specific decline message for display to customer + * + * @param string $response_code + * + * @return string + */ + public function get_gift_decline_message( string $response_code ) { + switch ($response_code) { + case '1': + case '2': + case '11': + return 'An unknown gift error has occurred.'; + case '3': + case '8': + return 'The card data is invalid.'; + case '4': + return 'The card has expired.'; + case '5': + case '12': + return 'The card was declined.'; + case '6': + case '7': + case '10': + return 'An error occurred while processing this card.'; + case '9': + return 'Must be greater than or equal 0.'; + case '13': + return 'The amount was partially approved.'; + case '14': + return 'The pin is invalid'; + default: + return 'An error occurred while processing the gift card.'; + } + } } From b571f89bce8c618a1daa23c59efecbd6b347a428 Mon Sep 17 00:00:00 2001 From: securesubmit-buildmaster Date: Tue, 10 Mar 2020 12:43:41 -0400 Subject: [PATCH 03/57] ++ default decline methods --- src/Gateways/AbstractGateway.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 1d4c7a7..aa34a24 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -580,4 +580,22 @@ protected function handle_response( Requests\RequestInterface $request, Transact protected function is_transaction_active( TransactionSummary $details ) { return false; } + + /** + * Should be overridden by each gateway implementation + * + * @return string + */ + public function get_decline_message() { + return 'An error occurred while processing the gift card.'; + } + + /** + * Should be overridden by each gateway implementation + * + * @return string + */ + public function get_gift_decline_message() { + return 'An error occurred while processing the gift card.'; + } } From c38c04c12b015dba35e5148ea4b89679d54b6256 Mon Sep 17 00:00:00 2001 From: Mark Anthony Smedal Jr Date: Fri, 17 Apr 2020 20:57:48 -0400 Subject: [PATCH 04/57] gc_fields_show;gc_sends_to_backend;minor_fixes --- assets/frontend/css/heartland-gift-cards.css | 27 + src/Gateways/AbstractGateway.php | 6 +- src/Gateways/HMS-fields.php | 78 +++ src/Gateways/HeartlandGateway.php | 32 ++ ...lass-wc-gateway-securesubmit-giftcards.php | 478 ++++++++++++++++++ src/Plugin.php | 7 + 6 files changed, 625 insertions(+), 3 deletions(-) create mode 100644 assets/frontend/css/heartland-gift-cards.css create mode 100644 src/Gateways/HMS-fields.php create mode 100644 src/Gateways/class-wc-gateway-securesubmit-giftcards.php diff --git a/assets/frontend/css/heartland-gift-cards.css b/assets/frontend/css/heartland-gift-cards.css new file mode 100644 index 0000000..ac0473c --- /dev/null +++ b/assets/frontend/css/heartland-gift-cards.css @@ -0,0 +1,27 @@ +#gift-card-label { + display: table-row; + text-transform: uppercase; + font-size: 13px; + letter-spacing: 1px; + white-space: nowrap; +} + +#gift-card-input { + display: table-cell; + position: relative; + width: 100%; +} + +#apply-gift-card { + display: table-cell; + white-space: nowrap; + margin-left: 1em; +} + +#gift-card-number { + width: 70%; +} + +#gift-card-pin { + width: 26%; +} diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index aa34a24..95e2134 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -278,7 +278,7 @@ public function init_form_fields() { 'title' => __( 'Enable/Disable', 'globalpayments-gateway-provider-for-woocommerce' ), 'type' => 'checkbox', 'label' => __( 'Enable Gateway', 'globalpayments-gateway-provider-for-woocommerce' ), - 'default' => 'yes', + 'default' => 'no', ), 'title' => array( 'title' => __( 'Title', 'globalpayments-gateway-provider-for-woocommerce' ), @@ -586,7 +586,7 @@ protected function is_transaction_active( TransactionSummary $details ) { * * @return string */ - public function get_decline_message() { + public function get_decline_message( string $response_code ) { return 'An error occurred while processing the gift card.'; } @@ -595,7 +595,7 @@ public function get_decline_message() { * * @return string */ - public function get_gift_decline_message() { + public function get_gift_decline_message( string $response_code ) { return 'An error occurred while processing the gift card.'; } } diff --git a/src/Gateways/HMS-fields.php b/src/Gateways/HMS-fields.php new file mode 100644 index 0000000..7646ccb --- /dev/null +++ b/src/Gateways/HMS-fields.php @@ -0,0 +1,78 @@ + +
+ +
+
+ +
+ + +

+

+
+ +'; + $html .= 'if( typeof ajaxurl === "undefined") { '; + $html .= 'var ajaxurl = "' . admin_url('admin-ajax.php') . '";'; + $html .= '}'; + $html .= ''; + + echo $html; +?> + + +
+
+
+ +
+ \ No newline at end of file diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index e5bedb1..296fc1c 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -28,6 +28,13 @@ class HeartlandGateway extends AbstractGateway { */ public $secret_key; + /** + * Allows payment via Heartland Marketing Solutions (gift cards) + * + * @var bool + */ + public $allow_gift_cards; + public function configure_method_settings() { $this->id = 'globalpayments_heartland'; $this->method_title = __( 'Heartland', 'globalpayments-gateway-provider-for-woocommerce' ); @@ -51,6 +58,15 @@ public function get_gateway_form_fields() { 'type' => 'text', 'description' => __( 'Get your API keys from your Heartland Online Payments account.', 'globalpayments-gateway-provider-for-woocommerce' ), 'default' => '', + ), + 'allow_gift_cards' => array( + 'title' => __( 'Enable Gift Cards', 'globalpayments-gateway-provider-for-woocommerce' ), + 'label' => __( 'Allow customers to use gift cards to pay for purchases in full or in part.', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'checkbox', + 'description' => sprintf( + __( 'This will display a gift card entry field directly below the credit card entry area.' ) + ), + 'default' => 'no' ), ); } @@ -172,4 +188,20 @@ public function get_gift_decline_message( string $response_code ) { return 'An error occurred while processing the gift card.'; } } + + /** + * Adds Heartland gift card fields + */ + public function payment_fields() { + parent::payment_fields(); + + if ( $this->allow_gift_cards === true ) { + include_once 'wp-content\plugins\globalpayments-gateway-provider-for-woocommerce\src\Gateways\HMS-fields.php'; + + // wp_enqueue_script('test', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/js/test.js', array('jquery'), false, true); + + // SecureSubmit custom CSS + wp_enqueue_style('heartland-gift-cards', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/css/heartland-gift-cards.css'); + } + } } diff --git a/src/Gateways/class-wc-gateway-securesubmit-giftcards.php b/src/Gateways/class-wc-gateway-securesubmit-giftcards.php new file mode 100644 index 0000000..def98c7 --- /dev/null +++ b/src/Gateways/class-wc-gateway-securesubmit-giftcards.php @@ -0,0 +1,478 @@ +allow_gift_cards) { + $title = $this->gift_card_title; + } + + return $title; + } + + // public function update_gateway_description_checkout($description, $id) + // { + // if ($id === 'securesubmit' && $this->getSetting('gift_cards') === 'yes') { + // $description = $this->getSetting('gift_cards_gateway_description'); + // } + + // return $description; + // } + + public function set_ajax_url() + { + // if ((is_checkout() || is_cart()) && $this->getSetting('gift_cards') === 'yes') { + $html = ''; + + // echo $html; + // } + } + + public function applyGiftCard() + { + $this->gift_card_submitted = $_POST['gift_card_number']; + $this->gift_card_pin_submitted = $_POST['gift_card_pin']; + $gift_card_balance = $this->gift_card_balance( + $this->gift_card_submitted, + $this->gift_card_pin_submitted + ); + + if ($gift_card_balance['error']) { + echo json_encode(array( + 'error' => 1, + 'message' => $gift_card_balance['message'], + )); + } else { + $this->gift_card->temp_balance = $gift_card_balance['message']; + + $this->addGiftCardToCartSession(); + $this->updateGiftCardCartTotal(); + echo json_encode(array( + 'error' => 0, + 'balance' => html_entity_decode(get_woocommerce_currency_symbol()) . $gift_card_balance['message'], + )); + } + + wp_die(); + } + + protected function updateGiftCardCartTotal() + { + $gift_card_object_entered = WC()->session->get('securesubmit_gift_card_object'); + if (is_null($gift_card_object_entered)) { + $gift_card_object_entered = (object)array(); + } + + $gift_card_object_applied = WC()->session->get('securesubmit_gift_card_applied'); + if (is_null($gift_card_object_applied)) { + $gift_card_object_applied = (object)array(); + } + + $original_total = $this->getOriginalCartTotal(); + + $securesubmit_data = WC()->session->get('securesubmit_data'); + if (!is_object($securesubmit_data)) { + $securesubmit_data = new stdClass; + } + + $securesubmit_data->original_total = $original_total; + WC()->session->set('securesubmit_data', $securesubmit_data); + + $this->updateGiftCardTotals(); + + if (is_object($gift_card_object_entered) && count(get_object_vars($gift_card_object_entered)) > 0) { + if ($gift_card_object_entered->temp_balance === '0.00') { + WC()->session->__unset('securesubmit_gift_card_object'); + + $zero_balance_message = apply_filters( + 'securesubmit_zero_balance_message', + sprintf( + __('%s has a balance of zero and could not be applied to this order.', 'wc_securesubmit'), + $gift_card_object_entered->gift_card_name + ) + ); + + wc_add_notice($zero_balance_message, 'error'); + } else { + if (!(is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0)) { + $gift_card_object_applied = new stdClass; + } + + $gift_card_object_entered->used_amount = $this->giftCardUsageAmount(); + $gift_card_object_applied->{$gift_card_object_entered->gift_card_id} = $gift_card_object_entered; + + WC()->session->set('securesubmit_gift_card_applied', $gift_card_object_applied); + WC()->session->__unset('securesubmit_gift_card_object'); + } + } + + return $gift_card_object_applied; + } + + public function addGiftCards() + { + // TODO: Add warnings and success messages + $gift_cards_allowed = $this->giftCardsAllowed(); + + // No gift cards if there are subscription products in the cart + if ($gift_cards_allowed) { + $original_total = $this->getOriginalCartTotal(); + $gift_card_object_applied = $this->updateGiftCardCartTotal(); + + if (is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0) { + $securesubmit_data = WC()->session->get('securesubmit_data'); + $securesubmit_data->original_total = $original_total; + WC()->session->set('securesubmit_data', $securesubmit_data); + + $message = __( 'Total Before Gift Cards', 'wc_securesubmit' ); + + $order_total_html = ''; + $order_total_html .= '' . $message . ''; + $order_total_html .= '' . wc_price($original_total) . ''; + $order_total_html .= ''; + + echo apply_filters('securesubmit_before_gift_cards_order_total', $order_total_html, $original_total, $message); + + foreach ($gift_card_object_applied as $applied_gift_card) { + $remove_link = '(Remove)'; + + $gift_card_html = ''; + $gift_card_html .= '' . $applied_gift_card->gift_card_name . ' ' . $remove_link . ''; + $gift_card_html .= '' . wc_price($applied_gift_card->used_amount) . ''; + $gift_card_html .= ''; + + echo apply_filters('securesubmit_gift_card_used_total', $gift_card_html, $applied_gift_card->gift_card_name, $remove_link, $applied_gift_card->used_amount); + } + } + } else { + $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); + + $this->removeAllGiftCardsFromSession(); + + if (is_object($applied_cards) && count(get_object_vars($applied_cards)) > 0) { + wc_add_notice(__('Sorry, we are unable to allow gift cards to be used when purchasing a subscription. Any gift cards already applied to the order have been cleared', 'wc_securesubmit'), 'notice'); + } + } + } + + public function removeGiftCard($removed_card = null) + { + if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { + $removed_card = $_POST['securesubmit_card_id']; + } + + $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); + + unset($applied_cards->{$removed_card}); + + if (count((array) $applied_cards) > 0) { + WC()->session->set('securesubmit_gift_card_applied', $applied_cards); + } else { + WC()->session->__unset('securesubmit_gift_card_applied'); + } + + if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { + echo ''; + wp_die(); + } + } + + public function removeGiftCardCode() + { + if ((is_cart() || is_checkout()) && $this->allow_gift_cards) { + wp_enqueue_script( + 'woocommerce_securesubmit_removegiftcard', + plugins_url('assets/js/removegiftcard.js', dirname(__FILE__)), + array('jquery'), + '1.0', + true + ); + } + } + + public function updateOrderTotal($cart_total, $cart_object) + { + $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); + + if (is_object($gift_cards) && count(get_object_vars($gift_cards)) > 0) { + $gift_card_totals = $this->getGiftCardTotals(); + $cart_total = $cart_total + $gift_card_totals; + } + + return $cart_total; + } + + public function removeAllGiftCardsFromSession() + { + WC()->session->__unset('securesubmit_gift_card_applied'); + WC()->session->__unset('securesubmit_gift_card_object'); + WC()->session->__unset('securesubmit_data'); + } + + public function processGiftCardSale($card_number, $card_pin, $used_amount) + { + $card = $this->giftCardObject($card_number, $card_pin); + $rounded_amount = round($used_amount, 2); + $positive_amount = abs($rounded_amount); + + try { + $response = $this->giftCardService()->sale() + ->withCard($card) + ->withAmount($positive_amount) + ->withCurrency('usd') + ->execute(); + } catch (HpsException $e) { + return $e; + } + + return $response; + } + + public function processGiftCardVoid($processed_cards, $order_id) + { + if (!empty($processed_cards)) { + foreach ($processed_cards as $card_id => $card) { + try { + $response = $this->giftCardService()->void($card->transaction_id) + ->execute(); + } catch (Exception $e) { + } + + if (isset($response->responseCode) && $response->responseCode === '0') { + unset($processed_cards[$card_id]); + } + } + } else { + $response = false; + delete_post_meta($order_id, '_securesubmit_used_card_data'); + } + + return $response; + } + + public function gift_card_balance($gift_card_number, $gift_card_pin) + { + if (empty($gift_card_pin)) { + return array( + 'error' => true, + 'message' => "PINs are required. Please enter a PIN and click apply again.", + ); + } + + $this->gift_card = $this->giftCardObject($gift_card_number, $gift_card_pin); + + try { + $response = $this->giftCardService()->balance() + ->withCard($this->gift_card) + ->execute(); + } catch (HpsException $e) { + return array( + 'error' => true, + 'message' => "The gift card number you entered is either incorrect or not yet activated.", + ); + } + + wc_clear_notices(); + + return array( + 'error' => false, + 'message' => $response->balanceAmount, + ); + } + + public function giftCardsAllowed() + { + $subscriptions_active = $this->subscriptionsActive(); + + if ($subscriptions_active) { + if (!empty($_GET['change_payment_method'])) { + $subscription = new WC_Subscription($_GET['change_payment_method']); + if (!empty($subscription) && (false !== strpos($subscription->order_type, 'subscription'))) { + return false; + } + } else { + return ($this->cartHasSubscriptionProducts()) ? false : true; + } + } + + return true; + } + + protected function subscriptionsActive() + { + if (class_exists('WC_Subscriptions')) { + return true; + } + + return false; + } + + protected function cartHasSubscriptionProducts() + { + $cart = WC()->cart->get_cart(); + + foreach ($cart as $cart_item) { + $productType = WC_SecureSubmit_Util::getData($cart_item['data'], 'get_type', 'product_type'); + $subscription_position = strpos($productType, 'subscription'); + + if ($subscription_position !== false) { + return true; + } + } + + return false; + } + + protected function updateGiftCardTotals() + { + $gift_cards_applied = WC()->session->get('securesubmit_gift_card_applied'); + $securesubmit_data = WC()->session->get('securesubmit_data'); + + $original_total = $this->getOriginalCartTotal(); + $remaining_total = $original_total; + + if (is_object($gift_cards_applied) && count(get_object_vars($gift_cards_applied)) > 0) { + foreach ($gift_cards_applied as $gift_card) { + $order_total_after_gift_card = $remaining_total - $gift_card->temp_balance; + + if ($order_total_after_gift_card > 0) { + $gift_card->used_amount = $gift_card->temp_balance; + } else { + $gift_card->used_amount = $remaining_total; + } + + $gift_cards_applied->{$gift_card->gift_card_id} = $gift_card; + $remaining_total = $remaining_total - $gift_card->used_amount; + } + } + + WC()->session->set('securesubmit_gift_card_applied', $gift_cards_applied); + } + + protected function getGiftCardTotals() + { + $this->updateGiftCardTotals(); + + $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); + + if (!empty($gift_cards)) { + $total = 0; + + foreach ($gift_cards as $gift_card) { + $total -= $gift_card->used_amount; + } + + return $total; + } + } + + protected function giftCardUsageAmount($updated = false) + { + if ($updated) { + $cart_total = $this->getTotalMinusSecureSubmitGiftCards(); + $gift_card_object = $this->applied_gift_card; + } else { + $cart_totals = WC()->session->get('cart_totals'); + $cart_total = round($cart_totals['total'], 2); + $gift_card_object = WC()->session->get('securesubmit_gift_card_object'); + } + + if (round($gift_card_object->temp_balance, 2) <= $cart_total) { + $gift_card_applied_amount = $gift_card_object->temp_balance; + } else { + $gift_card_applied_amount = $cart_total; + } + + return $gift_card_applied_amount; + } + + protected function giftCardName($gift_card_number) + { + $digits_to_display = 5; + $last_digits = substr($gift_card_number, $digits_to_display * - 1); + + return __( 'Gift Card', 'wc_securesubmit' ) . ' ' . $last_digits; + } + + protected function convertToNegativeAmount($amount) + { + if ($amount > 0) { + return $amount * - 1; + } + + return $amount; + } + + protected function addGiftCardToCartSession() + { + $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); + $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); + $this->gift_card->pin = $this->gift_card_pin_submitted; + + WC()->session->set('securesubmit_gift_card_object', $this->gift_card); + } + + protected function getCartDiscountTotal() + { + return WC()->cart->get_cart_discount_total(); + } + + protected function giftCardService() + { + $config = new HpsServicesConfig(); + $config->secretApiKey = $this->secret_key; + $config->versionNumber = '1510'; + $config->developerId = '002914'; + + return new HpsFluentGiftCardService($config); + } + + protected function giftCardObject($gift_card_number, $gift_card_pin) + { + $gift_card = new HpsGiftCard(); + $gift_card->number = $gift_card_number; + $gift_card->pin = $gift_card_pin; + + return $gift_card; + } + + protected function getOriginalCartTotal() + { + $cart_totals = WC()->session->get('cart_totals'); + $original_total = round( + array_sum( + array( + (!empty($cart_totals['subtotal']) ? $cart_totals['subtotal'] : 0), + (!empty($cart_totals['subtotal_tax']) ? $cart_totals['subtotal_tax'] : 0), + (!empty($cart_totals['shipping_total']) ? $cart_totals['shipping_total'] : 0), + (!empty($cart_totals['shipping_tax']) ? $cart_totals['shipping_tax'] : 0), + (!empty($cart_totals['fee_total']) ? $cart_totals['fee_total'] : 0), + (!empty($cart_totals['fee_tax']) ? $cart_totals['fee_tax'] : 0), + ) + ), + 2 + ); + return $original_total; + } +} diff --git a/src/Plugin.php b/src/Plugin.php index 66beaf0..89b5d47 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -18,6 +18,10 @@ class Plugin { */ const VERSION = '1.0.0'; + public static function do_a_barrell_roll() { + echo "please get here"; // it gets here now + } + /** * Init the package. */ @@ -28,6 +32,9 @@ public static function init() { return; } + add_action('wp_ajax_nopriv_use_gift_card', array(self::class, 'do_a_barrell_roll')); // dice? + add_action('wp_ajax_use_gift_card', array(self::class, 'do_a_barrell_roll')); // dice? + add_filter( 'woocommerce_payment_gateways', array( self::class, 'add_gateways' ) ); } From 01381d4c86d37eb53adb944801ff506f7460dba5 Mon Sep 17 00:00:00 2001 From: Mark Anthony Smedal Jr Date: Sat, 23 May 2020 12:32:18 -0400 Subject: [PATCH 05/57] solution-pure_jank --- src/Gateways/HMS-fields.php | 36 +- src/Gateways/HeartlandGateway.php | 64 +- ...giftcards.php => HeartlandGatewayGift.php} | 883 ++++++++---------- src/Gateways/gc.php | 149 +++ src/Gateways/gcOrder.php | 173 ++++ src/Plugin.php | 26 +- 6 files changed, 807 insertions(+), 524 deletions(-) rename src/Gateways/{class-wc-gateway-securesubmit-giftcards.php => HeartlandGatewayGift.php} (67%) create mode 100644 src/Gateways/gc.php create mode 100644 src/Gateways/gcOrder.php diff --git a/src/Gateways/HMS-fields.php b/src/Gateways/HMS-fields.php index 7646ccb..0a48055 100644 --- a/src/Gateways/HMS-fields.php +++ b/src/Gateways/HMS-fields.php @@ -1,6 +1,6 @@
@@ -62,13 +62,41 @@ function applyGiftCard () { // }); // httpRequest.send('action=use_gift_card&gift_card_number=5022440000000000098&gift_card_pin=1234'); httpRequest.send(post_string); + jQuery('body').trigger('update_checkout'); + alert(httpRequest.response); - httpRequest.onreadystatechange = function(){ - console.log('oh shit son I got a response back'); - }; + // httpRequest.response = function(){ + // alert('maybe') + // }; }; + jQuery(document).on( 'click', '.securesubmit-remove-gift-card', function (event) { + event.preventDefault(); + + var removedCardID = jQuery(this).attr('id'); + + jQuery.ajax({ + url: ajaxurl, + type: "POST", + data: { + action: 'remove_gift_card', + securesubmit_card_id: removedCardID + } + }).done(function () { + + jQuery('body').trigger('update_checkout'); + jQuery(".button[name='update_cart']") + .prop("disabled", false) + .trigger("click"); + + }); + }); + + function processGiftCardResponse () { + + } +
diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index 296fc1c..d25807d 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -4,6 +4,8 @@ use GlobalPayments\Api\Entities\Enums\GatewayProvider; use GlobalPayments\Api\Entities\Reporting\TransactionSummary; +use WC_Order; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gcOrder; defined( 'ABSPATH' ) || exit; @@ -153,42 +155,6 @@ public function get_decline_message( string $response_code ) { } } - /** - * returns gift-specific decline message for display to customer - * - * @param string $response_code - * - * @return string - */ - public function get_gift_decline_message( string $response_code ) { - switch ($response_code) { - case '1': - case '2': - case '11': - return 'An unknown gift error has occurred.'; - case '3': - case '8': - return 'The card data is invalid.'; - case '4': - return 'The card has expired.'; - case '5': - case '12': - return 'The card was declined.'; - case '6': - case '7': - case '10': - return 'An error occurred while processing this card.'; - case '9': - return 'Must be greater than or equal 0.'; - case '13': - return 'The amount was partially approved.'; - case '14': - return 'The pin is invalid'; - default: - return 'An error occurred while processing the gift card.'; - } - } - /** * Adds Heartland gift card fields */ @@ -204,4 +170,30 @@ public function payment_fields() { wp_enqueue_style('heartland-gift-cards', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/css/heartland-gift-cards.css'); } } + + /** + * Handle payment functions /-/override parent to add gift card functionality + * + * @param int $order_id + * + * @return array + * + */ + public function process_payment( $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 ); + + $session_applied_gift_card = WC()->session->get('securesubmit_gift_card_applied'); + if (!empty($session_applied_gift_card)) { + $gift_card_order_placement = new gcOrder(); + $gift_card_order_placement->processGiftCardPayment($order_id); + } + + return array( + 'result' => $is_successful ? 'success' : 'failure', + 'redirect' => $is_successful ? $this->get_return_url( $order ) : false, + ); + } } diff --git a/src/Gateways/class-wc-gateway-securesubmit-giftcards.php b/src/Gateways/HeartlandGatewayGift.php similarity index 67% rename from src/Gateways/class-wc-gateway-securesubmit-giftcards.php rename to src/Gateways/HeartlandGatewayGift.php index def98c7..5b490c4 100644 --- a/src/Gateways/class-wc-gateway-securesubmit-giftcards.php +++ b/src/Gateways/HeartlandGatewayGift.php @@ -1,478 +1,405 @@ -allow_gift_cards) { - $title = $this->gift_card_title; - } - - return $title; - } - - // public function update_gateway_description_checkout($description, $id) - // { - // if ($id === 'securesubmit' && $this->getSetting('gift_cards') === 'yes') { - // $description = $this->getSetting('gift_cards_gateway_description'); - // } - - // return $description; - // } - - public function set_ajax_url() - { - // if ((is_checkout() || is_cart()) && $this->getSetting('gift_cards') === 'yes') { - $html = ''; - - // echo $html; - // } - } - - public function applyGiftCard() - { - $this->gift_card_submitted = $_POST['gift_card_number']; - $this->gift_card_pin_submitted = $_POST['gift_card_pin']; - $gift_card_balance = $this->gift_card_balance( - $this->gift_card_submitted, - $this->gift_card_pin_submitted - ); - - if ($gift_card_balance['error']) { - echo json_encode(array( - 'error' => 1, - 'message' => $gift_card_balance['message'], - )); - } else { - $this->gift_card->temp_balance = $gift_card_balance['message']; - - $this->addGiftCardToCartSession(); - $this->updateGiftCardCartTotal(); - echo json_encode(array( - 'error' => 0, - 'balance' => html_entity_decode(get_woocommerce_currency_symbol()) . $gift_card_balance['message'], - )); - } - - wp_die(); - } - - protected function updateGiftCardCartTotal() - { - $gift_card_object_entered = WC()->session->get('securesubmit_gift_card_object'); - if (is_null($gift_card_object_entered)) { - $gift_card_object_entered = (object)array(); - } - - $gift_card_object_applied = WC()->session->get('securesubmit_gift_card_applied'); - if (is_null($gift_card_object_applied)) { - $gift_card_object_applied = (object)array(); - } - - $original_total = $this->getOriginalCartTotal(); - - $securesubmit_data = WC()->session->get('securesubmit_data'); - if (!is_object($securesubmit_data)) { - $securesubmit_data = new stdClass; - } - - $securesubmit_data->original_total = $original_total; - WC()->session->set('securesubmit_data', $securesubmit_data); - - $this->updateGiftCardTotals(); - - if (is_object($gift_card_object_entered) && count(get_object_vars($gift_card_object_entered)) > 0) { - if ($gift_card_object_entered->temp_balance === '0.00') { - WC()->session->__unset('securesubmit_gift_card_object'); - - $zero_balance_message = apply_filters( - 'securesubmit_zero_balance_message', - sprintf( - __('%s has a balance of zero and could not be applied to this order.', 'wc_securesubmit'), - $gift_card_object_entered->gift_card_name - ) - ); - - wc_add_notice($zero_balance_message, 'error'); - } else { - if (!(is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0)) { - $gift_card_object_applied = new stdClass; - } - - $gift_card_object_entered->used_amount = $this->giftCardUsageAmount(); - $gift_card_object_applied->{$gift_card_object_entered->gift_card_id} = $gift_card_object_entered; - - WC()->session->set('securesubmit_gift_card_applied', $gift_card_object_applied); - WC()->session->__unset('securesubmit_gift_card_object'); - } - } - - return $gift_card_object_applied; - } - - public function addGiftCards() - { - // TODO: Add warnings and success messages - $gift_cards_allowed = $this->giftCardsAllowed(); - - // No gift cards if there are subscription products in the cart - if ($gift_cards_allowed) { - $original_total = $this->getOriginalCartTotal(); - $gift_card_object_applied = $this->updateGiftCardCartTotal(); - - if (is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0) { - $securesubmit_data = WC()->session->get('securesubmit_data'); - $securesubmit_data->original_total = $original_total; - WC()->session->set('securesubmit_data', $securesubmit_data); - - $message = __( 'Total Before Gift Cards', 'wc_securesubmit' ); - - $order_total_html = ''; - $order_total_html .= '' . $message . ''; - $order_total_html .= '' . wc_price($original_total) . ''; - $order_total_html .= ''; - - echo apply_filters('securesubmit_before_gift_cards_order_total', $order_total_html, $original_total, $message); - - foreach ($gift_card_object_applied as $applied_gift_card) { - $remove_link = '(Remove)'; - - $gift_card_html = ''; - $gift_card_html .= '' . $applied_gift_card->gift_card_name . ' ' . $remove_link . ''; - $gift_card_html .= '' . wc_price($applied_gift_card->used_amount) . ''; - $gift_card_html .= ''; - - echo apply_filters('securesubmit_gift_card_used_total', $gift_card_html, $applied_gift_card->gift_card_name, $remove_link, $applied_gift_card->used_amount); - } - } - } else { - $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); - - $this->removeAllGiftCardsFromSession(); - - if (is_object($applied_cards) && count(get_object_vars($applied_cards)) > 0) { - wc_add_notice(__('Sorry, we are unable to allow gift cards to be used when purchasing a subscription. Any gift cards already applied to the order have been cleared', 'wc_securesubmit'), 'notice'); - } - } - } - - public function removeGiftCard($removed_card = null) - { - if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { - $removed_card = $_POST['securesubmit_card_id']; - } - - $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); - - unset($applied_cards->{$removed_card}); - - if (count((array) $applied_cards) > 0) { - WC()->session->set('securesubmit_gift_card_applied', $applied_cards); - } else { - WC()->session->__unset('securesubmit_gift_card_applied'); - } - - if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { - echo ''; - wp_die(); - } - } - - public function removeGiftCardCode() - { - if ((is_cart() || is_checkout()) && $this->allow_gift_cards) { - wp_enqueue_script( - 'woocommerce_securesubmit_removegiftcard', - plugins_url('assets/js/removegiftcard.js', dirname(__FILE__)), - array('jquery'), - '1.0', - true - ); - } - } - - public function updateOrderTotal($cart_total, $cart_object) - { - $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); - - if (is_object($gift_cards) && count(get_object_vars($gift_cards)) > 0) { - $gift_card_totals = $this->getGiftCardTotals(); - $cart_total = $cart_total + $gift_card_totals; - } - - return $cart_total; - } - - public function removeAllGiftCardsFromSession() - { - WC()->session->__unset('securesubmit_gift_card_applied'); - WC()->session->__unset('securesubmit_gift_card_object'); - WC()->session->__unset('securesubmit_data'); - } - - public function processGiftCardSale($card_number, $card_pin, $used_amount) - { - $card = $this->giftCardObject($card_number, $card_pin); - $rounded_amount = round($used_amount, 2); - $positive_amount = abs($rounded_amount); - - try { - $response = $this->giftCardService()->sale() - ->withCard($card) - ->withAmount($positive_amount) - ->withCurrency('usd') - ->execute(); - } catch (HpsException $e) { - return $e; - } - - return $response; - } - - public function processGiftCardVoid($processed_cards, $order_id) - { - if (!empty($processed_cards)) { - foreach ($processed_cards as $card_id => $card) { - try { - $response = $this->giftCardService()->void($card->transaction_id) - ->execute(); - } catch (Exception $e) { - } - - if (isset($response->responseCode) && $response->responseCode === '0') { - unset($processed_cards[$card_id]); - } - } - } else { - $response = false; - delete_post_meta($order_id, '_securesubmit_used_card_data'); - } - - return $response; - } - - public function gift_card_balance($gift_card_number, $gift_card_pin) - { - if (empty($gift_card_pin)) { - return array( - 'error' => true, - 'message' => "PINs are required. Please enter a PIN and click apply again.", - ); - } - - $this->gift_card = $this->giftCardObject($gift_card_number, $gift_card_pin); - - try { - $response = $this->giftCardService()->balance() - ->withCard($this->gift_card) - ->execute(); - } catch (HpsException $e) { - return array( - 'error' => true, - 'message' => "The gift card number you entered is either incorrect or not yet activated.", - ); - } - - wc_clear_notices(); - - return array( - 'error' => false, - 'message' => $response->balanceAmount, - ); - } - - public function giftCardsAllowed() - { - $subscriptions_active = $this->subscriptionsActive(); - - if ($subscriptions_active) { - if (!empty($_GET['change_payment_method'])) { - $subscription = new WC_Subscription($_GET['change_payment_method']); - if (!empty($subscription) && (false !== strpos($subscription->order_type, 'subscription'))) { - return false; - } - } else { - return ($this->cartHasSubscriptionProducts()) ? false : true; - } - } - - return true; - } - - protected function subscriptionsActive() - { - if (class_exists('WC_Subscriptions')) { - return true; - } - - return false; - } - - protected function cartHasSubscriptionProducts() - { - $cart = WC()->cart->get_cart(); - - foreach ($cart as $cart_item) { - $productType = WC_SecureSubmit_Util::getData($cart_item['data'], 'get_type', 'product_type'); - $subscription_position = strpos($productType, 'subscription'); - - if ($subscription_position !== false) { - return true; - } - } - - return false; - } - - protected function updateGiftCardTotals() - { - $gift_cards_applied = WC()->session->get('securesubmit_gift_card_applied'); - $securesubmit_data = WC()->session->get('securesubmit_data'); - - $original_total = $this->getOriginalCartTotal(); - $remaining_total = $original_total; - - if (is_object($gift_cards_applied) && count(get_object_vars($gift_cards_applied)) > 0) { - foreach ($gift_cards_applied as $gift_card) { - $order_total_after_gift_card = $remaining_total - $gift_card->temp_balance; - - if ($order_total_after_gift_card > 0) { - $gift_card->used_amount = $gift_card->temp_balance; - } else { - $gift_card->used_amount = $remaining_total; - } - - $gift_cards_applied->{$gift_card->gift_card_id} = $gift_card; - $remaining_total = $remaining_total - $gift_card->used_amount; - } - } - - WC()->session->set('securesubmit_gift_card_applied', $gift_cards_applied); - } - - protected function getGiftCardTotals() - { - $this->updateGiftCardTotals(); - - $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); - - if (!empty($gift_cards)) { - $total = 0; - - foreach ($gift_cards as $gift_card) { - $total -= $gift_card->used_amount; - } - - return $total; - } - } - - protected function giftCardUsageAmount($updated = false) - { - if ($updated) { - $cart_total = $this->getTotalMinusSecureSubmitGiftCards(); - $gift_card_object = $this->applied_gift_card; - } else { - $cart_totals = WC()->session->get('cart_totals'); - $cart_total = round($cart_totals['total'], 2); - $gift_card_object = WC()->session->get('securesubmit_gift_card_object'); - } - - if (round($gift_card_object->temp_balance, 2) <= $cart_total) { - $gift_card_applied_amount = $gift_card_object->temp_balance; - } else { - $gift_card_applied_amount = $cart_total; - } - - return $gift_card_applied_amount; - } - - protected function giftCardName($gift_card_number) - { - $digits_to_display = 5; - $last_digits = substr($gift_card_number, $digits_to_display * - 1); - - return __( 'Gift Card', 'wc_securesubmit' ) . ' ' . $last_digits; - } - - protected function convertToNegativeAmount($amount) - { - if ($amount > 0) { - return $amount * - 1; - } - - return $amount; - } - - protected function addGiftCardToCartSession() - { - $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); - $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); - $this->gift_card->pin = $this->gift_card_pin_submitted; - - WC()->session->set('securesubmit_gift_card_object', $this->gift_card); - } - - protected function getCartDiscountTotal() - { - return WC()->cart->get_cart_discount_total(); - } - - protected function giftCardService() - { - $config = new HpsServicesConfig(); - $config->secretApiKey = $this->secret_key; - $config->versionNumber = '1510'; - $config->developerId = '002914'; - - return new HpsFluentGiftCardService($config); - } - - protected function giftCardObject($gift_card_number, $gift_card_pin) - { - $gift_card = new HpsGiftCard(); - $gift_card->number = $gift_card_number; - $gift_card->pin = $gift_card_pin; - - return $gift_card; - } - - protected function getOriginalCartTotal() - { - $cart_totals = WC()->session->get('cart_totals'); - $original_total = round( - array_sum( - array( - (!empty($cart_totals['subtotal']) ? $cart_totals['subtotal'] : 0), - (!empty($cart_totals['subtotal_tax']) ? $cart_totals['subtotal_tax'] : 0), - (!empty($cart_totals['shipping_total']) ? $cart_totals['shipping_total'] : 0), - (!empty($cart_totals['shipping_tax']) ? $cart_totals['shipping_tax'] : 0), - (!empty($cart_totals['fee_total']) ? $cart_totals['fee_total'] : 0), - (!empty($cart_totals['fee_tax']) ? $cart_totals['fee_tax'] : 0), - ) - ), - 2 - ); - return $original_total; - } -} +secretApiKey = $this->get_backend_gateway_options()['secretApiKey']; + $config->developerId = "123456"; + $config->versionNumber = "1234"; + + ServicesContainer::configure($config); + } + + /** + * returns gift-specific decline message for display to customer + * + * @param string $response_code + * + * @return string + */ + public function get_gift_decline_message( string $response_code ) { + switch ($response_code) { + case '1': + case '2': + case '11': + return 'An unknown gift error has occurred.'; + case '3': + case '8': + return 'The card data is invalid.'; + case '4': + return 'The card has expired.'; + case '5': + case '12': + return 'The card was declined.'; + case '6': + case '7': + case '10': + return 'An error occurred while processing this card.'; + case '9': + return 'Must be greater than or equal 0.'; + case '13': + return 'The amount was partially approved.'; + case '14': + return 'The pin is invalid'; + default: + return 'An error occurred while processing the gift card.'; + } + } + + /** + * Adds Heartland gift card fields + */ + public function payment_fields() { + parent::payment_fields(); + + if ( $this->allow_gift_cards === true ) { + include_once 'wp-content\plugins\globalpayments-gateway-provider-for-woocommerce\src\Gateways\HMS-fields.php'; + + // wp_enqueue_script('test', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/js/test.js', array('jquery'), false, true); + + // SecureSubmit custom CSS + wp_enqueue_style('heartland-gift-cards', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/css/heartland-gift-cards.css'); + } + } + + // do base gift card stuff + public function applyGiftCard() { + // $this->gift_card_submitted = $_POST['gift_card_number']; + // $this->gift_card_pin_submitted = $_POST['gift_card_pin']; + $gift_card_balance = $this->gift_card_balance( + $_POST['gift_card_number'], + $_POST['gift_card_pin'] + ); + + if ($gift_card_balance['error']) { + echo json_encode(array( + 'error' => 1, + 'message' => $gift_card_balance['message'], + )); + } else { + $this->temp_balance = $gift_card_balance['message']; + + $this->addGiftCardToCartSession(); + $this->updateGiftCardCartTotal(); + echo json_encode(array( + 'error' => 0, + 'balance' => html_entity_decode(get_woocommerce_currency_symbol()) . $gift_card_balance['message'], + )); + } + + wp_die(); + } + + // stolen + public function gift_card_balance($gift_card_number, $gift_card_pin) + { + $this->configureServiceContainer(); + + if (empty($gift_card_pin)) { + return array( + 'error' => true, + 'message' => "PINs are required. Please enter a PIN and click apply again.", + ); + } + + $this->gift_card = $this->giftCardObject($gift_card_number, $gift_card_pin); + + try { + $response = $this->gift_card->balanceInquiry() + ->execute(); // need the service container for this to work + } catch (Exception $e) { + return array( + 'error' => true, + 'message' => "The gift card number you entered is either incorrect or not yet activated.", + ); + } + + // wc_clear_notices(); // I don't know what this does + + return array( + 'error' => false, + 'message' => $response->balanceAmount, + ); + } + + protected function giftCardObject($gift_card_number, $gift_card_pin) + { + $gift_card = new gc(); + $gift_card->number = $gift_card_number; + $gift_card->pin = $gift_card_pin; + + return $gift_card; + } + + protected function addGiftCardToCartSession() + { + $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); + $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); + $this->gift_card->temp_balance = floatval($this->temp_balance); + // $this->gift_card->pin = $this->gift_card_pin; + + WC()->session->set('securesubmit_gift_card_object', $this->gift_card); + } + + protected function giftCardName($gift_card_number) + { + $digits_to_display = 5; + $last_digits = substr($gift_card_number, $digits_to_display * - 1); + + return __( 'Gift Card', 'wc_securesubmit' ) . ' ' . $last_digits; + } + + protected function updateGiftCardCartTotal() + { + $gift_card_object_entered = WC()->session->get('securesubmit_gift_card_object'); + if (is_null($gift_card_object_entered)) { + $gift_card_object_entered = (object)array(); + } + + $gift_card_object_applied = WC()->session->get('securesubmit_gift_card_applied'); + if (is_null($gift_card_object_applied)) { + $gift_card_object_applied = (object)array(); + } + + $original_total = $this->getOriginalCartTotal(); + + $securesubmit_data = WC()->session->get('securesubmit_data'); + if (!is_object($securesubmit_data)) { + $securesubmit_data = new stdClass(); + } + + $securesubmit_data->original_total = $original_total; + WC()->session->set('securesubmit_data', $securesubmit_data); + + $this->updateGiftCardTotals(); + + if (is_object($gift_card_object_entered) && count(get_object_vars($gift_card_object_entered)) > 0) { + if ($gift_card_object_entered->temp_balance === '0.00') { + WC()->session->__unset('securesubmit_gift_card_object'); + + $zero_balance_message = apply_filters( + 'securesubmit_zero_balance_message', + sprintf( + __('%s has a balance of zero and could not be applied to this order.', 'wc_securesubmit'), + $gift_card_object_entered->gift_card_name + ) + ); + + wc_add_notice($zero_balance_message, 'error'); + } else { + if (!(is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0)) { + $gift_card_object_applied = new stdClass; + } + + $gift_card_object_entered->used_amount = $this->giftCardUsageAmount(); + $gift_card_object_applied->{$gift_card_object_entered->gift_card_id} = $gift_card_object_entered; + + WC()->session->set('securesubmit_gift_card_applied', $gift_card_object_applied); + WC()->session->__unset('securesubmit_gift_card_object'); + } + } + + return $gift_card_object_applied; + } + + protected function getOriginalCartTotal() + { + $cart_totals = WC()->session->get('cart_totals'); + $original_total = round( + array_sum( + array( + (!empty($cart_totals['subtotal']) ? $cart_totals['subtotal'] : 0), + (!empty($cart_totals['subtotal_tax']) ? $cart_totals['subtotal_tax'] : 0), + (!empty($cart_totals['shipping_total']) ? $cart_totals['shipping_total'] : 0), + (!empty($cart_totals['shipping_tax']) ? $cart_totals['shipping_tax'] : 0), + (!empty($cart_totals['fee_total']) ? $cart_totals['fee_total'] : 0), + (!empty($cart_totals['fee_tax']) ? $cart_totals['fee_tax'] : 0), + ) + ), + 2 + ); + return $original_total; + } + + protected function updateGiftCardTotals() + { + $gift_cards_applied = WC()->session->get('securesubmit_gift_card_applied'); + $securesubmit_data = WC()->session->get('securesubmit_data'); + + $original_total = $this->getOriginalCartTotal(); + $remaining_total = $original_total; + + if (is_object($gift_cards_applied) && count(get_object_vars($gift_cards_applied)) > 0) { + foreach ($gift_cards_applied as $gift_card) { + $order_total_after_gift_card = $remaining_total - $gift_card->temp_balance; + + if ($order_total_after_gift_card > 0) { + $gift_card->used_amount = $gift_card->temp_balance; + } else { + $gift_card->used_amount = $remaining_total; + } + + $gift_cards_applied->{$gift_card->gift_card_id} = $gift_card; + $remaining_total = $remaining_total - $gift_card->used_amount; + } + } + + WC()->session->set('securesubmit_gift_card_applied', $gift_cards_applied); + } + + protected function giftCardUsageAmount($updated = false) + { + if ($updated) { + $cart_total = $this->getTotalMinusSecureSubmitGiftCards(); + $gift_card_object = $this->applied_gift_card; + } else { + $cart_totals = WC()->session->get('cart_totals'); + $cart_total = round($cart_totals['total'], 2); + $gift_card_object = WC()->session->get('securesubmit_gift_card_object'); + } + + if (round($gift_card_object->temp_balance, 2) <= $cart_total) { + $gift_card_applied_amount = $gift_card_object->temp_balance; + } else { + $gift_card_applied_amount = $cart_total; + } + + return $gift_card_applied_amount; + } + + public function addGiftCards() + { + // TODO: Add warnings and success messages + // $gift_cards_allowed = $this->giftCardsAllowed(); + $gift_cards_allowed = true; + + // No gift cards if there are subscription products in the cart + if ($gift_cards_allowed) { + $original_total = $this->getOriginalCartTotal(); + $gift_card_object_applied = $this->updateGiftCardCartTotal(); + + if (is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0) { + $securesubmit_data = WC()->session->get('securesubmit_data'); + $securesubmit_data->original_total = $original_total; + WC()->session->set('securesubmit_data', $securesubmit_data); + + $message = __( 'Total Before Gift Cards', 'wc_securesubmit' ); + + $order_total_html = ''; + $order_total_html .= '' . $message . ''; + $order_total_html .= '' . wc_price($original_total) . ''; + $order_total_html .= ''; + + echo apply_filters('securesubmit_before_gift_cards_order_total', $order_total_html, $original_total, $message); + + foreach ($gift_card_object_applied as $applied_gift_card) { + $remove_link = '(Remove)'; + + $gift_card_html = ''; + $gift_card_html .= '' . $applied_gift_card->gift_card_name . ' ' . $remove_link . ''; + $gift_card_html .= '' . wc_price($applied_gift_card->used_amount) . ''; + $gift_card_html .= ''; + + echo apply_filters('securesubmit_gift_card_used_total', $gift_card_html, $applied_gift_card->gift_card_name, $remove_link, $applied_gift_card->used_amount); + } + } + } else { + $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); + + $this->removeAllGiftCardsFromSession(); + + if (is_object($applied_cards) && count(get_object_vars($applied_cards)) > 0) { + wc_add_notice(__('Sorry, we are unable to allow gift cards to be used when purchasing a subscription. Any gift cards already applied to the order have been cleared', 'wc_securesubmit'), 'notice'); + } + } + } + + public function updateOrderTotal($cart_total, $cart_object) + { + $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); + + if (is_object($gift_cards) && count(get_object_vars($gift_cards)) > 0) { + $gift_card_totals = $this->getGiftCardTotals(); + $cart_total = $cart_total + $gift_card_totals; + } + + return $cart_total; + } + + protected function getGiftCardTotals() + { + $this->updateGiftCardTotals(); + + $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); + + if (!empty($gift_cards)) { + $total = 0; + + foreach ($gift_cards as $gift_card) { + $total -= $gift_card->used_amount; + } + + return $total; + } + } + + public function processGiftCardSale($card_number, $card_pin, $used_amount) + { + $card = $this->giftCardObject($card_number, $card_pin); + $rounded_amount = round($used_amount, 2); + $positive_amount = abs($rounded_amount); + + $response = $card->charge($positive_amount) + ->withCurrency('USD') + ->execute(); + + return $response; + } + + public function removeAllGiftCardsFromSession() + { + WC()->session->__unset('securesubmit_gift_card_applied'); + WC()->session->__unset('securesubmit_gift_card_object'); + WC()->session->__unset('securesubmit_data'); + } + + public function removeGiftCard($removed_card = null) + { + if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { + $removed_card = $_POST['securesubmit_card_id']; + } + + $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); + + unset($applied_cards->{$removed_card}); + + if (count((array) $applied_cards) > 0) { + WC()->session->set('securesubmit_gift_card_applied', $applied_cards); + } else { + WC()->session->__unset('securesubmit_gift_card_applied'); + } + + if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { + echo ''; + wp_die(); + } + } + +} diff --git a/src/Gateways/gc.php b/src/Gateways/gc.php new file mode 100644 index 0000000..6232916 --- /dev/null +++ b/src/Gateways/gc.php @@ -0,0 +1,149 @@ +secretApiKey = $this->get_backend_gateway_options()['secretApiKey']; + $config->developerId = "123456"; + $config->versionNumber = "1234"; + + ServicesContainer::configure($config); + } + + /** + * returns gift-specific decline message for display to customer + * + * @param string $response_code + * + * @return string + */ + public function get_gift_decline_message( string $response_code ) { + switch ($response_code) { + case '1': + case '2': + case '11': + return 'An unknown gift error has occurred.'; + case '3': + case '8': + return 'The card data is invalid.'; + case '4': + return 'The card has expired.'; + case '5': + case '12': + return 'The card was declined.'; + case '6': + case '7': + case '10': + return 'An error occurred while processing this card.'; + case '9': + return 'Must be greater than or equal 0.'; + case '13': + return 'The amount was partially approved.'; + case '14': + return 'The pin is invalid'; + default: + return 'An error occurred while processing the gift card.'; + } + } + + // do base gift card stuff + public function applyGiftCard() { + // $this->gift_card_submitted = $_POST['gift_card_number']; + // $this->gift_card_pin_submitted = $_POST['gift_card_pin']; + $gift_card_balance = $this->gift_card_balance( + $_POST['gift_card_number'], + $_POST['gift_card_pin'] + ); + + if ($gift_card_balance['error']) { + echo json_encode(array( + 'error' => 1, + 'message' => $gift_card_balance['message'], + )); + } else { + $this->temp_balance = $gift_card_balance['message']; + + $this->addGiftCardToCartSession(); + $this->updateGiftCardCartTotal(); + echo json_encode(array( + 'error' => 0, + 'balance' => html_entity_decode(get_woocommerce_currency_symbol()) . $gift_card_balance['message'], + )); + } + + wp_die(); + } + + // stolen + public function gift_card_balance($gift_card_number, $gift_card_pin) + { + $this->configureServiceContainer(); + + if (empty($gift_card_pin)) { + return array( + 'error' => true, + 'message' => "PINs are required. Please enter a PIN and click apply again.", + ); + } + + $this->gift_card = $this->giftCardObject($gift_card_number, $gift_card_pin); + + try { + $response = $this->gift_card->balanceInquiry() + ->execute(); // need the service container for this to work + } catch (Exception $e) { + return array( + 'error' => true, + 'message' => "The gift card number you entered is either incorrect or not yet activated.", + ); + } + + // wc_clear_notices(); // I don't know what this does + + return array( + 'error' => false, + 'message' => $response->balanceAmount, + ); + } + + protected function giftCardObject($gift_card_number, $gift_card_pin) + { + $gift_card = new gc(); + $gift_card->number = $gift_card_number; + $gift_card->pin = $gift_card_pin; + + return $gift_card; + } + + protected function addGiftCardToCartSession() + { + $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); + $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); + $this->gift_card->pin = $this->gift_card_pin_submitted; + + WC()->session->set('securesubmit_gift_card_object', $this->gift_card); + } + + protected function giftCardName($gift_card_number) + { + $digits_to_display = 5; + $last_digits = substr($gift_card_number, $digits_to_display * - 1); + + return __( 'Gift Card', 'wc_securesubmit' ) . ' ' . $last_digits; + } + +} \ No newline at end of file diff --git a/src/Gateways/gcOrder.php b/src/Gateways/gcOrder.php new file mode 100644 index 0000000..a7920fe --- /dev/null +++ b/src/Gateways/gcOrder.php @@ -0,0 +1,173 @@ +id; + + $applied_gift_cards = unserialize( get_post_meta( $order_id, '_securesubmit_used_card_data', TRUE ) ); + $original_balance = get_post_meta( $order_id, '_securesubmit_original_reported_total', TRUE ); + + if ( ! empty ( $applied_gift_cards ) ) { + + $rows = $this->buildOrderRows( $rows, $original_balance, $applied_gift_cards ); + + } + + return $rows; + + } + + public function addItemsToOrderDisplay( $rows, $order_object ) { + if (null == WC()->session) { + return $rows; + } + + $securesubmit_data = WC()->session->get( 'securesubmit_data' ); + $applied_cards = WC()->session->get( 'securesubmit_gift_card_applied' ); + + if ( ! empty( $applied_cards ) ) { + + // buildOrderRows( $rows, $order_total, $applied_cards ) + $rows = $this->buildOrderRows( $rows, $securesubmit_data->original_total, $applied_cards ); + + } + + return $rows; + + } + + public static function processGiftCardPayment( $order_id ) { + + $applied_gift_card = WC()->session->get( 'securesubmit_gift_card_applied' ); // not going here + $securesubmit_data = WC()->session->get( 'securesubmit_data' ); + $order_awaiting_payment = $order_id; + $giftcard_gateway = new HeartlandGatewayGift(); + $gift_card_sales = array(); + + foreach ( $applied_gift_card as $gift_card ) { + + $gift_card_number = $gift_card->number; + $gift_card_pin = $gift_card->pin; + $gift_card_temp_balance = $gift_card->temp_balance; + $gift_card_balance = $giftcard_gateway->gift_card_balance( $gift_card_number, $gift_card_pin ); + + if ( $gift_card_balance[ 'message' ] < $gift_card_temp_balance ) { + + $giftcard_gateway->removeGiftCard( $gift_card->gift_card_id ); + + $balance_message = sprintf( __( 'The %s now has a lower balance than when it was originally applied to the order. It has been removed from the order. Please add it to the order again.', 'wc_securesubmit' ), $gift_card->gift_card_name ); + + // Void the already done transactions if any + $giftcard_gateway->processGiftCardVoid( $gift_card_sales, $order_awaiting_payment ); + + throw new Exception( $balance_message ); + + } + + $sale_response = $giftcard_gateway->processGiftCardSale( $gift_card_number, $gift_card_pin, $gift_card->used_amount ); + + if ( ! isset( $sale_response->responseCode ) || $sale_response->responseCode !== '00' ) { + + $sale_response_message = sprintf( __( 'The %s was not able to be processed.', 'wc_securesubmit' ), $gift_card->gift_card_name ); + + // Void the already done transactions if any + if ( ! empty( $gift_card_sales ) ) { + + $giftcard_gateway->processGiftCardVoid( $gift_card_sales, $order_awaiting_payment ); + + } + + throw new Exception( $sale_response_message ); + + } + + $used_amount_positive = $gift_card->used_amount * - 1; + + $gift_card_sales[ $gift_card->gift_card_id ] = new stdClass(); + + $gift_card_sales[ $gift_card->gift_card_id ]->gift_card_name = $gift_card->gift_card_name; + $gift_card_sales[ $gift_card->gift_card_id ]->gift_card_id = $gift_card->gift_card_id; + $gift_card_sales[ $gift_card->gift_card_id ]->transaction_id = $sale_response->transactionId; + $gift_card_sales[ $gift_card->gift_card_id ]->remaining_balance = $sale_response->balanceAmount; + $gift_card_sales[ $gift_card->gift_card_id ]->used_amount = $used_amount_positive; + + } + + update_post_meta( $order_awaiting_payment, '_securesubmit_used_card_data', serialize( $gift_card_sales ) ); + update_post_meta( $order_awaiting_payment, '_securesubmit_original_reported_total', $securesubmit_data->original_total ); + + foreach ( $gift_card_sales as $gift_card_sale ) { + + $balance_used = wc_price( $gift_card_sale->used_amount ); + + $note_text = sprintf( __( '%s was used on this order with a total used amount of %s. Transaction ID: %s ', 'wc_securesubmit' ), $gift_card_sale->gift_card_name, $balance_used, $gift_card_sale->transaction_id ); + + $order = new WC_Order( $order_awaiting_payment ); + $order->add_order_note( $note_text ); + + } + + $giftcard_gateway->removeAllGiftCardsFromSession(); + + } + + public function processGiftCardsZeroTotal( $order_id, $posted ) { + $appliedCards = WC()->session->get('securesubmit_gift_card_applied'); + + if ( empty( $posted[ 'payment_method' ] ) ) { + + $this->processGiftCardPayment( $order_id ); + + } + + } + + protected function buildOrderRows( $rows, $order_total, $applied_cards ) { + + $index_of_order_total = array_search( 'order_total', array_keys( $rows ) ); + + $gift_card_array[ 'original_total' ] = array( + 'label' => __( 'Total before Gift Cards', 'wc_securesubmit' ), + 'value' => wc_price( $order_total ), + ); + + foreach ( $applied_cards as $card ) { + + $gift_card_array[ $card->gift_card_id ] = array( + 'label' => $card->gift_card_name, + 'value' => wc_price( $card->used_amount * - 1 ), + ); + + } + + $rows_first_part = array_slice( $rows, 0, $index_of_order_total, TRUE ); + $rows_last_part = array_slice( $rows, $index_of_order_total, PHP_INT_MAX, TRUE ); + + $rows = array_merge( $rows_first_part, $gift_card_array, $rows_last_part ); + + return $rows; + + } + + + +} diff --git a/src/Plugin.php b/src/Plugin.php index 89b5d47..089e3d8 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -7,6 +7,12 @@ defined( 'ABSPATH' ) || exit; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\aGiftCard; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gc; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gcOrder; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGateway; // part of the uglyness +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGatewayGift; + /** * Main plugin class. */ @@ -18,10 +24,6 @@ class Plugin { */ const VERSION = '1.0.0'; - public static function do_a_barrell_roll() { - echo "please get here"; // it gets here now - } - /** * Init the package. */ @@ -32,8 +34,20 @@ public static function init() { return; } - add_action('wp_ajax_nopriv_use_gift_card', array(self::class, 'do_a_barrell_roll')); // dice? - add_action('wp_ajax_use_gift_card', array(self::class, 'do_a_barrell_roll')); // dice? + // probably want something cleaner than this, but for now: + $heartland_gateway = new HeartlandGatewayGift(); + $gcthing = new gcOrder(); + add_action('wp_ajax_nopriv_use_gift_card', array($heartland_gateway, 'applyGiftCard')); // dice? + add_action('wp_ajax_use_gift_card', array($heartland_gateway, 'applyGiftCard')); // dice? + add_action('woocommerce_review_order_before_order_total', array($heartland_gateway, 'addGiftCards')); + add_action('woocommerce_cart_totals_before_order_total', array($heartland_gateway, 'addGiftCards')); + add_filter('woocommerce_calculated_total', array($heartland_gateway, 'updateOrderTotal'), 10, 2); + add_action('wp_ajax_nopriv_remove_gift_card', array($heartland_gateway, 'removeGiftCard')); + add_action('wp_ajax_remove_gift_card', array($heartland_gateway, 'removeGiftCard')); + + // Display gift cards used after checkout and on email + add_filter('woocommerce_get_order_item_totals', array( $gcthing, 'addItemsToPostOrderDisplay'), PHP_INT_MAX, 2); + add_action('woocommerce_checkout_order_processed', array( $gcthing, 'processGiftCardsZeroTotal'), PHP_INT_MAX, 2); add_filter( 'woocommerce_payment_gateways', array( self::class, 'add_gateways' ) ); } From 16b9d3d9345ae61ff136c89ed90e20ee8ff79121 Mon Sep 17 00:00:00 2001 From: Mark Anthony Smedal Jr Date: Tue, 26 May 2020 16:23:57 -0400 Subject: [PATCH 06/57] refactoring-decreasing_the_jank --- assets/frontend/HeartlandGiftFields.php | 74 ++++++++++++ src/Gateways/HMS-fields.php | 106 ----------------- src/Gateways/HeartlandGateway.php | 4 +- src/Gateways/HeartlandGatewayGift.php | 27 +---- src/Gateways/HeartlandGiftCard.php | 14 +++ src/Gateways/gc.php | 149 ------------------------ src/Gateways/gcOrder.php | 24 +--- src/Plugin.php | 7 +- 8 files changed, 95 insertions(+), 310 deletions(-) create mode 100644 assets/frontend/HeartlandGiftFields.php delete mode 100644 src/Gateways/HMS-fields.php create mode 100644 src/Gateways/HeartlandGiftCard.php delete mode 100644 src/Gateways/gc.php diff --git a/assets/frontend/HeartlandGiftFields.php b/assets/frontend/HeartlandGiftFields.php new file mode 100644 index 0000000..2e65189 --- /dev/null +++ b/assets/frontend/HeartlandGiftFields.php @@ -0,0 +1,74 @@ + +
+
+
+ +
+ + +

+

+
+ +'; + $html .= 'if( typeof ajaxurl === "undefined") { '; + $html .= 'var ajaxurl = "' . admin_url('admin-ajax.php') . '";'; + $html .= '}'; + $html .= ''; + + echo $html; +?> + + +
+
+
+ +
diff --git a/src/Gateways/HMS-fields.php b/src/Gateways/HMS-fields.php deleted file mode 100644 index 0a48055..0000000 --- a/src/Gateways/HMS-fields.php +++ /dev/null @@ -1,106 +0,0 @@ - -
- -
-
- -
- - -

-

-
- -'; - $html .= 'if( typeof ajaxurl === "undefined") { '; - $html .= 'var ajaxurl = "' . admin_url('admin-ajax.php') . '";'; - $html .= '}'; - $html .= ''; - - echo $html; -?> - - -
-
-
- -
- \ No newline at end of file diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index d25807d..0e68e73 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -162,9 +162,7 @@ public function payment_fields() { parent::payment_fields(); if ( $this->allow_gift_cards === true ) { - include_once 'wp-content\plugins\globalpayments-gateway-provider-for-woocommerce\src\Gateways\HMS-fields.php'; - - // wp_enqueue_script('test', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/js/test.js', array('jquery'), false, true); + include_once dirname(plugin_dir_path(__FILE__)) . '/../assets/frontend/HeartlandGiftFields.php'; // SecureSubmit custom CSS wp_enqueue_style('heartland-gift-cards', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/css/heartland-gift-cards.css'); diff --git a/src/Gateways/HeartlandGatewayGift.php b/src/Gateways/HeartlandGatewayGift.php index 5b490c4..3c64e52 100644 --- a/src/Gateways/HeartlandGatewayGift.php +++ b/src/Gateways/HeartlandGatewayGift.php @@ -2,20 +2,14 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider\Gateways; -use GlobalPayments\Api\Entities\Enums\GatewayProvider; -use GlobalPayments\Api\Entities\Reporting\TransactionSummary; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gc; use GlobalPayments\Api\ServicesConfig; use GlobalPayments\Api\ServicesContainer; use stdClass; - defined( 'ABSPATH' ) || exit; class HeartlandGatewayGift extends HeartlandGateway { - protected $temp_balance; - protected $gift_card_pin_submitted; protected function configureServiceContainer() { @@ -63,26 +57,8 @@ public function get_gift_decline_message( string $response_code ) { } } - /** - * Adds Heartland gift card fields - */ - public function payment_fields() { - parent::payment_fields(); - - if ( $this->allow_gift_cards === true ) { - include_once 'wp-content\plugins\globalpayments-gateway-provider-for-woocommerce\src\Gateways\HMS-fields.php'; - - // wp_enqueue_script('test', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/js/test.js', array('jquery'), false, true); - - // SecureSubmit custom CSS - wp_enqueue_style('heartland-gift-cards', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/css/heartland-gift-cards.css'); - } - } - // do base gift card stuff public function applyGiftCard() { - // $this->gift_card_submitted = $_POST['gift_card_number']; - // $this->gift_card_pin_submitted = $_POST['gift_card_pin']; $gift_card_balance = $this->gift_card_balance( $_POST['gift_card_number'], $_POST['gift_card_pin'] @@ -141,7 +117,7 @@ public function gift_card_balance($gift_card_number, $gift_card_pin) protected function giftCardObject($gift_card_number, $gift_card_pin) { - $gift_card = new gc(); + $gift_card = new HeartlandGiftCard(); $gift_card->number = $gift_card_number; $gift_card->pin = $gift_card_pin; @@ -153,7 +129,6 @@ protected function addGiftCardToCartSession() $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); $this->gift_card->temp_balance = floatval($this->temp_balance); - // $this->gift_card->pin = $this->gift_card_pin; WC()->session->set('securesubmit_gift_card_object', $this->gift_card); } diff --git a/src/Gateways/HeartlandGiftCard.php b/src/Gateways/HeartlandGiftCard.php new file mode 100644 index 0000000..de58f94 --- /dev/null +++ b/src/Gateways/HeartlandGiftCard.php @@ -0,0 +1,14 @@ +secretApiKey = $this->get_backend_gateway_options()['secretApiKey']; - $config->developerId = "123456"; - $config->versionNumber = "1234"; - - ServicesContainer::configure($config); - } - - /** - * returns gift-specific decline message for display to customer - * - * @param string $response_code - * - * @return string - */ - public function get_gift_decline_message( string $response_code ) { - switch ($response_code) { - case '1': - case '2': - case '11': - return 'An unknown gift error has occurred.'; - case '3': - case '8': - return 'The card data is invalid.'; - case '4': - return 'The card has expired.'; - case '5': - case '12': - return 'The card was declined.'; - case '6': - case '7': - case '10': - return 'An error occurred while processing this card.'; - case '9': - return 'Must be greater than or equal 0.'; - case '13': - return 'The amount was partially approved.'; - case '14': - return 'The pin is invalid'; - default: - return 'An error occurred while processing the gift card.'; - } - } - - // do base gift card stuff - public function applyGiftCard() { - // $this->gift_card_submitted = $_POST['gift_card_number']; - // $this->gift_card_pin_submitted = $_POST['gift_card_pin']; - $gift_card_balance = $this->gift_card_balance( - $_POST['gift_card_number'], - $_POST['gift_card_pin'] - ); - - if ($gift_card_balance['error']) { - echo json_encode(array( - 'error' => 1, - 'message' => $gift_card_balance['message'], - )); - } else { - $this->temp_balance = $gift_card_balance['message']; - - $this->addGiftCardToCartSession(); - $this->updateGiftCardCartTotal(); - echo json_encode(array( - 'error' => 0, - 'balance' => html_entity_decode(get_woocommerce_currency_symbol()) . $gift_card_balance['message'], - )); - } - - wp_die(); - } - - // stolen - public function gift_card_balance($gift_card_number, $gift_card_pin) - { - $this->configureServiceContainer(); - - if (empty($gift_card_pin)) { - return array( - 'error' => true, - 'message' => "PINs are required. Please enter a PIN and click apply again.", - ); - } - - $this->gift_card = $this->giftCardObject($gift_card_number, $gift_card_pin); - - try { - $response = $this->gift_card->balanceInquiry() - ->execute(); // need the service container for this to work - } catch (Exception $e) { - return array( - 'error' => true, - 'message' => "The gift card number you entered is either incorrect or not yet activated.", - ); - } - - // wc_clear_notices(); // I don't know what this does - - return array( - 'error' => false, - 'message' => $response->balanceAmount, - ); - } - - protected function giftCardObject($gift_card_number, $gift_card_pin) - { - $gift_card = new gc(); - $gift_card->number = $gift_card_number; - $gift_card->pin = $gift_card_pin; - - return $gift_card; - } - - protected function addGiftCardToCartSession() - { - $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); - $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); - $this->gift_card->pin = $this->gift_card_pin_submitted; - - WC()->session->set('securesubmit_gift_card_object', $this->gift_card); - } - - protected function giftCardName($gift_card_number) - { - $digits_to_display = 5; - $last_digits = substr($gift_card_number, $digits_to_display * - 1); - - return __( 'Gift Card', 'wc_securesubmit' ) . ' ' . $last_digits; - } - -} \ No newline at end of file diff --git a/src/Gateways/gcOrder.php b/src/Gateways/gcOrder.php index a7920fe..7b7c459 100644 --- a/src/Gateways/gcOrder.php +++ b/src/Gateways/gcOrder.php @@ -5,9 +5,7 @@ use stdClass; use WC_Order; -if ( ! defined( 'ABSPATH' ) ) { - die(); -} +defined( 'ABSPATH' ) || exit; /* * @@ -15,28 +13,20 @@ class gcOrder { - public function __construct() { - - } - public function addItemsToPostOrderDisplay( $rows, $order_object ) { - $order_id = $order_object->id; $applied_gift_cards = unserialize( get_post_meta( $order_id, '_securesubmit_used_card_data', TRUE ) ); $original_balance = get_post_meta( $order_id, '_securesubmit_original_reported_total', TRUE ); if ( ! empty ( $applied_gift_cards ) ) { - $rows = $this->buildOrderRows( $rows, $original_balance, $applied_gift_cards ); - } return $rows; - } - public function addItemsToOrderDisplay( $rows, $order_object ) { + public function addItemsToOrderDisplay( $rows ) { if (null == WC()->session) { return $rows; } @@ -45,33 +35,26 @@ public function addItemsToOrderDisplay( $rows, $order_object ) { $applied_cards = WC()->session->get( 'securesubmit_gift_card_applied' ); if ( ! empty( $applied_cards ) ) { - - // buildOrderRows( $rows, $order_total, $applied_cards ) $rows = $this->buildOrderRows( $rows, $securesubmit_data->original_total, $applied_cards ); - } return $rows; - } public static function processGiftCardPayment( $order_id ) { - - $applied_gift_card = WC()->session->get( 'securesubmit_gift_card_applied' ); // not going here + $applied_gift_card = WC()->session->get( 'securesubmit_gift_card_applied' ); $securesubmit_data = WC()->session->get( 'securesubmit_data' ); $order_awaiting_payment = $order_id; $giftcard_gateway = new HeartlandGatewayGift(); $gift_card_sales = array(); foreach ( $applied_gift_card as $gift_card ) { - $gift_card_number = $gift_card->number; $gift_card_pin = $gift_card->pin; $gift_card_temp_balance = $gift_card->temp_balance; $gift_card_balance = $giftcard_gateway->gift_card_balance( $gift_card_number, $gift_card_pin ); if ( $gift_card_balance[ 'message' ] < $gift_card_temp_balance ) { - $giftcard_gateway->removeGiftCard( $gift_card->gift_card_id ); $balance_message = sprintf( __( 'The %s now has a lower balance than when it was originally applied to the order. It has been removed from the order. Please add it to the order again.', 'wc_securesubmit' ), $gift_card->gift_card_name ); @@ -80,7 +63,6 @@ public static function processGiftCardPayment( $order_id ) { $giftcard_gateway->processGiftCardVoid( $gift_card_sales, $order_awaiting_payment ); throw new Exception( $balance_message ); - } $sale_response = $giftcard_gateway->processGiftCardSale( $gift_card_number, $gift_card_pin, $gift_card->used_amount ); diff --git a/src/Plugin.php b/src/Plugin.php index 089e3d8..8df152b 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -5,14 +5,11 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider; -defined( 'ABSPATH' ) || exit; - -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\aGiftCard; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gc; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gcOrder; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGateway; // part of the uglyness use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGatewayGift; +defined( 'ABSPATH' ) || exit; + /** * Main plugin class. */ From de602f4aa011a102d46458156e54c4f07c5f845d Mon Sep 17 00:00:00 2001 From: Mark Anthony Smedal Jr Date: Wed, 27 May 2020 18:27:45 -0400 Subject: [PATCH 07/57] refactoring-decreasing_the_jank_2 --- assets/frontend/HeartlandGiftFields.php | 3 +- src/Gateways/HeartlandGateway.php | 10 +++---- src/Gateways/HeartlandGatewayGift.php | 37 +++++++++++++------------ src/Gateways/gcOrder.php | 10 +++---- src/Plugin.php | 28 +++++++++++++------ 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/assets/frontend/HeartlandGiftFields.php b/assets/frontend/HeartlandGiftFields.php index 2e65189..e005a69 100644 --- a/assets/frontend/HeartlandGiftFields.php +++ b/assets/frontend/HeartlandGiftFields.php @@ -3,6 +3,7 @@ defined( 'ABSPATH' ) || exit; ?> +
@@ -14,6 +15,7 @@

+ '; $html .= 'if( typeof ajaxurl === "undefined") { '; @@ -70,5 +72,4 @@ function applyGiftCard () {
-
diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index 0e68e73..796f9e7 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -156,7 +156,7 @@ public function get_decline_message( string $response_code ) { } /** - * Adds Heartland gift card fields + * Adds Heartland gift card functionality */ public function payment_fields() { parent::payment_fields(); @@ -170,7 +170,7 @@ public function payment_fields() { } /** - * Handle payment functions /-/override parent to add gift card functionality + * Handle payment functions * * @param int $order_id * @@ -183,10 +183,10 @@ public function process_payment( $order_id ) { $response = $this->submit_request( $request ); $is_successful = $this->handle_response( $request, $response ); - $session_applied_gift_card = WC()->session->get('securesubmit_gift_card_applied'); - if (!empty($session_applied_gift_card)) { + // Charge HPS gift cards if CC trans succeeds + if ($is_successful && !empty(WC()->session->get('heartland_gift_card_applied'))) { $gift_card_order_placement = new gcOrder(); - $gift_card_order_placement->processGiftCardPayment($order_id); + $gift_card_order_placement->processGiftCardPayment($order_id, $this->secret_key); } return array( diff --git a/src/Gateways/HeartlandGatewayGift.php b/src/Gateways/HeartlandGatewayGift.php index 3c64e52..9a1c4b1 100644 --- a/src/Gateways/HeartlandGatewayGift.php +++ b/src/Gateways/HeartlandGatewayGift.php @@ -8,15 +8,20 @@ defined( 'ABSPATH' ) || exit; -class HeartlandGatewayGift extends HeartlandGateway { +class HeartlandGatewayGift { + + function __construct($secretApiKey) { + $this->secretApiKey = $secretApiKey; + } + protected $temp_balance; protected $gift_card_pin_submitted; protected function configureServiceContainer() { $config = new ServicesConfig(); - $config->secretApiKey = $this->get_backend_gateway_options()['secretApiKey']; - $config->developerId = "123456"; - $config->versionNumber = "1234"; + $config->secretApiKey = $this->secretApiKey; + // $config->developerId = "123456"; + // $config->versionNumber = "1234"; ServicesContainer::configure($config); } @@ -107,8 +112,6 @@ public function gift_card_balance($gift_card_number, $gift_card_pin) ); } - // wc_clear_notices(); // I don't know what this does - return array( 'error' => false, 'message' => $response->balanceAmount, @@ -148,7 +151,7 @@ protected function updateGiftCardCartTotal() $gift_card_object_entered = (object)array(); } - $gift_card_object_applied = WC()->session->get('securesubmit_gift_card_applied'); + $gift_card_object_applied = WC()->session->get('heartland_gift_card_applied'); if (is_null($gift_card_object_applied)) { $gift_card_object_applied = (object)array(); } @@ -186,7 +189,7 @@ protected function updateGiftCardCartTotal() $gift_card_object_entered->used_amount = $this->giftCardUsageAmount(); $gift_card_object_applied->{$gift_card_object_entered->gift_card_id} = $gift_card_object_entered; - WC()->session->set('securesubmit_gift_card_applied', $gift_card_object_applied); + WC()->session->set('heartland_gift_card_applied', $gift_card_object_applied); WC()->session->__unset('securesubmit_gift_card_object'); } } @@ -215,7 +218,7 @@ protected function getOriginalCartTotal() protected function updateGiftCardTotals() { - $gift_cards_applied = WC()->session->get('securesubmit_gift_card_applied'); + $gift_cards_applied = WC()->session->get('heartland_gift_card_applied'); $securesubmit_data = WC()->session->get('securesubmit_data'); $original_total = $this->getOriginalCartTotal(); @@ -236,7 +239,7 @@ protected function updateGiftCardTotals() } } - WC()->session->set('securesubmit_gift_card_applied', $gift_cards_applied); + WC()->session->set('heartland_gift_card_applied', $gift_cards_applied); } protected function giftCardUsageAmount($updated = false) @@ -296,7 +299,7 @@ public function addGiftCards() } } } else { - $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); + $applied_cards = WC()->session->get('heartland_gift_card_applied'); $this->removeAllGiftCardsFromSession(); @@ -308,7 +311,7 @@ public function addGiftCards() public function updateOrderTotal($cart_total, $cart_object) { - $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); + $gift_cards = WC()->session->get('heartland_gift_card_applied'); if (is_object($gift_cards) && count(get_object_vars($gift_cards)) > 0) { $gift_card_totals = $this->getGiftCardTotals(); @@ -322,7 +325,7 @@ protected function getGiftCardTotals() { $this->updateGiftCardTotals(); - $gift_cards = WC()->session->get('securesubmit_gift_card_applied'); + $gift_cards = WC()->session->get('heartland_gift_card_applied'); if (!empty($gift_cards)) { $total = 0; @@ -350,7 +353,7 @@ public function processGiftCardSale($card_number, $card_pin, $used_amount) public function removeAllGiftCardsFromSession() { - WC()->session->__unset('securesubmit_gift_card_applied'); + WC()->session->__unset('heartland_gift_card_applied'); WC()->session->__unset('securesubmit_gift_card_object'); WC()->session->__unset('securesubmit_data'); } @@ -361,14 +364,14 @@ public function removeGiftCard($removed_card = null) $removed_card = $_POST['securesubmit_card_id']; } - $applied_cards = WC()->session->get('securesubmit_gift_card_applied'); + $applied_cards = WC()->session->get('heartland_gift_card_applied'); unset($applied_cards->{$removed_card}); if (count((array) $applied_cards) > 0) { - WC()->session->set('securesubmit_gift_card_applied', $applied_cards); + WC()->session->set('heartland_gift_card_applied', $applied_cards); } else { - WC()->session->__unset('securesubmit_gift_card_applied'); + WC()->session->__unset('heartland_gift_card_applied'); } if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { diff --git a/src/Gateways/gcOrder.php b/src/Gateways/gcOrder.php index 7b7c459..5100e0b 100644 --- a/src/Gateways/gcOrder.php +++ b/src/Gateways/gcOrder.php @@ -32,7 +32,7 @@ public function addItemsToOrderDisplay( $rows ) { } $securesubmit_data = WC()->session->get( 'securesubmit_data' ); - $applied_cards = WC()->session->get( 'securesubmit_gift_card_applied' ); + $applied_cards = WC()->session->get( 'heartland_gift_card_applied' ); if ( ! empty( $applied_cards ) ) { $rows = $this->buildOrderRows( $rows, $securesubmit_data->original_total, $applied_cards ); @@ -41,11 +41,11 @@ public function addItemsToOrderDisplay( $rows ) { return $rows; } - public static function processGiftCardPayment( $order_id ) { - $applied_gift_card = WC()->session->get( 'securesubmit_gift_card_applied' ); + public static function processGiftCardPayment( $order_id, $secret_api_key ) { + $applied_gift_card = WC()->session->get( 'heartland_gift_card_applied' ); $securesubmit_data = WC()->session->get( 'securesubmit_data' ); $order_awaiting_payment = $order_id; - $giftcard_gateway = new HeartlandGatewayGift(); + $giftcard_gateway = new HeartlandGatewayGift($secret_api_key); $gift_card_sales = array(); foreach ( $applied_gift_card as $gift_card ) { @@ -113,7 +113,7 @@ public static function processGiftCardPayment( $order_id ) { } public function processGiftCardsZeroTotal( $order_id, $posted ) { - $appliedCards = WC()->session->get('securesubmit_gift_card_applied'); + $appliedCards = WC()->session->get('heartland_gift_card_applied'); if ( empty( $posted[ 'payment_method' ] ) ) { diff --git a/src/Plugin.php b/src/Plugin.php index 8df152b..b7717b3 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -6,6 +6,7 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gcOrder; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGateway; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGatewayGift; defined( 'ABSPATH' ) || exit; @@ -32,21 +33,32 @@ public static function init() { } // probably want something cleaner than this, but for now: - $heartland_gateway = new HeartlandGatewayGift(); $gcthing = new gcOrder(); - add_action('wp_ajax_nopriv_use_gift_card', array($heartland_gateway, 'applyGiftCard')); // dice? - add_action('wp_ajax_use_gift_card', array($heartland_gateway, 'applyGiftCard')); // dice? - add_action('woocommerce_review_order_before_order_total', array($heartland_gateway, 'addGiftCards')); - add_action('woocommerce_cart_totals_before_order_total', array($heartland_gateway, 'addGiftCards')); - add_filter('woocommerce_calculated_total', array($heartland_gateway, 'updateOrderTotal'), 10, 2); - add_action('wp_ajax_nopriv_remove_gift_card', array($heartland_gateway, 'removeGiftCard')); - add_action('wp_ajax_remove_gift_card', array($heartland_gateway, 'removeGiftCard')); // Display gift cards used after checkout and on email add_filter('woocommerce_get_order_item_totals', array( $gcthing, 'addItemsToPostOrderDisplay'), PHP_INT_MAX, 2); add_action('woocommerce_checkout_order_processed', array( $gcthing, 'processGiftCardsZeroTotal'), PHP_INT_MAX, 2); add_filter( 'woocommerce_payment_gateways', array( self::class, 'add_gateways' ) ); + + $HeartlandGateway = new HeartlandGateway(); + + if ($HeartlandGateway->allow_gift_cards === true) { + $HeartlandGatewayGift = new HeartlandGatewayGift($HeartlandGateway->get_backend_gateway_options()['secretApiKey']); + + add_action('wp_ajax_nopriv_use_gift_card', array($HeartlandGatewayGift, 'applyGiftCard')); + add_action('wp_ajax_use_gift_card', array($HeartlandGatewayGift, 'applyGiftCard')); + add_action('woocommerce_review_order_before_order_total', array($HeartlandGatewayGift, 'addGiftCards')); + add_action('woocommerce_cart_totals_before_order_total', array($HeartlandGatewayGift, 'addGiftCards')); + add_filter('woocommerce_calculated_total', array($HeartlandGatewayGift, 'updateOrderTotal'), 10, 2); + add_action('wp_ajax_nopriv_remove_gift_card', array($HeartlandGatewayGift, 'removeGiftCard')); + add_action('wp_ajax_remove_gift_card', array($HeartlandGatewayGift, 'removeGiftCard')); + + $gcthing = new gcOrder(); + + add_filter('woocommerce_get_order_item_totals', array( $gcthing, 'addItemsToPostOrderDisplay'), PHP_INT_MAX, 2); + add_action('woocommerce_checkout_order_processed', array( $gcthing, 'processGiftCardsZeroTotal'), PHP_INT_MAX, 2); + } } /** From 82c7b9780d838a3fa19cef397543e0569bbfe316 Mon Sep 17 00:00:00 2001 From: Mark Anthony Smedal Jr Date: Thu, 11 Jun 2020 20:08:54 -0400 Subject: [PATCH 08/57] handle_GC_declines_at_checkout --- src/Gateways/HeartlandGateway.php | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index 796f9e7..a5a1453 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -2,9 +2,10 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider\Gateways; +use WC_Order; use GlobalPayments\Api\Entities\Enums\GatewayProvider; use GlobalPayments\Api\Entities\Reporting\TransactionSummary; -use WC_Order; +use GlobalPayments\Api\Entities\Transaction; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gcOrder; defined( 'ABSPATH' ) || exit; @@ -156,16 +157,17 @@ public function get_decline_message( string $response_code ) { } /** - * Adds Heartland gift card functionality + * Add gift card fields if enabled + * */ public function payment_fields() { parent::payment_fields(); if ( $this->allow_gift_cards === true ) { - include_once dirname(plugin_dir_path(__FILE__)) . '/../assets/frontend/HeartlandGiftFields.php'; + $path = dirname(plugin_dir_path(__FILE__)); - // SecureSubmit custom CSS - wp_enqueue_style('heartland-gift-cards', '/wp-content/plugins/globalpayments-gateway-provider-for-woocommerce/assets/frontend/css/heartland-gift-cards.css'); + include_once $path . '/../assets/frontend/HeartlandGiftFields.php'; + wp_enqueue_style('heartland-gift-cards', $path . '/../assets/frontend/css/heartland-gift-cards.css'); } } @@ -184,11 +186,21 @@ public function process_payment( $order_id ) { $is_successful = $this->handle_response( $request, $response ); // Charge HPS gift cards if CC trans succeeds - if ($is_successful && !empty(WC()->session->get('heartland_gift_card_applied'))) { + if ( $is_successful && !empty( WC()->session->get( 'heartland_gift_card_applied' ) ) ) { $gift_card_order_placement = new gcOrder(); - $gift_card_order_placement->processGiftCardPayment($order_id, $this->secret_key); + $gift_payments_successful = $gift_card_order_placement->processGiftCardPayment( $order_id ); } + // reverse the CC transaction if GC transactions didn't didn't succeed + if ( $gift_payments_successful !== true ) { + // hook directly into GP SDK to avoid collisions with the existing request + Transaction::fromId( $response->transactionReference->transactionId ) + ->reverse( $request->order->data[ 'total' ] ) + ->execute(); + + $is_successful = false; + } + return array( 'result' => $is_successful ? 'success' : 'failure', 'redirect' => $is_successful ? $this->get_return_url( $order ) : false, From 3f12e70bd90e038e91b09fa823beb5fede83351c Mon Sep 17 00:00:00 2001 From: Mark Anthony Smedal Jr Date: Sat, 13 Jun 2020 16:53:03 -0400 Subject: [PATCH 09/57] refactoring-decreasing_the_jank_3 --- src/Gateways/AbstractGateway.php | 10 +-- src/Gateways/HeartlandGateway.php | 7 +- .../HeartlandGiftCard.php | 5 +- .../HeartlandGiftCardOrder.php} | 24 +++--- .../HeartlandGiftGateway.php} | 73 ++++--------------- src/Plugin.php | 31 +++----- 6 files changed, 47 insertions(+), 103 deletions(-) rename src/Gateways/{ => HeartlandGiftCards}/HeartlandGiftCard.php (75%) rename src/Gateways/{gcOrder.php => HeartlandGiftCards/HeartlandGiftCardOrder.php} (88%) rename src/Gateways/{HeartlandGatewayGift.php => HeartlandGiftCards/HeartlandGiftGateway.php} (85%) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 95e2134..d6b543e 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -587,15 +587,7 @@ protected function is_transaction_active( TransactionSummary $details ) { * @return string */ public function get_decline_message( string $response_code ) { - return 'An error occurred while processing the gift card.'; + return 'An error occurred while processing the card.'; } - /** - * Should be overridden by each gateway implementation - * - * @return string - */ - public function get_gift_decline_message( string $response_code ) { - return 'An error occurred while processing the gift card.'; - } } diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index a5a1453..5740703 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -6,7 +6,7 @@ use GlobalPayments\Api\Entities\Enums\GatewayProvider; use GlobalPayments\Api\Entities\Reporting\TransactionSummary; use GlobalPayments\Api\Entities\Transaction; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gcOrder; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGiftCards\HeartlandGiftCardOrder; defined( 'ABSPATH' ) || exit; @@ -176,8 +176,7 @@ public function payment_fields() { * * @param int $order_id * - * @return array - * + * @return array * */ public function process_payment( $order_id ) { $order = new WC_Order( $order_id ); @@ -187,7 +186,7 @@ public function process_payment( $order_id ) { // Charge HPS gift cards if CC trans succeeds if ( $is_successful && !empty( WC()->session->get( 'heartland_gift_card_applied' ) ) ) { - $gift_card_order_placement = new gcOrder(); + $gift_card_order_placement = new HeartlandGiftCardOrder(); $gift_payments_successful = $gift_card_order_placement->processGiftCardPayment( $order_id ); } diff --git a/src/Gateways/HeartlandGiftCard.php b/src/Gateways/HeartlandGiftCards/HeartlandGiftCard.php similarity index 75% rename from src/Gateways/HeartlandGiftCard.php rename to src/Gateways/HeartlandGiftCards/HeartlandGiftCard.php index de58f94..13d44aa 100644 --- a/src/Gateways/HeartlandGiftCard.php +++ b/src/Gateways/HeartlandGiftCards/HeartlandGiftCard.php @@ -1,14 +1,15 @@ id; @@ -41,11 +39,11 @@ public function addItemsToOrderDisplay( $rows ) { return $rows; } - public static function processGiftCardPayment( $order_id, $secret_api_key ) { + public static function processGiftCardPayment( $order_id ) { $applied_gift_card = WC()->session->get( 'heartland_gift_card_applied' ); $securesubmit_data = WC()->session->get( 'securesubmit_data' ); $order_awaiting_payment = $order_id; - $giftcard_gateway = new HeartlandGatewayGift($secret_api_key); + $giftcard_gateway = new HeartlandGiftGateway(); $gift_card_sales = array(); foreach ( $applied_gift_card as $gift_card ) { @@ -69,7 +67,8 @@ public static function processGiftCardPayment( $order_id, $secret_api_key ) { if ( ! isset( $sale_response->responseCode ) || $sale_response->responseCode !== '00' ) { - $sale_response_message = sprintf( __( 'The %s was not able to be processed.', 'wc_securesubmit' ), $gift_card->gift_card_name ); + $error_response_message = sprintf( __( '%s was not able to be processed: %s', 'wc_securesubmit' ), $gift_card->gift_card_name, substr( $sale_response->responseMessage, 20 ) ); + // Void the already done transactions if any if ( ! empty( $gift_card_sales ) ) { @@ -78,11 +77,11 @@ public static function processGiftCardPayment( $order_id, $secret_api_key ) { } - throw new Exception( $sale_response_message ); + throw new Exception( $error_response_message ); } - $used_amount_positive = $gift_card->used_amount * - 1; + $used_amount_positive = abs( $gift_card->used_amount ); $gift_card_sales[ $gift_card->gift_card_id ] = new stdClass(); @@ -110,10 +109,11 @@ public static function processGiftCardPayment( $order_id, $secret_api_key ) { $giftcard_gateway->removeAllGiftCardsFromSession(); + return true; + } public function processGiftCardsZeroTotal( $order_id, $posted ) { - $appliedCards = WC()->session->get('heartland_gift_card_applied'); if ( empty( $posted[ 'payment_method' ] ) ) { diff --git a/src/Gateways/HeartlandGatewayGift.php b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php similarity index 85% rename from src/Gateways/HeartlandGatewayGift.php rename to src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php index 9a1c4b1..47ed501 100644 --- a/src/Gateways/HeartlandGatewayGift.php +++ b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php @@ -1,17 +1,20 @@ secretApiKey = $secretApiKey; + function __construct() { $HeartlandGateway = new HeartlandGateway(); + $this->secret_api_key = $HeartlandGateway->get_backend_gateway_options()['secretApiKey']; } protected $temp_balance; @@ -19,51 +22,15 @@ function __construct($secretApiKey) { protected function configureServiceContainer() { $config = new ServicesConfig(); - $config->secretApiKey = $this->secretApiKey; - // $config->developerId = "123456"; + $config->secretApiKey = $this->secret_api_key; + // $config->developerId = "123456"; // need these from SS team // $config->versionNumber = "1234"; ServicesContainer::configure($config); } - /** - * returns gift-specific decline message for display to customer - * - * @param string $response_code - * - * @return string - */ - public function get_gift_decline_message( string $response_code ) { - switch ($response_code) { - case '1': - case '2': - case '11': - return 'An unknown gift error has occurred.'; - case '3': - case '8': - return 'The card data is invalid.'; - case '4': - return 'The card has expired.'; - case '5': - case '12': - return 'The card was declined.'; - case '6': - case '7': - case '10': - return 'An error occurred while processing this card.'; - case '9': - return 'Must be greater than or equal 0.'; - case '13': - return 'The amount was partially approved.'; - case '14': - return 'The pin is invalid'; - default: - return 'An error occurred while processing the gift card.'; - } - } - - // do base gift card stuff public function applyGiftCard() { + $gift_card_balance = $this->gift_card_balance( $_POST['gift_card_number'], $_POST['gift_card_pin'] @@ -88,7 +55,6 @@ public function applyGiftCard() { wp_die(); } - // stolen public function gift_card_balance($gift_card_number, $gift_card_pin) { $this->configureServiceContainer(); @@ -104,7 +70,7 @@ public function gift_card_balance($gift_card_number, $gift_card_pin) try { $response = $this->gift_card->balanceInquiry() - ->execute(); // need the service container for this to work + ->execute(); } catch (Exception $e) { return array( 'error' => true, @@ -219,7 +185,6 @@ protected function getOriginalCartTotal() protected function updateGiftCardTotals() { $gift_cards_applied = WC()->session->get('heartland_gift_card_applied'); - $securesubmit_data = WC()->session->get('securesubmit_data'); $original_total = $this->getOriginalCartTotal(); $remaining_total = $original_total; @@ -244,14 +209,10 @@ protected function updateGiftCardTotals() protected function giftCardUsageAmount($updated = false) { - if ($updated) { - $cart_total = $this->getTotalMinusSecureSubmitGiftCards(); - $gift_card_object = $this->applied_gift_card; - } else { - $cart_totals = WC()->session->get('cart_totals'); - $cart_total = round($cart_totals['total'], 2); - $gift_card_object = WC()->session->get('securesubmit_gift_card_object'); - } + + $cart_totals = WC()->session->get('cart_totals'); + $cart_total = round($cart_totals['total'], 2); + $gift_card_object = WC()->session->get('securesubmit_gift_card_object'); if (round($gift_card_object->temp_balance, 2) <= $cart_total) { $gift_card_applied_amount = $gift_card_object->temp_balance; @@ -324,7 +285,6 @@ public function updateOrderTotal($cart_total, $cart_object) protected function getGiftCardTotals() { $this->updateGiftCardTotals(); - $gift_cards = WC()->session->get('heartland_gift_card_applied'); if (!empty($gift_cards)) { @@ -379,5 +339,4 @@ public function removeGiftCard($removed_card = null) wp_die(); } } - } diff --git a/src/Plugin.php b/src/Plugin.php index b7717b3..7515e22 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -5,9 +5,9 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\gcOrder; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGateway; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGatewayGift; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGiftCards\HeartlandGiftGateway; +use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\HeartlandGiftCards\HeartlandGiftCardOrder; defined( 'ABSPATH' ) || exit; @@ -32,31 +32,24 @@ public static function init() { return; } - // probably want something cleaner than this, but for now: - $gcthing = new gcOrder(); - - // Display gift cards used after checkout and on email - add_filter('woocommerce_get_order_item_totals', array( $gcthing, 'addItemsToPostOrderDisplay'), PHP_INT_MAX, 2); - add_action('woocommerce_checkout_order_processed', array( $gcthing, 'processGiftCardsZeroTotal'), PHP_INT_MAX, 2); - add_filter( 'woocommerce_payment_gateways', array( self::class, 'add_gateways' ) ); $HeartlandGateway = new HeartlandGateway(); if ($HeartlandGateway->allow_gift_cards === true) { - $HeartlandGatewayGift = new HeartlandGatewayGift($HeartlandGateway->get_backend_gateway_options()['secretApiKey']); + $HeartlandGiftGateway = new HeartlandGiftGateway(); - add_action('wp_ajax_nopriv_use_gift_card', array($HeartlandGatewayGift, 'applyGiftCard')); - add_action('wp_ajax_use_gift_card', array($HeartlandGatewayGift, 'applyGiftCard')); - add_action('woocommerce_review_order_before_order_total', array($HeartlandGatewayGift, 'addGiftCards')); - add_action('woocommerce_cart_totals_before_order_total', array($HeartlandGatewayGift, 'addGiftCards')); - add_filter('woocommerce_calculated_total', array($HeartlandGatewayGift, 'updateOrderTotal'), 10, 2); - add_action('wp_ajax_nopriv_remove_gift_card', array($HeartlandGatewayGift, 'removeGiftCard')); - add_action('wp_ajax_remove_gift_card', array($HeartlandGatewayGift, 'removeGiftCard')); + add_action('wp_ajax_nopriv_use_gift_card', array($HeartlandGiftGateway, 'applyGiftCard')); + add_action('wp_ajax_use_gift_card', array($HeartlandGiftGateway, 'applyGiftCard')); + add_action('woocommerce_review_order_before_order_total', array($HeartlandGiftGateway, 'addGiftCards')); + add_action('woocommerce_cart_totals_before_order_total', array($HeartlandGiftGateway, 'addGiftCards')); + add_filter('woocommerce_calculated_total', array($HeartlandGiftGateway, 'updateOrderTotal'), 10, 2); + add_action('wp_ajax_nopriv_remove_gift_card', array($HeartlandGiftGateway, 'removeGiftCard')); + add_action('wp_ajax_remove_gift_card', array($HeartlandGiftGateway, 'removeGiftCard')); - $gcthing = new gcOrder(); + $gcthing = new HeartlandGiftCardOrder(); - add_filter('woocommerce_get_order_item_totals', array( $gcthing, 'addItemsToPostOrderDisplay'), PHP_INT_MAX, 2); + add_filter('woocommerce_get_order_item_totals', array( $gcthing, 'addItemsToPostOrderDisplay'), PHP_INT_MAX - 1, 2); add_action('woocommerce_checkout_order_processed', array( $gcthing, 'processGiftCardsZeroTotal'), PHP_INT_MAX, 2); } } From 7e8382f7517a12124f3438c3e86125785bbce1ea Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Sun, 22 Nov 2020 20:15:53 -0500 Subject: [PATCH 10/57] composer require SDK v2.1 --- composer.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index be9e034..1cd103b 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "type": "wordpress-plugin", "require": { "composer/installers": "^1.7", - "globalpayments/php-sdk": "dev-transIT-support" + "globalpayments/php-sdk": "2.1.*" }, "require-dev": { "phpunit/phpunit": "^7.5", @@ -34,8 +34,5 @@ "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" - }, - "repositories": [ - { "type": "git", "url": "git@github.hps.com:devportal/php-sdk-v3" } - ] + } } From 47d7e56eca0fec05c3b20a653f8cd3cc7b7bede5 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Tue, 24 Nov 2020 12:01:45 -0500 Subject: [PATCH 11/57] HMS works --- src/Gateways/Clients/SdkClient.php | 6 +- src/Gateways/HeartlandGateway.php | 10 +- .../HeartlandGiftCards/HeartlandGiftCard.php | 30 +- .../HeartlandGiftCardOrder.php | 154 ++-- .../HeartlandGiftGateway.php | 716 +++++++++--------- 5 files changed, 471 insertions(+), 445 deletions(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index b77bd6d..4b1fb7c 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -8,8 +8,8 @@ use GlobalPayments\Api\Entities\Enums\AddressType; use GlobalPayments\Api\Gateways\IPaymentGateway; use GlobalPayments\Api\PaymentMethods\CreditCardData; +use GlobalPayments\Api\ServiceConfigs\Gateways\PorticoConfig; use GlobalPayments\Api\Services\ReportingService; -use GlobalPayments\Api\ServicesConfig; use GlobalPayments\Api\ServicesContainer; use GlobalPayments\WooCommercePaymentGatewayProvider\Data\PaymentTokenData; use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\AbstractGateway; @@ -208,10 +208,10 @@ protected function get_arg( $arg_type ) { protected function configure_sdk() { $config = $this->set_object_data( - new ServicesConfig(), + new PorticoConfig(), $this->args[ RequestArg::SERVICES_CONFIG ] ); - ServicesContainer::configure( $config ); + ServicesContainer::configureService( $config ); } protected function set_object_data( $obj, array $data ) { diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index 5740703..f6f7ae9 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -191,13 +191,15 @@ public function process_payment( $order_id ) { } // reverse the CC transaction if GC transactions didn't didn't succeed - if ( $gift_payments_successful !== true ) { + if ( !empty($gift_payments_successful)) { + if ($gift_card_order_placement !== false) { // hook directly into GP SDK to avoid collisions with the existing request Transaction::fromId( $response->transactionReference->transactionId ) - ->reverse( $request->order->data[ 'total' ] ) - ->execute(); + ->reverse( $request->order->data[ 'total' ] ) + ->execute(); - $is_successful = false; + $is_successful = false; + } } return array( diff --git a/src/Gateways/HeartlandGiftCards/HeartlandGiftCard.php b/src/Gateways/HeartlandGiftCards/HeartlandGiftCard.php index 13d44aa..08842c9 100644 --- a/src/Gateways/HeartlandGiftCards/HeartlandGiftCard.php +++ b/src/Gateways/HeartlandGiftCards/HeartlandGiftCard.php @@ -1,15 +1,15 @@ -id; - $applied_gift_cards = unserialize( get_post_meta( $order_id, '_securesubmit_used_card_data', TRUE ) ); - $original_balance = get_post_meta( $order_id, '_securesubmit_original_reported_total', TRUE ); + $applied_gift_cards = unserialize(get_post_meta($order_id, '_securesubmit_used_card_data', true)); + $original_balance = get_post_meta($order_id, '_securesubmit_original_reported_total', true); - if ( ! empty ( $applied_gift_cards ) ) { - $rows = $this->buildOrderRows( $rows, $original_balance, $applied_gift_cards ); + if (!empty($applied_gift_card)) { + $rows = $this->buildOrderRows($rows, $original_balance, $applied_gift_cards); } return $rows; } - public function addItemsToOrderDisplay( $rows ) { - if (null == WC()->session) { - return $rows; - } + public function addItemsToOrderDisplay($rows) + { + if (null == WC()->session) { + return $rows; + } - $securesubmit_data = WC()->session->get( 'securesubmit_data' ); - $applied_cards = WC()->session->get( 'heartland_gift_card_applied' ); + $securesubmit_data = WC()->session->get('securesubmit_data'); + $applied_cards = WC()->session->get('heartland_gift_card_applied'); - if ( ! empty( $applied_cards ) ) { - $rows = $this->buildOrderRows( $rows, $securesubmit_data->original_total, $applied_cards ); + if (!empty($applied_cards)) { + $rows = $this->buildOrderRows($rows, $securesubmit_data->original_total, $applied_cards); } return $rows; } - public static function processGiftCardPayment( $order_id ) { - $applied_gift_card = WC()->session->get( 'heartland_gift_card_applied' ); - $securesubmit_data = WC()->session->get( 'securesubmit_data' ); + public static function processGiftCardPayment($order_id) + { + $applied_gift_card = WC()->session->get('heartland_gift_card_applied'); + $securesubmit_data = WC()->session->get('securesubmit_data'); $order_awaiting_payment = $order_id; $giftcard_gateway = new HeartlandGiftGateway(); $gift_card_sales = array(); - foreach ( $applied_gift_card as $gift_card ) { + foreach ($applied_gift_card as $gift_card) { $gift_card_number = $gift_card->number; $gift_card_pin = $gift_card->pin; $gift_card_temp_balance = $gift_card->temp_balance; - $gift_card_balance = $giftcard_gateway->gift_card_balance( $gift_card_number, $gift_card_pin ); + $gift_card_balance = $giftcard_gateway->giftCardBalance($gift_card_number, $gift_card_pin); - if ( $gift_card_balance[ 'message' ] < $gift_card_temp_balance ) { - $giftcard_gateway->removeGiftCard( $gift_card->gift_card_id ); + if ($gift_card_balance[ 'message' ] < $gift_card_temp_balance) { + $giftcard_gateway->removeGiftCard($gift_card->gift_card_id); - $balance_message = sprintf( __( 'The %s now has a lower balance than when it was originally applied to the order. It has been removed from the order. Please add it to the order again.', 'wc_securesubmit' ), $gift_card->gift_card_name ); + $balance_message = sprintf(__('The %s now has a lower balance than when it was originally applied to the order. It has been removed from the order. Please add it to the order again.', 'wc_securesubmit'), $gift_card->gift_card_name); // Void the already done transactions if any - $giftcard_gateway->processGiftCardVoid( $gift_card_sales, $order_awaiting_payment ); + $giftcard_gateway->processGiftCardVoid($gift_card_sales, $order_awaiting_payment); - throw new Exception( $balance_message ); + throw new Exception($balance_message); } - $sale_response = $giftcard_gateway->processGiftCardSale( $gift_card_number, $gift_card_pin, $gift_card->used_amount ); - - if ( ! isset( $sale_response->responseCode ) || $sale_response->responseCode !== '00' ) { + $sale_response = $giftcard_gateway->processGiftCardSale($gift_card_number, $gift_card_pin, $gift_card->used_amount); - $error_response_message = sprintf( __( '%s was not able to be processed: %s', 'wc_securesubmit' ), $gift_card->gift_card_name, substr( $sale_response->responseMessage, 20 ) ); + if (!isset($sale_response->responseCode) || $sale_response->responseCode !== '00') { + $error_response_message = sprintf( + __('%s was not able to be processed: %s', 'wc_securesubmit'), + $gift_card->gift_card_name, + substr($sale_response->responseMessage, 20) + ); - // Void the already done transactions if any - if ( ! empty( $gift_card_sales ) ) { - - $giftcard_gateway->processGiftCardVoid( $gift_card_sales, $order_awaiting_payment ); - + if (!empty($gift_card_sales)) { + $giftcard_gateway->processGiftCardVoid($gift_card_sales, $order_awaiting_payment); } - throw new Exception( $error_response_message ); - + throw new Exception($error_response_message); } - $used_amount_positive = abs( $gift_card->used_amount ); - - $gift_card_sales[ $gift_card->gift_card_id ] = new stdClass(); - - $gift_card_sales[ $gift_card->gift_card_id ]->gift_card_name = $gift_card->gift_card_name; - $gift_card_sales[ $gift_card->gift_card_id ]->gift_card_id = $gift_card->gift_card_id; - $gift_card_sales[ $gift_card->gift_card_id ]->transaction_id = $sale_response->transactionId; - $gift_card_sales[ $gift_card->gift_card_id ]->remaining_balance = $sale_response->balanceAmount; - $gift_card_sales[ $gift_card->gift_card_id ]->used_amount = $used_amount_positive; + $used_amount_positive = abs($gift_card->used_amount); + $gift_card_sales[$gift_card->gift_card_id] = new stdClass(); + $gift_card_sales[$gift_card->gift_card_id]->gift_card_name = $gift_card->gift_card_name; + $gift_card_sales[$gift_card->gift_card_id]->gift_card_id = $gift_card->gift_card_id; + $gift_card_sales[$gift_card->gift_card_id]->transaction_id = $sale_response->transactionId; + $gift_card_sales[$gift_card->gift_card_id]->remaining_balance = $sale_response->balanceAmount; + $gift_card_sales[$gift_card->gift_card_id]->used_amount = $used_amount_positive; } - update_post_meta( $order_awaiting_payment, '_securesubmit_used_card_data', serialize( $gift_card_sales ) ); - update_post_meta( $order_awaiting_payment, '_securesubmit_original_reported_total', $securesubmit_data->original_total ); + update_post_meta($order_awaiting_payment, '_securesubmit_used_card_data', serialize($gift_card_sales)); + update_post_meta($order_awaiting_payment, '_securesubmit_original_reported_total', $securesubmit_data->original_total); - foreach ( $gift_card_sales as $gift_card_sale ) { + foreach ($gift_card_sales as $gift_card_sale) { + $balance_used = wc_price($gift_card_sale->used_amount); - $balance_used = wc_price( $gift_card_sale->used_amount ); - - $note_text = sprintf( __( '%s was used on this order with a total used amount of %s. Transaction ID: %s ', 'wc_securesubmit' ), $gift_card_sale->gift_card_name, $balance_used, $gift_card_sale->transaction_id ); - - $order = new WC_Order( $order_awaiting_payment ); - $order->add_order_note( $note_text ); + $note_text = sprintf( + __('%s was used on this order with a total used amount of %s. Transaction ID: %s ', 'wc_securesubmit'), + $gift_card_sale->gift_card_name, $balance_used, $gift_card_sale->transaction_id + ); + $order = new WC_Order($order_awaiting_payment); + $order->add_order_note($note_text); } $giftcard_gateway->removeAllGiftCardsFromSession(); return true; - } - public function processGiftCardsZeroTotal( $order_id, $posted ) { - - if ( empty( $posted[ 'payment_method' ] ) ) { - - $this->processGiftCardPayment( $order_id ); - - } - + public function processGiftCardsZeroTotal($order_id, $posted) + { + if (empty($posted['payment_method'])) { + $this->processGiftCardPayment($order_id); + } } - protected function buildOrderRows( $rows, $order_total, $applied_cards ) { + protected function buildOrderRows($rows, $order_total, $applied_cards) + { + $index_of_order_total = array_search('order_total', array_keys($rows)); - $index_of_order_total = array_search( 'order_total', array_keys( $rows ) ); - - $gift_card_array[ 'original_total' ] = array( - 'label' => __( 'Total before Gift Cards', 'wc_securesubmit' ), - 'value' => wc_price( $order_total ), + $gift_card_array['original_total'] = array( + 'label' => __('Total before Gift Cards', 'wc_securesubmit'), + 'value' => wc_price($order_total), ); - foreach ( $applied_cards as $card ) { + foreach ($applied_cards as $card) { - $gift_card_array[ $card->gift_card_id ] = array( + $gift_card_array[$card->gift_card_id] = array( 'label' => $card->gift_card_name, - 'value' => wc_price( $card->used_amount * - 1 ), + 'value' => wc_price($card->used_amount * - 1), ); } - $rows_first_part = array_slice( $rows, 0, $index_of_order_total, TRUE ); - $rows_last_part = array_slice( $rows, $index_of_order_total, PHP_INT_MAX, TRUE ); - - $rows = array_merge( $rows_first_part, $gift_card_array, $rows_last_part ); + $rows_first_part = array_slice($rows, 0, $index_of_order_total, true); + $rows_last_part = array_slice($rows, $index_of_order_total, PHP_INT_MAX, true); + $rows = array_merge($rows_first_part, $gift_card_array, $rows_last_part); return $rows; - } - - - } diff --git a/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php index 47ed501..7cf5886 100644 --- a/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php +++ b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php @@ -1,342 +1,374 @@ -secret_api_key = $HeartlandGateway->get_backend_gateway_options()['secretApiKey']; - } - - protected $temp_balance; - protected $gift_card_pin_submitted; - - protected function configureServiceContainer() { - $config = new ServicesConfig(); - $config->secretApiKey = $this->secret_api_key; - // $config->developerId = "123456"; // need these from SS team - // $config->versionNumber = "1234"; - - ServicesContainer::configure($config); - } - - public function applyGiftCard() { - - $gift_card_balance = $this->gift_card_balance( - $_POST['gift_card_number'], - $_POST['gift_card_pin'] - ); - - if ($gift_card_balance['error']) { - echo json_encode(array( - 'error' => 1, - 'message' => $gift_card_balance['message'], - )); - } else { - $this->temp_balance = $gift_card_balance['message']; - - $this->addGiftCardToCartSession(); - $this->updateGiftCardCartTotal(); - echo json_encode(array( - 'error' => 0, - 'balance' => html_entity_decode(get_woocommerce_currency_symbol()) . $gift_card_balance['message'], - )); - } - - wp_die(); - } - - public function gift_card_balance($gift_card_number, $gift_card_pin) - { - $this->configureServiceContainer(); - - if (empty($gift_card_pin)) { - return array( - 'error' => true, - 'message' => "PINs are required. Please enter a PIN and click apply again.", - ); - } - - $this->gift_card = $this->giftCardObject($gift_card_number, $gift_card_pin); - - try { - $response = $this->gift_card->balanceInquiry() - ->execute(); - } catch (Exception $e) { - return array( - 'error' => true, - 'message' => "The gift card number you entered is either incorrect or not yet activated.", - ); - } - - return array( - 'error' => false, - 'message' => $response->balanceAmount, - ); - } - - protected function giftCardObject($gift_card_number, $gift_card_pin) - { - $gift_card = new HeartlandGiftCard(); - $gift_card->number = $gift_card_number; - $gift_card->pin = $gift_card_pin; - - return $gift_card; - } - - protected function addGiftCardToCartSession() - { - $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); - $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); - $this->gift_card->temp_balance = floatval($this->temp_balance); - - WC()->session->set('securesubmit_gift_card_object', $this->gift_card); - } - - protected function giftCardName($gift_card_number) - { - $digits_to_display = 5; - $last_digits = substr($gift_card_number, $digits_to_display * - 1); - - return __( 'Gift Card', 'wc_securesubmit' ) . ' ' . $last_digits; - } - - protected function updateGiftCardCartTotal() - { - $gift_card_object_entered = WC()->session->get('securesubmit_gift_card_object'); - if (is_null($gift_card_object_entered)) { - $gift_card_object_entered = (object)array(); - } - - $gift_card_object_applied = WC()->session->get('heartland_gift_card_applied'); - if (is_null($gift_card_object_applied)) { - $gift_card_object_applied = (object)array(); - } - - $original_total = $this->getOriginalCartTotal(); - - $securesubmit_data = WC()->session->get('securesubmit_data'); - if (!is_object($securesubmit_data)) { - $securesubmit_data = new stdClass(); - } - - $securesubmit_data->original_total = $original_total; - WC()->session->set('securesubmit_data', $securesubmit_data); - - $this->updateGiftCardTotals(); - - if (is_object($gift_card_object_entered) && count(get_object_vars($gift_card_object_entered)) > 0) { - if ($gift_card_object_entered->temp_balance === '0.00') { - WC()->session->__unset('securesubmit_gift_card_object'); - - $zero_balance_message = apply_filters( - 'securesubmit_zero_balance_message', - sprintf( - __('%s has a balance of zero and could not be applied to this order.', 'wc_securesubmit'), - $gift_card_object_entered->gift_card_name - ) - ); - - wc_add_notice($zero_balance_message, 'error'); - } else { - if (!(is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0)) { - $gift_card_object_applied = new stdClass; - } - - $gift_card_object_entered->used_amount = $this->giftCardUsageAmount(); - $gift_card_object_applied->{$gift_card_object_entered->gift_card_id} = $gift_card_object_entered; - - WC()->session->set('heartland_gift_card_applied', $gift_card_object_applied); - WC()->session->__unset('securesubmit_gift_card_object'); - } - } - - return $gift_card_object_applied; - } - - protected function getOriginalCartTotal() - { - $cart_totals = WC()->session->get('cart_totals'); - $original_total = round( - array_sum( - array( - (!empty($cart_totals['subtotal']) ? $cart_totals['subtotal'] : 0), - (!empty($cart_totals['subtotal_tax']) ? $cart_totals['subtotal_tax'] : 0), - (!empty($cart_totals['shipping_total']) ? $cart_totals['shipping_total'] : 0), - (!empty($cart_totals['shipping_tax']) ? $cart_totals['shipping_tax'] : 0), - (!empty($cart_totals['fee_total']) ? $cart_totals['fee_total'] : 0), - (!empty($cart_totals['fee_tax']) ? $cart_totals['fee_tax'] : 0), - ) - ), - 2 - ); - return $original_total; - } - - protected function updateGiftCardTotals() - { - $gift_cards_applied = WC()->session->get('heartland_gift_card_applied'); - - $original_total = $this->getOriginalCartTotal(); - $remaining_total = $original_total; - - if (is_object($gift_cards_applied) && count(get_object_vars($gift_cards_applied)) > 0) { - foreach ($gift_cards_applied as $gift_card) { - $order_total_after_gift_card = $remaining_total - $gift_card->temp_balance; - - if ($order_total_after_gift_card > 0) { - $gift_card->used_amount = $gift_card->temp_balance; - } else { - $gift_card->used_amount = $remaining_total; - } - - $gift_cards_applied->{$gift_card->gift_card_id} = $gift_card; - $remaining_total = $remaining_total - $gift_card->used_amount; - } - } - - WC()->session->set('heartland_gift_card_applied', $gift_cards_applied); - } - - protected function giftCardUsageAmount($updated = false) - { - - $cart_totals = WC()->session->get('cart_totals'); - $cart_total = round($cart_totals['total'], 2); - $gift_card_object = WC()->session->get('securesubmit_gift_card_object'); - - if (round($gift_card_object->temp_balance, 2) <= $cart_total) { - $gift_card_applied_amount = $gift_card_object->temp_balance; - } else { - $gift_card_applied_amount = $cart_total; - } - - return $gift_card_applied_amount; - } - - public function addGiftCards() - { - // TODO: Add warnings and success messages - // $gift_cards_allowed = $this->giftCardsAllowed(); - $gift_cards_allowed = true; - - // No gift cards if there are subscription products in the cart - if ($gift_cards_allowed) { - $original_total = $this->getOriginalCartTotal(); - $gift_card_object_applied = $this->updateGiftCardCartTotal(); - - if (is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0) { - $securesubmit_data = WC()->session->get('securesubmit_data'); - $securesubmit_data->original_total = $original_total; - WC()->session->set('securesubmit_data', $securesubmit_data); - - $message = __( 'Total Before Gift Cards', 'wc_securesubmit' ); - - $order_total_html = ''; - $order_total_html .= '' . $message . ''; - $order_total_html .= '' . wc_price($original_total) . ''; - $order_total_html .= ''; - - echo apply_filters('securesubmit_before_gift_cards_order_total', $order_total_html, $original_total, $message); - - foreach ($gift_card_object_applied as $applied_gift_card) { - $remove_link = '(Remove)'; - - $gift_card_html = ''; - $gift_card_html .= '' . $applied_gift_card->gift_card_name . ' ' . $remove_link . ''; - $gift_card_html .= '' . wc_price($applied_gift_card->used_amount) . ''; - $gift_card_html .= ''; - - echo apply_filters('securesubmit_gift_card_used_total', $gift_card_html, $applied_gift_card->gift_card_name, $remove_link, $applied_gift_card->used_amount); - } - } - } else { - $applied_cards = WC()->session->get('heartland_gift_card_applied'); - - $this->removeAllGiftCardsFromSession(); - - if (is_object($applied_cards) && count(get_object_vars($applied_cards)) > 0) { - wc_add_notice(__('Sorry, we are unable to allow gift cards to be used when purchasing a subscription. Any gift cards already applied to the order have been cleared', 'wc_securesubmit'), 'notice'); - } - } - } - - public function updateOrderTotal($cart_total, $cart_object) - { - $gift_cards = WC()->session->get('heartland_gift_card_applied'); - - if (is_object($gift_cards) && count(get_object_vars($gift_cards)) > 0) { - $gift_card_totals = $this->getGiftCardTotals(); - $cart_total = $cart_total + $gift_card_totals; - } - - return $cart_total; - } - - protected function getGiftCardTotals() - { - $this->updateGiftCardTotals(); - $gift_cards = WC()->session->get('heartland_gift_card_applied'); - - if (!empty($gift_cards)) { - $total = 0; - - foreach ($gift_cards as $gift_card) { - $total -= $gift_card->used_amount; - } - - return $total; - } - } - - public function processGiftCardSale($card_number, $card_pin, $used_amount) - { - $card = $this->giftCardObject($card_number, $card_pin); - $rounded_amount = round($used_amount, 2); - $positive_amount = abs($rounded_amount); - - $response = $card->charge($positive_amount) - ->withCurrency('USD') - ->execute(); - - return $response; - } - - public function removeAllGiftCardsFromSession() - { - WC()->session->__unset('heartland_gift_card_applied'); - WC()->session->__unset('securesubmit_gift_card_object'); - WC()->session->__unset('securesubmit_data'); - } - - public function removeGiftCard($removed_card = null) - { - if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { - $removed_card = $_POST['securesubmit_card_id']; - } - - $applied_cards = WC()->session->get('heartland_gift_card_applied'); - - unset($applied_cards->{$removed_card}); - - if (count((array) $applied_cards) > 0) { - WC()->session->set('heartland_gift_card_applied', $applied_cards); - } else { - WC()->session->__unset('heartland_gift_card_applied'); - } - - if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { - echo ''; - wp_die(); - } - } -} +secret_api_key = $HeartlandGateway->get_backend_gateway_options()['secretApiKey']; + } + + protected $temp_balance; + protected $gift_card_pin_submitted; + + protected function configureServiceContainer() + { + $config = new PorticoConfig(); + $config->secretApiKey = $this->secret_api_key; + // $config->developerId = "123456"; // need these from SS team + // $config->versionNumber = "1234"; + + ServicesContainer::configureService($config); + } + + public function applyGiftCard() + { + $gift_card_balance = $this->giftCardBalance( + $_POST['gift_card_number'], + $_POST['gift_card_pin'] + ); + + if ($gift_card_balance['error']) { + echo json_encode( + array( + 'error' => 1, + 'message' => $gift_card_balance['message'], + ) + ); + } else { + $this->temp_balance = $gift_card_balance['message']; + + $this->addGiftCardToCartSession(); + $this->updateGiftCardCartTotal(); + + echo json_encode( + array( + 'error' => 0, + 'balance' => html_entity_decode(get_woocommerce_currency_symbol()) . $gift_card_balance['message'], + ) + ); + } + + wp_die(); + } + + public function giftCardBalance($gift_card_number, $gift_card_pin) + { + $this->configureServiceContainer(); + + if (empty($gift_card_pin)) { + return array( + 'error' => true, + 'message' => "PINs are required. Please enter a PIN and click apply again.", + ); + } + + $this->gift_card = $this->giftCardObject($gift_card_number, $gift_card_pin); + + try { + $response = $this->gift_card->balanceInquiry() + ->execute(); + } catch (Exception $e) { + return array( + 'error' => true, + 'message' => "The gift card number you entered is either incorrect or not yet activated.", + ); + } + + return array( + 'error' => false, + 'message' => $response->balanceAmount, + ); + } + + protected function giftCardObject($gift_card_number, $gift_card_pin) + { + $gift_card = new HeartlandGiftCard(); + $gift_card->number = $gift_card_number; + $gift_card->pin = $gift_card_pin; + + return $gift_card; + } + + protected function addGiftCardToCartSession() + { + $this->gift_card->gift_card_name = $this->giftCardName($this->gift_card->number); + $this->gift_card->gift_card_id = sanitize_title($this->gift_card->gift_card_name); + $this->gift_card->temp_balance = floatval($this->temp_balance); + + WC()->session->set('securesubmit_gift_card_object', $this->gift_card); + } + + protected function giftCardName($gift_card_number) + { + $digits_to_display = 5; + $last_digits = substr($gift_card_number, $digits_to_display * - 1); + + return __('Gift Card', 'wc_securesubmit') . ' ' . $last_digits; + } + + protected function updateGiftCardCartTotal() + { + $gift_card_object_entered = WC()->session->get('securesubmit_gift_card_object'); + if (is_null($gift_card_object_entered)) { + $gift_card_object_entered = (object)array(); + } + + $gift_card_object_applied = WC()->session->get('heartland_gift_card_applied'); + if (is_null($gift_card_object_applied)) { + $gift_card_object_applied = (object)array(); + } + + $original_total = $this->getOriginalCartTotal(); + + $securesubmit_data = WC()->session->get('securesubmit_data'); + if (!is_object($securesubmit_data)) { + $securesubmit_data = new stdClass(); + } + + $securesubmit_data->original_total = $original_total; + WC()->session->set('securesubmit_data', $securesubmit_data); + + $this->updateGiftCardTotals(); + + if (is_object($gift_card_object_entered) && count(get_object_vars($gift_card_object_entered)) > 0) { + if ($gift_card_object_entered->temp_balance === '0.00') { + WC()->session->__unset('securesubmit_gift_card_object'); + + $zero_balance_message = apply_filters( + 'securesubmit_zero_balance_message', + sprintf( + __('%s has a balance of zero and could not be applied to this order.', 'wc_securesubmit'), + $gift_card_object_entered->gift_card_name + ) + ); + + wc_add_notice($zero_balance_message, 'error'); + } else { + if (!(is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0)) { + $gift_card_object_applied = new stdClass; + } + + $gift_card_object_entered->used_amount = $this->giftCardUsageAmount(); + $gift_card_object_applied->{$gift_card_object_entered->gift_card_id} = $gift_card_object_entered; + + WC()->session->set('heartland_gift_card_applied', $gift_card_object_applied); + WC()->session->__unset('securesubmit_gift_card_object'); + } + } + + return $gift_card_object_applied; + } + + protected function getOriginalCartTotal() + { + $cart_totals = WC()->session->get('cart_totals'); + $original_total = round( + array_sum( + array( + (!empty($cart_totals['subtotal']) ? $cart_totals['subtotal'] : 0), + (!empty($cart_totals['subtotal_tax']) ? $cart_totals['subtotal_tax'] : 0), + (!empty($cart_totals['shipping_total']) ? $cart_totals['shipping_total'] : 0), + (!empty($cart_totals['shipping_tax']) ? $cart_totals['shipping_tax'] : 0), + (!empty($cart_totals['fee_total']) ? $cart_totals['fee_total'] : 0), + (!empty($cart_totals['fee_tax']) ? $cart_totals['fee_tax'] : 0), + ) + ), + 2 + ); + return $original_total; + } + + protected function updateGiftCardTotals() + { + $gift_cards_applied = WC()->session->get('heartland_gift_card_applied'); + + $original_total = $this->getOriginalCartTotal(); + $remaining_total = $original_total; + + if (is_object($gift_cards_applied) && count(get_object_vars($gift_cards_applied)) > 0) { + foreach ($gift_cards_applied as $gift_card) { + $order_total_after_gift_card = $remaining_total - $gift_card->temp_balance; + + if ($order_total_after_gift_card > 0) { + $gift_card->used_amount = $gift_card->temp_balance; + } else { + $gift_card->used_amount = $remaining_total; + } + + $gift_cards_applied->{$gift_card->gift_card_id} = $gift_card; + $remaining_total = $remaining_total - $gift_card->used_amount; + } + } + + WC()->session->set('heartland_gift_card_applied', $gift_cards_applied); + } + + protected function giftCardUsageAmount($updated = false) + { + + $cart_totals = WC()->session->get('cart_totals'); + $cart_total = round($cart_totals['total'], 2); + $gift_card_object = WC()->session->get('securesubmit_gift_card_object'); + + if (round($gift_card_object->temp_balance, 2) <= $cart_total) { + $gift_card_applied_amount = $gift_card_object->temp_balance; + } else { + $gift_card_applied_amount = $cart_total; + } + + return $gift_card_applied_amount; + } + + public function addGiftCards() + { + // TODO: Add warnings and success messages + // $gift_cards_allowed = $this->giftCardsAllowed(); + $gift_cards_allowed = true; + + // No gift cards if there are subscription products in the cart + if ($gift_cards_allowed) { + $original_total = $this->getOriginalCartTotal(); + $gift_card_object_applied = $this->updateGiftCardCartTotal(); + + if (is_object($gift_card_object_applied) && count(get_object_vars($gift_card_object_applied)) > 0) { + $securesubmit_data = WC()->session->get('securesubmit_data'); + $securesubmit_data->original_total = $original_total; + WC()->session->set('securesubmit_data', $securesubmit_data); + + $message = __('Total Before Gift Cards', 'wc_securesubmit'); + + $order_total_html = ''; + $order_total_html .= '' . $message . ''; + $order_total_html .= '' . wc_price($original_total) . ''; + $order_total_html .= ''; + + echo apply_filters('securesubmit_before_gift_cards_order_total', $order_total_html, $original_total, $message); + + foreach ($gift_card_object_applied as $applied_gift_card) { + $remove_link = '(Remove)'; + + $gift_card_html = ''; + $gift_card_html .= '' . $applied_gift_card->gift_card_name . ' ' . $remove_link . ''; + $gift_card_html .= '' . wc_price($applied_gift_card->used_amount) . ''; + $gift_card_html .= ''; + + echo apply_filters('securesubmit_gift_card_used_total', $gift_card_html, $applied_gift_card->gift_card_name, $remove_link, $applied_gift_card->used_amount); + } + } + } else { + $applied_cards = WC()->session->get('heartland_gift_card_applied'); + + $this->removeAllGiftCardsFromSession(); + + if (is_object($applied_cards) && count(get_object_vars($applied_cards)) > 0) { + wc_add_notice(__('Sorry, we are unable to allow gift cards to be used when purchasing a subscription. Any gift cards already applied to the order have been cleared', 'wc_securesubmit'), 'notice'); + } + } + } + + public function updateOrderTotal($cart_total, $cart_object) + { + $gift_cards = WC()->session->get('heartland_gift_card_applied'); + + if (is_object($gift_cards) && count(get_object_vars($gift_cards)) > 0) { + $gift_card_totals = $this->getGiftCardTotals(); + $cart_total = $cart_total + $gift_card_totals; + } + + return $cart_total; + } + + protected function getGiftCardTotals() + { + $this->updateGiftCardTotals(); + $gift_cards = WC()->session->get('heartland_gift_card_applied'); + + if (!empty($gift_cards)) { + $total = 0; + + foreach ($gift_cards as $gift_card) { + $total -= $gift_card->used_amount; + } + + return $total; + } + } + + public function processGiftCardSale($card_number, $card_pin, $used_amount) + { + $card = $this->giftCardObject($card_number, $card_pin); + $rounded_amount = round($used_amount, 2); + $positive_amount = abs($rounded_amount); + + $response = $card->charge($positive_amount) + ->withCurrency('USD') + ->execute(); + + return $response; + } + + public function removeAllGiftCardsFromSession() + { + WC()->session->__unset('heartland_gift_card_applied'); + WC()->session->__unset('securesubmit_gift_card_object'); + WC()->session->__unset('securesubmit_data'); + } + + public function removeGiftCard($removed_card = null) + { + if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { + $removed_card = $_POST['securesubmit_card_id']; + } + + $applied_cards = WC()->session->get('heartland_gift_card_applied'); + + unset($applied_cards->{$removed_card}); + + if (count((array) $applied_cards) > 0) { + WC()->session->set('heartland_gift_card_applied', $applied_cards); + } else { + WC()->session->__unset('heartland_gift_card_applied'); + } + + if (isset($_POST['securesubmit_card_id']) && empty($removed_card)) { + echo ''; + wp_die(); + } + } + + public function processGiftCardVoid($processed_cards, $order_id) + { + if (!empty($processed_cards)) { + foreach ($processed_cards as $card_id => $card) { + try { + $response = Transaction::fromId($card->transactionId) + ->void() + ->execute(); + } catch (Exception $e) { + } + + if (isset($response->responseCode) && $response->responseCode === '0') { + unset($processed_cards[$card_id]); + } + } + } else { + $response = false; + delete_post_meta($order_id, '_securesubmit_used_card_data'); + } + + return $response; + } +} From ba9d8166efd3c090c1bf2c92eecada54fa074b14 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 7 Dec 2020 11:01:49 -0500 Subject: [PATCH 12/57] update Heartland details --- src/Gateways/HeartlandGateway.php | 4 +++- src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index f6f7ae9..07dc130 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -45,7 +45,7 @@ public function configure_method_settings() { } public function get_first_line_support_email() { - return 'securesubmitcert@e-hps.com'; + return 'onlinepayments@heartland.us'; } public function get_gateway_form_fields() { @@ -83,6 +83,8 @@ public function get_frontend_gateway_options() { public function get_backend_gateway_options() { return array( 'secretApiKey' => $this->secret_key, + 'versionNumber' => '1510', + 'developerId' => '002914' ); } diff --git a/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php index 7cf5886..6f93161 100644 --- a/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php +++ b/src/Gateways/HeartlandGiftCards/HeartlandGiftGateway.php @@ -27,8 +27,8 @@ protected function configureServiceContainer() { $config = new PorticoConfig(); $config->secretApiKey = $this->secret_api_key; - // $config->developerId = "123456"; // need these from SS team - // $config->versionNumber = "1234"; + $config->developerId = "002914"; + $config->versionNumber = "1510"; ServicesContainer::configureService($config); } From e116f921d2938fba61e1a2fc6a443dac8aad0617 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 14 Dec 2020 13:01:02 -0500 Subject: [PATCH 13/57] support SDK 2.1^ --- src/Gateways/Clients/SdkClient.php | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 4b1fb7c..bda9060 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -6,9 +6,14 @@ use GlobalPayments\Api\Entities\Address; use GlobalPayments\Api\Entities\Transaction; use GlobalPayments\Api\Entities\Enums\AddressType; +use GlobalPayments\Api\Entities\Enums\GatewayProvider; use GlobalPayments\Api\Gateways\IPaymentGateway; use GlobalPayments\Api\PaymentMethods\CreditCardData; +use GlobalPayments\Api\ServiceConfigs\AcceptorConfig; +use GlobalPayments\Api\ServiceConfigs\Gateways\GatewayConfig; +use GlobalPayments\Api\ServiceConfigs\Gateways\GeniusConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\PorticoConfig; +use GlobalPayments\Api\ServiceConfigs\Gateways\TransitConfig; use GlobalPayments\Api\Services\ReportingService; use GlobalPayments\Api\ServicesContainer; use GlobalPayments\WooCommercePaymentGatewayProvider\Data\PaymentTokenData; @@ -207,10 +212,24 @@ protected function get_arg( $arg_type ) { } protected function configure_sdk() { - $config = $this->set_object_data( - new PorticoConfig(), + switch ($this->args['SERVICES_CONFIG']['gatewayProvider']) { + case GatewayProvider::PORTICO: + $gatewayConfig = new PorticoConfig(); + break; + case GatewayProvider::TRANSIT: + $gatewayConfig = new TransitConfig(); + $gatewayConfig->acceptorConfig = new AcceptorConfig(); // defaults should work here + break; + case GatewayProvider::GENIUS: + $gatewayConfig = new GeniusConfig(); + break; + } + + $config = $this->set_object_data( + $gatewayConfig, $this->args[ RequestArg::SERVICES_CONFIG ] ); + ServicesContainer::configureService( $config ); } From 5637d55f4ecde8fb4423d36e6fc67cdddc2376ea Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 14 Dec 2020 13:01:20 -0500 Subject: [PATCH 14/57] fix partial gift payments --- src/Gateways/HeartlandGateway.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index 07dc130..d5cc8cb 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -193,14 +193,15 @@ public function process_payment( $order_id ) { } // reverse the CC transaction if GC transactions didn't didn't succeed - if ( !empty($gift_payments_successful)) { + if (!$gift_payments_successful) { if ($gift_card_order_placement !== false) { + // hook directly into GP SDK to avoid collisions with the existing request Transaction::fromId( $response->transactionReference->transactionId ) - ->reverse( $request->order->data[ 'total' ] ) - ->execute(); + ->reverse( $request->order->data[ 'total' ] ) + ->execute(); - $is_successful = false; + $is_successful = false; } } From e7d09bb7adb3170bc2e4f5458b59e0abf5383d1d Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Thu, 7 Jan 2021 10:37:56 -0500 Subject: [PATCH 15/57] 1-7-21 notes --- todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/todo.txt b/todo.txt index 006d2c5..31ec7b6 100644 --- a/todo.txt +++ b/todo.txt @@ -68,3 +68,6 @@ admin capture auth capture verify refund / reverse + +Tony Notes: +12/7 - TransIT generate key wont' work until new version of SDK is pulled in \ No newline at end of file From a06728855d2c814782246dc64ddd5381ea741ab8 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Thu, 7 Jan 2021 15:01:43 -0500 Subject: [PATCH 16/57] 1-7-21 --- src/Gateways/Clients/SdkClient.php | 2 +- src/Gateways/HeartlandGateway.php | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index bda9060..fa125ec 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -122,7 +122,7 @@ protected function prepare_builder( TransactionBuilder $builder ) { */ protected function get_transaction_builder() { if ( in_array( $this->get_arg( RequestArg::TXN_TYPE ), $this->client_transactions, true ) ) { - return ServicesContainer::instance()->getClient(); + return ServicesContainer::instance()->getClient( 'default' ); // this value should always be safe here } if ( $this->get_arg( RequestArg::TXN_TYPE ) === 'transactionDetail' ) { diff --git a/src/Gateways/HeartlandGateway.php b/src/Gateways/HeartlandGateway.php index d5cc8cb..486299a 100644 --- a/src/Gateways/HeartlandGateway.php +++ b/src/Gateways/HeartlandGateway.php @@ -190,20 +190,20 @@ public function process_payment( $order_id ) { if ( $is_successful && !empty( WC()->session->get( 'heartland_gift_card_applied' ) ) ) { $gift_card_order_placement = new HeartlandGiftCardOrder(); $gift_payments_successful = $gift_card_order_placement->processGiftCardPayment( $order_id ); - } - // reverse the CC transaction if GC transactions didn't didn't succeed - if (!$gift_payments_successful) { - if ($gift_card_order_placement !== false) { + // reverse the CC transaction if GC transactions didn't didn't succeed + if (!$gift_payments_successful) { + if ($gift_card_order_placement !== false) { - // hook directly into GP SDK to avoid collisions with the existing request - Transaction::fromId( $response->transactionReference->transactionId ) - ->reverse( $request->order->data[ 'total' ] ) - ->execute(); + // hook directly into GP SDK to avoid collisions with the existing request + Transaction::fromId( $response->transactionReference->transactionId ) + ->reverse( $request->order->data[ 'total' ] ) + ->execute(); - $is_successful = false; - } - } + $is_successful = false; + } + } + } return array( 'result' => $is_successful ? 'success' : 'failure', From 3f77a8ef691bc6bfef0d46f46a46e30b137e06a2 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Thu, 7 Jan 2021 15:31:19 -0500 Subject: [PATCH 17/57] 1-7-21 --- todo.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/todo.txt b/todo.txt index 31ec7b6..ff6e67d 100644 --- a/todo.txt +++ b/todo.txt @@ -70,4 +70,3 @@ admin refund / reverse Tony Notes: -12/7 - TransIT generate key wont' work until new version of SDK is pulled in \ No newline at end of file From f4a33d2e573ca7db485d76197a0557758fb1fe66 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Fri, 8 Jan 2021 13:27:23 -0500 Subject: [PATCH 18/57] 1-8-21 --- .../globalpayments-secure-payment-fields.js | 65 ++++++++++++------- composer.json | 2 +- src/Gateways/AbstractGateway.php | 2 +- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index dad1d36..8698b2b 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -12,6 +12,14 @@ * @param {object} options */ function GlobalPaymentsWooCommerce(options) { + + /** + * Card form instance + * + * @type {any} + */ + this.cardForm = {}; + /** * Payment gateway id * @@ -114,17 +122,17 @@ GlobalPayments.configure( this.gatewayOptions ); - var cardForm = GlobalPayments.ui.form( + this.cardForm = GlobalPayments.ui.form( { fields: this.getFieldConfiguration(), styles: this.getStyleConfiguration() } ); - cardForm.on( 'submit', 'click', this.blockOnSubmit.bind( this ) ); - cardForm.on( 'token-success', this.handleResponse.bind( this ) ); - cardForm.on( 'token-error', this.handleErrors.bind( this ) ); - cardForm.on( 'error', this.handleErrors.bind( this ) ); + this.cardForm.on( 'submit', 'click', this.blockOnSubmit.bind( this ) ); + this.cardForm.on( 'token-success', this.handleResponse.bind( this ) ); + this.cardForm.on( 'token-error', this.handleErrors.bind( this ) ); + this.cardForm.on( 'error', this.handleErrors.bind( this ) ); GlobalPayments.on( 'error', this.handleErrors.bind( this ) ); }, @@ -181,23 +189,36 @@ return; } - var tokenResponseElement = - /** - * Get hidden - * - * @type {HTMLInputElement} - */ - (document.getElementById( this.id + '-token_response' )); - if ( ! tokenResponseElement) { - tokenResponseElement = document.createElement( 'input' ); - tokenResponseElement.id = this.id + '-token_response'; - tokenResponseElement.name = this.id + '[token_response]'; - tokenResponseElement.type = 'hidden'; - this.getForm().appendChild( tokenResponseElement ); - } + console.log(response); + + this.cardForm.frames["card-cvv"].getCvv().then(function (c) { + + // never makes it here + alert(c); + + var tokenResponseElement = + /** + * Get hidden + * + * @type {HTMLInputElement} + */ + (document.getElementById( this.id + '-token_response' )); + if ( ! tokenResponseElement) { + tokenResponseElement = document.createElement( 'input' ); + tokenResponseElement.id = this.id + '-token_response'; + tokenResponseElement.name = this.id + '[token_response]'; + tokenResponseElement.type = 'hidden'; + this.getForm().appendChild( tokenResponseElement ); + } + + tokenResponseElement.value = JSON.stringify( response ); + this.placeOrder(); + + }); + + + - tokenResponseElement.value = JSON.stringify( response ); - this.placeOrder(); }, /** @@ -335,7 +356,7 @@ * @returns {object} */ getStyleConfiguration: function () { - var imageBase = 'https://api2.heartlandportico.com/securesubmit.v1/token/gp-1.3.0/assets'; + var imageBase = 'https://api2.heartlandportico.com/securesubmit.v1/token/gp-1.6.0/assets'; return { 'html': { 'font-size': '62.5%' diff --git a/composer.json b/composer.json index 1cd103b..2fd9b08 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "type": "wordpress-plugin", "require": { "composer/installers": "^1.7", - "globalpayments/php-sdk": "2.1.*" + "globalpayments/php-sdk": "^2.2.3" }, "require-dev": { "phpunit/phpunit": "^7.5", diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index d6b543e..3eb282f 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -242,7 +242,7 @@ public function tokenization_script() { // Global Payments scripts for handling client-side tokenization wp_enqueue_script( 'globalpayments-secure-payment-fields-lib', - 'https://api2.heartlandportico.com/securesubmit.v1/token/gp-1.3.0/globalpayments' + 'https://api2.heartlandportico.com/securesubmit.v1/token/gp-1.6.0/globalpayments' . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js', array(), WC()->version, From 0e1892d38f2f1ffc8971388fbc6bf905aee0b4ac Mon Sep 17 00:00:00 2001 From: Shane Logsdon Date: Fri, 8 Jan 2021 14:33:24 -0500 Subject: [PATCH 19/57] transit: correct checkout issue when getting cvv --- .../js/globalpayments-secure-payment-fields.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index 8698b2b..27522b5 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -191,6 +191,8 @@ console.log(response); + var that = this; + this.cardForm.frames["card-cvv"].getCvv().then(function (c) { // never makes it here @@ -202,23 +204,19 @@ * * @type {HTMLInputElement} */ - (document.getElementById( this.id + '-token_response' )); + (document.getElementById( that.id + '-token_response' )); if ( ! tokenResponseElement) { tokenResponseElement = document.createElement( 'input' ); - tokenResponseElement.id = this.id + '-token_response'; - tokenResponseElement.name = this.id + '[token_response]'; + tokenResponseElement.id = that.id + '-token_response'; + tokenResponseElement.name = that.id + '[token_response]'; tokenResponseElement.type = 'hidden'; - this.getForm().appendChild( tokenResponseElement ); + that.getForm().appendChild( tokenResponseElement ); } tokenResponseElement.value = JSON.stringify( response ); - this.placeOrder(); + that.placeOrder(); }); - - - - }, /** From eb74d68dcbfe7d4f1835b5c2682a9384b8302e2b Mon Sep 17 00:00:00 2001 From: Shane Logsdon Date: Fri, 8 Jan 2021 14:34:00 -0500 Subject: [PATCH 20/57] prevent fields from being rendered more than once --- assets/frontend/js/globalpayments-secure-payment-fields.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index 27522b5..7968953 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -109,6 +109,10 @@ * @returns */ renderPaymentFields: function () { + if ( $( '#' + this.id + '-' + this.fieldOptions['card-number-field'].class ).children().length > 0 ) { + return; + } + if ( ! GlobalPayments.configure ) { console.log( 'Warning! Payment fields cannot be loaded' ); return; From 87fa84366fbcedff6c838f10bab37b8466f37a7d Mon Sep 17 00:00:00 2001 From: Shane Logsdon Date: Fri, 8 Jan 2021 14:47:53 -0500 Subject: [PATCH 21/57] ensure submit is shown when needed on first render --- .../js/globalpayments-secure-payment-fields.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index 7968953..9d24a51 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -138,6 +138,11 @@ this.cardForm.on( 'token-error', this.handleErrors.bind( this ) ); this.cardForm.on( 'error', this.handleErrors.bind( this ) ); GlobalPayments.on( 'error', this.handleErrors.bind( this ) ); + + // match the visibility of our payment form + this.cardForm.ready( function () { + this.toggleSubmitButtons(); + } ); }, /** @@ -150,7 +155,7 @@ el.id = this.getSubmitButtonTargetSelector().replace( '#', '' ); el.className = 'globalpayments ' + this.id + ' card-submit'; $( this.getPlaceOrderButtonSelector() ).after( el ); - // match the visibilit of our payment form + // match the visibility of our payment form this.toggleSubmitButtons(); }, @@ -162,7 +167,7 @@ */ toggleSubmitButtons: function () { var paymentGatewaySelected = $( this.getPaymentMethodRadioSelector() ).is( ':checked' ); - var savedCardsAvailable = $( this.getStoredPaymentMethodsRadioSelector() ).length > 0; + var savedCardsAvailable = $( this.getStoredPaymentMethodsRadioSelector() + '[value!="new"]' ).length > 0; var newSavedCardSelected = 'new' === $( this.getStoredPaymentMethodsRadioSelector() + ':checked' ).val(); var shouldBeVisible = (paymentGatewaySelected && ! savedCardsAvailable) || (savedCardsAvailable && newSavedCardSelected); @@ -198,7 +203,6 @@ var that = this; this.cardForm.frames["card-cvv"].getCvv().then(function (c) { - // never makes it here alert(c); From 33e148a31e9adf29aa17216a92917ef9d6f497d7 Mon Sep 17 00:00:00 2001 From: Shane Logsdon Date: Fri, 8 Jan 2021 15:02:19 -0500 Subject: [PATCH 22/57] only save token when needed --- src/Data/PaymentTokenData.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Data/PaymentTokenData.php b/src/Data/PaymentTokenData.php index 3ad5da2..94fedf8 100644 --- a/src/Data/PaymentTokenData.php +++ b/src/Data/PaymentTokenData.php @@ -59,6 +59,11 @@ public function save_new_token( $multi_use_token ) { } $token = $this->get_single_use_token(); + + if ( ! $token->get_meta( self::KEY_SHOULD_SAVE_TOKEN, true ) ) { + return; + } + $token->set_token( $multi_use_token ); $token->set_user_id( $user_id ); $token->set_gateway_id( $this->request->gateway_id ); From 0ecc936363fe55de12d95e417589b96fc78744e6 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 11 Jan 2021 10:21:54 -0500 Subject: [PATCH 23/57] TransIT is ready --- .../js/globalpayments-secure-payment-fields.js | 11 ++++++++--- src/Data/PaymentTokenData.php | 9 +++++++++ src/Gateways/Clients/SdkClient.php | 5 ++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index 9d24a51..b9248c4 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -203,8 +203,13 @@ var that = this; this.cardForm.frames["card-cvv"].getCvv().then(function (c) { - // never makes it here - alert(c); + + /** + * CVV; needed for TransIT gateway processing only + * + * @type {string} + */ + var cvvVal = c; var tokenResponseElement = /** @@ -221,9 +226,9 @@ that.getForm().appendChild( tokenResponseElement ); } + response.details.cardSecurityCode = cvvVal; tokenResponseElement.value = JSON.stringify( response ); that.placeOrder(); - }); }, diff --git a/src/Data/PaymentTokenData.php b/src/Data/PaymentTokenData.php index 94fedf8..379472c 100644 --- a/src/Data/PaymentTokenData.php +++ b/src/Data/PaymentTokenData.php @@ -26,6 +26,13 @@ class PaymentTokenData { */ protected $request; + /** + * Used w/TransIT gateway + * + * @var string + */ + public static $tsepCvv = null; + /** * Standardize getting single- and multi-use token data * @@ -96,6 +103,8 @@ public function get_single_use_token() { $token->set_expiry_month( $data->details->expiryMonth ); } + static::$tsepCvv = isset( $data->details->cardSecurityCode ) ? $data->details->cardSecurityCode : null; + if ( isset( $data->details->cardType ) && isset( $this->card_type_map[ $data->details->cardType ] ) ) { $token->set_card_type( $this->card_type_map[ $data->details->cardType ] ); } diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index fa125ec..5f4a2a8 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -10,7 +10,6 @@ use GlobalPayments\Api\Gateways\IPaymentGateway; use GlobalPayments\Api\PaymentMethods\CreditCardData; use GlobalPayments\Api\ServiceConfigs\AcceptorConfig; -use GlobalPayments\Api\ServiceConfigs\Gateways\GatewayConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\GeniusConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\PorticoConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\TransitConfig; @@ -193,6 +192,10 @@ protected function prepare_card_data( WC_Payment_Token_CC $token = null ) { $this->card_data->token = $token->get_token(); $this->card_data->expMonth = $token->get_expiry_month(); $this->card_data->expYear = $token->get_expiry_year(); + + if ( isset( PaymentTokenData::$tsepCvv ) ) { + $this->card_data->cvn = PaymentTokenData::$tsepCvv; + } } protected function prepare_address( $address_type, array $data ) { From 7b6f88d3023495713d63183ae312f049abbbe337 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Tue, 12 Jan 2021 14:28:18 -0500 Subject: [PATCH 24/57] fix TransIT admin refunds --- src/Gateways/TransitGateway.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Gateways/TransitGateway.php b/src/Gateways/TransitGateway.php index dd901ae..209641c 100644 --- a/src/Gateways/TransitGateway.php +++ b/src/Gateways/TransitGateway.php @@ -3,6 +3,7 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider\Gateways; use GlobalPayments\Api\Entities\Enums\GatewayProvider; +use WC_Order; defined( 'ABSPATH' ) || exit; @@ -176,4 +177,23 @@ protected function create_manifest() { $response = $this->submit_request( $request ); return $response; } + + /** + * Handle online refund requests via WP Admin > WooCommerce > Edit Order + * + * @param int $order_id + * @param null|number $amount + * @param string $reason + * + * @return array + */ + public function process_refund( $order_id, $amount = null, $reason = '' ) { + $txn_type = self::TXN_TYPE_REFUND; + $order = new WC_Order( $order_id ); + $request = $this->prepare_request( $txn_type, $order ); + $response = $this->submit_request( $request ); + $is_successful = $this->handle_response( $request, $response ); + + return $is_successful; + } } From bdbf634c5a13778ca2bec0392e6405c527d5beb2 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 25 Jan 2021 09:09:57 -0500 Subject: [PATCH 25/57] added Transit devID --- src/Gateways/TransitGateway.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gateways/TransitGateway.php b/src/Gateways/TransitGateway.php index 209641c..103cc8b 100644 --- a/src/Gateways/TransitGateway.php +++ b/src/Gateways/TransitGateway.php @@ -160,7 +160,7 @@ public function get_backend_gateway_options() { 'password' => $this->password, // only needed to create transation key 'transactionKey' => $this->transaction_key, 'deviceId' => $this->device_id, - 'developerId' => $this->developer_id, + 'developerId' => '003226G004', // provided during certification 'environment' => $this->is_production ? 'PRODUCTION' : 'TEST', ); } From 68bf03a1c255a8a25f9c8eb951292f37d7d83e39 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 8 Mar 2021 10:13:47 -0500 Subject: [PATCH 26/57] auto-reversal on partial-auth --- src/Gateways/AbstractGateway.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 3eb282f..c7a3262 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -5,6 +5,7 @@ defined( 'ABSPATH' ) || exit; use Exception; +use GlobalPayments\Api\Entities\Exceptions\ApiException; use GlobalPayments\Api\Entities\Reporting\TransactionSummary; use WC_Payment_Gateway_CC; use WC_Order; @@ -543,6 +544,18 @@ protected function submit_request( Requests\RequestInterface $request ) { * @return bool */ protected function handle_response( Requests\RequestInterface $request, Transaction $response ) { + + if ($response->responseCode !== '00' || $response->responseMessage === 'Partially Approved') { + if ($response->responseCode === '10' || $response->responseMessage === 'Partially Approved') { + try { + $response->void()->withDescription('POST_AUTH_USER_DECLINE')->execute(); + return false; + } catch (\Exception $e) { /** om nom */ } + } + + throw new ApiException($this->mapResponseCodeToFriendlyMessage($response->responseCode)); + } + // phpcs:ignore WordPress.NamingConventions.ValidVariableName if ( '00' !== $response->responseCode ) { $woocommerce = WC(); From c05a64168b651cc8a4eca3914e25a21e92865970 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 8 Mar 2021 10:14:28 -0500 Subject: [PATCH 27/57] fix MUT w/TransIT --- src/Data/PaymentTokenData.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Data/PaymentTokenData.php b/src/Data/PaymentTokenData.php index 379472c..036a4c4 100644 --- a/src/Data/PaymentTokenData.php +++ b/src/Data/PaymentTokenData.php @@ -58,6 +58,10 @@ public function save_new_token( $multi_use_token ) { $user_id = get_current_user_id(); $current_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, $this->request->gateway_id ); + if ( $this->request->gateway_id === "globalpayments_transit" ) { + return; + } + // a card number should only have a single token stored foreach ( $current_tokens as $t ) { if ( $t->get_token() === $multi_use_token ) { From 78046780a9a6654a0324c61dba107c42aa750a75 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 8 Mar 2021 11:38:46 -0500 Subject: [PATCH 28/57] correction to token saving --- src/Data/PaymentTokenData.php | 37 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/Data/PaymentTokenData.php b/src/Data/PaymentTokenData.php index 036a4c4..f5468fb 100644 --- a/src/Data/PaymentTokenData.php +++ b/src/Data/PaymentTokenData.php @@ -58,28 +58,26 @@ public function save_new_token( $multi_use_token ) { $user_id = get_current_user_id(); $current_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, $this->request->gateway_id ); - if ( $this->request->gateway_id === "globalpayments_transit" ) { - return; - } + $token = $this->get_single_use_token(); - // a card number should only have a single token stored - foreach ( $current_tokens as $t ) { - if ( $t->get_token() === $multi_use_token ) { - $t->delete( true ); + if ( !empty( $token ) ) { + // a card number should only have a single token stored + foreach ( $current_tokens as $t ) { + if ( $t->get_token() === $multi_use_token ) { + $t->delete( true ); + } } - } - $token = $this->get_single_use_token(); + if ( ! $token->get_meta( self::KEY_SHOULD_SAVE_TOKEN, true ) ) { + return; + } - if ( ! $token->get_meta( self::KEY_SHOULD_SAVE_TOKEN, true ) ) { - return; + $token->set_token( $multi_use_token ); + $token->set_user_id( $user_id ); + $token->set_gateway_id( $this->request->gateway_id ); + $token->add_meta_data( self::KEY_SHOULD_SAVE_TOKEN, false, true ); + $token->save(); } - - $token->set_token( $multi_use_token ); - $token->set_user_id( $user_id ); - $token->set_gateway_id( $this->request->gateway_id ); - $token->add_meta_data( self::KEY_SHOULD_SAVE_TOKEN, false, true ); - $token->save(); } public function get_single_use_token() { @@ -89,6 +87,11 @@ public function get_single_use_token() { $gateway = $this->request->get_request_data( 'payment_method' ); $data = json_decode( stripslashes( $this->request->get_request_data( $gateway )['token_response'] ) ); + + if ( empty( $data ) ) { + return null; + } + $token = new WC_Payment_Token_CC(); // phpcs:disable WordPress.NamingConventions.ValidVariableName From 3ac8a119b6c9609ca4ffdefba73eceb58060180d Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Fri, 12 Mar 2021 09:58:06 -0500 Subject: [PATCH 29/57] ++ order note for admin refund --- src/Gateways/AbstractGateway.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index c7a3262..d7b78c4 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -474,6 +474,13 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { $response = $this->submit_request( $request ); $is_successful = $this->handle_response( $request, $response ); + $note_text = sprintf( + '%s was reversed or refunded. Transaction ID: %s ', + $amount, $response->transactionReference->transactionId + ); + + $order->add_order_note($note_text); + return $is_successful; } From 15afea263466e42f5b3414d5d44b9591fc47133d Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Fri, 12 Mar 2021 10:08:06 -0500 Subject: [PATCH 30/57] improve admin refund notes --- src/Gateways/AbstractGateway.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index d7b78c4..8774393 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -474,12 +474,14 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { $response = $this->submit_request( $request ); $is_successful = $this->handle_response( $request, $response ); - $note_text = sprintf( - '%s was reversed or refunded. Transaction ID: %s ', - $amount, $response->transactionReference->transactionId - ); - - $order->add_order_note($note_text); + if ($is_successful) { + $note_text = sprintf( + '%s%s was reversed or refunded. Transaction ID: %s ', + get_woocommerce_currency_symbol(), $amount, $response->transactionReference->transactionId + ); + + $order->add_order_note($note_text); + } return $is_successful; } From 46a5915560c2a15ac2de98fcd9498ef152e702ab Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 15 Mar 2021 12:09:09 -0400 Subject: [PATCH 31/57] ++ capture auth support --- src/Gateways/AbstractGateway.php | 49 ++++++++++++++++- src/Gateways/Clients/SdkClient.php | 54 +++++++++++++++++++ .../Requests/CaptureAuthorizationRequest.php | 22 ++++++++ src/Plugin.php | 2 + 4 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/Gateways/Requests/CaptureAuthorizationRequest.php diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 8774393..8861c95 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -487,7 +487,41 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { } /** - * Handle online refund requests via WP Admin > WooCommerce > Edit Order + * Handle capture auth requests via WP Admin > WooCommerce > Edit Order + * + * @param int $order_id + * + * @return array + */ + public static function capture_credit_card_authorization( $order_id ) { + $order = new WC_Order( $order_id ); + + switch ($order->get_payment_method()) { + case "globalpayments_heartland": + $gateway = new HeartlandGateway(); + break; + case "globalpayments_transit": + $gateway = new TransitGateway(); + break; + case "globalpayments_genius": + $gateway = new GeniusGateway(); + break; + }; + + $request = $gateway->prepare_request( self::TXN_TYPE_CAPTURE, $order ); + $response = $gateway->submit_request( $request ); + + if ( $response->responseCode === "00" && $response->responseMessage === "Success" ) { + $order->add_order_note( + "Transaction captured. Transaction ID for the capture: " . $response->transactionReference->transactionId + ); + } + + return $response; + } + + /** + * Handle online refund requests via WP Admin > WooCommerce > Edit Order > Order actions * * @param int $order_id * @@ -519,6 +553,7 @@ protected function prepare_request( $txn_type, WC_Order $order = null ) { self::TXN_TYPE_REFUND => Requests\RefundRequest::class, self::TXN_TYPE_REVERSAL => Requests\ReversalRequest::class, self::TXN_TYPE_REPORT_TXN_DETAILS => Requests\TransactionDetailRequest::class, + self::TXN_TYPE_CAPTURE => Requests\CaptureAuthorizationRequest::class, ); if ( ! isset( $map[ $txn_type ] ) ) { @@ -612,4 +647,16 @@ public function get_decline_message( string $response_code ) { return 'An error occurred while processing the card.'; } + /** + * Adds delayed capture functionality to the "Edit Order" screen + * + * @param array $actions + * + * @return array + */ + public static function addCaptureOrderAction( $actions ) + { + $actions['capture_credit_card_authorization'] = 'Capture credit card authorization'; + return $actions; + } } diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 5f4a2a8..f21d0bc 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -6,7 +6,10 @@ use GlobalPayments\Api\Entities\Address; use GlobalPayments\Api\Entities\Transaction; use GlobalPayments\Api\Entities\Enums\AddressType; +use GlobalPayments\Api\Entities\Enums\CardType; use GlobalPayments\Api\Entities\Enums\GatewayProvider; +use GlobalPayments\Api\Entities\Enums\StoredCredentialInitiator; +use GlobalPayments\Api\Entities\StoredCredential; use GlobalPayments\Api\Gateways\IPaymentGateway; use GlobalPayments\Api\PaymentMethods\CreditCardData; use GlobalPayments\Api\ServiceConfigs\AcceptorConfig; @@ -133,6 +136,11 @@ protected function get_transaction_builder() { return $subject->{$this->get_arg( RequestArg::TXN_TYPE )}(); } + if ( $this->get_arg( RequestArg::TXN_TYPE ) === 'capture' ) { + $subject = Transaction::fromId( $this->get_arg( 'GATEWAY_ID' ) ); + return $subject->{$this->get_arg( RequestArg::TXN_TYPE )}(); + } + $subject = in_array( $this->get_arg( RequestArg::TXN_TYPE ), $this->auth_transactions, true ) ? $this->card_data : $this->previous_transaction; @@ -181,6 +189,18 @@ protected function prepare_request_objects() { if ( $this->has_arg( RequestArg::AUTH_AMOUNT ) ) { $this->builder_args['authAmount'] = array( $this->get_arg( RequestArg::AUTH_AMOUNT ) ); } + + if ( $this->has_arg( RequestArg::STORED_CREDENTIAL ) ) { + $this->builder_args['storedCredential'] = array( $this->prepare_stored_credential_data( $this->get_arg( RequestArg::STORED_CREDENTIAL ) ) ); + } + } + + protected function prepare_stored_credential_data( $storedCredsUsed ) { + if ( $storedCredsUsed ) { + $storedCredsDetails = new StoredCredential; + $storedCredsDetails->initiator = StoredCredentialInitiator::MERCHANT; + return $storedCredsDetails; + } } protected function prepare_card_data( WC_Payment_Token_CC $token = null ) { @@ -193,6 +213,40 @@ protected function prepare_card_data( WC_Payment_Token_CC $token = null ) { $this->card_data->expMonth = $token->get_expiry_month(); $this->card_data->expYear = $token->get_expiry_year(); + /** + * $token->get_card_type() will return one of: + * "visa" + * "mastercard" + * "american express" + * "discover" + * "diners" + * "jcb" + */ + + $this->card_data->cardType = CardType::DISCOVER; + + // map for use with GlobalPayments SDK + switch( $token->get_card_type() ) { + case "visa": + $this->card_data->cardType = CardType::VISA; + break; + case "mastercard": + $this->card_data->cardType = CardType::MASTERCARD; + break; + case "american express": + $this->card_data->cardType = CardType::AMEX; + break; + case "discover": + $this->card_data->cardType = CardType::DISCOVER; + break; + case "diners": + $this->card_data->cardType = CardType::DINERS; + break; + case "jcb": + $this->card_data->cardType = CardType::JCB; + break; + } + if ( isset( PaymentTokenData::$tsepCvv ) ) { $this->card_data->cvn = PaymentTokenData::$tsepCvv; } diff --git a/src/Gateways/Requests/CaptureAuthorizationRequest.php b/src/Gateways/Requests/CaptureAuthorizationRequest.php new file mode 100644 index 0000000..30bec1a --- /dev/null +++ b/src/Gateways/Requests/CaptureAuthorizationRequest.php @@ -0,0 +1,22 @@ +order->get_transaction_id(); + + return array( + RequestArg::GATEWAY_ID => $gateway_id + ); + } +} diff --git a/src/Plugin.php b/src/Plugin.php index 7515e22..542d52c 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -33,6 +33,8 @@ public static function init() { } add_filter( 'woocommerce_payment_gateways', array( self::class, 'add_gateways' ) ); + add_action( 'woocommerce_order_actions', array( Gateways\AbstractGateway::class, 'addCaptureOrderAction' ) ); + add_action( 'woocommerce_order_action_capture_credit_card_authorization', array( Gateways\AbstractGateway::class, 'capture_credit_card_authorization' ) ); $HeartlandGateway = new HeartlandGateway(); From 21fdb9ae5d107a1c3c9f668b788671023cced365 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 15 Mar 2021 12:09:50 -0400 Subject: [PATCH 32/57] ++ todo notes --- todo.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/todo.txt b/todo.txt index ff6e67d..7f31eeb 100644 --- a/todo.txt +++ b/todo.txt @@ -70,3 +70,12 @@ admin refund / reverse Tony Notes: +- Capture Auth doesn't work; now this works but I need to handle errors from duplicate captures +done - after using a saved payment method it no longer shows as an option on checkout screen +done - refund transaction IDs don't show up on order screen +don't see this issue anymore - TransIt transaction IDs are all the same on the order screens +- Need to support fields for both the TSEP device ID and the MultiPass device ID; finished the cert by hard-coding the multi-pass device ID in the PHP SDK for the trans +- TSEP error doesn't show to customer, just sits there +- Discover CUP card type isn't being passed to back-end; causes problems with TransIT + +- Need to freeze screen on order submit w/TransIT. Screen doesn't show that anything is happening \ No newline at end of file From f359d8bfb73e44aed8233d3fe3b5e6c91f0fb05f Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 15 Mar 2021 21:10:55 -0400 Subject: [PATCH 33/57] handle capture auth errors --- src/Gateways/AbstractGateway.php | 23 +++++++++++++++++------ todo.txt | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 8861c95..35a70a6 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -509,15 +509,26 @@ public static function capture_credit_card_authorization( $order_id ) { }; $request = $gateway->prepare_request( self::TXN_TYPE_CAPTURE, $order ); - $response = $gateway->submit_request( $request ); - if ( $response->responseCode === "00" && $response->responseMessage === "Success" ) { - $order->add_order_note( - "Transaction captured. Transaction ID for the capture: " . $response->transactionReference->transactionId + try { + $response = $gateway->submit_request( $request ); + + if ( $response->responseCode === "00" && $response->responseMessage === "Success" ) { + $order->add_order_note( + "Transaction captured. Transaction ID for the capture: " . $response->transactionReference->transactionId + ); + } + + return $response; + } catch ( Exception $e ) { + wp_die( + $e->responseMessage, + '', + array( + 'back_link' => true, + ) ); } - - return $response; } /** diff --git a/todo.txt b/todo.txt index 7f31eeb..511a81a 100644 --- a/todo.txt +++ b/todo.txt @@ -70,7 +70,7 @@ admin refund / reverse Tony Notes: -- Capture Auth doesn't work; now this works but I need to handle errors from duplicate captures +done - Capture Auth doesn't work; done - after using a saved payment method it no longer shows as an option on checkout screen done - refund transaction IDs don't show up on order screen don't see this issue anymore - TransIt transaction IDs are all the same on the order screens From c9b12e2a6d33c358ef43f3c043f528d142021405 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Tue, 16 Mar 2021 11:35:02 -0400 Subject: [PATCH 34/57] send stored cred info on transactions --- src/Gateways/Clients/SdkClient.php | 16 ++++++++-------- src/Gateways/Handlers/PaymentTokenHandler.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index f21d0bc..0100678 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -190,17 +190,17 @@ protected function prepare_request_objects() { $this->builder_args['authAmount'] = array( $this->get_arg( RequestArg::AUTH_AMOUNT ) ); } - if ( $this->has_arg( RequestArg::STORED_CREDENTIAL ) ) { - $this->builder_args['storedCredential'] = array( $this->prepare_stored_credential_data( $this->get_arg( RequestArg::STORED_CREDENTIAL ) ) ); + if ( !empty( $token->get_meta( 'card_brand_txn_id' ) ) ) { + $this->prepare_stored_credential_data( $token->get_meta( 'card_brand_txn_id' ) ); } } - protected function prepare_stored_credential_data( $storedCredsUsed ) { - if ( $storedCredsUsed ) { - $storedCredsDetails = new StoredCredential; - $storedCredsDetails->initiator = StoredCredentialInitiator::MERCHANT; - return $storedCredsDetails; - } + protected function prepare_stored_credential_data( $card_brand_txn_id ) { + $storedCredsDetails = new StoredCredential(); + $storedCredsDetails->initiator = StoredCredentialInitiator::CARDHOLDER; + $storedCredsDetails->cardBrandTransactionId = $card_brand_txn_id; + + return $storedCredsDetails; } protected function prepare_card_data( WC_Payment_Token_CC $token = null ) { diff --git a/src/Gateways/Handlers/PaymentTokenHandler.php b/src/Gateways/Handlers/PaymentTokenHandler.php index 5c10074..827c6d4 100644 --- a/src/Gateways/Handlers/PaymentTokenHandler.php +++ b/src/Gateways/Handlers/PaymentTokenHandler.php @@ -10,6 +10,6 @@ public function handle() { return; } - ( new PaymentTokenData( $this->request ) )->save_new_token( $this->response->token ); + ( new PaymentTokenData( $this->request ) )->save_new_token( $this->response->token, $this->response->cardBrandTransactionId ); } } From b1e3a1cfcc3ea86ac6e8030f8e4e532e2123d019 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Wed, 17 Mar 2021 10:06:36 -0400 Subject: [PATCH 35/57] fix add_payment_method() error handling w/Transit --- src/Gateways/AbstractGateway.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 35a70a6..29d3547 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -445,13 +445,23 @@ public function process_payment( $order_id ) { * @return array */ public function add_payment_method() { - $request = $this->prepare_request( self::TXN_TYPE_VERIFY ); - $response = $this->submit_request( $request ); + $request = $this->prepare_request( self::TXN_TYPE_VERIFY ); + $redirect = wc_get_endpoint_url( 'payment-methods' ); + + try { + $response = $this->submit_request( $request ); + } catch ( Exception $e ) { + return array( + 'result' => 'failure', + 'redirect' => $redirect, + ); + } + $is_successful = $this->handle_response( $request, $response ); return array( 'result' => $is_successful ? 'success' : 'failure', - 'redirect' => wc_get_endpoint_url( 'payment-methods' ), + 'redirect' => $redirect, ); } From 63285172d6543afcbfaeb35c1bcf47e6dc7e317e Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Wed, 17 Mar 2021 10:24:43 -0400 Subject: [PATCH 36/57] supplement to: send stored cred info on trans --- src/Data/PaymentTokenData.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Data/PaymentTokenData.php b/src/Data/PaymentTokenData.php index f5468fb..73805c3 100644 --- a/src/Data/PaymentTokenData.php +++ b/src/Data/PaymentTokenData.php @@ -54,7 +54,7 @@ public function get_token() { return $token; } - public function save_new_token( $multi_use_token ) { + public function save_new_token( $multi_use_token, $card_brand_txn_id = null ) { $user_id = get_current_user_id(); $current_tokens = WC_Payment_Tokens::get_customer_tokens( $user_id, $this->request->gateway_id ); @@ -73,6 +73,7 @@ public function save_new_token( $multi_use_token ) { } $token->set_token( $multi_use_token ); + $token->add_meta_data( 'card_brand_txn_id', $card_brand_txn_id ); $token->set_user_id( $user_id ); $token->set_gateway_id( $this->request->gateway_id ); $token->add_meta_data( self::KEY_SHOULD_SAVE_TOKEN, false, true ); From 762b443b3beae8419f3705d6c3a677bd13503159 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Wed, 17 Mar 2021 10:27:46 -0400 Subject: [PATCH 37/57] " " --- src/Gateways/Clients/SdkClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 0100678..6465125 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -190,7 +190,7 @@ protected function prepare_request_objects() { $this->builder_args['authAmount'] = array( $this->get_arg( RequestArg::AUTH_AMOUNT ) ); } - if ( !empty( $token->get_meta( 'card_brand_txn_id' ) ) ) { + if ( $token !== null && !empty( $token->get_meta( 'card_brand_txn_id' ) ) ) { $this->prepare_stored_credential_data( $token->get_meta( 'card_brand_txn_id' ) ); } } From e8bd324667b0c4331730d4f489366fb87d6318ae Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Wed, 17 Mar 2021 10:42:37 -0400 Subject: [PATCH 38/57] ++ card type handling comment --- src/Gateways/Clients/SdkClient.php | 4 ++++ todo.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 6465125..082ff7e 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -223,6 +223,10 @@ protected function prepare_card_data( WC_Payment_Token_CC $token = null ) { * "jcb" */ + /** + * Defaulting to Discover since it's currently the only card type not + * returned by JS library in the case of Discover CUP cards. + */ $this->card_data->cardType = CardType::DISCOVER; // map for use with GlobalPayments SDK diff --git a/todo.txt b/todo.txt index 511a81a..a9534fe 100644 --- a/todo.txt +++ b/todo.txt @@ -76,6 +76,6 @@ done - refund transaction IDs don't show up on order screen don't see this issue anymore - TransIt transaction IDs are all the same on the order screens - Need to support fields for both the TSEP device ID and the MultiPass device ID; finished the cert by hard-coding the multi-pass device ID in the PHP SDK for the trans - TSEP error doesn't show to customer, just sits there -- Discover CUP card type isn't being passed to back-end; causes problems with TransIT +done - Discover CUP card type isn't being passed to back-end; causes problems with TransIT - Need to freeze screen on order submit w/TransIT. Screen doesn't show that anything is happening \ No newline at end of file From 15c2587043eb2460882bf121caa1b2550431f764 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 18:27:11 +0200 Subject: [PATCH 39/57] TR-92: add GP-API gateway --- src/Gateways/AbstractGateway.php | 48 ++++++++----- src/Gateways/GpApiGateway.php | 119 +++++++++++++++++++++++++++++++ src/Plugin.php | 1 + 3 files changed, 149 insertions(+), 19 deletions(-) create mode 100644 src/Gateways/GpApiGateway.php diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 29d3547..024b251 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -35,6 +35,9 @@ abstract class AbstractGateway extends WC_Payment_Gateway_Cc { // report requests const TXN_TYPE_REPORT_TXN_DETAILS = 'transactionDetail'; + //gp-api requests + const TXN_TYPE_GET_ACCESS_TOKEN = 'getAccessToken'; + /** * Gateway provider. Should be overriden by individual gateway implementations * @@ -243,7 +246,7 @@ public function tokenization_script() { // Global Payments scripts for handling client-side tokenization wp_enqueue_script( 'globalpayments-secure-payment-fields-lib', - 'https://api2.heartlandportico.com/securesubmit.v1/token/gp-1.6.0/globalpayments' + 'https://js.globalpay.com/v1/globalpayments' . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js', array(), WC()->version, @@ -411,12 +414,11 @@ protected function add_hooks() { if ( 'no' === $this->enabled ) { return; } - - // hooks only active when the gateway is enabled + // hooks only active when the gateway is enabled add_filter( 'woocommerce_credit_card_form_fields', array( $this, 'woocommerce_credit_card_form_fields' ) ); if ( is_add_payment_method_page() ) { - add_filter( 'wp_enqueue_scripts', array( $this, 'tokenization_script' ) ); + add_action( 'wp_enqueue_scripts', array( $this, 'tokenization_script' ) ); } } @@ -431,7 +433,7 @@ public function process_payment( $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 ); + $is_successful = $this->handle_response( $request, $response ); return array( 'result' => $is_successful ? 'success' : 'failure', @@ -516,6 +518,9 @@ public static function capture_credit_card_authorization( $order_id ) { case "globalpayments_genius": $gateway = new GeniusGateway(); break; + case "globalpayments_gpapi": + $gateway = new GpApiGateway(); + break; }; $request = $gateway->prepare_request( self::TXN_TYPE_CAPTURE, $order ); @@ -523,16 +528,21 @@ public static function capture_credit_card_authorization( $order_id ) { try { $response = $gateway->submit_request( $request ); - if ( $response->responseCode === "00" && $response->responseMessage === "Success" ) { + if ( "00" === $response->responseCode && "Success" === $response->responseMessage + || 'SUCCESS' === $response->responseCode && "CAPTURED" === $response->responseMessage ) { $order->add_order_note( "Transaction captured. Transaction ID for the capture: " . $response->transactionReference->transactionId ); + + $order->payment_complete( $response->transactionReference->transactionId ); } + + return $response; } catch ( Exception $e ) { wp_die( - $e->responseMessage, + $e->getMessage(), '', array( 'back_link' => true, @@ -566,15 +576,16 @@ public function get_transaction_details( $order_id ) { */ protected function prepare_request( $txn_type, WC_Order $order = null ) { $map = array( - self::TXN_TYPE_AUTHORIZE => Requests\AuthorizationRequest::class, - self::TXN_TYPE_SALE => Requests\SaleRequest::class, - self::TXN_TYPE_VERIFY => Requests\VerifyRequest::class, - self::TXN_TYPE_CREATE_TRANSACTION_KEY => Requests\CreateTransactionKeyRequest::class, - self::TXN_TYPE_CREATE_MANIFEST => Requests\CreateManifestRequest::class, - self::TXN_TYPE_REFUND => Requests\RefundRequest::class, - self::TXN_TYPE_REVERSAL => Requests\ReversalRequest::class, - self::TXN_TYPE_REPORT_TXN_DETAILS => Requests\TransactionDetailRequest::class, - self::TXN_TYPE_CAPTURE => Requests\CaptureAuthorizationRequest::class, + self::TXN_TYPE_AUTHORIZE => Requests\AuthorizationRequest::class, + self::TXN_TYPE_SALE => Requests\SaleRequest::class, + self::TXN_TYPE_VERIFY => Requests\VerifyRequest::class, + self::TXN_TYPE_CREATE_TRANSACTION_KEY => Requests\CreateTransactionKeyRequest::class, + self::TXN_TYPE_CREATE_MANIFEST => Requests\CreateManifestRequest::class, + self::TXN_TYPE_REFUND => Requests\RefundRequest::class, + self::TXN_TYPE_REVERSAL => Requests\ReversalRequest::class, + 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, ); if ( ! isset( $map[ $txn_type ] ) ) { @@ -609,8 +620,7 @@ protected function submit_request( Requests\RequestInterface $request ) { * @return bool */ protected function handle_response( Requests\RequestInterface $request, Transaction $response ) { - - if ($response->responseCode !== '00' || $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(); @@ -622,7 +632,7 @@ protected function handle_response( Requests\RequestInterface $request, Transact } // phpcs:ignore WordPress.NamingConventions.ValidVariableName - if ( '00' !== $response->responseCode ) { + if ( '00' !== $response->responseCode && 'SUCCESS' !== $response->responseCode ) { $woocommerce = WC(); $decline_message = $this->get_decline_message($response->responseCode); diff --git a/src/Gateways/GpApiGateway.php b/src/Gateways/GpApiGateway.php new file mode 100644 index 0000000..0a28499 --- /dev/null +++ b/src/Gateways/GpApiGateway.php @@ -0,0 +1,119 @@ +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' ); + } + + public function get_first_line_support_email() { + return 'securesubmitcert@e-hps.com'; + } + + public function get_gateway_form_fields() { + return array( + 'app_id' => array( + 'title' => __( 'App Id', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your App Id from your Global Payments Developer Account.', 'wc_securesubmit' ), + 'default' => '', + ), + 'app_key' => array( + 'title' => __( 'App Key', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your App Key from your Global Payments Developer Account.', 'wc_securesubmit' ), + 'default' => '', + ), + 'is_production' => array( + 'title' => __( 'Live Mode', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'checkbox', + 'default' => 'no', + ), + ); + } + + public function get_frontend_gateway_options() { + return array( + 'accessToken' => $this->get_access_token(), + 'env' => $this->is_production ? self::ENVIRONMENT_PRODUCTION : self::ENVIRONMENT_SANDBOX, + ); + } + + public function get_backend_gateway_options() { + return array( + 'AppId' => $this->app_id, + 'AppKey' => $this->app_key, + 'developerId' => '', + 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, + ); + } + + protected function get_access_token() { + $request = $this->prepare_request( self::TXN_TYPE_GET_ACCESS_TOKEN ); + $response = $this->submit_request( $request ); + + return $response->token; + } + + public function mapResponseCodeToFriendlyMessage( $responseCode ) { + return $responseCode; + } +} diff --git a/src/Plugin.php b/src/Plugin.php index 542d52c..8961a68 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -68,6 +68,7 @@ public static function add_gateways( $methods ) { Gateways\HeartlandGateway::class, Gateways\GeniusGateway::class, Gateways\TransitGateway::class, + Gateways\GpApiGateway::class, ); foreach ( $gateways as $gateway ) { From 451e122477c1c273f54331f40c4e0d89f924136b Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 18:29:06 +0200 Subject: [PATCH 40/57] TR-92: add access token request --- src/Gateways/Requests/GetAccessTokenRequest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/Gateways/Requests/GetAccessTokenRequest.php diff --git a/src/Gateways/Requests/GetAccessTokenRequest.php b/src/Gateways/Requests/GetAccessTokenRequest.php new file mode 100644 index 0000000..043d025 --- /dev/null +++ b/src/Gateways/Requests/GetAccessTokenRequest.php @@ -0,0 +1,17 @@ + Date: Wed, 24 Mar 2021 18:30:17 +0200 Subject: [PATCH 41/57] TR-92: check for invalid key --- src/Gateways/Requests/AbstractRequest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Gateways/Requests/AbstractRequest.php b/src/Gateways/Requests/AbstractRequest.php index b21d65c..b9556c7 100644 --- a/src/Gateways/Requests/AbstractRequest.php +++ b/src/Gateways/Requests/AbstractRequest.php @@ -72,6 +72,10 @@ public function get_request_data( $key = null ) { return $_POST; } + if ( ! isset( $this->data[ $key ] ) ) { + return null; + } + return wc_clean( $this->data[ $key ] ); } } From 29dc4b07e9e34c2fab110fa2620129af83d8b837 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 18:58:43 +0200 Subject: [PATCH 42/57] TR-92: add more validation errors --- .../globalpayments-secure-payment-fields.js | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index b9248c4..c7efc6b 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -315,6 +315,7 @@ * @returns */ handleErrors: function ( error ) { + this.resetValidationErrors(); this.unblockOnError(); if ( ! error.reasons ) { @@ -329,6 +330,39 @@ case 'INVALID_CARD_NUMBER': this.showValidationError( 'card-number' ); break; + case 'INVALID_CARD_EXPIRATION': + this.showValidationError( 'card-expiration' ); + break; + case 'INVALID_CARD_SECURITY_CODE': + this.showValidationError( 'card-cvv' ); + break; + case 'MANDATORY_DATA_MISSING': + var n = reason.message.search( "expiry_month" ); + if ( n>=0 ) { + this.showValidationError( 'card-expiration' ); + break; + } + var n = reason.message.search( "card.cvn.number" ); + if ( n>=0 ) { + this.showValidationError( 'card-cvv' ); + break; + } + case 'INVALID_REQUEST_DATA': + var n = reason.message.search( "number contains unexpected data" ); + if ( n>=0 ) { + this.showValidationError( 'card-number' ); + break; + } + var n = reason.message.search( "Luhn Check" ); + if ( n>=0 ) { + this.showValidationError( 'card-number' ); + break; + } + var n = reason.message.search( "cvv contains unexpected data" ); + if ( n>=0 ) { + this.showValidationError( 'card-cvv' ); + break; + } default: break; } From 89f271154b648a6ad37a1e61bbc9c24de0841a44 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 19:03:26 +0200 Subject: [PATCH 43/57] TR-92: update sdk client --- src/Gateways/Clients/SdkClient.php | 32 ++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 6465125..62db56b 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -4,6 +4,7 @@ use GlobalPayments\Api\Builders\TransactionBuilder; use GlobalPayments\Api\Entities\Address; +use GlobalPayments\Api\Entities\Enums\GpApi\Channels; use GlobalPayments\Api\Entities\Transaction; use GlobalPayments\Api\Entities\Enums\AddressType; use GlobalPayments\Api\Entities\Enums\CardType; @@ -14,6 +15,7 @@ use GlobalPayments\Api\PaymentMethods\CreditCardData; use GlobalPayments\Api\ServiceConfigs\AcceptorConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\GeniusConfig; +use GlobalPayments\Api\ServiceConfigs\Gateways\GpApiConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\PorticoConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\TransitConfig; use GlobalPayments\Api\Services\ReportingService; @@ -51,6 +53,7 @@ class SdkClient implements ClientInterface { protected $client_transactions = array( AbstractGateway::TXN_TYPE_CREATE_TRANSACTION_KEY, AbstractGateway::TXN_TYPE_CREATE_MANIFEST, + AbstractGateway::TXN_TYPE_GET_ACCESS_TOKEN, ); protected $refund_transactions = array( @@ -74,18 +77,18 @@ class SdkClient implements ClientInterface { protected $previous_transaction = null; public function set_request( RequestInterface $request ) { - $this->args = array_merge( - $request->get_default_args(), - $request->get_args() - ); - $this->prepare_request_objects(); + $this->args = array_merge( + $request->get_default_args(), + $request->get_args() + ); + $this->prepare_request_objects(); + return $this; } public function execute() { $this->configure_sdk(); $builder = $this->get_transaction_builder(); - if ( 'transactionDetail' === $this->args['TXN_TYPE'] ) { return $builder->execute(); } @@ -96,8 +99,7 @@ public function execute() { $this->prepare_builder( $builder ); $response = $builder->execute(); - - if ( $response instanceof Transaction && $response->token ) { + if ( ! is_null( $this->card_data ) && $response instanceof Transaction && $response->token ) { $this->card_data->token = $response->token; $this->card_data->updateTokenExpiry(); } @@ -156,6 +158,7 @@ protected function prepare_request_objects() { $this->builder_args['currency'] = array( $this->get_arg( RequestArg::CURRENCY ) ); } + $token = null; if ( $this->has_arg( RequestArg::CARD_DATA ) ) { /** * Get the request's single- or multi-use token @@ -269,7 +272,7 @@ protected function get_arg( $arg_type ) { } protected function configure_sdk() { - switch ($this->args['SERVICES_CONFIG']['gatewayProvider']) { + switch ( $this->args['SERVICES_CONFIG']['gatewayProvider'] ) { case GatewayProvider::PORTICO: $gatewayConfig = new PorticoConfig(); break; @@ -280,9 +283,18 @@ protected function configure_sdk() { case GatewayProvider::GENIUS: $gatewayConfig = new GeniusConfig(); break; + case GatewayProvider::GP_API: + $gatewayConfig = new GpApiConfig(); + $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( + $config = $this->set_object_data( $gatewayConfig, $this->args[ RequestArg::SERVICES_CONFIG ] ); From 4d98c61e25f0375f21fcf245aec5ab11ad9c31c5 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 19:05:50 +0200 Subject: [PATCH 44/57] TR-92: check for invalid key --- src/Data/PaymentTokenData.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Data/PaymentTokenData.php b/src/Data/PaymentTokenData.php index 73805c3..bfbf53d 100644 --- a/src/Data/PaymentTokenData.php +++ b/src/Data/PaymentTokenData.php @@ -86,14 +86,19 @@ public function get_single_use_token() { return null; } - $gateway = $this->request->get_request_data( 'payment_method' ); - $data = json_decode( stripslashes( $this->request->get_request_data( $gateway )['token_response'] ) ); + $gateway = $this->request->get_request_data( 'payment_method' ); + $request_data = $this->request->get_request_data( $gateway ); + if ( ! isset( $request_data['token_response'] ) ) { + return null; + } + + $data = json_decode( stripslashes( $request_data['token_response'] ) ); if ( empty( $data ) ) { return null; } - $token = new WC_Payment_Token_CC(); + $token = new WC_Payment_Token_CC(); // phpcs:disable WordPress.NamingConventions.ValidVariableName $token->add_meta_data( self::KEY_SHOULD_SAVE_TOKEN, $this->get_should_save_for_later(), true ); From 2a4fca8c00f468e29fa6820209ec661c5a299475 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 19:06:59 +0200 Subject: [PATCH 45/57] TR-92: set payment complete only for paid orders --- src/Gateways/Handlers/PaymentActionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gateways/Handlers/PaymentActionHandler.php b/src/Gateways/Handlers/PaymentActionHandler.php index 5367011..3f0d8e4 100644 --- a/src/Gateways/Handlers/PaymentActionHandler.php +++ b/src/Gateways/Handlers/PaymentActionHandler.php @@ -24,7 +24,7 @@ public function handle() { $this->save_meta_to_order( $this->request->order, array( 'payment_action' => $txn_type ) ); - if ( AbstractGateway::TXN_TYPE_VERIFY !== $txn_type ) { + if ( AbstractGateway::TXN_TYPE_SALE === $txn_type ) { $this->request->order->payment_complete( $this->response->transactionId ); return; } From 6560bf22fefeb33878d7f1cd31c152ad9bb668c0 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 19:46:03 +0200 Subject: [PATCH 46/57] TR-92: fix spacing --- src/Data/PaymentTokenData.php | 2 +- src/Gateways/AbstractGateway.php | 34 +++++++++++++++--------------- src/Gateways/Clients/SdkClient.php | 22 +++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Data/PaymentTokenData.php b/src/Data/PaymentTokenData.php index bfbf53d..3fa3ddc 100644 --- a/src/Data/PaymentTokenData.php +++ b/src/Data/PaymentTokenData.php @@ -90,7 +90,7 @@ public function get_single_use_token() { $request_data = $this->request->get_request_data( $gateway ); if ( ! isset( $request_data['token_response'] ) ) { return null; - } + } $data = json_decode( stripslashes( $request_data['token_response'] ) ); diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index 024b251..da35e3b 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -36,7 +36,7 @@ abstract class AbstractGateway extends WC_Payment_Gateway_Cc { const TXN_TYPE_REPORT_TXN_DETAILS = 'transactionDetail'; //gp-api requests - const TXN_TYPE_GET_ACCESS_TOKEN = 'getAccessToken'; + const TXN_TYPE_GET_ACCESS_TOKEN = 'getAccessToken'; /** * Gateway provider. Should be overriden by individual gateway implementations @@ -414,7 +414,7 @@ protected function add_hooks() { if ( 'no' === $this->enabled ) { return; } - // hooks only active when the gateway is enabled + // hooks only active when the gateway is enabled add_filter( 'woocommerce_credit_card_form_fields', array( $this, 'woocommerce_credit_card_form_fields' ) ); if ( is_add_payment_method_page() ) { @@ -433,7 +433,7 @@ public function process_payment( $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 ); + $is_successful = $this->handle_response( $request, $response ); return array( 'result' => $is_successful ? 'success' : 'failure', @@ -458,7 +458,7 @@ public function add_payment_method() { 'redirect' => $redirect, ); } - + $is_successful = $this->handle_response( $request, $response ); return array( @@ -488,10 +488,10 @@ public function process_refund( $order_id, $amount = null, $reason = '' ) { if ($is_successful) { $note_text = sprintf( - '%s%s was reversed or refunded. Transaction ID: %s ', + '%s%s was reversed or refunded. Transaction ID: %s ', get_woocommerce_currency_symbol(), $amount, $response->transactionReference->transactionId ); - + $order->add_order_note($note_text); } @@ -518,9 +518,9 @@ public static function capture_credit_card_authorization( $order_id ) { case "globalpayments_genius": $gateway = new GeniusGateway(); break; - case "globalpayments_gpapi": - $gateway = new GpApiGateway(); - break; + case "globalpayments_gpapi": + $gateway = new GpApiGateway(); + break; }; $request = $gateway->prepare_request( self::TXN_TYPE_CAPTURE, $order ); @@ -529,20 +529,20 @@ public static function capture_credit_card_authorization( $order_id ) { $response = $gateway->submit_request( $request ); if ( "00" === $response->responseCode && "Success" === $response->responseMessage - || 'SUCCESS' === $response->responseCode && "CAPTURED" === $response->responseMessage ) { + || 'SUCCESS' === $response->responseCode && "CAPTURED" === $response->responseMessage ) { $order->add_order_note( "Transaction captured. Transaction ID for the capture: " . $response->transactionReference->transactionId ); - $order->payment_complete( $response->transactionReference->transactionId ); + $order->payment_complete( $response->transactionReference->transactionId ); } - + return $response; } catch ( Exception $e ) { wp_die( - $e->getMessage(), + $e->getMessage(), '', array( 'back_link' => true, @@ -584,7 +584,7 @@ protected function prepare_request( $txn_type, WC_Order $order = null ) { self::TXN_TYPE_REFUND => Requests\RefundRequest::class, self::TXN_TYPE_REVERSAL => Requests\ReversalRequest::class, self::TXN_TYPE_REPORT_TXN_DETAILS => Requests\TransactionDetailRequest::class, - self::TXN_TYPE_CAPTURE => Requests\CaptureAuthorizationRequest::class, + self::TXN_TYPE_CAPTURE => Requests\CaptureAuthorizationRequest::class, self::TXN_TYPE_GET_ACCESS_TOKEN => Requests\GetAccessTokenRequest::class, ); @@ -620,7 +620,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(); @@ -634,7 +634,7 @@ protected function handle_response( Requests\RequestInterface $request, Transact // phpcs:ignore WordPress.NamingConventions.ValidVariableName if ( '00' !== $response->responseCode && 'SUCCESS' !== $response->responseCode ) { $woocommerce = WC(); - $decline_message = $this->get_decline_message($response->responseCode); + $decline_message = $this->get_decline_message($response->responseCode); if (function_exists('wc_add_notice')) { wc_add_notice($decline_message, 'error'); @@ -670,7 +670,7 @@ protected function is_transaction_active( TransactionSummary $details ) { } /** - * Should be overridden by each gateway implementation + * Should be overridden by each gateway implementation * * @return string */ diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 62db56b..ffac7e3 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -158,7 +158,7 @@ protected function prepare_request_objects() { $this->builder_args['currency'] = array( $this->get_arg( RequestArg::CURRENCY ) ); } - $token = null; + $token = null; if ( $this->has_arg( RequestArg::CARD_DATA ) ) { /** * Get the request's single- or multi-use token @@ -272,7 +272,7 @@ protected function get_arg( $arg_type ) { } protected function configure_sdk() { - switch ( $this->args['SERVICES_CONFIG']['gatewayProvider'] ) { + switch ( $this->args['SERVICES_CONFIG']['gatewayProvider'] ) { case GatewayProvider::PORTICO: $gatewayConfig = new PorticoConfig(); break; @@ -283,15 +283,15 @@ protected function configure_sdk() { case GatewayProvider::GENIUS: $gatewayConfig = new GeniusConfig(); break; - case GatewayProvider::GP_API: - $gatewayConfig = new GpApiConfig(); - $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; + case GatewayProvider::GP_API: + $gatewayConfig = new GpApiConfig(); + $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( From 976917f4010110b420ba69a109478bc10d512281 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Wed, 24 Mar 2021 19:51:01 +0200 Subject: [PATCH 47/57] TR-92: fix spacing --- src/Gateways/Clients/SdkClient.php | 10 +++++----- src/Gateways/Requests/AbstractRequest.php | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index ffac7e3..32b88f5 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -77,11 +77,11 @@ class SdkClient implements ClientInterface { protected $previous_transaction = null; public function set_request( RequestInterface $request ) { - $this->args = array_merge( - $request->get_default_args(), - $request->get_args() - ); - $this->prepare_request_objects(); + $this->args = array_merge( + $request->get_default_args(), + $request->get_args() + ); + $this->prepare_request_objects(); return $this; } diff --git a/src/Gateways/Requests/AbstractRequest.php b/src/Gateways/Requests/AbstractRequest.php index b9556c7..52ce27b 100644 --- a/src/Gateways/Requests/AbstractRequest.php +++ b/src/Gateways/Requests/AbstractRequest.php @@ -73,8 +73,8 @@ public function get_request_data( $key = null ) { } if ( ! isset( $this->data[ $key ] ) ) { - return null; - } + return null; + } return wc_clean( $this->data[ $key ] ); } From 8a3cf36cc0c805f3605a65205e7d531489b6963c Mon Sep 17 00:00:00 2001 From: apetrovici Date: Thu, 25 Mar 2021 08:17:34 +0200 Subject: [PATCH 48/57] TR-92: remove unused spaces --- src/Gateways/GpApiGateway.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Gateways/GpApiGateway.php b/src/Gateways/GpApiGateway.php index 0a28499..18c35e9 100644 --- a/src/Gateways/GpApiGateway.php +++ b/src/Gateways/GpApiGateway.php @@ -4,10 +4,6 @@ use GlobalPayments\Api\Entities\Enums\Environment; use GlobalPayments\Api\Entities\Enums\GatewayProvider; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\ThreeDSecure\CheckEnrollment; -use GlobalPayments\WooCommercePaymentGatewayProvider\Gateways\ThreeDSecure\GpApiGateway_Webhook_Handler; -use GlobalPayments\WooCommercePaymentGatewayProvider\Plugin; -use WC_Order; defined( 'ABSPATH' ) || exit; From c15481045b640e219a4eed014699026368ea74ea Mon Sep 17 00:00:00 2001 From: apetrovici Date: Thu, 25 Mar 2021 08:38:39 +0200 Subject: [PATCH 49/57] TR-92: change envs to constants --- src/Gateways/AbstractGateway.php | 10 +++ src/Gateways/GeniusGateway.php | 5 +- src/Gateways/GpApiGateway.php | 104 ++++++++++++++----------------- src/Gateways/TransitGateway.php | 5 +- 4 files changed, 63 insertions(+), 61 deletions(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index da35e3b..e6cbce5 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -17,6 +17,16 @@ * Shared gateway method implementations */ abstract class AbstractGateway extends WC_Payment_Gateway_Cc { + /** + * Defines production environment + */ + const ENVIRONMENT_PRODUCTION = 'production'; + + /** + * Defines sandbox environment + */ + const ENVIRONMENT_SANDBOX = 'sandbox'; + // auth requests const TXN_TYPE_AUTHORIZE = 'authorize'; const TXN_TYPE_SALE = 'charge'; diff --git a/src/Gateways/GeniusGateway.php b/src/Gateways/GeniusGateway.php index 4e856d4..e1cc1e6 100644 --- a/src/Gateways/GeniusGateway.php +++ b/src/Gateways/GeniusGateway.php @@ -2,6 +2,7 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider\Gateways; +use GlobalPayments\Api\Entities\Enums\Environment; use GlobalPayments\Api\Entities\Enums\GatewayProvider; defined( 'ABSPATH' ) || exit; @@ -89,7 +90,7 @@ public function get_gateway_form_fields() { public function get_frontend_gateway_options() { return array( 'webApiKey' => $this->web_api_key, - 'env' => $this->is_production ? 'production' : 'sandbox', + 'env' => $this->is_production ? parent::ENVIRONMENT_PRODUCTION : parent::ENVIRONMENT_SANDBOX, ); } @@ -98,7 +99,7 @@ public function get_backend_gateway_options() { 'merchantName' => $this->merchant_name, 'merchantSiteId' => $this->merchant_site_id, 'merchantKey' => $this->merchant_key, - 'environment' => $this->is_production ? 'PRODUCTION' : 'TEST', + 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, ); } } diff --git a/src/Gateways/GpApiGateway.php b/src/Gateways/GpApiGateway.php index 18c35e9..0b466e1 100644 --- a/src/Gateways/GpApiGateway.php +++ b/src/Gateways/GpApiGateway.php @@ -8,24 +8,14 @@ defined( 'ABSPATH' ) || exit; class GpApiGateway extends AbstractGateway { - /** - * Defines production environment - */ - const ENVIRONMENT_PRODUCTION = 'production'; - - /** - * Defines sandbox environment - */ - const ENVIRONMENT_SANDBOX = 'sandbox'; - - /** - * SDK gateway provider - * - * @var string - */ - public $gateway_provider = GatewayProvider::GP_API; - - /** + /** + * SDK gateway provider + * + * @var string + */ + public $gateway_provider = GatewayProvider::GP_API; + + /** * App ID * * @var string @@ -66,19 +56,19 @@ public function get_first_line_support_email() { public function get_gateway_form_fields() { return array( - 'app_id' => array( - 'title' => __( 'App Id', 'globalpayments-gateway-provider-for-woocommerce' ), - 'type' => 'text', - 'description' => __( 'Get your App Id from your Global Payments Developer Account.', 'wc_securesubmit' ), - 'default' => '', - ), - 'app_key' => array( - 'title' => __( 'App Key', 'globalpayments-gateway-provider-for-woocommerce' ), - 'type' => 'text', - 'description' => __( 'Get your App Key from your Global Payments Developer Account.', 'wc_securesubmit' ), - 'default' => '', - ), - 'is_production' => array( + 'app_id' => array( + 'title' => __('App Id', 'globalpayments-gateway-provider-for-woocommerce'), + 'type' => 'text', + 'description' => __('Get your App Id from your Global Payments Developer Account.', 'wc_securesubmit'), + 'default' => '', + ), + 'app_key' => array( + 'title' => __('App Key', 'globalpayments-gateway-provider-for-woocommerce'), + 'type' => 'text', + 'description' => __('Get your App Key from your Global Payments Developer Account.', 'wc_securesubmit'), + 'default' => '', + ), + 'is_production' => array( 'title' => __( 'Live Mode', 'globalpayments-gateway-provider-for-woocommerce' ), 'type' => 'checkbox', 'default' => 'no', @@ -86,30 +76,30 @@ public function get_gateway_form_fields() { ); } - public function get_frontend_gateway_options() { - return array( - 'accessToken' => $this->get_access_token(), - 'env' => $this->is_production ? self::ENVIRONMENT_PRODUCTION : self::ENVIRONMENT_SANDBOX, - ); - } - - public function get_backend_gateway_options() { - return array( - 'AppId' => $this->app_id, - 'AppKey' => $this->app_key, - 'developerId' => '', - 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, - ); - } - - protected function get_access_token() { - $request = $this->prepare_request( self::TXN_TYPE_GET_ACCESS_TOKEN ); - $response = $this->submit_request( $request ); - - return $response->token; - } - - public function mapResponseCodeToFriendlyMessage( $responseCode ) { - return $responseCode; - } + public function get_frontend_gateway_options() { + return array( + 'accessToken' => $this->get_access_token(), + 'env' => $this->is_production ? parent::ENVIRONMENT_PRODUCTION : parent::ENVIRONMENT_SANDBOX, + ); + } + + public function get_backend_gateway_options() { + return array( + 'AppId' => $this->app_id, + 'AppKey' => $this->app_key, + 'developerId' => '', + 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, + ); + } + + protected function get_access_token() { + $request = $this->prepare_request(self::TXN_TYPE_GET_ACCESS_TOKEN); + $response = $this->submit_request($request); + + return $response->token; + } + + public function mapResponseCodeToFriendlyMessage($responseCode) { + return $responseCode; + } } diff --git a/src/Gateways/TransitGateway.php b/src/Gateways/TransitGateway.php index 103cc8b..ceeb570 100644 --- a/src/Gateways/TransitGateway.php +++ b/src/Gateways/TransitGateway.php @@ -2,6 +2,7 @@ namespace GlobalPayments\WooCommercePaymentGatewayProvider\Gateways; +use GlobalPayments\Api\Entities\Enums\Environment; use GlobalPayments\Api\Entities\Enums\GatewayProvider; use WC_Order; @@ -149,7 +150,7 @@ public function get_frontend_gateway_options() { return array( 'deviceId' => $this->device_id, 'manifest' => $this->create_manifest(), - 'env' => $this->is_production ? 'production' : 'sandbox', + 'env' => $this->is_production ? parent::ENVIRONMENT_PRODUCTION : parent::ENVIRONMENT_SANDBOX, ); } @@ -161,7 +162,7 @@ public function get_backend_gateway_options() { 'transactionKey' => $this->transaction_key, 'deviceId' => $this->device_id, 'developerId' => '003226G004', // provided during certification - 'environment' => $this->is_production ? 'PRODUCTION' : 'TEST', + 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, ); } From f84a6e0e13c48ffae9239a49768c1c50a1572941 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Thu, 25 Mar 2021 10:07:36 +0200 Subject: [PATCH 50/57] TR-92: map response code --- src/Gateways/GpApiGateway.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Gateways/GpApiGateway.php b/src/Gateways/GpApiGateway.php index 0b466e1..238bfd8 100644 --- a/src/Gateways/GpApiGateway.php +++ b/src/Gateways/GpApiGateway.php @@ -57,15 +57,21 @@ public function get_first_line_support_email() { public function get_gateway_form_fields() { return array( 'app_id' => array( - 'title' => __('App Id', 'globalpayments-gateway-provider-for-woocommerce'), + 'title' => __( 'App Id', 'globalpayments-gateway-provider-for-woocommerce' ), 'type' => 'text', - 'description' => __('Get your App Id from your Global Payments Developer Account.', 'wc_securesubmit'), + 'description' => __( + 'Get your App Id from your Global Payments Developer Account.', + 'globalpayments-gateway-provider-for-woocommerce' + ), 'default' => '', ), 'app_key' => array( - 'title' => __('App Key', 'globalpayments-gateway-provider-for-woocommerce'), + 'title' => __( 'App Key', 'globalpayments-gateway-provider-for-woocommerce' ), 'type' => 'text', - 'description' => __('Get your App Key from your Global Payments Developer Account.', 'wc_securesubmit'), + 'description' => __( + 'Get your App Key from your Global Payments Developer Account.', + 'globalpayments-gateway-provider-for-woocommerce' + ), 'default' => '', ), 'is_production' => array( @@ -99,7 +105,11 @@ protected function get_access_token() { return $response->token; } - public function mapResponseCodeToFriendlyMessage($responseCode) { - return $responseCode; + public function mapResponseCodeToFriendlyMessage( $responseCode ) { + if ( 'DECLINED' === $responseCode ) { + return __( 'Your card has been declined by the bank.', 'globalpayments-gateway-provider-for-woocommerce' ); + } + + return __( 'An error occurred while processing the card.', 'globalpayments-gateway-provider-for-woocommerce' ); } } From b48652e2832f1cde17255cad35319039c7d1b90e Mon Sep 17 00:00:00 2001 From: apetrovici Date: Thu, 25 Mar 2021 10:21:56 +0200 Subject: [PATCH 51/57] TR-92: revert order status for authorize --- src/Gateways/AbstractGateway.php | 4 ---- src/Gateways/Handlers/PaymentActionHandler.php | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index e6cbce5..cf38f81 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -543,12 +543,8 @@ public static function capture_credit_card_authorization( $order_id ) { $order->add_order_note( "Transaction captured. Transaction ID for the capture: " . $response->transactionReference->transactionId ); - - $order->payment_complete( $response->transactionReference->transactionId ); } - - return $response; } catch ( Exception $e ) { wp_die( diff --git a/src/Gateways/Handlers/PaymentActionHandler.php b/src/Gateways/Handlers/PaymentActionHandler.php index 3f0d8e4..5367011 100644 --- a/src/Gateways/Handlers/PaymentActionHandler.php +++ b/src/Gateways/Handlers/PaymentActionHandler.php @@ -24,7 +24,7 @@ public function handle() { $this->save_meta_to_order( $this->request->order, array( 'payment_action' => $txn_type ) ); - if ( AbstractGateway::TXN_TYPE_SALE === $txn_type ) { + if ( AbstractGateway::TXN_TYPE_VERIFY !== $txn_type ) { $this->request->order->payment_complete( $this->response->transactionId ); return; } From 0ce2294b73b3eb2b31b9c5ce45615bfd49e784c4 Mon Sep 17 00:00:00 2001 From: apetrovici Date: Thu, 25 Mar 2021 12:04:45 +0200 Subject: [PATCH 52/57] TR-92: update support email --- src/Gateways/GpApiGateway.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gateways/GpApiGateway.php b/src/Gateways/GpApiGateway.php index 238bfd8..1448521 100644 --- a/src/Gateways/GpApiGateway.php +++ b/src/Gateways/GpApiGateway.php @@ -51,7 +51,7 @@ public function configure_method_settings() { } public function get_first_line_support_email() { - return 'securesubmitcert@e-hps.com'; + return 'api.integrations@globalpay.com'; } public function get_gateway_form_fields() { From c7c6fa34bdb8de65b047b10269c8cad79eb0be2e Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 29 Mar 2021 10:55:00 -0400 Subject: [PATCH 53/57] use TSEP device ID on front-end --- src/Gateways/TransitGateway.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Gateways/TransitGateway.php b/src/Gateways/TransitGateway.php index 103cc8b..a90e0f2 100644 --- a/src/Gateways/TransitGateway.php +++ b/src/Gateways/TransitGateway.php @@ -40,6 +40,13 @@ class TransitGateway extends AbstractGateway { */ public $device_id; + /** + * Device ID for TSEP entity specifically + * + * @var string + */ + public $tsep_device_id; + /** * Merchant location's Transaction Key * @@ -104,6 +111,12 @@ public function get_gateway_form_fields() { 'description' => __( 'Get your API keys from your TSYS TransIT account.', 'globalpayments-gateway-provider-for-woocommerce' ), 'default' => '', ), + 'tsep_device_id' => array( + 'title' => __( 'TSEP Device ID', 'globalpayments-gateway-provider-for-woocommerce' ), + 'type' => 'text', + 'description' => __( 'Get your API keys from your TSYS TransIT account.', 'globalpayments-gateway-provider-for-woocommerce' ), + 'default' => '', + ), 'transaction_key' => array( 'title' => __( 'Transaction Key', 'globalpayments-gateway-provider-for-woocommerce' ), 'type' => 'text', @@ -147,7 +160,7 @@ public function process_admin_options() { public function get_frontend_gateway_options() { return array( - 'deviceId' => $this->device_id, + 'deviceId' => $this->tsep_device_id, 'manifest' => $this->create_manifest(), 'env' => $this->is_production ? 'production' : 'sandbox', ); From 3f1a82c16eb0a3a918acd193589518cb8f5f3c72 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 29 Mar 2021 11:38:38 -0400 Subject: [PATCH 54/57] display TSEP error alert --- assets/frontend/js/globalpayments-secure-payment-fields.js | 3 +++ todo.txt | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/frontend/js/globalpayments-secure-payment-fields.js b/assets/frontend/js/globalpayments-secure-payment-fields.js index b9248c4..760e58e 100644 --- a/assets/frontend/js/globalpayments-secure-payment-fields.js +++ b/assets/frontend/js/globalpayments-secure-payment-fields.js @@ -329,6 +329,9 @@ case 'INVALID_CARD_NUMBER': this.showValidationError( 'card-number' ); break; + case 'ERROR': + alert(reason.message); + break; default: break; } diff --git a/todo.txt b/todo.txt index a9534fe..a4de537 100644 --- a/todo.txt +++ b/todo.txt @@ -74,8 +74,8 @@ done - Capture Auth doesn't work; done - after using a saved payment method it no longer shows as an option on checkout screen done - refund transaction IDs don't show up on order screen don't see this issue anymore - TransIt transaction IDs are all the same on the order screens -- Need to support fields for both the TSEP device ID and the MultiPass device ID; finished the cert by hard-coding the multi-pass device ID in the PHP SDK for the trans -- TSEP error doesn't show to customer, just sits there +done - Need to support fields for both the TSEP device ID and the MultiPass device ID; finished the cert by hard-coding the multi-pass device ID in the PHP SDK for the trans +done - TSEP error doesn't show to customer, just sits there done - Discover CUP card type isn't being passed to back-end; causes problems with TransIT - Need to freeze screen on order submit w/TransIT. Screen doesn't show that anything is happening \ No newline at end of file From 27b72f01bf9f440582a87aa93c5d2316ed46f643 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 29 Mar 2021 11:42:30 -0400 Subject: [PATCH 55/57] cleanup --- assets/frontend/HeartlandGiftFields.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/frontend/HeartlandGiftFields.php b/assets/frontend/HeartlandGiftFields.php index e005a69..d760209 100644 --- a/assets/frontend/HeartlandGiftFields.php +++ b/assets/frontend/HeartlandGiftFields.php @@ -9,8 +9,8 @@
- - + +

From cd8bffe69f4f6e71e33d73d17de09c79d8a29386 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Mon, 29 Mar 2021 21:14:47 -0400 Subject: [PATCH 56/57] fix TSEP on TransIT --- src/Gateways/AbstractGateway.php | 3 +-- src/Gateways/Clients/SdkClient.php | 7 +++++++ src/Gateways/TransitGateway.php | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Gateways/AbstractGateway.php b/src/Gateways/AbstractGateway.php index cf38f81..8a511e5 100644 --- a/src/Gateways/AbstractGateway.php +++ b/src/Gateways/AbstractGateway.php @@ -252,11 +252,10 @@ public function tokenization_script() { 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, diff --git a/src/Gateways/Clients/SdkClient.php b/src/Gateways/Clients/SdkClient.php index 86a9750..79f9501 100644 --- a/src/Gateways/Clients/SdkClient.php +++ b/src/Gateways/Clients/SdkClient.php @@ -303,6 +303,13 @@ protected function configure_sdk() { $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/TransitGateway.php b/src/Gateways/TransitGateway.php index 2ad3ff1..3c89203 100644 --- a/src/Gateways/TransitGateway.php +++ b/src/Gateways/TransitGateway.php @@ -173,6 +173,7 @@ public function get_backend_gateway_options() { 'username' => $this->user_id, // only needed to create transation key 'password' => $this->password, // only needed to create transation key 'transactionKey' => $this->transaction_key, + 'tsepDeviceId' => $this->tsep_device_id, 'deviceId' => $this->device_id, 'developerId' => '003226G004', // provided during certification 'environment' => $this->is_production ? Environment::PRODUCTION : Environment::TEST, From 3fefa10664072069c2a3f5f1fd23564f517c5171 Mon Sep 17 00:00:00 2001 From: Tony Smedal Date: Tue, 30 Mar 2021 21:57:39 -0400 Subject: [PATCH 57/57] clean --- todo.txt | 81 -------------------------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 todo.txt diff --git a/todo.txt b/todo.txt deleted file mode 100644 index a4de537..0000000 --- a/todo.txt +++ /dev/null @@ -1,81 +0,0 @@ -button / field style matching options: - -1) pull current styles off another/default field -2) textarea in admin for style overrides -3) filter/module overload for styles -4) individual options for style overrides - -tests: - -each scenario below should be tested across all supported gateways - -checkout - new card with no allow card saving - authorize - sale - verify - new card with allow card saving and no save to account - authorize - sale - verify - new card with allow card saving and save to account (store multi-use token) - authorize - sale - verify - new card with allow card saving and save to account (store multi-use token) + overwrite previously stored card - authorize - sale - verify - stored card - authorize - sale - verify - -order pay - new card with no allow card saving - authorize - sale - verify - new card with allow card saving and no save to account - authorize - sale - verify - new card with allow card saving and save to account (store multi-use token) - authorize - sale - verify - new card with allow card saving and save to account (store multi-use token) + overwrite previously stored card - authorize - sale - verify - stored card - authorize - sale - verify - -add payment method - new card (store multi-use token) - authorize - sale - verify - new card (store multi-use token) + overwrite previously stored card - authorize - sale - verify - -admin - void - capture auth - capture verify - refund / reverse - -Tony Notes: -done - Capture Auth doesn't work; -done - after using a saved payment method it no longer shows as an option on checkout screen -done - refund transaction IDs don't show up on order screen -don't see this issue anymore - TransIt transaction IDs are all the same on the order screens -done - Need to support fields for both the TSEP device ID and the MultiPass device ID; finished the cert by hard-coding the multi-pass device ID in the PHP SDK for the trans -done - TSEP error doesn't show to customer, just sits there -done - Discover CUP card type isn't being passed to back-end; causes problems with TransIT - -- Need to freeze screen on order submit w/TransIT. Screen doesn't show that anything is happening \ No newline at end of file