diff --git a/modules/ppcp-api-client/services.php b/modules/ppcp-api-client/services.php index 0173031c0..f05db4c3f 100644 --- a/modules/ppcp-api-client/services.php +++ b/modules/ppcp-api-client/services.php @@ -241,10 +241,11 @@ return array( $bn_code ); }, - 'api.endpoint.orders' => static function (ContainerInterface $container): Orders { + 'api.endpoint.orders' => static function ( ContainerInterface $container ): Orders { return new Orders( $container->get( 'api.host' ), - $container->get( 'api.bearer' ) + $container->get( 'api.bearer' ), + $container->get( 'woocommerce.logger.woocommerce' ) ); }, 'api.endpoint.billing-agreements' => static function ( ContainerInterface $container ): BillingAgreementsEndpoint { diff --git a/modules/ppcp-api-client/src/Endpoint/Orders.php b/modules/ppcp-api-client/src/Endpoint/Orders.php index 51d01a24d..555404b21 100644 --- a/modules/ppcp-api-client/src/Endpoint/Orders.php +++ b/modules/ppcp-api-client/src/Endpoint/Orders.php @@ -10,6 +10,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint; +use Psr\Log\LoggerInterface; use RuntimeException; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WP_Error; @@ -19,6 +20,8 @@ use WP_Error; */ class Orders { + use RequestTrait; + /** * The host. * @@ -33,29 +36,47 @@ class Orders { */ private $bearer; + /** + * The logger. + * + * @var LoggerInterface + */ + private $logger; + /** * Orders constructor. * - * @param string $host - * @param Bearer $bearer + * @param string $host The host. + * @param Bearer $bearer The bearer. + * @param LoggerInterface $logger The logger. */ public function __construct( string $host, - Bearer $bearer + Bearer $bearer, + LoggerInterface $logger ) { - $this->host = $host; + $this->host = $host; $this->bearer = $bearer; + $this->logger = $logger; } - public function create(array $request_body, array $headers = array()): array { + /** + * Creates a PayPal order. + * + * @param array $request_body The request body. + * @param array $headers The request headers. + * @return array + * @throws RuntimeException If something is wrong with the request. + */ + public function create( array $request_body, array $headers = array() ): array { $bearer = $this->bearer->bearer(); - $url = trailingslashit( $this->host ) . 'v2/checkout/orders'; + $url = trailingslashit( $this->host ) . 'v2/checkout/orders'; $default_headers = array( 'Authorization' => 'Bearer ' . $bearer->token(), - 'Content-Type' => 'application/json', + 'Content-Type' => 'application/json', ); - $headers = array_merge( + $headers = array_merge( $default_headers, $headers ); @@ -66,7 +87,7 @@ class Orders { 'body' => wp_json_encode( $request_body ), ); - $response = wp_remote_get( $url, $args ); + $response = $this->request( $url, $args ); if ( $response instanceof WP_Error ) { throw new RuntimeException( $response->get_error_message() ); } diff --git a/modules/ppcp-local-alternative-payment-methods/services.php b/modules/ppcp-local-alternative-payment-methods/services.php index 167916ae0..8e2431005 100644 --- a/modules/ppcp-local-alternative-payment-methods/services.php +++ b/modules/ppcp-local-alternative-payment-methods/services.php @@ -12,7 +12,10 @@ namespace WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; return array( - 'ppcp-local-apms.bancontact.wc-gateway' => static function ( ContainerInterface $container ): BancontactGateway { - return new BancontactGateway(); + 'ppcp-local-apms.bancontact.wc-gateway' => static function ( ContainerInterface $container ): BancontactGateway { + return new BancontactGateway( + $container->get( 'api.endpoint.orders' ), + $container->get( 'api.factory.purchase-unit' ) + ); }, ); diff --git a/modules/ppcp-local-alternative-payment-methods/src/BancontactGateway.php b/modules/ppcp-local-alternative-payment-methods/src/BancontactGateway.php index 54735b999..e013fcfc1 100644 --- a/modules/ppcp-local-alternative-payment-methods/src/BancontactGateway.php +++ b/modules/ppcp-local-alternative-payment-methods/src/BancontactGateway.php @@ -10,12 +10,40 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods; use WC_Payment_Gateway; +use WooCommerce\PayPalCommerce\ApiClient\Endpoint\Orders; +use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory; +/** + * Class BancontactGateway + */ class BancontactGateway extends WC_Payment_Gateway { const ID = 'ppcp-bancontact'; - public function __construct() { + /** + * PayPal Orders endpoint. + * + * @var Orders + */ + private $orders_endpoint; + + /** + * Purchase unit factory. + * + * @var PurchaseUnitFactory + */ + private $purchase_unit_factory; + + /** + * BancontactGateway constructor. + * + * @param Orders $orders_endpoint PayPal Orders endpoint. + * @param PurchaseUnitFactory $purchase_unit_factory Purchase unit factory. + */ + public function __construct( + Orders $orders_endpoint, + PurchaseUnitFactory $purchase_unit_factory + ) { $this->id = self::ID; $this->method_title = __( 'Bancontact', 'woocommerce-paypal-payments' ); @@ -30,8 +58,14 @@ class BancontactGateway extends WC_Payment_Gateway { $this->init_settings(); add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + + $this->orders_endpoint = $orders_endpoint; + $this->purchase_unit_factory = $purchase_unit_factory; } + /** + * Initialize the form fields. + */ public function init_form_fields() { $this->form_fields = array( 'enabled' => array( @@ -59,14 +93,63 @@ class BancontactGateway extends WC_Payment_Gateway { ); } + /** + * Processes the order. + * + * @param int $order_id The WC order ID. + * @return array + */ public function process_payment( $order_id ) { $wc_order = wc_get_order( $order_id ); + $wc_order->update_status( 'on-hold', __( 'Awaiting Bancontact to confirm the payment.', 'woocommerce-paypal-payments' ) ); + $purchase_unit = $this->purchase_unit_factory->from_wc_order( $wc_order ); + $amount = $purchase_unit->amount()->to_array(); + $request_body = array( + 'intent' => 'CAPTURE', + 'payment_source' => array( + 'bancontact' => array( + 'country_code' => 'BE', + 'name' => 'John Doe', + ), + ), + 'processing_instruction' => 'ORDER_COMPLETE_ON_PAYMENT_APPROVAL', + 'purchase_units' => array( + array( + 'reference_id' => $purchase_unit->reference_id(), + 'amount' => array( + 'currency_code' => $amount['currency_code'], + 'value' => $amount['value'], + ), + 'custom_id' => $purchase_unit->custom_id(), + 'invoice_id' => $purchase_unit->invoice_id(), + ), + ), + 'application_context' => array( + 'locale' => 'en-BE', + 'return_url' => $this->get_return_url( $wc_order ), + 'cancel_url' => $this->get_return_url( $wc_order ), + ), + ); + + $headers = array( + 'PayPal-Request-Id' => uniqid( 'ppcp-', true ), + ); + + $response = $this->orders_endpoint->create( $request_body, $headers ); + $body = json_decode( $response['body'] ); + + $payer_action = ''; + foreach ( $body->links as $link ) { + if ( $link->rel === 'payer-action' ) { + $payer_action = $link->href; + } + } return array( 'result' => 'success', - 'redirect' => $this->get_return_url( $wc_order ), + 'redirect' => esc_url( $payer_action ), ); } }