2020-09-14 14:17:39 +03:00
< ? php
/**
* The process_payment functionality for the both gateways .
*
* @ package WooCommerce\PayPalCommerce\WcGateway\Gateway
*/
declare ( strict_types = 1 );
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway ;
2021-10-06 16:03:38 +03:00
use Exception ;
2021-03-25 16:11:45 +01:00
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus ;
2020-09-14 14:17:39 +03:00
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException ;
2020-11-20 15:40:01 +01:00
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException ;
2020-09-14 14:17:39 +03:00
/**
* Trait ProcessPaymentTrait
*/
trait ProcessPaymentTrait {
/**
* Process a payment for an WooCommerce order .
*
* @ param int $order_id The WooCommerce order id .
*
2021-03-15 16:43:39 +02:00
* @ return array
2020-09-14 14:17:39 +03:00
*/
public function process_payment ( $order_id ) {
2021-03-15 16:43:39 +02:00
$failure_data = array (
'result' => 'failure' ,
'redirect' => wc_get_checkout_url (),
);
2020-09-14 14:17:39 +03:00
$wc_order = wc_get_order ( $order_id );
if ( ! is_a ( $wc_order , \WC_Order :: class ) ) {
2021-03-15 17:33:20 +02:00
wc_add_notice (
2021-03-17 13:59:18 +02:00
__ ( 'Couldn\'t find order to process' , 'woocommerce-paypal-payments' ),
2021-03-15 17:33:20 +02:00
'error'
);
2021-03-15 16:43:39 +02:00
return $failure_data ;
2020-09-14 14:17:39 +03:00
}
2021-03-25 16:57:42 +01:00
/**
2021-05-10 17:12:46 +02:00
* If customer has chosen a saved credit card payment .
2021-03-25 16:57:42 +01:00
*/
$saved_credit_card = filter_input ( INPUT_POST , 'saved_credit_card' , FILTER_SANITIZE_STRING );
2021-05-10 17:12:46 +02:00
$pay_for_order = filter_input ( INPUT_GET , 'pay_for_order' , FILTER_SANITIZE_STRING );
if ( $saved_credit_card && ! isset ( $pay_for_order ) ) {
2021-03-25 16:11:45 +01:00
2021-03-25 16:57:42 +01:00
$user_id = ( int ) $wc_order -> get_customer_id ();
$customer = new \WC_Customer ( $user_id );
$tokens = $this -> payment_token_repository -> all_for_user_id ( ( int ) $customer -> get_id () );
2021-03-25 16:11:45 +01:00
2021-03-25 16:57:42 +01:00
$selected_token = null ;
foreach ( $tokens as $token ) {
if ( $token -> id () === $saved_credit_card ) {
$selected_token = $token ;
break ;
}
}
2021-03-25 16:11:45 +01:00
2021-03-25 16:57:42 +01:00
if ( ! $selected_token ) {
return null ;
}
2021-03-25 16:11:45 +01:00
2021-03-25 16:57:42 +01:00
$purchase_unit = $this -> purchase_unit_factory -> from_wc_order ( $wc_order );
$payer = $this -> payer_factory -> from_customer ( $customer );
try {
$order = $this -> order_endpoint -> create (
array ( $purchase_unit ),
$payer ,
$selected_token
);
2021-03-25 16:11:45 +01:00
2021-03-25 16:57:42 +01:00
if ( $order -> status () -> is ( OrderStatus :: COMPLETED ) && $order -> intent () === 'CAPTURE' ) {
$wc_order -> update_status (
'processing' ,
__ ( 'Payment received.' , 'woocommerce-paypal-payments' )
);
2021-03-25 16:11:45 +01:00
2021-03-25 16:57:42 +01:00
$this -> session_handler -> destroy_session_data ();
return array (
'result' => 'success' ,
'redirect' => $this -> get_return_url ( $wc_order ),
);
}
2021-09-27 17:49:08 +02:00
if ( $order -> status () -> is ( OrderStatus :: COMPLETED ) && $order -> intent () === 'AUTHORIZE' ) {
$this -> order_endpoint -> authorize ( $order );
$wc_order -> update_meta_data ( PayPalGateway :: CAPTURED_META_KEY , 'false' );
$wc_order -> update_meta_data ( PayPalGateway :: ORDER_ID_META_KEY , $order -> id () );
$wc_order -> update_status (
'on-hold' ,
__ ( 'Awaiting payment.' , 'woocommerce-paypal-payments' )
);
$this -> session_handler -> destroy_session_data ();
return array (
'result' => 'success' ,
'redirect' => $this -> get_return_url ( $wc_order ),
);
}
$this -> logger -> warning ( " Could neither capture nor authorize order { $order -> id () } using a saved credit card: " . 'Status: ' . $order -> status () -> name () . ' Intent: ' . $order -> intent () );
2021-03-25 16:57:42 +01:00
} catch ( RuntimeException $error ) {
2021-10-06 16:03:38 +03:00
$this -> handle_failure ( $wc_order , $error );
2021-03-25 16:57:42 +01:00
return null ;
}
}
2021-03-25 16:11:45 +01:00
2021-05-17 11:00:57 +02:00
/**
* If customer has chosen change Subscription payment .
*/
2021-05-19 15:39:33 +02:00
if ( $this -> subscription_helper -> has_subscription ( $order_id ) && $this -> subscription_helper -> is_subscription_change_payment () ) {
if ( 'ppcp-credit-card-gateway' === $this -> id && $saved_credit_card ) {
2021-05-17 11:00:57 +02:00
update_post_meta ( $order_id , 'payment_token_id' , $saved_credit_card );
$this -> session_handler -> destroy_session_data ();
return array (
'result' => 'success' ,
'redirect' => $this -> get_return_url ( $wc_order ),
);
}
2021-05-19 15:39:33 +02:00
$saved_paypal_payment = filter_input ( INPUT_POST , 'saved_paypal_payment' , FILTER_SANITIZE_STRING );
if ( 'ppcp-gateway' === $this -> id && $saved_paypal_payment ) {
update_post_meta ( $order_id , 'payment_token_id' , $saved_paypal_payment );
2021-05-17 11:00:57 +02:00
2021-05-19 15:39:33 +02:00
$this -> session_handler -> destroy_session_data ();
return array (
'result' => 'success' ,
'redirect' => $this -> get_return_url ( $wc_order ),
);
2021-05-17 11:00:57 +02:00
}
}
2020-09-14 14:17:39 +03:00
/**
* If the WC_Order is payed through the approved webhook .
*/
//phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( isset ( $_REQUEST [ 'ppcp-resume-order' ] ) && $wc_order -> has_status ( 'processing' ) ) {
$this -> session_handler -> destroy_session_data ();
return array (
'result' => 'success' ,
'redirect' => $this -> get_return_url ( $wc_order ),
);
}
//phpcs:enable WordPress.Security.NonceVerification.Recommended
try {
2021-03-15 17:57:55 +02:00
if ( $this -> order_processor -> process ( $wc_order ) ) {
2020-09-14 14:17:39 +03:00
$this -> session_handler -> destroy_session_data ();
return array (
'result' => 'success' ,
'redirect' => $this -> get_return_url ( $wc_order ),
);
}
} catch ( PayPalApiException $error ) {
if ( $error -> has_detail ( 'INSTRUMENT_DECLINED' ) ) {
2021-08-11 15:01:23 +02:00
$wc_order -> update_status (
'failed' ,
__ ( 'Instrument declined.' , 'woocommerce-paypal-payments' )
);
2020-09-14 14:17:39 +03:00
$this -> session_handler -> increment_insufficient_funding_tries ();
$host = $this -> config -> has ( 'sandbox_on' ) && $this -> config -> get ( 'sandbox_on' ) ?
'https://www.sandbox.paypal.com/' : 'https://www.paypal.com/' ;
$url = $host . 'checkoutnow?token=' . $this -> session_handler -> order () -> id ();
if ( $this -> session_handler -> insufficient_funding_tries () >= 3 ) {
$this -> session_handler -> destroy_session_data ();
wc_add_notice (
2020-10-08 20:03:07 -03:00
__ ( 'Please use a different payment method.' , 'woocommerce-paypal-payments' ),
2020-09-14 14:17:39 +03:00
'error'
);
2021-03-15 16:43:39 +02:00
return $failure_data ;
2020-09-14 14:17:39 +03:00
}
return array (
'result' => 'success' ,
'redirect' => $url ,
);
}
$this -> session_handler -> destroy_session_data ();
2020-11-20 15:40:01 +01:00
} catch ( RuntimeException $error ) {
2021-10-06 16:03:38 +03:00
$this -> handle_failure ( $wc_order , $error );
2021-03-15 16:43:39 +02:00
return $failure_data ;
2020-09-14 14:17:39 +03:00
}
2020-11-20 15:40:01 +01:00
2020-09-14 14:17:39 +03:00
wc_add_notice (
$this -> order_processor -> last_error (),
'error'
);
2021-08-13 11:00:55 +02:00
$wc_order -> update_status (
'failed' ,
__ ( 'Could not process order.' , 'woocommerce-paypal-payments' )
);
2020-09-14 14:17:39 +03:00
2021-03-15 16:43:39 +02:00
return $failure_data ;
2020-09-14 14:17:39 +03:00
}
2021-03-10 12:10:12 +01:00
2021-04-22 12:43:17 +02:00
/**
* Checks if PayPal or Credit Card gateways are enabled .
*
* @ return bool Whether any of the gateways is enabled .
*/
protected function gateways_enabled () : bool {
if ( $this -> config -> has ( 'enabled' ) && $this -> config -> get ( 'enabled' ) ) {
return true ;
}
if ( $this -> config -> has ( 'dcc_enabled' ) && $this -> config -> get ( 'dcc_enabled' ) ) {
return true ;
}
return false ;
}
2021-03-10 12:10:12 +01:00
/**
2021-04-23 10:33:28 +02:00
* Checks if vault setting is enabled .
2021-03-10 12:55:35 +01:00
*
* @ return bool Whether vault settings are enabled or not .
* @ throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting hasn ' t been found .
2021-03-10 12:10:12 +01:00
*/
2021-04-23 10:33:28 +02:00
protected function vault_setting_enabled () : bool {
2021-03-12 10:52:07 +01:00
if ( $this -> config -> has ( 'vault_enabled' ) && $this -> config -> get ( 'vault_enabled' ) ) {
return true ;
2021-03-10 12:10:12 +01:00
}
2021-03-12 10:52:07 +01:00
return false ;
2021-03-10 12:10:12 +01:00
}
2021-10-06 16:03:38 +03:00
/**
* Handles the payment failure .
*
* @ param \WC_Order $wc_order The order .
* @ param Exception $error The error causing the failure .
*/
protected function handle_failure ( \WC_Order $wc_order , Exception $error ) : void {
$this -> logger -> error ( 'Payment failed: ' . $error -> getMessage () );
$wc_order -> update_status (
'failed' ,
__ ( 'Could not process order.' , 'woocommerce-paypal-payments' )
);
$this -> session_handler -> destroy_session_data ();
wc_add_notice ( $error -> getMessage (), 'error' );
}
2020-09-14 14:17:39 +03:00
}