mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-01 07:02:48 +08:00
Merge branch 'master' into pay-now
This commit is contained in:
commit
06728d616b
27 changed files with 1106 additions and 475 deletions
|
@ -23,6 +23,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\AddressFactory;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Factory\AmountFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ItemFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PatchCollectionFactory;
|
||||
|
@ -213,6 +214,11 @@ return array(
|
|||
'api.factory.webhook' => static function ( $container ): WebhookFactory {
|
||||
return new WebhookFactory();
|
||||
},
|
||||
'api.factory.capture' => static function ( $container ): CaptureFactory {
|
||||
|
||||
$amount_factory = $container->get( 'api.factory.amount' );
|
||||
return new CaptureFactory( $amount_factory );
|
||||
},
|
||||
'api.factory.purchase-unit' => static function ( $container ): PurchaseUnitFactory {
|
||||
|
||||
$amount_factory = $container->get( 'api.factory.amount' );
|
||||
|
@ -276,7 +282,8 @@ return array(
|
|||
},
|
||||
'api.factory.payments' => static function ( $container ): PaymentsFactory {
|
||||
$authorizations_factory = $container->get( 'api.factory.authorization' );
|
||||
return new PaymentsFactory( $authorizations_factory );
|
||||
$capture_factory = $container->get( 'api.factory.capture' );
|
||||
return new PaymentsFactory( $authorizations_factory, $capture_factory );
|
||||
},
|
||||
'api.factory.authorization' => static function ( $container ): AuthorizationFactory {
|
||||
return new AuthorizationFactory();
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
|||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
|
||||
|
@ -188,4 +189,63 @@ class PaymentsEndpoint {
|
|||
$authorization = $this->authorizations_factory->from_paypal_response( $json );
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refunds a payment.
|
||||
*
|
||||
* @param Refund $refund The refund to be processed.
|
||||
*
|
||||
* @return bool
|
||||
* @throws RuntimeException If the request fails.
|
||||
*/
|
||||
public function refund( Refund $refund ) : bool {
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit( $this->host ) . 'v2/payments/captures/' . $refund->for_capture()->id() . '/refund';
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
),
|
||||
'body' => wp_json_encode( $refund->to_array() ),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
$json = json_decode( $response['body'] );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$error = new RuntimeException(
|
||||
__( 'Could not refund payment.', 'paypal-payments-for-woocommerce' )
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
array(
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
)
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 201 !== $status_code ) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$status_code
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
array(
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
)
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
197
modules/ppcp-api-client/src/Entity/class-capture.php
Normal file
197
modules/ppcp-api-client/src/Entity/class-capture.php
Normal file
|
@ -0,0 +1,197 @@
|
|||
<?php
|
||||
/**
|
||||
* The capture entity.
|
||||
*
|
||||
* @link https://developer.paypal.com/docs/api/orders/v2/#definition-capture
|
||||
*
|
||||
* @package Woocommerce\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
|
||||
namespace Woocommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class Capture
|
||||
*/
|
||||
class Capture {
|
||||
|
||||
/**
|
||||
* The ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* The status.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
* The status details.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $status_details;
|
||||
|
||||
/**
|
||||
* The amount.
|
||||
*
|
||||
* @var Amount
|
||||
*/
|
||||
private $amount;
|
||||
|
||||
/**
|
||||
* Whether this is the final capture or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $final_capture;
|
||||
|
||||
/**
|
||||
* The seller protection.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $seller_protection;
|
||||
|
||||
/**
|
||||
* The invoice id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $invoice_id;
|
||||
|
||||
/**
|
||||
* The custom id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $custom_id;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public function __construct(
|
||||
string $id,
|
||||
string $status,
|
||||
string $status_details,
|
||||
Amount $amount,
|
||||
bool $final_capture,
|
||||
string $seller_protection,
|
||||
string $invoice_id,
|
||||
string $custom_id
|
||||
) {
|
||||
|
||||
$this->id = $id;
|
||||
$this->status = $status;
|
||||
$this->status_details = $status_details;
|
||||
$this->amount = $amount;
|
||||
$this->final_capture = $final_capture;
|
||||
$this->seller_protection = $seller_protection;
|
||||
$this->invoice_id = $invoice_id;
|
||||
$this->custom_id = $custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id() : string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function status() : string {
|
||||
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.
|
||||
*
|
||||
* @return Amount
|
||||
*/
|
||||
public function amount() : Amount {
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this is the final capture or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function final_capture() : bool {
|
||||
return $this->final_capture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the seller protection object.
|
||||
*
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function seller_protection() : \stdClass {
|
||||
return (object) array( 'status' => $this->seller_protection );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the invoice id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function invoice_id() : string {
|
||||
return $this->invoice_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function custom_id() : string {
|
||||
return $this->custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array() : array {
|
||||
return array(
|
||||
'id' => $this->id(),
|
||||
'status' => $this->status(),
|
||||
'status_details' => (array) $this->status_details(),
|
||||
'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(),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -21,13 +21,34 @@ class Payments {
|
|||
*/
|
||||
private $authorizations;
|
||||
|
||||
/**
|
||||
* The Captures.
|
||||
*
|
||||
* @var Capture[]
|
||||
*/
|
||||
private $captures;
|
||||
|
||||
/**
|
||||
* Payments constructor.
|
||||
*
|
||||
* @param Authorization ...$authorizations The Authorizations.
|
||||
* @param array $authorizations The Authorizations.
|
||||
* @param array $captures The Captures.
|
||||
*/
|
||||
public function __construct( Authorization ...$authorizations ) {
|
||||
public function __construct( array $authorizations, array $captures ) {
|
||||
foreach ( $authorizations as $key => $authorization ) {
|
||||
if ( is_a( $authorization, Authorization::class ) ) {
|
||||
continue;
|
||||
}
|
||||
unset( $authorizations[ $key ] );
|
||||
}
|
||||
foreach ( $captures as $key => $capture ) {
|
||||
if ( is_a( $capture, Capture::class ) ) {
|
||||
continue;
|
||||
}
|
||||
unset( $captures[ $key ] );
|
||||
}
|
||||
$this->authorizations = $authorizations;
|
||||
$this->captures = $captures;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,6 +64,12 @@ class Payments {
|
|||
},
|
||||
$this->authorizations()
|
||||
),
|
||||
'captures' => array_map(
|
||||
static function ( Capture $capture ): array {
|
||||
return $capture->to_array();
|
||||
},
|
||||
$this->captures()
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -54,4 +81,13 @@ class Payments {
|
|||
public function authorizations(): array {
|
||||
return $this->authorizations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Captures.
|
||||
*
|
||||
* @return Capture[]
|
||||
**/
|
||||
public function captures(): array {
|
||||
return $this->captures;
|
||||
}
|
||||
}
|
||||
|
|
118
modules/ppcp-api-client/src/Entity/class-refund.php
Normal file
118
modules/ppcp-api-client/src/Entity/class-refund.php
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
/**
|
||||
* The refund object.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class Refund
|
||||
*/
|
||||
class Refund {
|
||||
|
||||
/**
|
||||
* The Capture.
|
||||
*
|
||||
* @var Capture
|
||||
*/
|
||||
private $capture;
|
||||
|
||||
/**
|
||||
* The invoice id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $invoice_id;
|
||||
|
||||
/**
|
||||
* The note to the payer.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $note_to_payer;
|
||||
|
||||
/**
|
||||
* The Amount.
|
||||
*
|
||||
* @var Amount|null
|
||||
*/
|
||||
private $amount;
|
||||
|
||||
/**
|
||||
* Refund constructor.
|
||||
*
|
||||
* @param Capture $capture The capture where the refund is supposed to be applied at.
|
||||
* @param string $invoice_id The invoice id.
|
||||
* @param string $note_to_payer The note to the payer.
|
||||
* @param Amount|null $amount The Amount.
|
||||
*/
|
||||
public function __construct(
|
||||
Capture $capture,
|
||||
string $invoice_id,
|
||||
string $note_to_payer = '',
|
||||
Amount $amount = null
|
||||
) {
|
||||
$this->capture = $capture;
|
||||
$this->invoice_id = $invoice_id;
|
||||
$this->note_to_payer = $note_to_payer;
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the capture for the refund.
|
||||
*
|
||||
* @return Capture
|
||||
*/
|
||||
public function for_capture() : Capture {
|
||||
return $this->capture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the invoice id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function invoice_id() : string {
|
||||
return $this->invoice_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the note to the payer.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function note_to_payer() : string {
|
||||
return $this->note_to_payer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Amount.
|
||||
*
|
||||
* @return Amount|null
|
||||
*/
|
||||
public function amount() {
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object as array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array() : array {
|
||||
$data = array(
|
||||
'invoice_id' => $this->invoice_id(),
|
||||
);
|
||||
if ( $this->note_to_payer() ) {
|
||||
$data['note_to_payer'] = $this->note_to_payer();
|
||||
}
|
||||
if ( $this->amount() ) {
|
||||
$data['amount'] = $this->amount()->to_array();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
57
modules/ppcp-api-client/src/Factory/class-capturefactory.php
Normal file
57
modules/ppcp-api-client/src/Factory/class-capturefactory.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/**
|
||||
* The capture factory.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
|
||||
|
||||
/**
|
||||
* Class CaptureFactory
|
||||
*/
|
||||
class CaptureFactory {
|
||||
|
||||
/**
|
||||
* The Amount factory.
|
||||
*
|
||||
* @var AmountFactory
|
||||
*/
|
||||
private $amount_factory;
|
||||
|
||||
/**
|
||||
* CaptureFactory constructor.
|
||||
*
|
||||
* @param AmountFactory $amount_factory The amount factory.
|
||||
*/
|
||||
public function __construct( AmountFactory $amount_factory ) {
|
||||
|
||||
$this->amount_factory = $amount_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the capture object based off the PayPal response.
|
||||
*
|
||||
* @param \stdClass $data The PayPal response.
|
||||
*
|
||||
* @return Capture
|
||||
*/
|
||||
public function from_paypal_response( \stdClass $data ) : Capture {
|
||||
|
||||
$reason = isset( $data->status_details->reason ) ? (string) $data->status_details->reason : '';
|
||||
return new Capture(
|
||||
(string) $data->id,
|
||||
(string) $data->status,
|
||||
$reason,
|
||||
$this->amount_factory->from_paypal_response( $data->amount ),
|
||||
(bool) $data->final_capture,
|
||||
(string) $data->seller_protection->status,
|
||||
(string) $data->invoice_id,
|
||||
(string) $data->custom_id
|
||||
);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
|
||||
|
||||
/**
|
||||
|
@ -24,16 +25,26 @@ class PaymentsFactory {
|
|||
*/
|
||||
private $authorization_factory;
|
||||
|
||||
/**
|
||||
* The Capture factory.
|
||||
*
|
||||
* @var CaptureFactory
|
||||
*/
|
||||
private $capture_factory;
|
||||
|
||||
/**
|
||||
* PaymentsFactory constructor.
|
||||
*
|
||||
* @param AuthorizationFactory $authorization_factory The AuthorizationFactory.
|
||||
* @param AuthorizationFactory $authorization_factory The Authorization factory.
|
||||
* @param CaptureFactory $capture_factory The Capture factory.
|
||||
*/
|
||||
public function __construct(
|
||||
AuthorizationFactory $authorization_factory
|
||||
AuthorizationFactory $authorization_factory,
|
||||
CaptureFactory $capture_factory
|
||||
) {
|
||||
|
||||
$this->authorization_factory = $authorization_factory;
|
||||
$this->capture_factory = $capture_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,7 +61,13 @@ class PaymentsFactory {
|
|||
},
|
||||
isset( $data->authorizations ) ? $data->authorizations : array()
|
||||
);
|
||||
$payments = new Payments( ...$authorizations );
|
||||
$captures = array_map(
|
||||
function ( \stdClass $authorization ): Capture {
|
||||
return $this->capture_factory->from_paypal_response( $authorization );
|
||||
},
|
||||
isset( $data->captures ) ? $data->captures : array()
|
||||
);
|
||||
$payments = new Payments( $authorizations, $captures );
|
||||
return $payments;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,115 +38,7 @@ class DccApplies {
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'BE' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'BG' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'CY' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'CZ' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'DK' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'EE' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'FI' => array(
|
||||
'ES' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
|
@ -182,25 +74,7 @@ class DccApplies {
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'GR' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'HU' => array(
|
||||
'GB' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
|
@ -236,258 +110,6 @@ class DccApplies {
|
|||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'LV' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'LI' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'LT' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'LU' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'MT' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'NL' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'NO' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'PL' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'PT' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'RO' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'SK' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'SI' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'ES' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'SE' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
'US' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
|
@ -496,25 +118,45 @@ class DccApplies {
|
|||
'JPY',
|
||||
'USD',
|
||||
),
|
||||
'GB' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'JPY',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'USD',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Which countries support which credit cards. Empty credit card arrays mean no restriction on
|
||||
* currency. Otherwise only the currencies in the array are supported.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $country_card_matrix = array(
|
||||
'AU' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
),
|
||||
'ES' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'FR' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'GB' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'GBP', 'USD' ),
|
||||
),
|
||||
'IT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
),
|
||||
'US' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'USD' ),
|
||||
'discover' => array( 'USD' ),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -523,8 +165,7 @@ class DccApplies {
|
|||
* @return bool
|
||||
*/
|
||||
public function for_country_currency(): bool {
|
||||
$region = wc_get_base_location();
|
||||
$country = $region['country'];
|
||||
$country = $this->country();
|
||||
$currency = get_woocommerce_currency();
|
||||
if ( ! in_array( $country, array_keys( $this->allowed_country_currency_matrix ), true ) ) {
|
||||
return false;
|
||||
|
@ -532,4 +173,67 @@ class DccApplies {
|
|||
$applies = in_array( $currency, $this->allowed_country_currency_matrix[ $country ], true );
|
||||
return $applies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns credit cards, which can be used.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function valid_cards() : array {
|
||||
$country = $this->country();
|
||||
$cards = array();
|
||||
if ( ! isset( $this->country_card_matrix[ $country ] ) ) {
|
||||
return $cards;
|
||||
}
|
||||
|
||||
$supported_currencies = $this->country_card_matrix[ $country ];
|
||||
foreach ( $supported_currencies as $card => $currencies ) {
|
||||
if ( $this->can_process_card( $card ) ) {
|
||||
$cards[] = $card;
|
||||
}
|
||||
}
|
||||
if ( in_array( 'amex', $cards, true ) ) {
|
||||
$cards[] = 'american-express';
|
||||
}
|
||||
if ( in_array( 'mastercard', $cards, true ) ) {
|
||||
$cards[] = 'master-card';
|
||||
}
|
||||
return $cards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a card can be used or not.
|
||||
*
|
||||
* @param string $card The card.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function can_process_card( string $card ) : bool {
|
||||
$country = $this->country();
|
||||
if ( ! isset( $this->country_card_matrix[ $country ] ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! isset( $this->country_card_matrix[ $country ][ $card ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the supported currencies array is empty, there are no
|
||||
* restrictions, which currencies are supported by a card.
|
||||
*/
|
||||
$supported_currencies = $this->country_card_matrix[ $country ][ $card ];
|
||||
$currency = get_woocommerce_currency();
|
||||
return empty( $supported_currencies ) || in_array( $currency, $supported_currencies, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the country code of the shop.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function country() : string {
|
||||
$region = wc_get_base_location();
|
||||
$country = $region['country'];
|
||||
return $country;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,12 @@ import ErrorHandler from './modules/ErrorHandler';
|
|||
import CreditCardRenderer from "./modules/Renderer/CreditCardRenderer";
|
||||
import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
|
||||
import MessageRenderer from "./modules/Renderer/MessageRenderer";
|
||||
import Spinner from "./modules/Helper/Spinner";
|
||||
|
||||
const bootstrap = () => {
|
||||
const errorHandler = new ErrorHandler(PayPalCommerceGateway.labels.error.generic);
|
||||
const creditCardRenderer = new CreditCardRenderer(PayPalCommerceGateway, errorHandler);
|
||||
const spinner = new Spinner();
|
||||
const creditCardRenderer = new CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);
|
||||
const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway);
|
||||
const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);
|
||||
const context = PayPalCommerceGateway.context;
|
||||
|
@ -47,7 +49,8 @@ const bootstrap = () => {
|
|||
const checkoutBootstap = new CheckoutBootstap(
|
||||
PayPalCommerceGateway,
|
||||
renderer,
|
||||
messageRenderer
|
||||
messageRenderer,
|
||||
spinner
|
||||
);
|
||||
|
||||
checkoutBootstap.init();
|
||||
|
|
|
@ -3,12 +3,14 @@ import {payerData} from "../Helper/PayerData";
|
|||
|
||||
class CheckoutActionHandler {
|
||||
|
||||
constructor(config, errorHandler) {
|
||||
constructor(config, errorHandler, spinner) {
|
||||
this.config = config;
|
||||
this.errorHandler = errorHandler;
|
||||
this.spinner = spinner;
|
||||
}
|
||||
|
||||
configuration() {
|
||||
const spinner = this.spinner;
|
||||
const createOrder = (data, actions) => {
|
||||
const payer = payerData();
|
||||
const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ?
|
||||
|
@ -33,6 +35,7 @@ class CheckoutActionHandler {
|
|||
return res.json();
|
||||
}).then(function (data) {
|
||||
if (!data.success) {
|
||||
spinner.unblock();
|
||||
errorHandler.message(data.data.message, true);
|
||||
return;
|
||||
}
|
||||
|
@ -46,7 +49,7 @@ class CheckoutActionHandler {
|
|||
}
|
||||
return {
|
||||
createOrder,
|
||||
onApprove:onApprove(this, this.errorHandler),
|
||||
onApprove:onApprove(this, this.errorHandler, this.spinner),
|
||||
onError: (error) => {
|
||||
this.errorHandler.genericError();
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@ import ErrorHandler from '../ErrorHandler';
|
|||
import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
|
||||
|
||||
class CheckoutBootstap {
|
||||
constructor(gateway, renderer, messages) {
|
||||
constructor(gateway, renderer, messages, spinner) {
|
||||
this.gateway = gateway;
|
||||
this.renderer = renderer;
|
||||
this.messages = messages
|
||||
this.messages = messages;
|
||||
this.spinner = spinner;
|
||||
}
|
||||
|
||||
init() {
|
||||
|
@ -41,6 +42,7 @@ class CheckoutBootstap {
|
|||
const actionHandler = new CheckoutActionHandler(
|
||||
PayPalCommerceGateway,
|
||||
new ErrorHandler(this.gateway.labels.error.generic),
|
||||
this.spinner
|
||||
);
|
||||
|
||||
this.renderer.render(
|
||||
|
|
23
modules/ppcp-button/resources/js/modules/Helper/Spinner.js
Normal file
23
modules/ppcp-button/resources/js/modules/Helper/Spinner.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
class Spinner {
|
||||
|
||||
constructor() {
|
||||
this.target = 'form.woocommerce-checkout';
|
||||
}
|
||||
block() {
|
||||
|
||||
jQuery( this.target ).block({
|
||||
message: null,
|
||||
overlayCSS: {
|
||||
background: '#fff',
|
||||
opacity: 0.6
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
unblock() {
|
||||
|
||||
jQuery( this.target ).unblock();
|
||||
}
|
||||
}
|
||||
|
||||
export default Spinner;
|
|
@ -1,5 +1,6 @@
|
|||
const onApprove = (context, errorHandler) => {
|
||||
const onApprove = (context, errorHandler, spinner) => {
|
||||
return (data, actions) => {
|
||||
spinner.block();
|
||||
return fetch(context.config.ajax.approve_order.endpoint, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
|
@ -9,9 +10,13 @@ const onApprove = (context, errorHandler) => {
|
|||
}).then((res)=>{
|
||||
return res.json();
|
||||
}).then((data)=>{
|
||||
spinner.unblock();
|
||||
if (!data.success) {
|
||||
errorHandler.genericError();
|
||||
console.error(data);
|
||||
if (data.data.code === 100) {
|
||||
errorHandler.message(data.data.message);
|
||||
} else {
|
||||
errorHandler.genericError();
|
||||
}
|
||||
if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {
|
||||
return actions.restart();
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@ import dccInputFactory from "../Helper/DccInputFactory";
|
|||
|
||||
class CreditCardRenderer {
|
||||
|
||||
constructor(defaultConfig, errorHandler) {
|
||||
constructor(defaultConfig, errorHandler, spinner) {
|
||||
this.defaultConfig = defaultConfig;
|
||||
this.errorHandler = errorHandler;
|
||||
this.spinner = spinner;
|
||||
this.cardValid = false;
|
||||
}
|
||||
|
||||
render(wrapper, contextConfig) {
|
||||
|
@ -90,6 +92,7 @@ class CreditCardRenderer {
|
|||
}
|
||||
}).then(hostedFields => {
|
||||
const submitEvent = (event) => {
|
||||
this.spinner.block();
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
@ -99,7 +102,7 @@ class CreditCardRenderer {
|
|||
return state.fields[key].isValid;
|
||||
});
|
||||
|
||||
if (formValid) {
|
||||
if (formValid && this.cardValid) {
|
||||
|
||||
let vault = document.querySelector(wrapper + ' .ppcp-credit-card-vault') ?
|
||||
document.querySelector(wrapper + ' .ppcp-credit-card-vault').checked : false;
|
||||
|
@ -110,15 +113,26 @@ class CreditCardRenderer {
|
|||
vault
|
||||
}).then((payload) => {
|
||||
payload.orderID = payload.orderId;
|
||||
this.spinner.unblock();
|
||||
return contextConfig.onApprove(payload);
|
||||
});
|
||||
} else {
|
||||
this.errorHandler.message(this.defaultConfig.hosted_fields.labels.fields_not_valid);
|
||||
this.spinner.unblock();
|
||||
const message = ! this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;
|
||||
this.errorHandler.message(message);
|
||||
}
|
||||
}
|
||||
hostedFields.on('inputSubmitRequest', function () {
|
||||
submitEvent(null);
|
||||
});
|
||||
hostedFields.on('cardTypeChange', (event) => {
|
||||
if ( ! event.cards.length ) {
|
||||
this.cardValid = false;
|
||||
return;
|
||||
}
|
||||
const validCards = this.defaultConfig.hosted_fields.valid_cards;
|
||||
this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;
|
||||
})
|
||||
document.querySelector(wrapper + ' button').addEventListener(
|
||||
'click',
|
||||
submitEvent
|
||||
|
|
|
@ -9,7 +9,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Button;
|
||||
|
||||
use Dhii\Data\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\DisabledSmartButton;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
|
@ -136,10 +135,19 @@ return array(
|
|||
},
|
||||
'button.endpoint.approve-order' => static function ( $container ): ApproveOrderEndpoint {
|
||||
$request_data = $container->get( 'button.request-data' );
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
$session_handler = $container->get( 'session.handler' );
|
||||
$three_d_secure = $container->get( 'button.helper.three-d-secure' );
|
||||
return new ApproveOrderEndpoint( $request_data, $order_endpoint, $session_handler, $three_d_secure );
|
||||
$three_d_secure = $container->get( 'button.helper.three-d-secure' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
return new ApproveOrderEndpoint(
|
||||
$request_data,
|
||||
$order_endpoint,
|
||||
$session_handler,
|
||||
$three_d_secure,
|
||||
$settings,
|
||||
$dcc_applies
|
||||
);
|
||||
},
|
||||
'button.endpoint.data-client-id' => static function( $container ) : DataClientIdEndpoint {
|
||||
$request_data = $container->get( 'button.request-data' );
|
||||
|
|
|
@ -638,7 +638,12 @@ class SmartButton implements SmartButtonInterface {
|
|||
'Unfortunatly, your credit card details are not valid.',
|
||||
'paypal-payments-for-woocommerce'
|
||||
),
|
||||
'card_not_supported' => __(
|
||||
'Unfortunatly, we do not support your credit card.',
|
||||
'paypal-payments-for-woocommerce'
|
||||
),
|
||||
),
|
||||
'valid_cards' => $this->dcc_applies->valid_cards(),
|
||||
),
|
||||
'messages' => $this->message_values(),
|
||||
'labels' => array(
|
||||
|
@ -722,9 +727,9 @@ class SmartButton implements SmartButtonInterface {
|
|||
if ( 'GB' === $country ) {
|
||||
$disable_funding[] = 'card';
|
||||
}
|
||||
|
||||
$params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
|
||||
$smart_button_url = add_query_arg( $params, 'https://www.paypal.com/sdk/js' );
|
||||
|
||||
$smart_button_url = add_query_arg( $params, 'https://www.paypal.com/sdk/js' );
|
||||
return $smart_button_url;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,11 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* Class ApproveOrderEndpoint
|
||||
|
@ -53,6 +55,20 @@ class ApproveOrderEndpoint implements EndpointInterface {
|
|||
*/
|
||||
private $threed_secure;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* The DCC applies object.
|
||||
*
|
||||
* @var DccApplies
|
||||
*/
|
||||
private $dcc_applies;
|
||||
|
||||
/**
|
||||
* ApproveOrderEndpoint constructor.
|
||||
*
|
||||
|
@ -60,18 +76,24 @@ class ApproveOrderEndpoint implements EndpointInterface {
|
|||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
* @param SessionHandler $session_handler The session handler.
|
||||
* @param ThreeDSecure $three_d_secure The 3d secure helper object.
|
||||
* @param Settings $settings The settings.
|
||||
* @param DccApplies $dcc_applies The DCC applies object.
|
||||
*/
|
||||
public function __construct(
|
||||
RequestData $request_data,
|
||||
OrderEndpoint $order_endpoint,
|
||||
SessionHandler $session_handler,
|
||||
ThreeDSecure $three_d_secure
|
||||
ThreeDSecure $three_d_secure,
|
||||
Settings $settings,
|
||||
DccApplies $dcc_applies
|
||||
) {
|
||||
|
||||
$this->request_data = $request_data;
|
||||
$this->api_endpoint = $order_endpoint;
|
||||
$this->session_handler = $session_handler;
|
||||
$this->threed_secure = $three_d_secure;
|
||||
$this->settings = $settings;
|
||||
$this->dcc_applies = $dcc_applies;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,6 +132,23 @@ class ApproveOrderEndpoint implements EndpointInterface {
|
|||
}
|
||||
|
||||
if ( $order->payment_source() && $order->payment_source()->card() ) {
|
||||
if ( $this->settings->has( 'disable_cards' ) ) {
|
||||
$disabled_cards = (array) $this->settings->get( 'disable_cards' );
|
||||
$card = strtolower( $order->payment_source()->card()->brand() );
|
||||
if ( 'master_card' === $card ) {
|
||||
$card = 'mastercard';
|
||||
}
|
||||
|
||||
if ( ! $this->dcc_applies->can_process_card( $card ) || in_array( $card, $disabled_cards, true ) ) {
|
||||
throw new RuntimeException(
|
||||
__(
|
||||
'Unfortunately, we do not accept this card.',
|
||||
'paypal-payments-for-woocommerce'
|
||||
),
|
||||
100
|
||||
);
|
||||
}
|
||||
}
|
||||
$proceed = $this->threed_secure->proceed_with_order( $order );
|
||||
if ( ThreeDSecure::RETRY === $proceed ) {
|
||||
throw new RuntimeException(
|
||||
|
|
|
@ -12,9 +12,11 @@ namespace WooCommerce\PayPalCommerce\WcGateway;
|
|||
use Dhii\Data\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\RenderAuthorizeAction;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
|
||||
|
@ -25,6 +27,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
|
||||
|
@ -36,9 +39,11 @@ return array(
|
|||
$order_processor = $container->get( 'wcgateway.order-processor' );
|
||||
$settings_renderer = $container->get( 'wcgateway.settings.render' );
|
||||
$authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
|
||||
$notice = $container->get( 'wcgateway.notice.authorize-order-action' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$notice = $container->get( 'wcgateway.notice.authorize-order-action' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$session_handler = $container->get( 'session.handler' );
|
||||
$refund_processor = $container->get( 'wcgateway.processor.refunds' );
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
|
||||
return new PayPalGateway(
|
||||
$settings_renderer,
|
||||
|
@ -46,7 +51,9 @@ return array(
|
|||
$authorized_payments,
|
||||
$notice,
|
||||
$settings,
|
||||
$session_handler
|
||||
$session_handler,
|
||||
$refund_processor,
|
||||
$state
|
||||
);
|
||||
},
|
||||
'wcgateway.credit-card-gateway' => static function ( $container ): CreditCardGateway {
|
||||
|
@ -57,6 +64,8 @@ return array(
|
|||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$module_url = $container->get( 'wcgateway.url' );
|
||||
$session_handler = $container->get( 'session.handler' );
|
||||
$refund_processor = $container->get( 'wcgateway.processor.refunds' );
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
return new CreditCardGateway(
|
||||
$settings_renderer,
|
||||
$order_processor,
|
||||
|
@ -64,7 +73,9 @@ return array(
|
|||
$notice,
|
||||
$settings,
|
||||
$module_url,
|
||||
$session_handler
|
||||
$session_handler,
|
||||
$refund_processor,
|
||||
$state
|
||||
);
|
||||
},
|
||||
'wcgateway.disabler' => static function ( $container ): DisableGateways {
|
||||
|
@ -132,11 +143,20 @@ return array(
|
|||
$settings
|
||||
);
|
||||
},
|
||||
'wcgateway.processor.refunds' => static function ( $container ): RefundProcessor {
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
$payments_endpoint = $container->get( 'api.endpoint.payments' );
|
||||
return new RefundProcessor( $order_endpoint, $payments_endpoint );
|
||||
},
|
||||
'wcgateway.processor.authorized-payments' => static function ( $container ): AuthorizedPaymentsProcessor {
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
$payments_endpoint = $container->get( 'api.endpoint.payments' );
|
||||
return new AuthorizedPaymentsProcessor( $order_endpoint, $payments_endpoint );
|
||||
},
|
||||
'wcgateway.admin.render-authorize-action' => static function ( $container ): RenderAuthorizeAction {
|
||||
|
||||
return new RenderAuthorizeAction();
|
||||
},
|
||||
'wcgateway.admin.order-payment-status' => static function ( $container ): PaymentStatusOrderDetail {
|
||||
return new PaymentStatusOrderDetail();
|
||||
},
|
||||
|
@ -1592,6 +1612,25 @@ return array(
|
|||
if ( 'GB' === $country ) {
|
||||
unset( $fields['disable_funding']['options']['card'] );
|
||||
}
|
||||
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
/**
|
||||
* Depending on your store location, some credit cards can't be used.
|
||||
* Here, we filter them out.
|
||||
*
|
||||
* The DCC Applies object.
|
||||
*
|
||||
* @var DccApplies $dcc_applies
|
||||
*/
|
||||
$card_options = $fields['disable_cards']['options'];
|
||||
foreach ( $card_options as $card => $label ) {
|
||||
if ( $dcc_applies->can_process_card( $card ) ) {
|
||||
continue;
|
||||
}
|
||||
unset( $card_options[ $card ] );
|
||||
}
|
||||
$fields['disable_cards']['options'] = $card_options;
|
||||
$fields['card_icons']['options'] = $card_options;
|
||||
return $fields;
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/**
|
||||
* Renders the order action "Capture authorized PayPal payment"
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Admin
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
/**
|
||||
* Class RenderAuthorizeAction
|
||||
*/
|
||||
class RenderAuthorizeAction {
|
||||
|
||||
/**
|
||||
* Renders the action into the $order_actions array based on the WooCommerce order.
|
||||
*
|
||||
* @param array $order_actions The actions to render into.
|
||||
* @param \WC_Order $wc_order The order for which to render the action.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function render( array $order_actions, \WC_Order $wc_order ) : array {
|
||||
|
||||
if ( ! $this->should_render_for_order( $wc_order ) ) {
|
||||
return $order_actions;
|
||||
}
|
||||
|
||||
$order_actions['ppcp_authorize_order'] = esc_html__(
|
||||
'Capture authorized PayPal payment',
|
||||
'paypal-payments-for-woocommerce'
|
||||
);
|
||||
return $order_actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the action should be rendered for a certain WooCommerce order.
|
||||
*
|
||||
* @param \WC_Order $order The Woocommerce order.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function should_render_for_order( \WC_Order $order ) : bool {
|
||||
$data = $order->get_meta( PayPalGateway::CAPTURED_META_KEY );
|
||||
return in_array( $data, array( 'true', 'false' ), true );
|
||||
}
|
||||
}
|
|
@ -9,10 +9,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
|
@ -32,6 +34,13 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
*/
|
||||
private $module_url;
|
||||
|
||||
/**
|
||||
* The refund processor.
|
||||
*
|
||||
* @var RefundProcessor
|
||||
*/
|
||||
private $refund_processor;
|
||||
|
||||
/**
|
||||
* CreditCardGateway constructor.
|
||||
*
|
||||
|
@ -42,6 +51,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
* @param ContainerInterface $config The settings.
|
||||
* @param string $module_url The URL to the module.
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
* @param RefundProcessor $refund_processor The refund processor.
|
||||
* @param State $state The state.
|
||||
*/
|
||||
public function __construct(
|
||||
SettingsRenderer $settings_renderer,
|
||||
|
@ -50,7 +61,9 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
AuthorizeOrderActionNotice $notice,
|
||||
ContainerInterface $config,
|
||||
string $module_url,
|
||||
SessionHandler $session_handler
|
||||
SessionHandler $session_handler,
|
||||
RefundProcessor $refund_processor,
|
||||
State $state
|
||||
) {
|
||||
|
||||
$this->id = self::ID;
|
||||
|
@ -60,6 +73,11 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
$this->settings_renderer = $settings_renderer;
|
||||
$this->config = $config;
|
||||
$this->session_handler = $session_handler;
|
||||
$this->refund_processor = $refund_processor;
|
||||
|
||||
if ( $state->current_state() === State::STATE_ONBOARDED ) {
|
||||
$this->supports = array( 'refunds' );
|
||||
}
|
||||
if (
|
||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||
&& PPCP_FLAG_SUBSCRIPTION
|
||||
|
@ -67,6 +85,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
&& $this->config->get( 'vault_enabled' )
|
||||
) {
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
|
@ -211,4 +230,24 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
public function is_available() : bool {
|
||||
return $this->config->has( 'dcc_enabled' ) && $this->config->get( 'dcc_enabled' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process refund.
|
||||
*
|
||||
* If the gateway declares 'refunds' support, this will allow it to refund.
|
||||
* a passed in amount.
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param float $amount Refund amount.
|
||||
* @param string $reason Refund reason.
|
||||
* @return boolean True or false based on success, or a WP_Error object.
|
||||
*/
|
||||
public function process_refund( $order_id, $amount = null, $reason = '' ) {
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $order, \WC_Order::class ) ) {
|
||||
return false;
|
||||
}
|
||||
return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
@ -72,6 +74,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
*/
|
||||
protected $session_handler;
|
||||
|
||||
/**
|
||||
* The Refund Processor.
|
||||
*
|
||||
* @var RefundProcessor
|
||||
*/
|
||||
private $refund_processor;
|
||||
|
||||
/**
|
||||
* PayPalGateway constructor.
|
||||
*
|
||||
|
@ -81,6 +90,8 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
* @param AuthorizeOrderActionNotice $notice The Order Action Notice object.
|
||||
* @param ContainerInterface $config The settings.
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
* @param RefundProcessor $refund_processor The Refund Processor.
|
||||
* @param State $state The state.
|
||||
*/
|
||||
public function __construct(
|
||||
SettingsRenderer $settings_renderer,
|
||||
|
@ -88,7 +99,9 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||
AuthorizeOrderActionNotice $notice,
|
||||
ContainerInterface $config,
|
||||
SessionHandler $session_handler
|
||||
SessionHandler $session_handler,
|
||||
RefundProcessor $refund_processor,
|
||||
State $state
|
||||
) {
|
||||
|
||||
$this->id = self::ID;
|
||||
|
@ -98,6 +111,11 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
$this->settings_renderer = $settings_renderer;
|
||||
$this->config = $config;
|
||||
$this->session_handler = $session_handler;
|
||||
$this->refund_processor = $refund_processor;
|
||||
|
||||
if ( $state->current_state() === State::STATE_ONBOARDED ) {
|
||||
$this->supports = array( 'refunds' );
|
||||
}
|
||||
if (
|
||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||
&& PPCP_FLAG_SUBSCRIPTION
|
||||
|
@ -105,6 +123,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
&& $this->config->get( 'vault_enabled' )
|
||||
) {
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
|
@ -300,4 +319,23 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
&& self::ID === sanitize_text_field( wp_unslash( $_GET['section'] ) );
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
/**
|
||||
* Process refund.
|
||||
*
|
||||
* If the gateway declares 'refunds' support, this will allow it to refund.
|
||||
* a passed in amount.
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param float $amount Refund amount.
|
||||
* @param string $reason Refund reason.
|
||||
* @return boolean True or false based on success, or a WP_Error object.
|
||||
*/
|
||||
public function process_refund( $order_id, $amount = null, $reason = '' ) {
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $order, \WC_Order::class ) ) {
|
||||
return false;
|
||||
}
|
||||
return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* Processes refunds started in the WooCommerce environment.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Processor
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
/**
|
||||
* Class RefundProcessor
|
||||
*/
|
||||
class RefundProcessor {
|
||||
|
||||
/**
|
||||
* The order endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
private $order_endpoint;
|
||||
|
||||
/**
|
||||
* The payments endpoint.
|
||||
*
|
||||
* @var PaymentsEndpoint
|
||||
*/
|
||||
private $payments_endpoint;
|
||||
|
||||
/**
|
||||
* RefundProcessor constructor.
|
||||
*
|
||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
|
||||
*/
|
||||
public function __construct( OrderEndpoint $order_endpoint, PaymentsEndpoint $payments_endpoint ) {
|
||||
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->payments_endpoint = $payments_endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a refund.
|
||||
*
|
||||
* @param \WC_Order $wc_order The WooCommerce order.
|
||||
* @param float|null $amount The refund amount.
|
||||
* @param string $reason The reason for the refund.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function process( \WC_Order $wc_order, float $amount = null, string $reason = '' ) : bool {
|
||||
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
if ( ! $order_id ) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$order = $this->order_endpoint->order( $order_id );
|
||||
if ( ! $order ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$purchase_units = $order->purchase_units();
|
||||
if ( ! $purchase_units ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$payments = $purchase_units[0]->payments();
|
||||
if ( ! $payments ) {
|
||||
return false;
|
||||
}
|
||||
$captures = $payments->captures();
|
||||
if ( ! $captures ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$capture = $captures[0];
|
||||
$refund = new Refund(
|
||||
$capture,
|
||||
$capture->invoice_id(),
|
||||
$reason,
|
||||
new Amount(
|
||||
new Money( $amount, get_woocommerce_currency() )
|
||||
)
|
||||
);
|
||||
return $this->payments_endpoint->refund( $refund );
|
||||
} catch ( RuntimeException $error ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -427,19 +427,6 @@ class SettingsRenderer {
|
|||
'paypal-payments-for-woocommerce'
|
||||
);
|
||||
?>
|
||||
|
||||
<a
|
||||
href="https://developer.paypal.com/docs/platforms/checkout/reference/country-availability-advanced-cards/"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'Click here to see, in which countries this option is currently available.',
|
||||
'paypal-payments-for-woocommerce'
|
||||
);
|
||||
?>
|
||||
</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -16,6 +16,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\RenderAuthorizeAction;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
|
||||
|
@ -257,12 +258,20 @@ class WcGatewayModule implements ModuleInterface {
|
|||
private function register_order_functionality( ContainerInterface $container ) {
|
||||
add_filter(
|
||||
'woocommerce_order_actions',
|
||||
static function ( $order_actions ): array {
|
||||
$order_actions['ppcp_authorize_order'] = __(
|
||||
'Capture authorized PayPal payment',
|
||||
'paypal-payments-for-woocommerce'
|
||||
);
|
||||
return $order_actions;
|
||||
static function ( $order_actions ) use ( $container ): array {
|
||||
global $theorder;
|
||||
|
||||
if ( ! is_a( $theorder, \WC_Order::class ) ) {
|
||||
return $order_actions;
|
||||
}
|
||||
|
||||
$render = $container->get( 'wcgateway.admin.render-authorize-action' );
|
||||
/**
|
||||
* Renders the authorize action in the select field.
|
||||
*
|
||||
* @var RenderAuthorizeAction $render
|
||||
*/
|
||||
return $render->render( $order_actions, $theorder );
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -8,15 +8,24 @@ use WooCommerce\PayPalCommerce\ApiClient\TestCase;
|
|||
|
||||
class PaymentsTest extends TestCase
|
||||
{
|
||||
public function testAuthorizations()
|
||||
{
|
||||
$authorization = \Mockery::mock(Authorization::class);
|
||||
$authorizations = [$authorization];
|
||||
public function testAuthorizations()
|
||||
{
|
||||
$authorization = \Mockery::mock(Authorization::class);
|
||||
$authorizations = [$authorization];
|
||||
|
||||
$testee = new Payments(...$authorizations);
|
||||
$testee = new Payments($authorizations, []);
|
||||
|
||||
$this->assertEquals($authorizations, $testee->authorizations());
|
||||
}
|
||||
$this->assertEquals($authorizations, $testee->authorizations());
|
||||
}
|
||||
public function testCaptures()
|
||||
{
|
||||
$capture = \Mockery::mock(Capture::class);
|
||||
$captures = [$capture];
|
||||
|
||||
$testee = new Payments([], $captures);
|
||||
|
||||
$this->assertEquals($captures, $testee->captures());
|
||||
}
|
||||
|
||||
public function testToArray()
|
||||
{
|
||||
|
@ -27,9 +36,17 @@ class PaymentsTest extends TestCase
|
|||
'status' => 'CREATED',
|
||||
]
|
||||
);
|
||||
$capture = \Mockery::mock(Capture::class);
|
||||
$capture->shouldReceive('to_array')->andReturn(
|
||||
[
|
||||
'id' => 'capture',
|
||||
'status' => 'CREATED',
|
||||
]
|
||||
);
|
||||
$captures = [$capture];
|
||||
$authorizations = [$authorization];
|
||||
|
||||
$testee = new Payments(...$authorizations);
|
||||
$testee = new Payments($authorizations, $captures);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
|
@ -39,6 +56,12 @@ class PaymentsTest extends TestCase
|
|||
'status' => 'CREATED',
|
||||
],
|
||||
],
|
||||
'captures' => [
|
||||
[
|
||||
'id' => 'capture',
|
||||
'status' => 'CREATED',
|
||||
],
|
||||
],
|
||||
],
|
||||
$testee->to_array()
|
||||
);
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
@ -13,27 +14,36 @@ class PaymentsFactoryTest extends TestCase
|
|||
{
|
||||
public function testFromPayPalResponse()
|
||||
{
|
||||
$authorization = Mockery::mock(Authorization::class);
|
||||
$authorization->shouldReceive('to_array')->andReturn(['id' => 'foo', 'status' => 'CREATED']);
|
||||
$authorization = Mockery::mock(Authorization::class);
|
||||
$authorization->shouldReceive('to_array')->andReturn(['id' => 'foo', 'status' => 'CREATED']);
|
||||
$capture = Mockery::mock(Capture::class);
|
||||
$capture->shouldReceive('to_array')->andReturn(['id' => 'capture', 'status' => 'CREATED']);
|
||||
|
||||
$authorizationsFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
$authorizationsFactory->shouldReceive('from_paypal_response')->andReturn($authorization);
|
||||
|
||||
$authorizationsFactory->shouldReceive('from_paypal_response')->andReturn($authorization);
|
||||
$captureFactory = Mockery::mock(CaptureFactory::class);
|
||||
$captureFactory->shouldReceive('from_paypal_response')->andReturn($capture);
|
||||
$response = (object)[
|
||||
'authorizations' => [
|
||||
(object)['id' => 'foo', 'status' => 'CREATED'],
|
||||
],
|
||||
'authorizations' => [
|
||||
(object)['id' => 'foo', 'status' => 'CREATED'],
|
||||
],
|
||||
'captures' => [
|
||||
(object)['id' => 'capture', 'status' => 'CREATED'],
|
||||
],
|
||||
];
|
||||
|
||||
$testee = new PaymentsFactory($authorizationsFactory);
|
||||
$testee = new PaymentsFactory($authorizationsFactory, $captureFactory);
|
||||
$result = $testee->from_paypal_response($response);
|
||||
|
||||
$this->assertInstanceOf(Payments::class, $result);
|
||||
|
||||
$expectedToArray = [
|
||||
'authorizations' => [
|
||||
['id' => 'foo', 'status' => 'CREATED'],
|
||||
],
|
||||
'authorizations' => [
|
||||
['id' => 'foo', 'status' => 'CREATED'],
|
||||
],
|
||||
'captures' => [
|
||||
['id' => 'capture', 'status' => 'CREATED'],
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expectedToArray, $result->to_array());
|
||||
}
|
||||
|
|
|
@ -5,11 +5,13 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
|||
|
||||
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\TestCase;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsFields;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||
|
@ -42,13 +44,19 @@ class WcGatewayTest extends TestCase
|
|||
->shouldReceive('destroy_session_data');
|
||||
$settings
|
||||
->shouldReceive('has')->andReturnFalse();
|
||||
$refundProcessor = Mockery::mock(RefundProcessor::class);
|
||||
$state = Mockery::mock(State::class);
|
||||
$state
|
||||
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
|
||||
$testee = new PayPalGateway(
|
||||
$settingsRenderer,
|
||||
$orderProcessor,
|
||||
$authorizedPaymentsProcessor,
|
||||
$authorizedOrderActionNotice,
|
||||
$settings,
|
||||
$sessionHandler
|
||||
$sessionHandler,
|
||||
$refundProcessor,
|
||||
$state
|
||||
);
|
||||
|
||||
expect('wc_get_order')
|
||||
|
@ -76,13 +84,19 @@ class WcGatewayTest extends TestCase
|
|||
$settings
|
||||
->shouldReceive('has')->andReturnFalse();
|
||||
$sessionHandler = Mockery::mock(SessionHandler::class);
|
||||
$refundProcessor = Mockery::mock(RefundProcessor::class);
|
||||
$state = Mockery::mock(State::class);
|
||||
$state
|
||||
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
|
||||
$testee = new PayPalGateway(
|
||||
$settingsRenderer,
|
||||
$orderProcessor,
|
||||
$authorizedPaymentsProcessor,
|
||||
$authorizedOrderActionNotice,
|
||||
$settings,
|
||||
$sessionHandler
|
||||
$sessionHandler,
|
||||
$refundProcessor,
|
||||
$state
|
||||
);
|
||||
|
||||
expect('wc_get_order')
|
||||
|
@ -116,13 +130,19 @@ class WcGatewayTest extends TestCase
|
|||
$settings
|
||||
->shouldReceive('has')->andReturnFalse();
|
||||
$sessionHandler = Mockery::mock(SessionHandler::class);
|
||||
$refundProcessor = Mockery::mock(RefundProcessor::class);
|
||||
$state = Mockery::mock(State::class);
|
||||
$state
|
||||
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
|
||||
$testee = new PayPalGateway(
|
||||
$settingsRenderer,
|
||||
$orderProcessor,
|
||||
$authorizedPaymentsProcessor,
|
||||
$authorizedOrderActionNotice,
|
||||
$settings,
|
||||
$sessionHandler
|
||||
$sessionHandler,
|
||||
$refundProcessor,
|
||||
$state
|
||||
);
|
||||
|
||||
expect('wc_get_order')
|
||||
|
@ -171,13 +191,19 @@ class WcGatewayTest extends TestCase
|
|||
$settings
|
||||
->shouldReceive('has')->andReturnFalse();
|
||||
$sessionHandler = Mockery::mock(SessionHandler::class);
|
||||
$refundProcessor = Mockery::mock(RefundProcessor::class);
|
||||
$state = Mockery::mock(State::class);
|
||||
$state
|
||||
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
|
||||
$testee = new PayPalGateway(
|
||||
$settingsRenderer,
|
||||
$orderProcessor,
|
||||
$authorizedPaymentsProcessor,
|
||||
$authorizedOrderActionNotice,
|
||||
$settings,
|
||||
$sessionHandler
|
||||
$sessionHandler,
|
||||
$refundProcessor,
|
||||
$state
|
||||
);
|
||||
|
||||
$this->assertTrue($testee->capture_authorized_payment($wcOrder));
|
||||
|
@ -218,13 +244,19 @@ class WcGatewayTest extends TestCase
|
|||
$settings
|
||||
->shouldReceive('has')->andReturnFalse();
|
||||
$sessionHandler = Mockery::mock(SessionHandler::class);
|
||||
$refundProcessor = Mockery::mock(RefundProcessor::class);
|
||||
$state = Mockery::mock(State::class);
|
||||
$state
|
||||
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
|
||||
$testee = new PayPalGateway(
|
||||
$settingsRenderer,
|
||||
$orderProcessor,
|
||||
$authorizedPaymentsProcessor,
|
||||
$authorizedOrderActionNotice,
|
||||
$settings,
|
||||
$sessionHandler
|
||||
$sessionHandler,
|
||||
$refundProcessor,
|
||||
$state
|
||||
);
|
||||
|
||||
$this->assertTrue($testee->capture_authorized_payment($wcOrder));
|
||||
|
@ -258,13 +290,19 @@ class WcGatewayTest extends TestCase
|
|||
$settings
|
||||
->shouldReceive('has')->andReturnFalse();
|
||||
$sessionHandler = Mockery::mock(SessionHandler::class);
|
||||
$refundProcessor = Mockery::mock(RefundProcessor::class);
|
||||
$state = Mockery::mock(State::class);
|
||||
$state
|
||||
->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
|
||||
$testee = new PayPalGateway(
|
||||
$settingsRenderer,
|
||||
$orderProcessor,
|
||||
$authorizedPaymentsProcessor,
|
||||
$authorizedOrderActionNotice,
|
||||
$settings,
|
||||
$sessionHandler
|
||||
$sessionHandler,
|
||||
$refundProcessor,
|
||||
$state
|
||||
);
|
||||
|
||||
$this->assertFalse($testee->capture_authorized_payment($wcOrder));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue