diff --git a/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php b/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php index 33c2aed4d..cf9a65f4c 100644 --- a/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php +++ b/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php @@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext; use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus; +use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer; @@ -339,8 +340,8 @@ class OrderEndpoint { $order = $this->order_factory->from_paypal_response( $json ); - $purchase_units_payments_captures_status = $order->purchase_units()[0]->payments()->captures()[0]->status() ?? ''; - if ( $purchase_units_payments_captures_status && 'DECLINED' === $purchase_units_payments_captures_status ) { + $capture_status = $order->purchase_units()[0]->payments()->captures()[0]->status() ?? null; + if ( $capture_status && $capture_status->is( CaptureStatus::DECLINED ) ) { throw new RuntimeException( __( 'Payment provider declined the payment, please use a different payment method.', 'woocommerce-paypal-payments' ) ); } diff --git a/modules/ppcp-api-client/src/Entity/class-capture.php b/modules/ppcp-api-client/src/Entity/class-capture.php index 9aad9e029..4b4853add 100644 --- a/modules/ppcp-api-client/src/Entity/class-capture.php +++ b/modules/ppcp-api-client/src/Entity/class-capture.php @@ -26,17 +26,10 @@ class Capture { /** * The status. * - * @var string + * @var CaptureStatus */ private $status; - /** - * The status details. - * - * @var string - */ - private $status_details; - /** * The amount. * @@ -75,19 +68,17 @@ class Capture { /** * Capture constructor. * - * @param string $id The ID. - * @param string $status The status. - * @param string $status_details The status details. - * @param Amount $amount The amount. - * @param bool $final_capture The final capture. - * @param string $seller_protection The seller protection. - * @param string $invoice_id The invoice id. - * @param string $custom_id The custom id. + * @param string $id The ID. + * @param CaptureStatus $status The status. + * @param Amount $amount The amount. + * @param bool $final_capture The final capture. + * @param string $seller_protection The seller protection. + * @param string $invoice_id The invoice id. + * @param string $custom_id The custom id. */ public function __construct( string $id, - string $status, - string $status_details, + CaptureStatus $status, Amount $amount, bool $final_capture, string $seller_protection, @@ -97,7 +88,6 @@ class Capture { $this->id = $id; $this->status = $status; - $this->status_details = $status_details; $this->amount = $amount; $this->final_capture = $final_capture; $this->seller_protection = $seller_protection; @@ -117,21 +107,12 @@ class Capture { /** * Returns the status. * - * @return string + * @return CaptureStatus */ - public function status() : string { + public function status() : CaptureStatus { return $this->status; } - /** - * Returns the status details object. - * - * @return \stdClass - */ - public function status_details() : \stdClass { - return (object) array( 'reason' => $this->status_details ); - } - /** * Returns the amount. * @@ -183,15 +164,18 @@ class Capture { * @return array */ public function to_array() : array { - return array( + $data = array( 'id' => $this->id(), - 'status' => $this->status(), - 'status_details' => (array) $this->status_details(), + 'status' => $this->status()->name(), 'amount' => $this->amount()->to_array(), 'final_capture' => $this->final_capture(), 'seller_protection' => (array) $this->seller_protection(), 'invoice_id' => $this->invoice_id(), 'custom_id' => $this->custom_id(), ); + if ( $this->status()->details() ) { + $data['status_details'] = array( 'reason' => $this->status()->details()->reason() ); + } + return $data; } } diff --git a/modules/ppcp-api-client/src/Entity/class-capturestatus.php b/modules/ppcp-api-client/src/Entity/class-capturestatus.php new file mode 100644 index 000000000..aae0c920d --- /dev/null +++ b/modules/ppcp-api-client/src/Entity/class-capturestatus.php @@ -0,0 +1,79 @@ +status = $status; + $this->details = $details; + } + + /** + * Compares the current status with a given one. + * + * @param string $status The status to compare with. + * + * @return bool + */ + public function is( string $status ): bool { + return $this->status === $status; + } + + /** + * Returns the status. + * + * @return string + */ + public function name(): string { + return $this->status; + } + + /** + * Returns the details. + * + * @return CaptureStatusDetails|null + */ + public function details(): ?CaptureStatusDetails { + return $this->details; + } +} diff --git a/modules/ppcp-api-client/src/Entity/class-capturestatusdetails.php b/modules/ppcp-api-client/src/Entity/class-capturestatusdetails.php new file mode 100644 index 000000000..326875da9 --- /dev/null +++ b/modules/ppcp-api-client/src/Entity/class-capturestatusdetails.php @@ -0,0 +1,66 @@ +reason = $reason; + } + + /** + * Compares the current reason with a given one. + * + * @param string $reason The reason to compare with. + * + * @return bool + */ + public function is( string $reason ): bool { + return $this->reason === $reason; + } + + /** + * Returns the reason explaining capture status. + * + * @return string + */ + public function reason(): string { + return $this->reason; + } +} diff --git a/modules/ppcp-api-client/src/Factory/class-capturefactory.php b/modules/ppcp-api-client/src/Factory/class-capturefactory.php index 7389f67e5..ec0309014 100644 --- a/modules/ppcp-api-client/src/Factory/class-capturefactory.php +++ b/modules/ppcp-api-client/src/Factory/class-capturefactory.php @@ -10,6 +10,8 @@ declare( strict_types=1 ); namespace WooCommerce\PayPalCommerce\ApiClient\Factory; use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture; +use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus; +use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatusDetails; /** * Class CaptureFactory @@ -42,11 +44,14 @@ class CaptureFactory { */ public function from_paypal_response( \stdClass $data ) : Capture { - $reason = isset( $data->status_details->reason ) ? (string) $data->status_details->reason : ''; + $reason = $data->status_details->reason ?? null; + return new Capture( (string) $data->id, - (string) $data->status, - $reason, + new CaptureStatus( + (string) $data->status, + $reason ? new CaptureStatusDetails( $reason ) : null + ), $this->amount_factory->from_paypal_response( $data->amount ), (bool) $data->final_capture, (string) $data->seller_protection->status, diff --git a/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php b/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php index d44471319..16bd945f7 100644 --- a/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php +++ b/tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php @@ -8,6 +8,7 @@ use Requests_Utility_CaseInsensitiveDictionary; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext; use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture; +use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\Order; use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus; use WooCommerce\PayPalCommerce\ApiClient\Entity\PatchCollection; @@ -278,7 +279,7 @@ class OrderEndpointTest extends TestCase $expectedOrder->shouldReceive('purchase_units')->once()->andReturn(['0'=>$purchaseUnit]); $purchaseUnit->shouldReceive('payments')->once()->andReturn($payment); $payment->shouldReceive('captures')->once()->andReturn(['0'=>$capture]); - $capture->shouldReceive('status')->once()->andReturn(''); + $capture->shouldReceive('status')->once()->andReturn(new CaptureStatus(CaptureStatus::COMPLETED)); $result = $testee->capture($orderToCapture); $this->assertEquals($expectedOrder, $result);