From e1dd10b9c12be3e17f99f96190b785bc0dd86c74 Mon Sep 17 00:00:00 2001 From: kcppdevelopers Date: Thu, 30 Nov 2017 17:24:57 +0530 Subject: [PATCH] Authorization order status in WC (EC, Pro). #883 --- ...teway-paypal-express-request-angelleye.php | 44 ++-- .../wc-gateway-paypal-express-angelleye.php | 21 ++ classes/wc-gateway-paypal-pro-angelleye.php | 211 ++++++++++++++++-- 3 files changed, 238 insertions(+), 38 deletions(-) diff --git a/angelleye-includes/express-checkout/class-wc-gateway-paypal-express-request-angelleye.php b/angelleye-includes/express-checkout/class-wc-gateway-paypal-express-request-angelleye.php index c2a99b495..b09d6e91d 100644 --- a/angelleye-includes/express-checkout/class-wc-gateway-paypal-express-request-angelleye.php +++ b/angelleye-includes/express-checkout/class-wc-gateway-paypal-express-request-angelleye.php @@ -30,6 +30,7 @@ public function __construct($gateway) { $this->testmode = 'yes' === $this->gateway->get_option('testmode', 'yes'); $this->fraud_management_filters = $this->gateway->get_option('fraud_management_filters', 'place_order_on_hold_for_further_review'); $this->email_notify_order_cancellations = $this->gateway->get_option('email_notify_order_cancellations', 'no'); + $this->pending_authorization_order_status = $this->gateway->get_option('pending_authorization_order_status', 'On Hold'); if ($this->testmode == false) { $this->testmode = AngellEYE_Utility::angelleye_paypal_for_woocommerce_is_set_sandbox_product(); } @@ -736,7 +737,8 @@ public function update_payment_status_by_paypal_responce($orderid, $result) { } switch (strtolower($payment_status)) : case 'completed' : - if ($order->status == 'completed') { + $order_status = version_compare(WC_VERSION, '3.0', '<') ? $order->status : $this->order->get_status(); + if ($order_status == 'completed') { break; } if (!in_array(strtolower($transaction_type), array('merchtpmt', 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money'))) { @@ -751,49 +753,53 @@ public function update_payment_status_by_paypal_responce($orderid, $result) { } switch (strtolower($pending_reason)) { case 'address': - $pending_reason = __('Address: The payment is pending because your customer did not include a confirmed shipping address and your Payment Receiving Preferences is set such that you want to manually accept or deny each of these payments. To change your preference, go to the Preferences section of your Profile.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Address: The payment is pending because your customer did not include a confirmed shipping address and your Payment Receiving Preferences is set such that you want to manually accept or deny each of these payments. To change your preference, go to the Preferences section of your Profile.', 'paypal-for-woocommerce'); break; case 'authorization': - $pending_reason = __('Authorization: The payment is pending because it has been authorized but not settled. You must capture the funds first.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Authorization: The payment is pending because it has been authorized but not settled. You must capture the funds first.', 'paypal-for-woocommerce'); break; case 'echeck': - $pending_reason = __('eCheck: The payment is pending because it was made by an eCheck that has not yet cleared.', 'paypal-for-woocommerce'); + $pending_reason_text = __('eCheck: The payment is pending because it was made by an eCheck that has not yet cleared.', 'paypal-for-woocommerce'); break; case 'intl': - $pending_reason = __('intl: The payment is pending because you hold a non-U.S. account and do not have a withdrawal mechanism. You must manually accept or deny this payment from your Account Overview.', 'paypal-for-woocommerce'); + $pending_reason_text = __('intl: The payment is pending because you hold a non-U.S. account and do not have a withdrawal mechanism. You must manually accept or deny this payment from your Account Overview.', 'paypal-for-woocommerce'); break; case 'multicurrency': case 'multi-currency': - $pending_reason = __('Multi-currency: You do not have a balance in the currency sent, and you do not have your Payment Receiving Preferences set to automatically convert and accept this payment. You must manually accept or deny this payment.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Multi-currency: You do not have a balance in the currency sent, and you do not have your Payment Receiving Preferences set to automatically convert and accept this payment. You must manually accept or deny this payment.', 'paypal-for-woocommerce'); break; case 'order': - $pending_reason = __('Order: The payment is pending because it is part of an order that has been authorized but not settled.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Order: The payment is pending because it is part of an order that has been authorized but not settled.', 'paypal-for-woocommerce'); break; case 'paymentreview': - $pending_reason = __('Payment Review: The payment is pending while it is being reviewed by PayPal for risk.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Payment Review: The payment is pending while it is being reviewed by PayPal for risk.', 'paypal-for-woocommerce'); break; case 'unilateral': - $pending_reason = __('Unilateral: The payment is pending because it was made to an email address that is not yet registered or confirmed.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Unilateral: The payment is pending because it was made to an email address that is not yet registered or confirmed.', 'paypal-for-woocommerce'); break; case 'verify': - $pending_reason = __('Verify: The payment is pending because you are not yet verified. You must verify your account before you can accept this payment.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Verify: The payment is pending because you are not yet verified. You must verify your account before you can accept this payment.', 'paypal-for-woocommerce'); break; case 'other': - $pending_reason = __('Other: For more information, contact PayPal customer service.', 'paypal-for-woocommerce'); + $pending_reason_text = __('Other: For more information, contact PayPal customer service.', 'paypal-for-woocommerce'); break; case 'none': default: - $pending_reason = __('No pending reason provided.', 'paypal-for-woocommerce'); + $pending_reason_text = __('No pending reason provided.', 'paypal-for-woocommerce'); break; } - $order->add_order_note(sprintf(__('Payment via Express Checkout Pending. PayPal reason: %s.', 'paypal-for-woocommerce'), $pending_reason)); - $order->update_status('on-hold'); - if ( $old_wc ) { - if ( ! get_post_meta( $orderid, '_order_stock_reduced', true ) ) { - $order->reduce_order_stock(); - } + $order->add_order_note(sprintf(__('Payment via Express Checkout Pending. PayPal reason: %s.', 'paypal-for-woocommerce'), $pending_reason_text)); + if ( strtolower($pending_reason) == 'authorization' && $this->pending_authorization_order_status == 'Processing' ) { + $order->payment_complete($transaction_id); } else { - wc_maybe_reduce_stock_levels( $orderid ); + $order->update_status('on-hold'); + if ( $old_wc ) { + if ( ! get_post_meta( $orderid, '_order_stock_reduced', true ) ) { + $order->reduce_order_stock(); + } + } else { + wc_maybe_reduce_stock_levels( $orderid ); + } } break; case 'denied' : diff --git a/classes/wc-gateway-paypal-express-angelleye.php b/classes/wc-gateway-paypal-express-angelleye.php index cf6ba1a22..9077b79d3 100644 --- a/classes/wc-gateway-paypal-express-angelleye.php +++ b/classes/wc-gateway-paypal-express-angelleye.php @@ -86,6 +86,7 @@ public function __construct() { $this->invoice_id_prefix = $this->get_option('invoice_id_prefix', ''); $this->paypal_marketing_solutions_cid_production = $this->get_option('paypal_marketing_solutions_cid_production', ''); $this->show_on_minicart = $this->get_option('show_on_minicart', 'yes'); + $this->pending_authorization_order_status = $this->get_option('pending_authorization_order_status', 'On Hold'); if ($this->enable_notifyurl == 'yes') { $this->notifyurl = $this->get_option('notifyurl'); if (isset($this->notifyurl) && !empty($this->notifyurl)) { @@ -225,6 +226,13 @@ function callback_onsuccess_production(containerId) { + APICallSuccessful($PayPalResult['ACK'])) { // Add order note - $order->add_order_note(sprintf(__('PayPal Pro payment completed (Transaction ID: %s, Correlation ID: %s)', 'paypal-for-woocommerce'), $PayPalResult['TRANSACTIONID'], $PayPalResult['CORRELATIONID'])); + $order->add_order_note(sprintf(__('PayPal Pro (Transaction ID: %s, Correlation ID: %s)', 'paypal-for-woocommerce'), $PayPalResult['TRANSACTIONID'], $PayPalResult['CORRELATIONID'])); //$order->add_order_note("PayPal Results: ".print_r($PayPalResult,true)); /* Checkout Note */ @@ -1221,7 +1266,6 @@ function do_payment($order, $card_number, $card_type, $card_exp_month, $card_exp $this->save_payment_token($order, $TRANSACTIONID); } } - // Payment complete if($PayPalResult['ACK'] == 'SuccessWithWarning' && !empty($PayPalResult['L_ERRORCODE0'])) { if($this->fraud_management_filters == 'place_order_on_hold_for_further_review' && $PayPalResult['L_ERRORCODE0'] == '11610') { @@ -1269,7 +1313,6 @@ function do_payment($order, $card_number, $card_type, $card_exp_month, $card_exp AngellEYE_Utility::angelleye_paypal_for_woocommerce_add_paypal_transaction($PayPalResult, $order, $this->payment_action); $angelleye_utility = new AngellEYE_Utility(null, null); $angelleye_utility->angelleye_get_transactionDetails($PayPalResult['TRANSACTIONID']); - $this->angelleye_update_status($order, $PayPalResult['TRANSACTIONID']); $order->add_order_note('Payment Action: ' . $this->payment_action); } @@ -1565,7 +1608,7 @@ public function paypal_pro_error_handler($request_name = '', $redirect_url = '', $message .= __('Detailed Error Message: ', 'paypal-for-woocommerce') . $ErrorLongMsg . "\n"; $message .= __('User IP: ', 'paypal-for-woocommerce') . $this->get_user_ip() . "\n"; $error_email_notify_mes = apply_filters('ae_ppec_error_email_message', $message, $ErrorCode, $ErrorSeverityCode, $ErrorShortMsg, $ErrorLongMsg); - $subject = "PayPal Express Checkout Error Notification"; + $subject = "PayPal Pro Error Notification"; $error_email_notify_subject = apply_filters('ae_ppec_error_email_subject', $subject); wp_mail($admin_email, $error_email_notify_subject, $error_email_notify_mes); } @@ -1990,16 +2033,21 @@ public function angelleye_update_status($order, $transaction_id ) { if( $this->payment_action == 'Sale') { $order->payment_complete($transaction_id); } else { - $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); - $old_wc = version_compare(WC_VERSION, '3.0', '<'); - if ( $old_wc ) { - if ( ! get_post_meta( $order_id, '_order_stock_reduced', true ) ) { - $order->reduce_order_stock(); - } + if ( $this->payment_action == 'Authorization') { + $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); + $this->angelleye_get_transaction_details($order_id, $transaction_id); } else { - wc_maybe_reduce_stock_levels( $order_id ); + $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); + $old_wc = version_compare(WC_VERSION, '3.0', '<'); + if ( $old_wc ) { + if ( ! get_post_meta( $order_id, '_order_stock_reduced', true ) ) { + $order->reduce_order_stock(); + } + } else { + wc_maybe_reduce_stock_levels( $order_id ); + } + $order->update_status('on-hold'); } - $order->update_status('on-hold'); } } @@ -2024,4 +2072,129 @@ public function angelleye_reload_gateway_credentials_for_woo_subscription_renewa } } + public function angelleye_get_transaction_details($order_id, $transaction_id) { + $PayPalConfig = array( + 'Sandbox' => $this->testmode, + 'APIUsername' => $this->api_username, + 'APIPassword' => $this->api_password, + 'APISignature' => $this->api_signature, + 'Force_tls_one_point_two' => $this->Force_tls_one_point_two + ); + $PayPal = new Angelleye_PayPal($PayPalConfig); + $GTDFields = array( + 'transactionid' => $transaction_id + ); + $PayPalRequestData = array('GTDFields' => $GTDFields); + $get_transactionDetails_result = $PayPal->GetTransactionDetails($PayPalRequestData); + $this->log(print_r($get_transactionDetails_result, true)); + $this->update_payment_status_by_paypal_responce($order_id, $get_transactionDetails_result, $transaction_id); + } + + public function update_payment_status_by_paypal_responce($orderid, $result, $transaction_id) { + try { + $order = wc_get_order($orderid); + $old_wc = version_compare( WC_VERSION, '3.0', '<' ); + if(!empty($result['PAYMENTINFO_0_PAYMENTSTATUS'])) { + $payment_status = $result['PAYMENTINFO_0_PAYMENTSTATUS']; + } elseif ( !empty ($result['PAYMENTSTATUS'])) { + $payment_status = $result['PAYMENTSTATUS']; + } + if( !empty($result['PAYMENTINFO_0_TRANSACTIONTYPE']) ) { + $transaction_type = $result['PAYMENTINFO_0_TRANSACTIONTYPE']; + } elseif ( !empty ($result['TRANSACTIONTYPE'])) { + $transaction_type = $result['TRANSACTIONTYPE']; + } + if( !empty($result['PAYMENTINFO_0_TRANSACTIONID']) ) { + $transaction_id = $result['PAYMENTINFO_0_TRANSACTIONID']; + } elseif ( !empty ($result['BILLINGAGREEMENTID'])) { + $transaction_id = $result['BILLINGAGREEMENTID']; + } + if( !empty($result['PAYMENTINFO_0_PENDINGREASON']) ) { + $pending_reason = $result['PAYMENTINFO_0_PENDINGREASON']; + } elseif ( !empty ($result['PENDINGREASON'])) { + $pending_reason = $result['PENDINGREASON']; + } + switch (strtolower($payment_status)) : + case 'completed' : + $order_status = version_compare(WC_VERSION, '3.0', '<') ? $order->status : $this->order->get_status(); + if ($order_status == 'completed') { + break; + } + if (!in_array(strtolower($transaction_type), array('merchtpmt', 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money'))) { + break; + } + $order->add_order_note(__('Payment Completed via PayPal Pro', 'paypal-for-woocommerce')); + $order->payment_complete($transaction_id); + break; + case 'pending' : + if (!in_array(strtolower($transaction_type), array('merchtpmt', 'cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money', 'expresscheckout'))) { + break; + } + switch (strtolower($pending_reason)) { + case 'address': + $pending_reason_text = __('Address: The payment is pending because your customer did not include a confirmed shipping address and your Payment Receiving Preferences is set such that you want to manually accept or deny each of these payments. To change your preference, go to the Preferences section of your Profile.', 'paypal-for-woocommerce'); + break; + case 'authorization': + $pending_reason_text = __('Authorization: The payment is pending because it has been authorized but not settled. You must capture the funds first.', 'paypal-for-woocommerce'); + break; + case 'echeck': + $pending_reason_text = __('eCheck: The payment is pending because it was made by an eCheck that has not yet cleared.', 'paypal-for-woocommerce'); + break; + case 'intl': + $pending_reason_text = __('intl: The payment is pending because you hold a non-U.S. account and do not have a withdrawal mechanism. You must manually accept or deny this payment from your Account Overview.', 'paypal-for-woocommerce'); + break; + case 'multicurrency': + case 'multi-currency': + $pending_reason_text = __('Multi-currency: You do not have a balance in the currency sent, and you do not have your Payment Receiving Preferences set to automatically convert and accept this payment. You must manually accept or deny this payment.', 'paypal-for-woocommerce'); + break; + case 'order': + $pending_reason_text = __('Order: The payment is pending because it is part of an order that has been authorized but not settled.', 'paypal-for-woocommerce'); + break; + case 'paymentreview': + $pending_reason_text = __('Payment Review: The payment is pending while it is being reviewed by PayPal for risk.', 'paypal-for-woocommerce'); + break; + case 'unilateral': + $pending_reason_text = __('Unilateral: The payment is pending because it was made to an email address that is not yet registered or confirmed.', 'paypal-for-woocommerce'); + break; + case 'verify': + $pending_reason_text = __('Verify: The payment is pending because you are not yet verified. You must verify your account before you can accept this payment.', 'paypal-for-woocommerce'); + break; + case 'other': + $pending_reason_text = __('Other: For more information, contact PayPal customer service.', 'paypal-for-woocommerce'); + break; + case 'none': + default: + $pending_reason_text = __('No pending reason provided.', 'paypal-for-woocommerce'); + break; + } + $order->add_order_note(sprintf(__('Payment via PayPal Pro Pending. PayPal reason: %s', 'paypal-for-woocommerce'), $pending_reason_text)); + if ( strtolower($pending_reason) == 'authorization' && $this->pending_authorization_order_status == 'Processing' ) { + $order->payment_complete($transaction_id); + } else { + $order->update_status('on-hold'); + if ( $old_wc ) { + if ( ! get_post_meta( $orderid, '_order_stock_reduced', true ) ) { + $order->reduce_order_stock(); + } + } else { + wc_maybe_reduce_stock_levels( $orderid ); + } + } + break; + case 'denied' : + case 'expired' : + case 'failed' : + case 'voided' : + $order->update_status('failed', sprintf(__('Payment %s via PayPal Pro.', 'paypal-for-woocommerce'), strtolower($payment_status))); + break; + default: + break; + endswitch; + return; + } catch (Exception $ex) { + + } + } + + } \ No newline at end of file