Merge branch 'trunk' into PCP-417-new-feature---pay-upon-invoice

This commit is contained in:
dinamiko 2022-05-17 11:10:36 +02:00
commit 6ed616802d
18 changed files with 326 additions and 63 deletions

View file

@ -27,6 +27,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ExchangeRateFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\FraudProcessorResponseFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\ItemFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\MoneyFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
@ -257,7 +258,8 @@ return array(
$amount_factory = $container->get( 'api.factory.amount' );
return new CaptureFactory(
$amount_factory,
$container->get( 'api.factory.seller-receivable-breakdown' )
$container->get( 'api.factory.seller-receivable-breakdown' ),
$container->get( 'api.factory.fraud-processor-response' )
);
},
'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory {
@ -354,6 +356,9 @@ return array(
$container->get( 'api.factory.platform-fee' )
);
},
'api.factory.fraud-processor-response' => static function ( ContainerInterface $container ): FraudProcessorResponseFactory {
return new FraudProcessorResponseFactory();
},
'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
return new DccApplies(
$container->get( 'api.dcc-supported-country-currency-matrix' ),

View file

@ -198,11 +198,11 @@ class PaymentsEndpoint {
*
* @param Refund $refund The refund to be processed.
*
* @return void
* @return string Refund ID.
* @throws RuntimeException If the request fails.
* @throws PayPalApiException If the request fails.
*/
public function refund( Refund $refund ) : void {
public function refund( Refund $refund ) : string {
$bearer = $this->bearer->bearer();
$url = trailingslashit( $this->host ) . 'v2/payments/captures/' . $refund->for_capture()->id() . '/refund';
$args = array(
@ -216,19 +216,21 @@ class PaymentsEndpoint {
);
$response = $this->request( $url, $args );
$json = json_decode( $response['body'] );
if ( is_wp_error( $response ) ) {
throw new RuntimeException( 'Could not refund payment.' );
}
$status_code = (int) wp_remote_retrieve_response_code( $response );
if ( 201 !== $status_code ) {
$json = json_decode( $response['body'] );
if ( 201 !== $status_code || ! is_object( $json ) ) {
throw new PayPalApiException(
$json,
$status_code
);
}
return $json->id;
}
/**

View file

@ -58,6 +58,13 @@ class Capture {
*/
private $seller_receivable_breakdown;
/**
* The fraud processor response (AVS, CVV ...).
*
* @var FraudProcessorResponse|null
*/
protected $fraud_processor_response;
/**
* The invoice id.
*
@ -83,6 +90,7 @@ class Capture {
* @param string $invoice_id The invoice id.
* @param string $custom_id The custom id.
* @param SellerReceivableBreakdown|null $seller_receivable_breakdown The detailed breakdown of the capture activity (fees, ...).
* @param FraudProcessorResponse|null $fraud_processor_response The fraud processor response (AVS, CVV ...).
*/
public function __construct(
string $id,
@ -92,7 +100,8 @@ class Capture {
string $seller_protection,
string $invoice_id,
string $custom_id,
?SellerReceivableBreakdown $seller_receivable_breakdown
?SellerReceivableBreakdown $seller_receivable_breakdown,
?FraudProcessorResponse $fraud_processor_response
) {
$this->id = $id;
@ -103,6 +112,7 @@ class Capture {
$this->invoice_id = $invoice_id;
$this->custom_id = $custom_id;
$this->seller_receivable_breakdown = $seller_receivable_breakdown;
$this->fraud_processor_response = $fraud_processor_response;
}
/**
@ -177,6 +187,15 @@ class Capture {
return $this->seller_receivable_breakdown;
}
/**
* Returns the fraud processor response (AVS, CVV ...).
*
* @return FraudProcessorResponse|null
*/
public function fraud_processor_response() : ?FraudProcessorResponse {
return $this->fraud_processor_response;
}
/**
* Returns the entity as array.
*
@ -199,6 +218,9 @@ class Capture {
if ( $this->seller_receivable_breakdown ) {
$data['seller_receivable_breakdown'] = $this->seller_receivable_breakdown->to_array();
}
if ( $this->fraud_processor_response ) {
$data['fraud_processor_response'] = $this->fraud_processor_response->to_array();
}
return $data;
}
}

View file

@ -0,0 +1,74 @@
<?php
/**
* The FraudProcessorResponse object.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
/**
* Class FraudProcessorResponse
*/
class FraudProcessorResponse {
/**
* The AVS response code.
*
* @var string|null
*/
protected $avs_code;
/**
* The CVV response code.
*
* @var string|null
*/
protected $cvv_code;
/**
* FraudProcessorResponse constructor.
*
* @param string|null $avs_code The AVS response code.
* @param string|null $cvv_code The CVV response code.
*/
public function __construct( ?string $avs_code, ?string $cvv_code ) {
$this->avs_code = $avs_code;
$this->cvv_code = $cvv_code;
}
/**
* Returns the AVS response code.
*
* @return string|null
*/
public function avs_code(): ?string {
return $this->avs_code;
}
/**
* Returns the CVV response code.
*
* @return string|null
*/
public function cvv_code(): ?string {
return $this->cvv_code;
}
/**
* Returns the object as array.
*
* @return array
*/
public function to_array(): array {
return array(
'avs_code' => $this->avs_code() ?: '',
'address_match' => $this->avs_code() === 'M' ? 'Y' : 'N',
'postal_match' => $this->avs_code() === 'M' ? 'Y' : 'N',
'cvv_match' => $this->cvv_code() === 'M' ? 'Y' : 'N',
);
}
}

View file

@ -127,7 +127,7 @@ class AmountFactory {
$total_value = (float) $order->get_total();
if ( (
CreditCardGateway::ID === $order->get_payment_method()
|| ( PayPalGateway::ID === $order->get_payment_method() && 'card' === $order->get_meta( PayPalGateway::ORDER_PAYMENT_SOURCE ) )
|| ( PayPalGateway::ID === $order->get_payment_method() && 'card' === $order->get_meta( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY ) )
)
&& $this->is_free_trial_order( $order )
) {

View file

@ -32,19 +32,29 @@ class CaptureFactory {
*/
private $seller_receivable_breakdown_factory;
/**
* The FraudProcessorResponseFactory factory.
*
* @var FraudProcessorResponseFactory
*/
protected $fraud_processor_response_factory;
/**
* CaptureFactory constructor.
*
* @param AmountFactory $amount_factory The amount factory.
* @param SellerReceivableBreakdownFactory $seller_receivable_breakdown_factory The SellerReceivableBreakdown factory.
* @param FraudProcessorResponseFactory $fraud_processor_response_factory The FraudProcessorResponseFactory factory.
*/
public function __construct(
AmountFactory $amount_factory,
SellerReceivableBreakdownFactory $seller_receivable_breakdown_factory
SellerReceivableBreakdownFactory $seller_receivable_breakdown_factory,
FraudProcessorResponseFactory $fraud_processor_response_factory
) {
$this->amount_factory = $amount_factory;
$this->seller_receivable_breakdown_factory = $seller_receivable_breakdown_factory;
$this->fraud_processor_response_factory = $fraud_processor_response_factory;
}
/**
@ -55,12 +65,15 @@ class CaptureFactory {
* @return Capture
*/
public function from_paypal_response( \stdClass $data ) : Capture {
$reason = $data->status_details->reason ?? null;
$seller_receivable_breakdown = isset( $data->seller_receivable_breakdown ) ?
$this->seller_receivable_breakdown_factory->from_paypal_response( $data->seller_receivable_breakdown )
: null;
$fraud_processor_response = isset( $data->processor_response ) ?
$this->fraud_processor_response_factory->from_paypal_response( $data->processor_response )
: null;
return new Capture(
(string) $data->id,
new CaptureStatus(
@ -72,7 +85,8 @@ class CaptureFactory {
(string) $data->seller_protection->status,
(string) $data->invoice_id,
(string) $data->custom_id,
$seller_receivable_breakdown
$seller_receivable_breakdown,
$fraud_processor_response
);
}
}

View file

@ -0,0 +1,33 @@
<?php
/**
* The FraudProcessorResponseFactory Factory.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
use stdClass;
use WooCommerce\PayPalCommerce\ApiClient\Entity\FraudProcessorResponse;
/**
* Class FraudProcessorResponseFactory
*/
class FraudProcessorResponseFactory {
/**
* Returns a FraudProcessorResponse object based off a PayPal Response.
*
* @param stdClass $data The JSON object.
*
* @return FraudProcessorResponse
*/
public function from_paypal_response( stdClass $data ): FraudProcessorResponse {
$avs_code = $data->avs_code ?: null;
$cvv_code = $data->cvv_code ?: null;
return new FraudProcessorResponse( $avs_code, $cvv_code );
}
}