mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
add api client to main repository
This commit is contained in:
parent
7c5638764e
commit
f5bb4048cd
100 changed files with 10765 additions and 2 deletions
2
.github/workflows/php.yml
vendored
2
.github/workflows/php.yml
vendored
|
@ -29,4 +29,4 @@ jobs:
|
|||
- name: Run test suite
|
||||
run: ./vendor/bin/phpunit
|
||||
- name: Run cs
|
||||
run: ./vendor/bin/phpcs src inc modules.local/ppcp-wc-gateway/ modules.local/ppcp-webhooks/ modules.local/ppcp-button/ modules.local/ppcp-onboarding/ modules.local/ppcp-subscription --extensions=php
|
||||
run: ./vendor/bin/phpcs src inc modules.local --extensions=php
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
"dhii/module-interface": "0.2.x-dev",
|
||||
"psr/container": "^1.0",
|
||||
"inpsyde/ppcp-admin-notices": "dev-master",
|
||||
"inpsyde/ppcp-api-client": "dev-master",
|
||||
"inpsyde/ppcp-session": "dev-master",
|
||||
"oomphinc/composer-installers-extender": "^1.1",
|
||||
"container-interop/service-provider": "^0.4.0",
|
||||
|
|
3
modules.local/ppcp-api-client/.gitignore
vendored
Normal file
3
modules.local/ppcp-api-client/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
vendor/
|
||||
build/
|
||||
composer.lock
|
3
modules.local/ppcp-api-client/README.md
Normal file
3
modules.local/ppcp-api-client/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# PPCP API Client
|
||||
|
||||
This module takes care of the api client for the woocommerce-paypal-commerce-gateway.
|
9
modules.local/ppcp-api-client/extensions.php
Normal file
9
modules.local/ppcp-api-client/extensions.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient;
|
||||
|
||||
use Dhii\Data\Container\ContainerInterface;
|
||||
|
||||
return [
|
||||
];
|
10
modules.local/ppcp-api-client/module.php
Normal file
10
modules.local/ppcp-api-client/module.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient;
|
||||
|
||||
use Dhii\Modular\Module\ModuleInterface;
|
||||
|
||||
return function (): ModuleInterface {
|
||||
return new ApiModule();
|
||||
};
|
21
modules.local/ppcp-api-client/phpcs.xml.dist
Normal file
21
modules.local/ppcp-api-client/phpcs.xml.dist
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0"?>
|
||||
<ruleset name="WooCommerce Coding Standards">
|
||||
<description>My projects ruleset.</description>
|
||||
|
||||
<!-- Configs -->
|
||||
<config name="minimum_supported_wp_version" value="4.7" />
|
||||
<config name="testVersion" value="7.2-" />
|
||||
|
||||
<!-- Rules -->
|
||||
<rule ref="WooCommerce-Core" />
|
||||
|
||||
<rule ref="WordPress.WP.I18n">
|
||||
<properties>
|
||||
<property name="text_domain" type="array" value="woocommerce-paypal-commerce-gateway" />
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<rule ref="PHPCompatibility">
|
||||
<exclude-pattern>tests/</exclude-pattern>
|
||||
</rule>
|
||||
</ruleset>
|
270
modules.local/ppcp-api-client/services.php
Normal file
270
modules.local/ppcp-api-client/services.php
Normal file
|
@ -0,0 +1,270 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient;
|
||||
|
||||
use Dhii\Data\Container\ContainerInterface;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\AddressFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\AmountFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ItemFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PatchCollectionFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PayeeFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PaymentsFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PaymentSourceFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ShippingFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\WebhookFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
||||
use Inpsyde\PayPalCommerce\Onboarding\Environment;
|
||||
use Inpsyde\PayPalCommerce\Onboarding\State;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WpOop\TransientCache\CachePoolFactory;
|
||||
|
||||
return [
|
||||
'api.host' => function(ContainerInterface $container) : string {
|
||||
return 'https://api.paypal.com';
|
||||
},
|
||||
'api.paypal-host' => function(ContainerInterface $container) : string {
|
||||
return 'https://api.paypal.com';
|
||||
},
|
||||
'api.partner_merchant_id' => static function () : string {
|
||||
return '';
|
||||
},
|
||||
'api.merchant_email' => function () : string {
|
||||
return '';
|
||||
},
|
||||
'api.merchant_id' => function () : string {
|
||||
return '';
|
||||
},
|
||||
'api.key' => static function (): string {
|
||||
return '';
|
||||
},
|
||||
'api.secret' => static function (): string {
|
||||
return '';
|
||||
},
|
||||
'api.prefix' => static function (): string {
|
||||
return 'WC-';
|
||||
},
|
||||
'api.bearer' => static function (ContainerInterface $container): Bearer {
|
||||
global $wpdb;
|
||||
$cacheFactory = new CachePoolFactory($wpdb);
|
||||
$pool = $cacheFactory->createCachePool('ppcp-token');
|
||||
$key = $container->get('api.key');
|
||||
$secret = $container->get('api.secret');
|
||||
|
||||
$host = $container->get('api.host');
|
||||
$logger = $container->get('woocommerce.logger.woocommerce');
|
||||
return new PayPalBearer(
|
||||
$pool,
|
||||
$host,
|
||||
$key,
|
||||
$secret,
|
||||
$logger
|
||||
);
|
||||
},
|
||||
'api.endpoint.payment-token' => static function (ContainerInterface $container) : PaymentTokenEndpoint {
|
||||
return new PaymentTokenEndpoint(
|
||||
$container->get('api.host'),
|
||||
$container->get('api.bearer'),
|
||||
$container->get('api.factory.payment-token'),
|
||||
$container->get('woocommerce.logger.woocommerce'),
|
||||
$container->get('api.prefix')
|
||||
);
|
||||
},
|
||||
'api.endpoint.webhook' => static function (ContainerInterface $container) : WebhookEndpoint {
|
||||
|
||||
return new WebhookEndpoint(
|
||||
$container->get('api.host'),
|
||||
$container->get('api.bearer'),
|
||||
$container->get('api.factory.webhook'),
|
||||
$container->get('woocommerce.logger.woocommerce')
|
||||
);
|
||||
},
|
||||
'api.endpoint.partner-referrals' => static function (ContainerInterface $container) : PartnerReferrals {
|
||||
|
||||
return new PartnerReferrals(
|
||||
$container->get('api.host'),
|
||||
$container->get('api.bearer'),
|
||||
$container->get('api.repository.partner-referrals-data'),
|
||||
$container->get('woocommerce.logger.woocommerce')
|
||||
);
|
||||
},
|
||||
'api.endpoint.identity-token' => static function (ContainerInterface $container) : IdentityToken {
|
||||
|
||||
$logger = $container->get('woocommerce.logger.woocommerce');
|
||||
$prefix = $container->get('api.prefix');
|
||||
return new IdentityToken(
|
||||
$container->get('api.host'),
|
||||
$container->get('api.bearer'),
|
||||
$logger,
|
||||
$prefix
|
||||
);
|
||||
},
|
||||
'api.endpoint.payments' => static function (ContainerInterface $container): PaymentsEndpoint {
|
||||
$authorizationFactory = $container->get('api.factory.authorization');
|
||||
$logger = $container->get('woocommerce.logger.woocommerce');
|
||||
|
||||
return new PaymentsEndpoint(
|
||||
$container->get('api.host'),
|
||||
$container->get('api.bearer'),
|
||||
$authorizationFactory,
|
||||
$logger
|
||||
);
|
||||
},
|
||||
'api.endpoint.login-seller' => static function (ContainerInterface $container) : LoginSeller {
|
||||
|
||||
$logger = $container->get('woocommerce.logger.woocommerce');
|
||||
return new LoginSeller(
|
||||
|
||||
$container->get('api.paypal-host'),
|
||||
$container->get('api.partner_merchant_id'),
|
||||
$logger
|
||||
);
|
||||
},
|
||||
'api.endpoint.order' => static function (ContainerInterface $container): OrderEndpoint {
|
||||
$orderFactory = $container->get('api.factory.order');
|
||||
$patchCollectionFactory = $container->get('api.factory.patch-collection-factory');
|
||||
$logger = $container->get('woocommerce.logger.woocommerce');
|
||||
|
||||
/**
|
||||
* @var Settings $settings
|
||||
*/
|
||||
$settings = $container->get('wcgateway.settings');
|
||||
$intent = $settings->has('intent') && strtoupper((string) $settings->get('intent')) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
|
||||
$applicationContextRepository = $container->get('api.repository.application-context');
|
||||
$paypalRequestId = $container->get('api.repository.paypal-request-id');
|
||||
return new OrderEndpoint(
|
||||
$container->get('api.host'),
|
||||
$container->get('api.bearer'),
|
||||
$orderFactory,
|
||||
$patchCollectionFactory,
|
||||
$intent,
|
||||
$logger,
|
||||
$applicationContextRepository,
|
||||
$paypalRequestId
|
||||
);
|
||||
},
|
||||
'api.repository.paypal-request-id' => static function(ContainerInterface $container) : PayPalRequestIdRepository {
|
||||
return new PayPalRequestIdRepository();
|
||||
},
|
||||
'api.repository.application-context' => static function(ContainerInterface $container) : ApplicationContextRepository {
|
||||
|
||||
$settings = $container->get('wcgateway.settings');
|
||||
return new ApplicationContextRepository($settings);
|
||||
},
|
||||
'api.repository.partner-referrals-data' => static function (ContainerInterface $container) : PartnerReferralsData {
|
||||
|
||||
$merchantEmail = $container->get('api.merchant_email');
|
||||
$dccApplies = $container->get('api.helpers.dccapplies');
|
||||
return new PartnerReferralsData($merchantEmail, $dccApplies);
|
||||
},
|
||||
'api.repository.cart' => static function (ContainerInterface $container): CartRepository {
|
||||
$factory = $container->get('api.factory.purchase-unit');
|
||||
return new CartRepository($factory);
|
||||
},
|
||||
'api.repository.payee' => static function (ContainerInterface $container): PayeeRepository {
|
||||
$merchantEmail = $container->get('api.merchant_email');
|
||||
$merchantId = $container->get('api.merchant_id');
|
||||
return new PayeeRepository($merchantEmail, $merchantId);
|
||||
},
|
||||
'api.factory.application-context' => static function (ContainerInterface $container) : ApplicationContextFactory {
|
||||
return new ApplicationContextFactory();
|
||||
},
|
||||
'api.factory.payment-token' => static function (ContainerInterface $container) : PaymentTokenFactory {
|
||||
return new PaymentTokenFactory();
|
||||
},
|
||||
'api.factory.webhook' => static function (ContainerInterface $container): WebhookFactory {
|
||||
return new WebhookFactory();
|
||||
},
|
||||
'api.factory.purchase-unit' => static function (ContainerInterface $container): PurchaseUnitFactory {
|
||||
|
||||
$amountFactory = $container->get('api.factory.amount');
|
||||
$payeeRepository = $container->get('api.repository.payee');
|
||||
$payeeFactory = $container->get('api.factory.payee');
|
||||
$itemFactory = $container->get('api.factory.item');
|
||||
$shippingFactory = $container->get('api.factory.shipping');
|
||||
$paymentsFactory = $container->get('api.factory.payments');
|
||||
$prefix = $container->get('api.prefix');
|
||||
|
||||
return new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFactory,
|
||||
$prefix
|
||||
);
|
||||
},
|
||||
'api.factory.patch-collection-factory' => static function (ContainerInterface $container): PatchCollectionFactory {
|
||||
return new PatchCollectionFactory();
|
||||
},
|
||||
'api.factory.payee' => static function (ContainerInterface $container): PayeeFactory {
|
||||
return new PayeeFactory();
|
||||
},
|
||||
'api.factory.item' => static function (ContainerInterface $container): ItemFactory {
|
||||
return new ItemFactory();
|
||||
},
|
||||
'api.factory.shipping' => static function (ContainerInterface $container): ShippingFactory {
|
||||
$addressFactory = $container->get('api.factory.address');
|
||||
return new ShippingFactory($addressFactory);
|
||||
},
|
||||
'api.factory.amount' => static function (ContainerInterface $container): AmountFactory {
|
||||
$itemFactory = $container->get('api.factory.item');
|
||||
return new AmountFactory($itemFactory);
|
||||
},
|
||||
'api.factory.payer' => static function (ContainerInterface $container): PayerFactory {
|
||||
$addressFactory = $container->get('api.factory.address');
|
||||
return new PayerFactory($addressFactory);
|
||||
},
|
||||
'api.factory.address' => static function (ContainerInterface $container): AddressFactory {
|
||||
return new AddressFactory();
|
||||
},
|
||||
'api.factory.payment-source' => static function (ContainerInterface $container): PaymentSourceFactory {
|
||||
return new PaymentSourceFactory();
|
||||
},
|
||||
'api.factory.order' => static function (ContainerInterface $container): OrderFactory {
|
||||
$purchaseUnitFactory = $container->get('api.factory.purchase-unit');
|
||||
$payerFactory = $container->get('api.factory.payer');
|
||||
$applicationContextRepository = $container->get('api.repository.application-context');
|
||||
$applicationContextFactory = $container->get('api.factory.application-context');
|
||||
$paymentSourceFactory = $container->get('api.factory.payment-source');
|
||||
return new OrderFactory(
|
||||
$purchaseUnitFactory,
|
||||
$payerFactory,
|
||||
$applicationContextRepository,
|
||||
$applicationContextFactory,
|
||||
$paymentSourceFactory
|
||||
);
|
||||
},
|
||||
'api.factory.payments' => static function (ContainerInterface $container): PaymentsFactory {
|
||||
$authorizationFactory = $container->get('api.factory.authorization');
|
||||
return new PaymentsFactory($authorizationFactory);
|
||||
},
|
||||
'api.factory.authorization' => static function (ContainerInterface $container): AuthorizationFactory {
|
||||
return new AuthorizationFactory();
|
||||
},
|
||||
'api.helpers.dccapplies' => static function (ContainerInterface $container) : DccApplies {
|
||||
return new DccApplies();
|
||||
},
|
||||
];
|
28
modules.local/ppcp-api-client/src/ApiModule.php
Normal file
28
modules.local/ppcp-api-client/src/ApiModule.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient;
|
||||
|
||||
use Dhii\Container\ServiceProvider;
|
||||
use Dhii\Modular\Module\Exception\ModuleExceptionInterface;
|
||||
use Dhii\Modular\Module\ModuleInterface;
|
||||
use Interop\Container\ServiceProviderInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class ApiModule implements ModuleInterface
|
||||
{
|
||||
|
||||
public function setup(): ServiceProviderInterface
|
||||
{
|
||||
return new ServiceProvider(
|
||||
require __DIR__ . '/../services.php',
|
||||
require __DIR__ . '/../extensions.php'
|
||||
);
|
||||
}
|
||||
|
||||
public function run(ContainerInterface $container)
|
||||
{
|
||||
// TODO: Implement run() method.
|
||||
}
|
||||
}
|
13
modules.local/ppcp-api-client/src/Authentication/Bearer.php
Normal file
13
modules.local/ppcp-api-client/src/Authentication/Bearer.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Authentication;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Token;
|
||||
|
||||
interface Bearer
|
||||
{
|
||||
|
||||
public function bearer(): Token;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Authentication;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Token;
|
||||
|
||||
class ConnectBearer implements Bearer
|
||||
{
|
||||
|
||||
public function bearer(): Token
|
||||
{
|
||||
$data = (object) [
|
||||
'created' => time(),
|
||||
'expires_in' => 3600,
|
||||
'token' => 'token',
|
||||
];
|
||||
return new Token($data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Authentication;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\RequestTrait;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Token;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
class PayPalBearer implements Bearer
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
public const CACHE_KEY = 'ppcp-bearer';
|
||||
private $cache;
|
||||
private $host;
|
||||
private $key;
|
||||
private $secret;
|
||||
private $logger;
|
||||
public function __construct(
|
||||
CacheInterface $cache,
|
||||
string $host,
|
||||
string $key,
|
||||
string $secret,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
|
||||
$this->cache = $cache;
|
||||
$this->host = $host;
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function bearer(): Token
|
||||
{
|
||||
try {
|
||||
$bearer = Token::fromJson((string) $this->cache->get(self::CACHE_KEY));
|
||||
return ($bearer->isValid()) ? $bearer : $this->newBearer();
|
||||
} catch (RuntimeException $error) {
|
||||
return $this->newBearer();
|
||||
}
|
||||
}
|
||||
|
||||
private function newBearer(): Token
|
||||
{
|
||||
$url = trailingslashit($this->host) . 'v1/oauth2/token?grant_type=client_credentials';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Basic ' . base64_encode($this->key . ':' . $this->secret),
|
||||
],
|
||||
];
|
||||
$response = $this->request(
|
||||
$url,
|
||||
$args
|
||||
);
|
||||
|
||||
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not create token.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$token = Token::fromJson($response['body']);
|
||||
$this->cache->set(self::CACHE_KEY, $token->asJson());
|
||||
return $token;
|
||||
}
|
||||
}
|
88
modules.local/ppcp-api-client/src/Endpoint/IdentityToken.php
Normal file
88
modules.local/ppcp-api-client/src/Endpoint/IdentityToken.php
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Token;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class IdentityToken
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
private $bearer;
|
||||
private $host;
|
||||
private $logger;
|
||||
private $prefix;
|
||||
|
||||
public function __construct(string $host, Bearer $bearer, LoggerInterface $logger, string $prefix)
|
||||
{
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->logger = $logger;
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
public function generateForCustomer(int $customerId): Token
|
||||
{
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v1/identity/generate-token';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
];
|
||||
if ($customerId && defined('PPCP_FLAG_SUBSCRIPTION') && PPCP_FLAG_SUBSCRIPTION) {
|
||||
$args['body'] = json_encode(['customer_id' => $this->prefix . $customerId]);
|
||||
}
|
||||
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__(
|
||||
'Could not create identity token.',
|
||||
'woocommerce-paypal-commerce-gateway'
|
||||
)
|
||||
);
|
||||
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 200) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$token = Token::fromJson($response['body']);
|
||||
return $token;
|
||||
}
|
||||
}
|
143
modules.local/ppcp-api-client/src/Endpoint/LoginSeller.php
Normal file
143
modules.local/ppcp-api-client/src/Endpoint/LoginSeller.php
Normal file
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ErrorResponseCollectionFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class LoginSeller
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
private $host;
|
||||
private $partnerMerchantId;
|
||||
private $logger;
|
||||
public function __construct(
|
||||
string $host,
|
||||
string $partnerMerchantId,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
|
||||
$this->host = $host;
|
||||
$this->partnerMerchantId = $partnerMerchantId;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function credentialsFor(
|
||||
string $sharedId,
|
||||
string $authCode,
|
||||
string $sellerNonce
|
||||
): \stdClass {
|
||||
|
||||
$token = $this->generateTokenFor($sharedId, $authCode, $sellerNonce);
|
||||
$url = trailingslashit($this->host) .
|
||||
'v1/customer/partners/' . $this->partnerMerchantId .
|
||||
'/merchant-integrations/credentials/';
|
||||
$args = [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
];
|
||||
$response = $this->request($url, $args);
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not fetch credentials.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if (! isset($json->client_id) || ! isset($json->client_secret)) {
|
||||
$error = isset($json->details) ?
|
||||
new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
) : new RuntimeException(
|
||||
__('Credentials not found.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
private function generateTokenFor(
|
||||
string $sharedId,
|
||||
string $authCode,
|
||||
string $sellerNonce
|
||||
): string {
|
||||
|
||||
$url = trailingslashit($this->host) . 'v1/oauth2/token/';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Basic ' . base64_encode($sharedId . ':'),
|
||||
],
|
||||
'body' => [
|
||||
'grant_type' => 'authorization_code',
|
||||
'code' => $authCode,
|
||||
'code_verifier' => $sellerNonce,
|
||||
],
|
||||
];
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not create token.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if (! isset($json->access_token)) {
|
||||
$error = isset($json->details) ?
|
||||
new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
) : new RuntimeException(
|
||||
__('No token found.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
return (string) $json->access_token;
|
||||
}
|
||||
}
|
418
modules.local/ppcp-api-client/src/Endpoint/OrderEndpoint.php
Normal file
418
modules.local/ppcp-api-client/src/Endpoint/OrderEndpoint.php
Normal file
|
@ -0,0 +1,418 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentMethod;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PatchCollectionFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Helper\ErrorResponse;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
//phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
|
||||
|
||||
class OrderEndpoint
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
private $host;
|
||||
private $bearer;
|
||||
private $orderFactory;
|
||||
private $patchCollectionFactory;
|
||||
private $intent;
|
||||
private $logger;
|
||||
private $applicationContextRepository;
|
||||
private $bnCode;
|
||||
private $payPalRequestIdRepository;
|
||||
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
OrderFactory $orderFactory,
|
||||
PatchCollectionFactory $patchCollectionFactory,
|
||||
string $intent,
|
||||
LoggerInterface $logger,
|
||||
ApplicationContextRepository $applicationContextRepository,
|
||||
PayPalRequestIdRepository $payPalRequestIdRepository,
|
||||
string $bnCode = ''
|
||||
) {
|
||||
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->orderFactory = $orderFactory;
|
||||
$this->patchCollectionFactory = $patchCollectionFactory;
|
||||
$this->intent = $intent;
|
||||
$this->logger = $logger;
|
||||
$this->applicationContextRepository = $applicationContextRepository;
|
||||
$this->bnCode = $bnCode;
|
||||
$this->payPalRequestIdRepository = $payPalRequestIdRepository;
|
||||
}
|
||||
|
||||
public function withBnCode(string $bnCode): OrderEndpoint
|
||||
{
|
||||
|
||||
$this->bnCode = $bnCode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PurchaseUnit[] $items
|
||||
*/
|
||||
public function createForPurchaseUnits(
|
||||
array $items,
|
||||
Payer $payer = null,
|
||||
PaymentToken $paymentToken = null,
|
||||
PaymentMethod $paymentMethod = null,
|
||||
string $paypalRequestId = ''
|
||||
): Order {
|
||||
|
||||
$containsPhysicalGoods = false;
|
||||
$items = array_filter(
|
||||
$items,
|
||||
//phpcs:ignore Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
||||
static function ($item) use (&$containsPhysicalGoods): bool {
|
||||
$isPurchaseUnit = is_a($item, PurchaseUnit::class);
|
||||
if ($isPurchaseUnit && $item->containsPhysicalGoodsItems()) {
|
||||
$containsPhysicalGoods = true;
|
||||
}
|
||||
|
||||
return $isPurchaseUnit;
|
||||
}
|
||||
);
|
||||
$shippingPreference = $containsPhysicalGoods
|
||||
? ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE
|
||||
: ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
|
||||
$bearer = $this->bearer->bearer();
|
||||
$data = [
|
||||
'intent' => $this->intent,
|
||||
'purchase_units' => array_map(
|
||||
static function (PurchaseUnit $item): array {
|
||||
return $item->toArray();
|
||||
},
|
||||
$items
|
||||
),
|
||||
'application_context' => $this->applicationContextRepository
|
||||
->currentContext($shippingPreference)->toArray(),
|
||||
];
|
||||
if ($payer) {
|
||||
$data['payer'] = $payer->toArray();
|
||||
}
|
||||
if ($paymentToken) {
|
||||
$data['payment_source']['token'] = $paymentToken->toArray();
|
||||
}
|
||||
if ($paymentMethod) {
|
||||
$data['payment_method'] = $paymentMethod->toArray();
|
||||
}
|
||||
$url = trailingslashit($this->host) . 'v2/checkout/orders';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
],
|
||||
'body' => json_encode($data),
|
||||
];
|
||||
|
||||
$paypalRequestId = $paypalRequestId ? $paypalRequestId : uniqid('ppcp-', true);
|
||||
$args['headers']['PayPal-Request-Id'] = $paypalRequestId;
|
||||
if ($this->bnCode) {
|
||||
$args['headers']['PayPal-Partner-Attribution-Id'] = $this->bnCode;
|
||||
}
|
||||
$response = $this->request($url, $args);
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not create order.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 201) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$order = $this->orderFactory->fromPayPalResponse($json);
|
||||
$this->payPalRequestIdRepository->setForOrder($order, $paypalRequestId);
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function capture(Order $order): Order
|
||||
{
|
||||
if ($order->status()->is(OrderStatus::COMPLETED)) {
|
||||
return $order;
|
||||
}
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v2/checkout/orders/' . $order->id() . '/capture';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
'PayPal-Request-Id' => $this->payPalRequestIdRepository->getForOrder($order),
|
||||
],
|
||||
];
|
||||
if ($this->bnCode) {
|
||||
$args['headers']['PayPal-Partner-Attribution-Id'] = $this->bnCode;
|
||||
}
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not capture order.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 201) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
// If the order has already been captured, we return the updated order.
|
||||
if (strpos($response['body'], ErrorResponse::ORDER_ALREADY_CAPTURED) !== false) {
|
||||
return $this->order($order->id());
|
||||
}
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$order = $this->orderFactory->fromPayPalResponse($json);
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function authorize(Order $order): Order
|
||||
{
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v2/checkout/orders/' . $order->id() . '/authorize';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
'PayPal-Request-Id' => $this->payPalRequestIdRepository->getForOrder($order),
|
||||
],
|
||||
];
|
||||
if ($this->bnCode) {
|
||||
$args['headers']['PayPal-Partner-Attribution-Id'] = $this->bnCode;
|
||||
}
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__(
|
||||
'Could not authorize order.',
|
||||
'woocommerce-paypal-commerce-gateway'
|
||||
)
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 201) {
|
||||
if (strpos($response['body'], ErrorResponse::ORDER_ALREADY_AUTHORIZED) !== false) {
|
||||
return $this->order($order->id());
|
||||
}
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$order = $this->orderFactory->fromPayPalResponse($json);
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function order(string $id): Order
|
||||
{
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v2/checkout/orders/' . $id;
|
||||
$args = [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'PayPal-Request-Id' => $this->payPalRequestIdRepository->getForOrderId($id),
|
||||
],
|
||||
];
|
||||
if ($this->bnCode) {
|
||||
$args['headers']['PayPal-Partner-Attribution-Id'] = $this->bnCode;
|
||||
}
|
||||
$response = $this->request($url, $args);
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not retrieve order.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode === 404 || empty($response['body'])) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not retrieve order.', 'woocommerce-paypal-commerce-gateway'),
|
||||
404
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
if ($statusCode !== 200) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$order = $this->orderFactory->fromPayPalResponse($json);
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function patchOrderWith(Order $orderToUpdate, Order $orderToCompare): Order
|
||||
{
|
||||
$patches = $this->patchCollectionFactory->fromOrders($orderToUpdate, $orderToCompare);
|
||||
if (! count($patches->patches())) {
|
||||
return $orderToUpdate;
|
||||
}
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v2/checkout/orders/' . $orderToUpdate->id();
|
||||
$args = [
|
||||
'method' => 'PATCH',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
'PayPal-Request-Id' => $this->payPalRequestIdRepository->getForOrder(
|
||||
$orderToUpdate
|
||||
),
|
||||
],
|
||||
'body' => json_encode($patches->toArray()),
|
||||
];
|
||||
if ($this->bnCode) {
|
||||
$args['headers']['PayPal-Partner-Attribution-Id'] = $this->bnCode;
|
||||
}
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not retrieve order.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 204) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$newOrder = $this->order($orderToUpdate->id());
|
||||
return $newOrder;
|
||||
}
|
||||
}
|
104
modules.local/ppcp-api-client/src/Endpoint/PartnerReferrals.php
Normal file
104
modules.local/ppcp-api-client/src/Endpoint/PartnerReferrals.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ErrorResponseCollectionFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
//phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
|
||||
class PartnerReferrals
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
private $host;
|
||||
private $bearer;
|
||||
private $data;
|
||||
private $logger;
|
||||
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
PartnerReferralsData $data,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->data = $data;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function signupLink(): string
|
||||
{
|
||||
$data = $this->data->data();
|
||||
$bearer = $this->bearer->bearer();
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
],
|
||||
'body' => json_encode($data),
|
||||
];
|
||||
$url = trailingslashit($this->host) . 'v2/customer/partner-referrals';
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not create referral.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 201) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
foreach ($json->links as $link) {
|
||||
if ($link->rel === 'action_url') {
|
||||
return (string) $link->href;
|
||||
}
|
||||
}
|
||||
|
||||
$error = new RuntimeException(
|
||||
__('Action URL not found.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class PaymentTokenEndpoint
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
private $bearer;
|
||||
private $host;
|
||||
private $factory;
|
||||
private $logger;
|
||||
private $prefix;
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
PaymentTokenFactory $factory,
|
||||
LoggerInterface $logger,
|
||||
string $prefix
|
||||
) {
|
||||
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->factory = $factory;
|
||||
$this->logger = $logger;
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
// phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
|
||||
/**
|
||||
* @param int $id
|
||||
* @return PaymentToken[]
|
||||
*/
|
||||
public function forUser(int $id): array
|
||||
{
|
||||
$bearer = $this->bearer->bearer();
|
||||
|
||||
$customerId = $this->prefix . $id;
|
||||
$url = trailingslashit($this->host) . 'v2/vault/payment-tokens/?customer_id=' . $customerId;
|
||||
$args = [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
];
|
||||
|
||||
$response = $this->request($url, $args);
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not fetch payment token.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 200) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$tokens = [];
|
||||
foreach ($json->payment_tokens as $tokenValue) {
|
||||
$tokens[] = $this->factory->fromPayPalResponse($tokenValue);
|
||||
}
|
||||
if (empty($tokens)) {
|
||||
$error = new RuntimeException(
|
||||
sprintf(
|
||||
// translators: %d is the customer id.
|
||||
__('No token stored for customer %d.', 'woocommerce-paypal-commerce-gateway'),
|
||||
$id
|
||||
)
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
return $tokens;
|
||||
}
|
||||
// phpcs:enable Inpsyde.CodeQuality.FunctionLength.TooLong
|
||||
|
||||
public function deleteToken(PaymentToken $token): bool
|
||||
{
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
|
||||
$url = trailingslashit($this->host) . 'v2/vault/payment-tokens/' . $token->id();
|
||||
$args = [
|
||||
'method' => 'DELETE',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
];
|
||||
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not delete payment token.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
return wp_remote_retrieve_response_code($response) === 204;
|
||||
}
|
||||
}
|
140
modules.local/ppcp-api-client/src/Endpoint/PaymentsEndpoint.php
Normal file
140
modules.local/ppcp-api-client/src/Endpoint/PaymentsEndpoint.php
Normal file
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ErrorResponseCollectionFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class PaymentsEndpoint
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
private $host;
|
||||
private $bearer;
|
||||
private $authorizationFactory;
|
||||
private $logger;
|
||||
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
AuthorizationFactory $authorizationsFactory,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->authorizationFactory = $authorizationsFactory;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function authorization(string $authorizationId): Authorization
|
||||
{
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v2/payments/authorizations/' . $authorizationId;
|
||||
$args = [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
],
|
||||
];
|
||||
|
||||
$response = $this->request($url, $args);
|
||||
$json = json_decode($response['body']);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not get authorized payment info.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 200) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$authorization = $this->authorizationFactory->fromPayPalRequest($json);
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
public function capture(string $authorizationId): Authorization
|
||||
{
|
||||
$bearer = $this->bearer->bearer();
|
||||
//phpcs:ignore Inpsyde.CodeQuality.LineLength.TooLong
|
||||
$url = trailingslashit($this->host) . 'v2/payments/authorizations/' . $authorizationId . '/capture';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
'Prefer' => 'return=representation',
|
||||
],
|
||||
];
|
||||
|
||||
$response = $this->request($url, $args);
|
||||
$json = json_decode($response['body']);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Could not capture authorized payment.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 201) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$authorization = $this->authorizationFactory->fromPayPalRequest($json);
|
||||
return $authorization;
|
||||
}
|
||||
}
|
26
modules.local/ppcp-api-client/src/Endpoint/RequestTrait.php
Normal file
26
modules.local/ppcp-api-client/src/Endpoint/RequestTrait.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
trait RequestTrait
|
||||
{
|
||||
|
||||
//phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
|
||||
private function request(string $url, array $args)
|
||||
{
|
||||
|
||||
/**
|
||||
* This filter can be used to alter the request args.
|
||||
* For example, during testing, the PayPal-Mock-Response header could be
|
||||
* added here.
|
||||
*/
|
||||
$args = apply_filters('ppcp-request-args', $args, $url);
|
||||
if (! isset($args['headers']['PayPal-Partner-Attribution-Id'])) {
|
||||
$args['headers']['PayPal-Partner-Attribution-Id'] = 'Woo_PPCP';
|
||||
}
|
||||
|
||||
return wp_remote_get($url, $args);
|
||||
}
|
||||
}
|
227
modules.local/ppcp-api-client/src/Endpoint/WebhookEndpoint.php
Normal file
227
modules.local/ppcp-api-client/src/Endpoint/WebhookEndpoint.php
Normal file
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Webhook;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\WebhookFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class WebhookEndpoint
|
||||
{
|
||||
use RequestTrait;
|
||||
|
||||
private $host;
|
||||
private $bearer;
|
||||
private $webhookFactory;
|
||||
private $logger;
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
WebhookFactory $webhookFactory,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->webhookFactory = $webhookFactory;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function create(Webhook $hook): Webhook
|
||||
{
|
||||
/**
|
||||
* An hook, which has an ID has already been created.
|
||||
*/
|
||||
if ($hook->id()) {
|
||||
return $hook;
|
||||
}
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v1/notifications/webhooks';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => json_encode($hook->toArray()),
|
||||
];
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Not able to create a webhook.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$json = json_decode($response['body']);
|
||||
$statusCode = (int) wp_remote_retrieve_response_code($response);
|
||||
if ($statusCode !== 201) {
|
||||
$error = new PayPalApiException(
|
||||
$json,
|
||||
$statusCode
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$hook = $this->webhookFactory->fromPayPalResponse($json);
|
||||
return $hook;
|
||||
}
|
||||
|
||||
public function delete(Webhook $hook): bool
|
||||
{
|
||||
if (! $hook->id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v1/notifications/webhooks/' . $hook->id();
|
||||
$args = [
|
||||
'method' => 'DELETE',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
],
|
||||
];
|
||||
$response = $this->request($url, $args);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Not able to delete the webhook.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
[
|
||||
'args' => $args,
|
||||
'response' => $response,
|
||||
]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
return wp_remote_retrieve_response_code($response) === 204;
|
||||
}
|
||||
|
||||
public function verifyEvent(
|
||||
string $authAlgo,
|
||||
string $certUrl,
|
||||
string $transmissionId,
|
||||
string $transmissionSig,
|
||||
string $transmissionTime,
|
||||
string $webhookId,
|
||||
\stdClass $webhookEvent
|
||||
): bool {
|
||||
|
||||
$bearer = $this->bearer->bearer();
|
||||
$url = trailingslashit($this->host) . 'v1/notifications/verify-webhook-signature';
|
||||
$args = [
|
||||
'method' => 'POST',
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => json_encode(
|
||||
[
|
||||
'transmission_id' => $transmissionId,
|
||||
'transmission_time' => $transmissionTime,
|
||||
'cert_url' => $certUrl,
|
||||
'auth_algo' => $authAlgo,
|
||||
'transmission_sig' => $transmissionSig,
|
||||
'webhook_id' => $webhookId,
|
||||
'webhook_event' => $webhookEvent,
|
||||
]
|
||||
),
|
||||
];
|
||||
$response = $this->request($url, $args);
|
||||
if (is_wp_error($response)) {
|
||||
$error = new RuntimeException(
|
||||
__('Not able to verify webhook event.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log(
|
||||
'warning',
|
||||
$error->getMessage(),
|
||||
['args' => $args, 'response' => $response]
|
||||
);
|
||||
throw $error;
|
||||
}
|
||||
$json = json_decode($response['body']);
|
||||
return isset($json->verification_status) && $json->verification_status === "SUCCESS";
|
||||
}
|
||||
|
||||
public function verifyCurrentRequestForWebhook(Webhook $webhook): bool
|
||||
{
|
||||
|
||||
if (! $webhook->id()) {
|
||||
$error = new RuntimeException(
|
||||
__('Not a valid webhook to verify.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
$this->logger->log('warning', $error->getMessage(), ['webhook' => $webhook]);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$expectedHeaders = [
|
||||
'PAYPAL-AUTH-ALGO' => '',
|
||||
'PAYPAL-CERT-URL' => '',
|
||||
'PAYPAL-TRANSMISSION-ID' => '',
|
||||
'PAYPAL-TRANSMISSION-SIG' => '',
|
||||
'PAYPAL-TRANSMISSION-TIME' => '',
|
||||
];
|
||||
$headers = getallheaders();
|
||||
foreach ($headers as $key => $header) {
|
||||
$key = strtoupper($key);
|
||||
if (isset($expectedHeaders[$key])) {
|
||||
$expectedHeaders[$key] = $header;
|
||||
}
|
||||
};
|
||||
|
||||
foreach ($expectedHeaders as $key => $value) {
|
||||
if (! empty($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$error = new RuntimeException(
|
||||
sprintf(
|
||||
// translators: %s is the headers key.
|
||||
__(
|
||||
'Not a valid webhook event. Header %s is missing',
|
||||
'woocommerce-paypal-commerce-gateway'
|
||||
),
|
||||
$key
|
||||
)
|
||||
);
|
||||
$this->logger->log('warning', $error->getMessage(), ['webhook' => $webhook]);
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$requestBody = json_decode(file_get_contents("php://input"));
|
||||
return $this->verifyEvent(
|
||||
$expectedHeaders['PAYPAL-AUTH-ALGO'],
|
||||
$expectedHeaders['PAYPAL-CERT-URL'],
|
||||
$expectedHeaders['PAYPAL-TRANSMISSION-ID'],
|
||||
$expectedHeaders['PAYPAL-TRANSMISSION-SIG'],
|
||||
$expectedHeaders['PAYPAL-TRANSMISSION-TIME'],
|
||||
$webhook->id(),
|
||||
$requestBody ? $requestBody : new \stdClass()
|
||||
);
|
||||
}
|
||||
}
|
73
modules.local/ppcp-api-client/src/Entity/Address.php
Normal file
73
modules.local/ppcp-api-client/src/Entity/Address.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Address
|
||||
{
|
||||
private $countryCode;
|
||||
private $addressLine1;
|
||||
private $addressLine2;
|
||||
private $adminArea1;
|
||||
private $adminArea2;
|
||||
private $postalCode;
|
||||
public function __construct(
|
||||
string $countryCode,
|
||||
string $addressLine1 = '',
|
||||
string $addressLine2 = '',
|
||||
string $adminArea1 = '',
|
||||
string $adminArea2 = '',
|
||||
string $postalCode = ''
|
||||
) {
|
||||
|
||||
$this->countryCode = $countryCode;
|
||||
$this->addressLine1 = $addressLine1;
|
||||
$this->addressLine2 = $addressLine2;
|
||||
$this->adminArea1 = $adminArea1;
|
||||
$this->adminArea2 = $adminArea2;
|
||||
$this->postalCode = $postalCode;
|
||||
}
|
||||
|
||||
public function countryCode(): string
|
||||
{
|
||||
return $this->countryCode;
|
||||
}
|
||||
|
||||
public function addressLine1(): string
|
||||
{
|
||||
return $this->addressLine1;
|
||||
}
|
||||
|
||||
public function addressLine2(): string
|
||||
{
|
||||
return $this->addressLine2;
|
||||
}
|
||||
|
||||
public function adminArea1(): string
|
||||
{
|
||||
return $this->adminArea1;
|
||||
}
|
||||
|
||||
public function adminArea2(): string
|
||||
{
|
||||
return $this->adminArea2;
|
||||
}
|
||||
|
||||
public function postalCode(): string
|
||||
{
|
||||
return $this->postalCode;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'country_code' => $this->countryCode(),
|
||||
'address_line_1' => $this->addressLine1(),
|
||||
'address_line_2' => $this->addressLine2(),
|
||||
'admin_area_1' => $this->adminArea1(),
|
||||
'admin_area_2' => $this->adminArea2(),
|
||||
'postal_code' => $this->postalCode(),
|
||||
];
|
||||
}
|
||||
}
|
45
modules.local/ppcp-api-client/src/Entity/Amount.php
Normal file
45
modules.local/ppcp-api-client/src/Entity/Amount.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Amount
|
||||
{
|
||||
|
||||
private $money;
|
||||
private $breakdown;
|
||||
|
||||
public function __construct(Money $money, AmountBreakdown $breakdown = null)
|
||||
{
|
||||
$this->money = $money;
|
||||
$this->breakdown = $breakdown;
|
||||
}
|
||||
|
||||
public function currencyCode(): string
|
||||
{
|
||||
return $this->money->currencyCode();
|
||||
}
|
||||
|
||||
public function value(): float
|
||||
{
|
||||
return $this->money->value();
|
||||
}
|
||||
|
||||
public function breakdown(): ?AmountBreakdown
|
||||
{
|
||||
return $this->breakdown;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$amount = [
|
||||
'currency_code' => $this->currencyCode(),
|
||||
'value' => $this->value(),
|
||||
];
|
||||
if ($this->breakdown() && count($this->breakdown()->toArray())) {
|
||||
$amount['breakdown'] = $this->breakdown()->toArray();
|
||||
}
|
||||
return $amount;
|
||||
}
|
||||
}
|
98
modules.local/ppcp-api-client/src/Entity/AmountBreakdown.php
Normal file
98
modules.local/ppcp-api-client/src/Entity/AmountBreakdown.php
Normal file
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class AmountBreakdown
|
||||
{
|
||||
|
||||
private $itemTotal;
|
||||
private $shipping;
|
||||
private $taxTotal;
|
||||
private $handling;
|
||||
private $insurance;
|
||||
private $shippingDiscount;
|
||||
private $discount;
|
||||
public function __construct(
|
||||
Money $itemTotal = null,
|
||||
Money $shipping = null,
|
||||
Money $taxTotal = null,
|
||||
Money $handling = null,
|
||||
Money $insurance = null,
|
||||
Money $shippingDiscount = null,
|
||||
Money $discount = null
|
||||
) {
|
||||
|
||||
$this->itemTotal = $itemTotal;
|
||||
$this->shipping = $shipping;
|
||||
$this->taxTotal = $taxTotal;
|
||||
$this->handling = $handling;
|
||||
$this->insurance = $insurance;
|
||||
$this->shippingDiscount = $shippingDiscount;
|
||||
$this->discount = $discount;
|
||||
}
|
||||
|
||||
public function itemTotal(): ?Money
|
||||
{
|
||||
return $this->itemTotal;
|
||||
}
|
||||
|
||||
public function shipping(): ?Money
|
||||
{
|
||||
return $this->shipping;
|
||||
}
|
||||
|
||||
public function taxTotal(): ?Money
|
||||
{
|
||||
return $this->taxTotal;
|
||||
}
|
||||
|
||||
public function handling(): ?Money
|
||||
{
|
||||
return $this->handling;
|
||||
}
|
||||
|
||||
public function insurance(): ?Money
|
||||
{
|
||||
return $this->insurance;
|
||||
}
|
||||
|
||||
public function shippingDiscount(): ?Money
|
||||
{
|
||||
return $this->shippingDiscount;
|
||||
}
|
||||
|
||||
public function discount(): ?Money
|
||||
{
|
||||
return $this->discount;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$breakdown = [];
|
||||
if ($this->itemTotal) {
|
||||
$breakdown['item_total'] = $this->itemTotal->toArray();
|
||||
}
|
||||
if ($this->shipping) {
|
||||
$breakdown['shipping'] = $this->shipping->toArray();
|
||||
}
|
||||
if ($this->taxTotal) {
|
||||
$breakdown['tax_total'] = $this->taxTotal->toArray();
|
||||
}
|
||||
if ($this->handling) {
|
||||
$breakdown['handling'] = $this->handling->toArray();
|
||||
}
|
||||
if ($this->insurance) {
|
||||
$breakdown['insurance'] = $this->insurance->toArray();
|
||||
}
|
||||
if ($this->shippingDiscount) {
|
||||
$breakdown['shipping_discount'] = $this->shippingDiscount->toArray();
|
||||
}
|
||||
if ($this->discount) {
|
||||
$breakdown['discount'] = $this->discount->toArray();
|
||||
}
|
||||
|
||||
return $breakdown;
|
||||
}
|
||||
}
|
154
modules.local/ppcp-api-client/src/Entity/ApplicationContext.php
Normal file
154
modules.local/ppcp-api-client/src/Entity/ApplicationContext.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class ApplicationContext
|
||||
{
|
||||
public const LANDING_PAGE_LOGIN = 'LOGIN';
|
||||
public const LANDING_PAGE_BILLING = 'BILLING';
|
||||
public const LANDING_PAGE_NO_PREFERENCE = 'NO_PREFERENCE';
|
||||
private const VALID_LANDING_PAGE_VALUES = [
|
||||
self::LANDING_PAGE_LOGIN,
|
||||
self::LANDING_PAGE_BILLING,
|
||||
self::LANDING_PAGE_NO_PREFERENCE,
|
||||
];
|
||||
|
||||
public const SHIPPING_PREFERENCE_GET_FROM_FILE = 'GET_FROM_FILE';
|
||||
public const SHIPPING_PREFERENCE_NO_SHIPPING = 'NO_SHIPPING';
|
||||
public const SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS = 'SET_PROVIDED_ADDRESS';
|
||||
private const VALID_SHIPPING_PREFERENCE_VALUES = [
|
||||
self::SHIPPING_PREFERENCE_GET_FROM_FILE,
|
||||
self::SHIPPING_PREFERENCE_NO_SHIPPING,
|
||||
self::SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS,
|
||||
];
|
||||
|
||||
public const USER_ACTION_CONTINUE = 'CONTINUE';
|
||||
public const USER_ACTION_PAY_NOW = 'PAY_NOW';
|
||||
private const VALID_USER_ACTION_VALUES = [
|
||||
self::USER_ACTION_CONTINUE,
|
||||
self::USER_ACTION_PAY_NOW,
|
||||
];
|
||||
|
||||
private $brandName;
|
||||
private $locale;
|
||||
private $landingPage;
|
||||
private $shippingPreference;
|
||||
private $userAction;
|
||||
private $returnUrl;
|
||||
private $cancelUrl;
|
||||
private $paymentMethod;
|
||||
|
||||
public function __construct(
|
||||
string $returnUrl = '',
|
||||
string $cancelUrl = '',
|
||||
string $brandName = '',
|
||||
string $locale = '',
|
||||
string $landingPage = self::LANDING_PAGE_NO_PREFERENCE,
|
||||
string $shippingPreference = self::SHIPPING_PREFERENCE_NO_SHIPPING,
|
||||
string $userAction = self::USER_ACTION_CONTINUE
|
||||
) {
|
||||
|
||||
if (! in_array($landingPage, self::VALID_LANDING_PAGE_VALUES, true)) {
|
||||
throw new RuntimeException("Landingpage not correct");
|
||||
}
|
||||
if (! in_array($shippingPreference, self::VALID_SHIPPING_PREFERENCE_VALUES, true)) {
|
||||
throw new RuntimeException("Shipping preference not correct");
|
||||
}
|
||||
if (! in_array($userAction, self::VALID_USER_ACTION_VALUES, true)) {
|
||||
throw new RuntimeException("User action preference not correct");
|
||||
}
|
||||
$this->returnUrl = $returnUrl;
|
||||
$this->cancelUrl = $cancelUrl;
|
||||
$this->brandName = $brandName;
|
||||
$this->locale = $locale;
|
||||
$this->landingPage = $landingPage;
|
||||
$this->shippingPreference = $shippingPreference;
|
||||
$this->userAction = $userAction;
|
||||
|
||||
//Currently we have not implemented the payment method.
|
||||
$this->paymentMethod = null;
|
||||
}
|
||||
|
||||
public function brandName(): string
|
||||
{
|
||||
return $this->brandName;
|
||||
}
|
||||
|
||||
public function locale(): string
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
public function landingPage(): string
|
||||
{
|
||||
return $this->landingPage;
|
||||
}
|
||||
|
||||
public function shippingPreference(): string
|
||||
{
|
||||
return $this->shippingPreference;
|
||||
}
|
||||
|
||||
public function userAction(): string
|
||||
{
|
||||
return $this->userAction;
|
||||
}
|
||||
|
||||
public function returnUrl(): string
|
||||
{
|
||||
return $this->returnUrl;
|
||||
}
|
||||
|
||||
public function cancelUrl(): string
|
||||
{
|
||||
return $this->cancelUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently, we have not implemented this.
|
||||
*
|
||||
* If we would follow our schema, we would create a paymentMethod entity which could
|
||||
* get returned here.
|
||||
*/
|
||||
public function paymentMethod(): ?\stdClass
|
||||
{
|
||||
return $this->paymentMethod;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$data = [];
|
||||
if ($this->userAction()) {
|
||||
$data['user_action'] = $this->userAction();
|
||||
}
|
||||
if ($this->paymentMethod()) {
|
||||
$data['payment_method'] = $this->paymentMethod();
|
||||
}
|
||||
if ($this->shippingPreference()) {
|
||||
$data['shipping_preference'] = $this->shippingPreference();
|
||||
}
|
||||
if ($this->landingPage()) {
|
||||
$data['landing_page'] = $this->landingPage();
|
||||
}
|
||||
if ($this->locale()) {
|
||||
$data['locale'] = $this->locale();
|
||||
}
|
||||
if ($this->brandName()) {
|
||||
$data['brand_name'] = $this->brandName();
|
||||
}
|
||||
if ($this->returnUrl()) {
|
||||
$data['return_url'] = $this->returnUrl();
|
||||
}
|
||||
if ($this->cancelUrl()) {
|
||||
$data['cancel_url'] = $this->cancelUrl();
|
||||
}
|
||||
if ($this->paymentMethod()) {
|
||||
$data['payment_method'] = $this->paymentMethod();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
38
modules.local/ppcp-api-client/src/Entity/Authorization.php
Normal file
38
modules.local/ppcp-api-client/src/Entity/Authorization.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Authorization
|
||||
{
|
||||
private $id;
|
||||
private $authorizationStatus;
|
||||
|
||||
public function __construct(
|
||||
string $id,
|
||||
AuthorizationStatus $authorizationStatus
|
||||
) {
|
||||
|
||||
$this->id = $id;
|
||||
$this->authorizationStatus = $authorizationStatus;
|
||||
}
|
||||
|
||||
public function id(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function status(): AuthorizationStatus
|
||||
{
|
||||
return $this->authorizationStatus;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'status' => $this->authorizationStatus->name(),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class AuthorizationStatus
|
||||
{
|
||||
public const INTERNAL = 'INTERNAL';
|
||||
public const CREATED = 'CREATED';
|
||||
public const CAPTURED = 'CAPTURED';
|
||||
public const COMPLETED = 'COMPLETED';
|
||||
public const DENIED = 'DENIED';
|
||||
public const EXPIRED = 'EXPIRED';
|
||||
public const PARTIALLY_CAPTURED = 'PARTIALLY_CAPTURED';
|
||||
public const VOIDED = 'VOIDED';
|
||||
public const PENDING = 'PENDING';
|
||||
public const VALID_STATUS = [
|
||||
self::INTERNAL,
|
||||
self::CREATED,
|
||||
self::CAPTURED,
|
||||
self::COMPLETED,
|
||||
self::DENIED,
|
||||
self::EXPIRED,
|
||||
self::PARTIALLY_CAPTURED,
|
||||
self::VOIDED,
|
||||
self::PENDING,
|
||||
];
|
||||
private $status;
|
||||
|
||||
public function __construct(string $status)
|
||||
{
|
||||
if (!in_array($status, self::VALID_STATUS, true)) {
|
||||
throw new RuntimeException(
|
||||
sprintf(
|
||||
// translators: %s is the current status.
|
||||
__("%s is not a valid status", 'woocmmerce-paypal-commerce-gateway'),
|
||||
$status
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
public static function asInternal(): AuthorizationStatus
|
||||
{
|
||||
return new self(self::INTERNAL);
|
||||
}
|
||||
|
||||
public function is(string $status): bool
|
||||
{
|
||||
return $this->status === $status;
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class CardAuthenticationResult
|
||||
{
|
||||
|
||||
public const LIABILITY_SHIFT_POSSIBLE = 'POSSIBLE';
|
||||
public const LIABILITY_SHIFT_NO = 'NO';
|
||||
public const LIABILITY_SHIFT_UNKNOWN = 'UNKNOWN';
|
||||
|
||||
public const ENROLLMENT_STATUS_YES = 'Y';
|
||||
public const ENROLLMENT_STATUS_NO = 'N';
|
||||
public const ENROLLMENT_STATUS_UNAVAILABLE = 'U';
|
||||
public const ENROLLMENT_STATUS_BYPASS = 'B';
|
||||
|
||||
public const AUTHENTICATION_RESULT_YES = 'Y';
|
||||
public const AUTHENTICATION_RESULT_NO = 'N';
|
||||
public const AUTHENTICATION_RESULT_REJECTED = 'R';
|
||||
public const AUTHENTICATION_RESULT_ATTEMPTED = 'A';
|
||||
public const AUTHENTICATION_RESULT_UNABLE = 'U';
|
||||
public const AUTHENTICATION_RESULT_CHALLENGE_REQUIRED = 'C';
|
||||
public const AUTHENTICATION_RESULT_INFO = 'I';
|
||||
public const AUTHENTICATION_RESULT_DECOUPLED = 'D';
|
||||
|
||||
private $liabilityShift;
|
||||
private $enrollmentStatus;
|
||||
private $authenticationResult;
|
||||
|
||||
public function __construct(
|
||||
string $liabilityShift,
|
||||
string $enrollmentStatus,
|
||||
string $authenticationResult
|
||||
) {
|
||||
|
||||
$this->liabilityShift = strtoupper($liabilityShift);
|
||||
$this->enrollmentStatus = strtoupper($enrollmentStatus);
|
||||
$this->authenticationResult = strtoupper($authenticationResult);
|
||||
}
|
||||
|
||||
public function liabilityShift(): string
|
||||
{
|
||||
|
||||
return $this->liabilityShift;
|
||||
}
|
||||
|
||||
public function enrollmentStatus(): string
|
||||
{
|
||||
|
||||
return $this->enrollmentStatus;
|
||||
}
|
||||
|
||||
public function authenticationResult(): string
|
||||
{
|
||||
|
||||
return $this->authenticationResult;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$data = [];
|
||||
$data['liability_shift'] = $this->liabilityShift();
|
||||
$data['three_d_secure'] = [
|
||||
'enrollment_status' => $this->enrollmentStatus(),
|
||||
'authentication_result' => $this->authenticationResult(),
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
}
|
93
modules.local/ppcp-api-client/src/Entity/Item.php
Normal file
93
modules.local/ppcp-api-client/src/Entity/Item.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Item
|
||||
{
|
||||
|
||||
public const PHYSICAL_GOODS = 'PHYSICAL_GOODS';
|
||||
public const DIGITAL_GOODS = 'DIGITAL_GOODS';
|
||||
|
||||
private $name;
|
||||
private $unitAmount;
|
||||
private $quantity;
|
||||
private $description;
|
||||
private $tax;
|
||||
private $sku;
|
||||
private $category;
|
||||
|
||||
public function __construct(
|
||||
string $name,
|
||||
Money $unitAmount,
|
||||
int $quantity,
|
||||
string $description = '',
|
||||
Money $tax = null,
|
||||
string $sku = '',
|
||||
string $category = 'PHYSICAL_GOODS'
|
||||
) {
|
||||
|
||||
$this->name = $name;
|
||||
$this->unitAmount = $unitAmount;
|
||||
$this->quantity = $quantity;
|
||||
$this->description = $description;
|
||||
$this->tax = $tax;
|
||||
$this->sku = $sku;
|
||||
$this->category = ($category === self::DIGITAL_GOODS) ?
|
||||
self::DIGITAL_GOODS : self::PHYSICAL_GOODS;
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function unitAmount(): Money
|
||||
{
|
||||
return $this->unitAmount;
|
||||
}
|
||||
|
||||
public function quantity(): int
|
||||
{
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
public function description(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function tax(): ?Money
|
||||
{
|
||||
return $this->tax;
|
||||
}
|
||||
|
||||
public function sku(): string
|
||||
{
|
||||
return $this->sku;
|
||||
}
|
||||
|
||||
public function category(): string
|
||||
{
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$item = [
|
||||
'name' => $this->name(),
|
||||
'unit_amount' => $this->unitAmount()->toArray(),
|
||||
'quantity' => $this->quantity(),
|
||||
'description' => $this->description(),
|
||||
'sku' => $this->sku(),
|
||||
'category' => $this->category(),
|
||||
];
|
||||
|
||||
if ($this->tax()) {
|
||||
$item['tax'] = $this->tax()->toArray();
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
}
|
35
modules.local/ppcp-api-client/src/Entity/Money.php
Normal file
35
modules.local/ppcp-api-client/src/Entity/Money.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Money
|
||||
{
|
||||
|
||||
private $currencyCode;
|
||||
private $value;
|
||||
public function __construct(float $value, string $currencyCode)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->currencyCode = $currencyCode;
|
||||
}
|
||||
|
||||
public function value(): float
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function currencyCode(): string
|
||||
{
|
||||
return $this->currencyCode;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'currency_code' => $this->currencyCode(),
|
||||
'value' => number_format($this->value(), 2),
|
||||
];
|
||||
}
|
||||
}
|
137
modules.local/ppcp-api-client/src/Entity/Order.php
Normal file
137
modules.local/ppcp-api-client/src/Entity/Order.php
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Order
|
||||
{
|
||||
|
||||
private $id;
|
||||
private $createTime;
|
||||
private $purchaseUnits;
|
||||
private $payer;
|
||||
private $orderStatus;
|
||||
private $intent;
|
||||
private $updateTime;
|
||||
private $applicationContext;
|
||||
private $paymentSource;
|
||||
|
||||
/**
|
||||
* Order constructor.
|
||||
*
|
||||
* @see https://developer.paypal.com/docs/api/orders/v2/#orders-create-response
|
||||
*/
|
||||
public function __construct(
|
||||
string $id,
|
||||
array $purchaseUnits,
|
||||
OrderStatus $orderStatus,
|
||||
ApplicationContext $applicationContext = null,
|
||||
PaymentSource $paymentSource = null,
|
||||
Payer $payer = null,
|
||||
string $intent = 'CAPTURE',
|
||||
\DateTime $createTime = null,
|
||||
\DateTime $updateTime = null
|
||||
) {
|
||||
|
||||
$this->id = $id;
|
||||
$this->applicationContext = $applicationContext;
|
||||
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
||||
$this->purchaseUnits = array_values(array_filter(
|
||||
$purchaseUnits,
|
||||
static function ($unit): bool {
|
||||
return is_a($unit, PurchaseUnit::class);
|
||||
}
|
||||
));
|
||||
//phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
||||
$this->payer = $payer;
|
||||
$this->orderStatus = $orderStatus;
|
||||
$this->intent = ($intent === 'CAPTURE') ? 'CAPTURE' : 'AUTHORIZE';
|
||||
$this->purchaseUnits = $purchaseUnits;
|
||||
$this->createTime = $createTime;
|
||||
$this->updateTime = $updateTime;
|
||||
$this->paymentSource = $paymentSource;
|
||||
}
|
||||
|
||||
public function id(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function createTime(): ?\DateTime
|
||||
{
|
||||
return $this->createTime;
|
||||
}
|
||||
|
||||
public function updateTime(): ?\DateTime
|
||||
{
|
||||
return $this->updateTime;
|
||||
}
|
||||
|
||||
public function intent(): string
|
||||
{
|
||||
return $this->intent;
|
||||
}
|
||||
|
||||
public function payer(): ?Payer
|
||||
{
|
||||
return $this->payer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PurchaseUnit[]
|
||||
*/
|
||||
public function purchaseUnits(): array
|
||||
{
|
||||
return $this->purchaseUnits;
|
||||
}
|
||||
|
||||
public function status(): OrderStatus
|
||||
{
|
||||
return $this->orderStatus;
|
||||
}
|
||||
|
||||
public function applicationContext(): ?ApplicationContext
|
||||
{
|
||||
|
||||
return $this->applicationContext;
|
||||
}
|
||||
|
||||
public function paymentSource(): ?PaymentSource
|
||||
{
|
||||
|
||||
return $this->paymentSource;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$order = [
|
||||
'id' => $this->id(),
|
||||
'intent' => $this->intent(),
|
||||
'status' => $this->status()->name(),
|
||||
'purchase_units' => array_map(
|
||||
static function (PurchaseUnit $unit): array {
|
||||
return $unit->toArray();
|
||||
},
|
||||
$this->purchaseUnits()
|
||||
),
|
||||
];
|
||||
if ($this->createTime()) {
|
||||
$order['create_time'] = $this->createTime()->format(\DateTimeInterface::ISO8601);
|
||||
}
|
||||
if ($this->payer()) {
|
||||
$order['payer'] = $this->payer()->toArray();
|
||||
}
|
||||
if ($this->updateTime()) {
|
||||
$order['update_time'] = $this->updateTime()->format(\DateTimeInterface::ISO8601);
|
||||
}
|
||||
if ($this->applicationContext()) {
|
||||
$order['application_context'] = $this->applicationContext()->toArray();
|
||||
}
|
||||
if ($this->paymentSource()) {
|
||||
$order['payment_source'] = $this->paymentSource()->toArray();
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
}
|
54
modules.local/ppcp-api-client/src/Entity/OrderStatus.php
Normal file
54
modules.local/ppcp-api-client/src/Entity/OrderStatus.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class OrderStatus
|
||||
{
|
||||
|
||||
public const INTERNAL = 'INTERNAL';
|
||||
public const CREATED = 'CREATED';
|
||||
public const SAVED = 'SAVED';
|
||||
public const APPROVED = 'APPROVED';
|
||||
public const VOIDED = 'VOIDED';
|
||||
public const COMPLETED = 'COMPLETED';
|
||||
public const VALID_STATI = [
|
||||
self::INTERNAL,
|
||||
self::CREATED,
|
||||
self::SAVED,
|
||||
self::APPROVED,
|
||||
self::VOIDED,
|
||||
self::COMPLETED,
|
||||
];
|
||||
private $status;
|
||||
|
||||
public function __construct(string $status)
|
||||
{
|
||||
if (! in_array($status, self::VALID_STATI, true)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
// translators: %s is the current status.
|
||||
__("%s is not a valid status", "woocmmerce-paypal-commerce-gateway"),
|
||||
$status
|
||||
));
|
||||
}
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
public static function asInternal(): OrderStatus
|
||||
{
|
||||
return new self(self::INTERNAL);
|
||||
}
|
||||
|
||||
public function is(string $status): bool
|
||||
{
|
||||
return $this->status === $status;
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
}
|
57
modules.local/ppcp-api-client/src/Entity/Patch.php
Normal file
57
modules.local/ppcp-api-client/src/Entity/Patch.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
//phpcs:disable Inpsyde.CodeQuality.ElementNameMinimalLength.TooShort
|
||||
class Patch
|
||||
{
|
||||
|
||||
private $op;
|
||||
private $path;
|
||||
private $value;
|
||||
public function __construct(string $op, string $path, array $value)
|
||||
{
|
||||
$this->op = $op;
|
||||
$this->path = $path;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function op(): string
|
||||
{
|
||||
return $this->op;
|
||||
}
|
||||
|
||||
public function path(): string
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
// phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
|
||||
public function value()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
// phpcs:enable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'op' => $this->op(),
|
||||
'value' => $this->value(),
|
||||
'path' => $this->path(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed for the move operation. We currently do not
|
||||
* support the move operation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function from(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
33
modules.local/ppcp-api-client/src/Entity/PatchCollection.php
Normal file
33
modules.local/ppcp-api-client/src/Entity/PatchCollection.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class PatchCollection
|
||||
{
|
||||
|
||||
private $patches;
|
||||
public function __construct(Patch ...$patches)
|
||||
{
|
||||
$this->patches = $patches;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Patch[]
|
||||
*/
|
||||
public function patches(): array
|
||||
{
|
||||
return $this->patches;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return array_map(
|
||||
static function (Patch $patch): array {
|
||||
return $patch->toArray();
|
||||
},
|
||||
$this->patches()
|
||||
);
|
||||
}
|
||||
}
|
48
modules.local/ppcp-api-client/src/Entity/Payee.php
Normal file
48
modules.local/ppcp-api-client/src/Entity/Payee.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class Payee
|
||||
* The entity, which receives the money.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
class Payee
|
||||
{
|
||||
|
||||
private $email;
|
||||
private $merchantId;
|
||||
|
||||
public function __construct(
|
||||
string $email,
|
||||
string $merchantId
|
||||
) {
|
||||
|
||||
$this->email = $email;
|
||||
$this->merchantId = $merchantId;
|
||||
}
|
||||
|
||||
public function email(): string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function merchantId(): string
|
||||
{
|
||||
return $this->merchantId;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$data = [
|
||||
'email_address' => $this->email(),
|
||||
];
|
||||
if ($this->merchantId) {
|
||||
$data['merchant_id'] = $this->merchantId();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
100
modules.local/ppcp-api-client/src/Entity/Payer.php
Normal file
100
modules.local/ppcp-api-client/src/Entity/Payer.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
/**
|
||||
* Class Payer
|
||||
* The customer who sends the money.
|
||||
*
|
||||
* @package Inpsyde\PayPalCommerce\ApiClient\Entity
|
||||
*/
|
||||
class Payer
|
||||
{
|
||||
|
||||
private $name;
|
||||
private $emailAddress;
|
||||
private $payerId;
|
||||
private $birthDate;
|
||||
private $address;
|
||||
private $phone;
|
||||
private $taxInfo;
|
||||
|
||||
public function __construct(
|
||||
PayerName $name,
|
||||
string $emailAddress,
|
||||
string $payerId,
|
||||
Address $address,
|
||||
\DateTime $birthDate = null,
|
||||
PhoneWithType $phone = null,
|
||||
PayerTaxInfo $taxInfo = null
|
||||
) {
|
||||
|
||||
$this->name = $name;
|
||||
$this->emailAddress = $emailAddress;
|
||||
$this->payerId = $payerId;
|
||||
$this->birthDate = $birthDate;
|
||||
$this->address = $address;
|
||||
$this->phone = $phone;
|
||||
$this->taxInfo = $taxInfo;
|
||||
}
|
||||
|
||||
public function name(): PayerName
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function emailAddress(): string
|
||||
{
|
||||
return $this->emailAddress;
|
||||
}
|
||||
|
||||
public function payerId(): string
|
||||
{
|
||||
return $this->payerId;
|
||||
}
|
||||
|
||||
public function birthDate(): ?\DateTime
|
||||
{
|
||||
return $this->birthDate;
|
||||
}
|
||||
|
||||
public function address(): Address
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function phone(): ?PhoneWithType
|
||||
{
|
||||
return $this->phone;
|
||||
}
|
||||
|
||||
public function taxInfo(): ?PayerTaxInfo
|
||||
{
|
||||
return $this->taxInfo;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$payer = [
|
||||
'name' => $this->name()->toArray(),
|
||||
'email_address' => $this->emailAddress(),
|
||||
'address' => $this->address()->toArray(),
|
||||
];
|
||||
if ($this->payerId()) {
|
||||
$payer['payer_id'] = $this->payerId();
|
||||
}
|
||||
|
||||
if ($this->phone()) {
|
||||
$payer['phone'] = $this->phone()->toArray();
|
||||
}
|
||||
if ($this->taxInfo()) {
|
||||
$payer['tax_info'] = $this->taxInfo()->toArray();
|
||||
}
|
||||
if ($this->birthDate()) {
|
||||
$payer['birth_date'] = $this->birthDate()->format('Y-m-d');
|
||||
}
|
||||
return $payer;
|
||||
}
|
||||
}
|
39
modules.local/ppcp-api-client/src/Entity/PayerName.php
Normal file
39
modules.local/ppcp-api-client/src/Entity/PayerName.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class PayerName
|
||||
{
|
||||
|
||||
private $givenName;
|
||||
private $surname;
|
||||
|
||||
public function __construct(
|
||||
string $givenName,
|
||||
string $surname
|
||||
) {
|
||||
|
||||
$this->givenName = $givenName;
|
||||
$this->surname = $surname;
|
||||
}
|
||||
|
||||
public function givenName(): string
|
||||
{
|
||||
return $this->givenName;
|
||||
}
|
||||
|
||||
public function surname(): string
|
||||
{
|
||||
return $this->surname;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'given_name' => $this->givenName(),
|
||||
'surname' => $this->surname(),
|
||||
];
|
||||
}
|
||||
}
|
51
modules.local/ppcp-api-client/src/Entity/PayerTaxInfo.php
Normal file
51
modules.local/ppcp-api-client/src/Entity/PayerTaxInfo.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class PayerTaxInfo
|
||||
{
|
||||
|
||||
public const VALID_TYPES = [
|
||||
'BR_CPF',
|
||||
'BR_CNPJ',
|
||||
];
|
||||
private $taxId;
|
||||
private $type;
|
||||
public function __construct(
|
||||
string $taxId,
|
||||
string $type
|
||||
) {
|
||||
|
||||
if (! in_array($type, self::VALID_TYPES, true)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
// translators: %s is the current type.
|
||||
__("%s is not a valid tax type.", "woocommerce-paypal-commerce-gateway"),
|
||||
$type
|
||||
));
|
||||
}
|
||||
$this->taxId = $taxId;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function taxId(): string
|
||||
{
|
||||
return $this->taxId;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'tax_id' => $this->taxId(),
|
||||
'tax_id_type' => $this->type(),
|
||||
];
|
||||
}
|
||||
}
|
43
modules.local/ppcp-api-client/src/Entity/PaymentMethod.php
Normal file
43
modules.local/ppcp-api-client/src/Entity/PaymentMethod.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class PaymentMethod
|
||||
{
|
||||
|
||||
public const PAYER_SELECTED_DEFAULT = 'PAYPAL';
|
||||
|
||||
public const PAYEE_PREFERRED_UNRESTRICTED = 'UNRESTRICTED';
|
||||
public const PAYEE_PREFERRED_IMMEDIATE_PAYMENT_REQUIRED = 'IMMEDIATE_PAYMENT_REQUIRED';
|
||||
|
||||
private $preferred;
|
||||
private $selected;
|
||||
public function __construct(
|
||||
string $preferred = self::PAYEE_PREFERRED_UNRESTRICTED,
|
||||
string $selected = self::PAYER_SELECTED_DEFAULT
|
||||
) {
|
||||
|
||||
$this->preferred = $preferred;
|
||||
$this->selected = $selected;
|
||||
}
|
||||
|
||||
public function payeePreferred(): string
|
||||
{
|
||||
return $this->preferred;
|
||||
}
|
||||
|
||||
public function payerSelected(): string
|
||||
{
|
||||
return $this->selected;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'payee_preferred' => $this->payeePreferred(),
|
||||
'payer_selected' => $this->payerSelected(),
|
||||
];
|
||||
}
|
||||
}
|
45
modules.local/ppcp-api-client/src/Entity/PaymentSource.php
Normal file
45
modules.local/ppcp-api-client/src/Entity/PaymentSource.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class PaymentSource
|
||||
{
|
||||
|
||||
private $card;
|
||||
private $wallet;
|
||||
public function __construct(
|
||||
PaymentSourceCard $card = null,
|
||||
PaymentSourceWallet $wallet = null
|
||||
) {
|
||||
|
||||
$this->card = $card;
|
||||
$this->wallet = $wallet;
|
||||
}
|
||||
|
||||
public function card(): ?PaymentSourceCard
|
||||
{
|
||||
|
||||
return $this->card;
|
||||
}
|
||||
|
||||
public function wallet(): ?PaymentSourceWallet
|
||||
{
|
||||
|
||||
return $this->wallet;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
|
||||
$data = [];
|
||||
if ($this->card()) {
|
||||
$data['card'] = $this->card()->toArray();
|
||||
}
|
||||
if ($this->wallet()) {
|
||||
$data['wallet'] = $this->wallet()->toArray();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class PaymentSourceCard
|
||||
{
|
||||
|
||||
private $lastDigits;
|
||||
private $brand;
|
||||
private $type;
|
||||
private $authenticationResult;
|
||||
public function __construct(
|
||||
string $lastDigits,
|
||||
string $brand,
|
||||
string $type,
|
||||
CardAuthenticationResult $authenticationResult = null
|
||||
) {
|
||||
|
||||
$this->lastDigits = $lastDigits;
|
||||
$this->brand = $brand;
|
||||
$this->type = $type;
|
||||
$this->authenticationResult = $authenticationResult;
|
||||
}
|
||||
|
||||
public function lastDigits(): string
|
||||
{
|
||||
|
||||
return $this->lastDigits;
|
||||
}
|
||||
|
||||
public function brand(): string
|
||||
{
|
||||
|
||||
return $this->brand;
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function authenticationResult(): ?CardAuthenticationResult
|
||||
{
|
||||
|
||||
return $this->authenticationResult;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
|
||||
$data = [
|
||||
'last_digits' => $this->lastDigits(),
|
||||
'brand' => $this->brand(),
|
||||
'type' => $this->type(),
|
||||
];
|
||||
if ($this->authenticationResult()) {
|
||||
$data['authentication_result'] = $this->authenticationResult()->toArray();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class PaymentSourceWallet
|
||||
{
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
47
modules.local/ppcp-api-client/src/Entity/PaymentToken.php
Normal file
47
modules.local/ppcp-api-client/src/Entity/PaymentToken.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class PaymentToken
|
||||
{
|
||||
|
||||
public const TYPE_PAYMENT_METHOD_TOKEN = 'PAYMENT_METHOD_TOKEN';
|
||||
public const VALID_TYPES = [
|
||||
self::TYPE_PAYMENT_METHOD_TOKEN,
|
||||
];
|
||||
|
||||
private $id;
|
||||
private $type;
|
||||
public function __construct(string $id, string $type = self::TYPE_PAYMENT_METHOD_TOKEN)
|
||||
{
|
||||
if (! in_array($type, self::VALID_TYPES, true)) {
|
||||
throw new RuntimeException(
|
||||
__("Not a valid payment source type.", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function id(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id(),
|
||||
'type' => $this->type(),
|
||||
];
|
||||
}
|
||||
}
|
35
modules.local/ppcp-api-client/src/Entity/Payments.php
Normal file
35
modules.local/ppcp-api-client/src/Entity/Payments.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Payments
|
||||
{
|
||||
private $authorizations;
|
||||
|
||||
public function __construct(Authorization ...$authorizations)
|
||||
{
|
||||
$this->authorizations = $authorizations;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'authorizations' => array_map(
|
||||
static function (Authorization $authorization): array {
|
||||
return $authorization->toArray();
|
||||
},
|
||||
$this->authorizations()
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Authorization[]
|
||||
**/
|
||||
public function authorizations(): array
|
||||
{
|
||||
return $this->authorizations;
|
||||
}
|
||||
}
|
27
modules.local/ppcp-api-client/src/Entity/Phone.php
Normal file
27
modules.local/ppcp-api-client/src/Entity/Phone.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Phone
|
||||
{
|
||||
|
||||
private $nationalNumber;
|
||||
public function __construct(string $nationalNumber)
|
||||
{
|
||||
$this->nationalNumber = $nationalNumber;
|
||||
}
|
||||
|
||||
public function nationalNumber(): string
|
||||
{
|
||||
return $this->nationalNumber;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'national_number' => $this->nationalNumber(),
|
||||
];
|
||||
}
|
||||
}
|
42
modules.local/ppcp-api-client/src/Entity/PhoneWithType.php
Normal file
42
modules.local/ppcp-api-client/src/Entity/PhoneWithType.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class PhoneWithType
|
||||
{
|
||||
public const VALLID_TYPES = [
|
||||
'FAX',
|
||||
'HOME',
|
||||
'MOBILE',
|
||||
'OTHER',
|
||||
'PAGER',
|
||||
];
|
||||
|
||||
private $type;
|
||||
private $phone;
|
||||
public function __construct(string $type, Phone $phone)
|
||||
{
|
||||
$this->type = in_array($type, self::VALLID_TYPES, true) ? $type : 'OTHER';
|
||||
$this->phone = $phone;
|
||||
}
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function phone(): Phone
|
||||
{
|
||||
return $this->phone;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'phone_type' => $this->type(),
|
||||
'phone_number' => $this->phone()->toArray(),
|
||||
];
|
||||
}
|
||||
}
|
231
modules.local/ppcp-api-client/src/Entity/PurchaseUnit.php
Normal file
231
modules.local/ppcp-api-client/src/Entity/PurchaseUnit.php
Normal file
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
//phpcs:disable Inpsyde.CodeQuality.PropertyPerClassLimit.TooManyProperties
|
||||
class PurchaseUnit
|
||||
{
|
||||
|
||||
private $amount;
|
||||
private $items;
|
||||
private $shipping;
|
||||
private $referenceId;
|
||||
private $description;
|
||||
private $payee;
|
||||
private $customId;
|
||||
private $invoiceId;
|
||||
private $softDescriptor;
|
||||
private $payments;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $containsPhysicalGoodsItems = false;
|
||||
|
||||
public function __construct(
|
||||
Amount $amount,
|
||||
array $items = [],
|
||||
Shipping $shipping = null,
|
||||
string $referenceId = 'default',
|
||||
string $description = '',
|
||||
Payee $payee = null,
|
||||
string $customId = '',
|
||||
string $invoiceId = '',
|
||||
string $softDescriptor = '',
|
||||
Payments $payments = null
|
||||
) {
|
||||
|
||||
$this->amount = $amount;
|
||||
$this->shipping = $shipping;
|
||||
$this->referenceId = $referenceId;
|
||||
$this->description = $description;
|
||||
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
||||
$this->items = array_values(array_filter(
|
||||
$items,
|
||||
function ($item): bool {
|
||||
$isItem = is_a($item, Item::class);
|
||||
/**
|
||||
* @var Item $item
|
||||
*/
|
||||
if ($isItem && Item::PHYSICAL_GOODS === $item->category()) {
|
||||
$this->containsPhysicalGoodsItems = true;
|
||||
}
|
||||
|
||||
return $isItem;
|
||||
}
|
||||
));
|
||||
//phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
|
||||
$this->payee = $payee;
|
||||
$this->customId = $customId;
|
||||
$this->invoiceId = $invoiceId;
|
||||
$this->softDescriptor = $softDescriptor;
|
||||
$this->payments = $payments;
|
||||
}
|
||||
|
||||
public function amount(): Amount
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
public function shipping(): ?Shipping
|
||||
{
|
||||
return $this->shipping;
|
||||
}
|
||||
|
||||
public function referenceId(): string
|
||||
{
|
||||
return $this->referenceId;
|
||||
}
|
||||
|
||||
public function description(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function customId(): string
|
||||
{
|
||||
return $this->customId;
|
||||
}
|
||||
|
||||
public function invoiceId(): string
|
||||
{
|
||||
return $this->invoiceId;
|
||||
}
|
||||
|
||||
public function softDescriptor(): string
|
||||
{
|
||||
return $this->softDescriptor;
|
||||
}
|
||||
|
||||
public function payee(): ?Payee
|
||||
{
|
||||
return $this->payee;
|
||||
}
|
||||
|
||||
public function payments(): ?Payments
|
||||
{
|
||||
return $this->payments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Item[]
|
||||
*/
|
||||
public function items(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
public function containsPhysicalGoodsItems(): bool
|
||||
{
|
||||
return $this->containsPhysicalGoodsItems;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$purchaseUnit = [
|
||||
'reference_id' => $this->referenceId(),
|
||||
'amount' => $this->amount()->toArray(),
|
||||
'description' => $this->description(),
|
||||
'items' => array_map(
|
||||
static function (Item $item): array {
|
||||
return $item->toArray();
|
||||
},
|
||||
$this->items()
|
||||
),
|
||||
];
|
||||
if ($this->ditchItemsWhenMismatch($this->amount(), ...$this->items())) {
|
||||
unset($purchaseUnit['items']);
|
||||
unset($purchaseUnit['amount']['breakdown']);
|
||||
}
|
||||
|
||||
if ($this->payee()) {
|
||||
$purchaseUnit['payee'] = $this->payee()->toArray();
|
||||
}
|
||||
|
||||
if ($this->payments()) {
|
||||
$purchaseUnit['payments'] = $this->payments()->toArray();
|
||||
}
|
||||
|
||||
if ($this->shipping()) {
|
||||
$purchaseUnit['shipping'] = $this->shipping()->toArray();
|
||||
}
|
||||
if ($this->customId()) {
|
||||
$purchaseUnit['custom_id'] = $this->customId();
|
||||
}
|
||||
if ($this->invoiceId()) {
|
||||
$purchaseUnit['invoice_id'] = $this->invoiceId();
|
||||
}
|
||||
if ($this->softDescriptor()) {
|
||||
$purchaseUnit['soft_descriptor'] = $this->softDescriptor();
|
||||
}
|
||||
return $purchaseUnit;
|
||||
}
|
||||
|
||||
/**
|
||||
* All money values send to PayPal can only have 2 decimal points. Woocommerce internally does
|
||||
* not have this restriction. Therefore the totals of the cart in Woocommerce and the totals
|
||||
* of the rounded money values of the items, we send to PayPal, can differ. In those cases,
|
||||
* we can not send the line items.
|
||||
*
|
||||
* @param Amount $amount
|
||||
* @param Item ...$items
|
||||
* @return bool
|
||||
*/
|
||||
//phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
private function ditchItemsWhenMismatch(Amount $amount, Item ...$items): bool
|
||||
{
|
||||
$feeItemsTotal = ($amount->breakdown() && $amount->breakdown()->itemTotal()) ?
|
||||
$amount->breakdown()->itemTotal()->value() : null;
|
||||
$feeTaxTotal = ($amount->breakdown() && $amount->breakdown()->taxTotal()) ?
|
||||
$amount->breakdown()->taxTotal()->value() : null;
|
||||
|
||||
foreach ($items as $item) {
|
||||
if (null !== $feeItemsTotal) {
|
||||
$feeItemsTotal -= $item->unitAmount()->value() * $item->quantity();
|
||||
}
|
||||
if (null !== $feeTaxTotal) {
|
||||
$feeTaxTotal -= $item->tax()->value() * $item->quantity();
|
||||
}
|
||||
}
|
||||
|
||||
$feeItemsTotal = round($feeItemsTotal, 2);
|
||||
$feeTaxTotal = round($feeTaxTotal, 2);
|
||||
|
||||
if ($feeItemsTotal !== 0.0 || $feeTaxTotal !== 0.0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$breakdown = $this->amount()->breakdown();
|
||||
if (! $breakdown) {
|
||||
return false;
|
||||
}
|
||||
$amountTotal = 0;
|
||||
if ($breakdown->shipping()) {
|
||||
$amountTotal += $breakdown->shipping()->value();
|
||||
}
|
||||
if ($breakdown->itemTotal()) {
|
||||
$amountTotal += $breakdown->itemTotal()->value();
|
||||
}
|
||||
if ($breakdown->discount()) {
|
||||
$amountTotal -= $breakdown->discount()->value();
|
||||
}
|
||||
if ($breakdown->taxTotal()) {
|
||||
$amountTotal += $breakdown->taxTotal()->value();
|
||||
}
|
||||
if ($breakdown->shippingDiscount()) {
|
||||
$amountTotal -= $breakdown->shippingDiscount()->value();
|
||||
}
|
||||
if ($breakdown->handling()) {
|
||||
$amountTotal += $breakdown->handling()->value();
|
||||
}
|
||||
if ($breakdown->insurance()) {
|
||||
$amountTotal += $breakdown->insurance()->value();
|
||||
}
|
||||
|
||||
$amountValue = $this->amount()->value();
|
||||
$needsToDitch = (string) $amountTotal !== (string) $amountValue;
|
||||
return $needsToDitch;
|
||||
}
|
||||
}
|
37
modules.local/ppcp-api-client/src/Entity/Shipping.php
Normal file
37
modules.local/ppcp-api-client/src/Entity/Shipping.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Shipping
|
||||
{
|
||||
|
||||
private $name;
|
||||
private $address;
|
||||
public function __construct(string $name, Address $address)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->address = $address;
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function address(): Address
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'full_name' => $this->name(),
|
||||
],
|
||||
'address' => $this->address()->toArray(),
|
||||
];
|
||||
}
|
||||
}
|
72
modules.local/ppcp-api-client/src/Entity/Token.php
Normal file
72
modules.local/ppcp-api-client/src/Entity/Token.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class Token
|
||||
{
|
||||
|
||||
private $json;
|
||||
private $created;
|
||||
|
||||
public function __construct(\stdClass $json)
|
||||
{
|
||||
if (! isset($json->created)) {
|
||||
$json->created = time();
|
||||
}
|
||||
if (! $this->validate($json)) {
|
||||
throw new RuntimeException("Token not valid");
|
||||
}
|
||||
$this->json = $json;
|
||||
}
|
||||
|
||||
public function expirationTimestamp(): int
|
||||
{
|
||||
|
||||
return $this->json->created + $this->json->expires_in;
|
||||
}
|
||||
|
||||
public function token(): string
|
||||
{
|
||||
return (string) $this->json->token;
|
||||
}
|
||||
|
||||
public function isValid(): bool
|
||||
{
|
||||
return time() < $this->json->created + $this->json->expires_in;
|
||||
}
|
||||
|
||||
public function asJson(): string
|
||||
{
|
||||
return json_encode($this->json);
|
||||
}
|
||||
|
||||
public static function fromJson(string $json): self
|
||||
{
|
||||
$json = (object) json_decode($json);
|
||||
if (isset($json->access_token) || isset($json->client_token)) {
|
||||
$json->token = isset($json->access_token) ? $json->access_token : $json->client_token;
|
||||
}
|
||||
|
||||
return new Token($json);
|
||||
}
|
||||
|
||||
private function validate(\stdClass $json): bool
|
||||
{
|
||||
$propertyMap = [
|
||||
'created' => 'is_int',
|
||||
'expires_in' => 'is_int',
|
||||
'token' => 'is_string',
|
||||
];
|
||||
|
||||
foreach ($propertyMap as $property => $validator) {
|
||||
if (! isset($json->{$property}) || ! $validator($json->{$property})) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
50
modules.local/ppcp-api-client/src/Entity/Webhook.php
Normal file
50
modules.local/ppcp-api-client/src/Entity/Webhook.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
class Webhook
|
||||
{
|
||||
|
||||
private $id;
|
||||
private $url;
|
||||
private $eventTypes;
|
||||
public function __construct(string $url, array $eventTypes, string $id = '')
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->eventTypes = $eventTypes;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function id(): string
|
||||
{
|
||||
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function url(): string
|
||||
{
|
||||
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function eventTypes(): array
|
||||
{
|
||||
|
||||
return $this->eventTypes;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
|
||||
$data = [
|
||||
'url' => $this->url(),
|
||||
'event_types' => $this->eventTypes(),
|
||||
];
|
||||
if ($this->id()) {
|
||||
$data['id'] = $this->id();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Exception;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Exception;
|
||||
|
||||
class NotFoundException extends Exception implements NotFoundExceptionInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Exception;
|
||||
|
||||
class PayPalApiException extends RuntimeException
|
||||
{
|
||||
|
||||
private $response;
|
||||
private $statusCode;
|
||||
public function __construct(\stdClass $response = null, int $statusCode = 0)
|
||||
{
|
||||
if (is_null($response)) {
|
||||
$response = new \stdClass();
|
||||
}
|
||||
if (! isset($response->message)) {
|
||||
$response->message = __(
|
||||
'Unknown error while connecting to PayPal.',
|
||||
'woocommerce-paypal-commerce-gateway'
|
||||
);
|
||||
}
|
||||
if (! isset($response->name)) {
|
||||
$response->name = __('Error', 'woocommerce-paypal-commerce-gateway');
|
||||
}
|
||||
if (! isset($response->details)) {
|
||||
$response->details = [];
|
||||
}
|
||||
if (! isset($response->links) || ! is_array($response->links)) {
|
||||
$response->links = [];
|
||||
}
|
||||
|
||||
$this->response = $response;
|
||||
$this->statusCode = $statusCode;
|
||||
$message = $response->message;
|
||||
if ($response->name) {
|
||||
$message = '[' . $response->name . '] ' . $message;
|
||||
}
|
||||
foreach ($response->links as $link) {
|
||||
if (isset($link->rel) && $link->rel === 'information_link') {
|
||||
$message .= ' ' . $link->href;
|
||||
}
|
||||
}
|
||||
parent::__construct($message, $statusCode);
|
||||
}
|
||||
|
||||
public function name(): string
|
||||
{
|
||||
return $this->response->name;
|
||||
}
|
||||
|
||||
public function details(): array
|
||||
{
|
||||
return $this->response->details;
|
||||
}
|
||||
|
||||
public function hasDetail(string $issue): bool
|
||||
{
|
||||
foreach ($this->details() as $detail) {
|
||||
if (isset($detail->issue) && $detail->issue === $issue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Exception;
|
||||
|
||||
class RuntimeException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
63
modules.local/ppcp-api-client/src/Factory/AddressFactory.php
Normal file
63
modules.local/ppcp-api-client/src/Factory/AddressFactory.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Address;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class AddressFactory
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function fromWcCustomer(\WC_Customer $customer, string $type = 'shipping'): Address
|
||||
{
|
||||
return new Address(
|
||||
($type === 'shipping') ?
|
||||
$customer->get_shipping_country() : $customer->get_billing_country(),
|
||||
($type === 'shipping') ?
|
||||
$customer->get_shipping_address_1() : $customer->get_billing_address_1(),
|
||||
($type === 'shipping') ?
|
||||
$customer->get_shipping_address_2() : $customer->get_billing_address_2(),
|
||||
($type === 'shipping') ?
|
||||
$customer->get_shipping_state() : $customer->get_billing_state(),
|
||||
($type === 'shipping') ?
|
||||
$customer->get_shipping_city() : $customer->get_billing_city(),
|
||||
($type === 'shipping') ?
|
||||
$customer->get_shipping_postcode() : $customer->get_billing_postcode(),
|
||||
);
|
||||
}
|
||||
|
||||
public function fromWcOrder(\WC_Order $order): Address
|
||||
{
|
||||
return new Address(
|
||||
$order->get_shipping_country(),
|
||||
$order->get_shipping_address_1(),
|
||||
$order->get_shipping_address_2(),
|
||||
$order->get_shipping_state(),
|
||||
$order->get_shipping_city(),
|
||||
$order->get_shipping_postcode()
|
||||
);
|
||||
}
|
||||
|
||||
public function fromPayPalRequest(\stdClass $data): Address
|
||||
{
|
||||
if (! isset($data->country_code)) {
|
||||
throw new RuntimeException(
|
||||
__('No country given for address.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
}
|
||||
return new Address(
|
||||
$data->country_code,
|
||||
(isset($data->address_line_1)) ? $data->address_line_1 : '',
|
||||
(isset($data->address_line_2)) ? $data->address_line_2 : '',
|
||||
(isset($data->admin_area_1)) ? $data->admin_area_1 : '',
|
||||
(isset($data->admin_area_2)) ? $data->admin_area_2 : '',
|
||||
(isset($data->postal_code)) ? $data->postal_code : ''
|
||||
);
|
||||
}
|
||||
}
|
169
modules.local/ppcp-api-client/src/Factory/AmountFactory.php
Normal file
169
modules.local/ppcp-api-client/src/Factory/AmountFactory.php
Normal file
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Amount;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\AmountBreakdown;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class AmountFactory
|
||||
{
|
||||
|
||||
private $itemFactory;
|
||||
public function __construct(ItemFactory $itemFactory)
|
||||
{
|
||||
$this->itemFactory = $itemFactory;
|
||||
}
|
||||
|
||||
public function fromWcCart(\WC_Cart $cart): Amount
|
||||
{
|
||||
$currency = get_woocommerce_currency();
|
||||
$total = new Money((float) $cart->get_total('numeric'), $currency);
|
||||
$itemsTotal = $cart->get_cart_contents_total() + $cart->get_discount_total();
|
||||
$itemsTotal = new Money((float) $itemsTotal, $currency);
|
||||
$shipping = new Money(
|
||||
(float) $cart->get_shipping_total() + $cart->get_shipping_tax(),
|
||||
$currency
|
||||
);
|
||||
|
||||
$taxes = new Money(
|
||||
(float) $cart->get_cart_contents_tax() + (float) $cart->get_discount_tax(),
|
||||
$currency
|
||||
);
|
||||
|
||||
$discount = null;
|
||||
if ($cart->get_discount_total()) {
|
||||
$discount = new Money(
|
||||
(float) $cart->get_discount_total() + $cart->get_discount_tax(),
|
||||
$currency
|
||||
);
|
||||
}
|
||||
//ToDo: Evaluate if more is needed? Fees?
|
||||
$breakdown = new AmountBreakdown(
|
||||
$itemsTotal,
|
||||
$shipping,
|
||||
$taxes,
|
||||
null, // insurance?
|
||||
null, // handling?
|
||||
null, //shipping discounts?
|
||||
$discount
|
||||
);
|
||||
$amount = new Amount(
|
||||
$total,
|
||||
$breakdown
|
||||
);
|
||||
return $amount;
|
||||
}
|
||||
|
||||
public function fromWcOrder(\WC_Order $order): Amount
|
||||
{
|
||||
$currency = $order->get_currency();
|
||||
$items = $this->itemFactory->fromWcOrder($order);
|
||||
$total = new Money((float) $order->get_total(), $currency);
|
||||
$itemsTotal = new Money((float)array_reduce(
|
||||
$items,
|
||||
static function (float $total, Item $item): float {
|
||||
return $total + $item->quantity() * $item->unitAmount()->value();
|
||||
},
|
||||
0
|
||||
), $currency);
|
||||
$shipping = new Money(
|
||||
(float) $order->get_shipping_total() + (float) $order->get_shipping_tax(),
|
||||
$currency
|
||||
);
|
||||
$taxes = new Money((float)array_reduce(
|
||||
$items,
|
||||
static function (float $total, Item $item): float {
|
||||
return $total + $item->quantity() * $item->tax()->value();
|
||||
},
|
||||
0
|
||||
), $currency);
|
||||
|
||||
$discount = null;
|
||||
if ((float) $order->get_total_discount(false)) {
|
||||
$discount = new Money(
|
||||
(float) $order->get_total_discount(false),
|
||||
$currency
|
||||
);
|
||||
}
|
||||
|
||||
//ToDo: Evaluate if more is needed? Fees?
|
||||
$breakdown = new AmountBreakdown(
|
||||
$itemsTotal,
|
||||
$shipping,
|
||||
$taxes,
|
||||
null, // insurance?
|
||||
null, // handling?
|
||||
null, //shipping discounts?
|
||||
$discount
|
||||
);
|
||||
$amount = new Amount(
|
||||
$total,
|
||||
$breakdown
|
||||
);
|
||||
return $amount;
|
||||
}
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): Amount
|
||||
{
|
||||
if (! isset($data->value) || ! is_numeric($data->value)) {
|
||||
throw new RuntimeException(__("No value given", "woocommerce-paypal-commerce-gateway"));
|
||||
}
|
||||
if (! isset($data->currency_code)) {
|
||||
throw new RuntimeException(
|
||||
__("No currency given", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
|
||||
$money = new Money((float) $data->value, $data->currency_code);
|
||||
$breakdown = (isset($data->breakdown)) ? $this->breakdown($data->breakdown) : null;
|
||||
return new Amount($money, $breakdown);
|
||||
}
|
||||
|
||||
private function breakDown(\stdClass $data): AmountBreakdown
|
||||
{
|
||||
/**
|
||||
* The order of the keys equals the necessary order of the constructor arguments.
|
||||
*/
|
||||
$orderedConstructorKeys = [
|
||||
'item_total',
|
||||
'shipping',
|
||||
'tax_total',
|
||||
'handling',
|
||||
'insurance',
|
||||
'shipping_discount',
|
||||
'discount',
|
||||
];
|
||||
|
||||
$money = [];
|
||||
foreach ($orderedConstructorKeys as $key) {
|
||||
if (! isset($data->{$key})) {
|
||||
$money[] = null;
|
||||
continue;
|
||||
}
|
||||
$item = $data->{$key};
|
||||
|
||||
if (! isset($item->value) || ! is_numeric($item->value)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
// translators: %s is the current breakdown key.
|
||||
__("No value given for breakdown %s", "woocommerce-paypal-commerce-gateway"),
|
||||
$key
|
||||
));
|
||||
}
|
||||
if (! isset($item->currency_code)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
// translators: %s is the current breakdown key.
|
||||
__("No currency given for breakdown %s", "woocommerce-paypal-commerce-gateway"),
|
||||
$key
|
||||
));
|
||||
}
|
||||
$money[] = new Money((float) $item->value, $item->currency_code);
|
||||
}
|
||||
|
||||
return new AmountBreakdown(...$money);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
||||
|
||||
class ApplicationContextFactory
|
||||
{
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): ApplicationContext
|
||||
{
|
||||
return new ApplicationContext(
|
||||
isset($data->return_url) ?
|
||||
$data->return_url : '',
|
||||
isset($data->cancel_url) ?
|
||||
$data->cancel_url : '',
|
||||
isset($data->brand_name) ?
|
||||
$data->brand_name : '',
|
||||
isset($data->locale) ?
|
||||
$data->locale : '',
|
||||
isset($data->landing_page) ?
|
||||
$data->landing_page : ApplicationContext::LANDING_PAGE_NO_PREFERENCE,
|
||||
isset($data->shipping_preference) ?
|
||||
$data->shipping_preference : ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE,
|
||||
isset($data->user_action) ?
|
||||
$data->user_action : ApplicationContext::USER_ACTION_CONTINUE,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class AuthorizationFactory
|
||||
{
|
||||
public function fromPayPalRequest(\stdClass $data): Authorization
|
||||
{
|
||||
if (!isset($data->id)) {
|
||||
throw new RuntimeException(
|
||||
__('Does not contain an id.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset($data->status)) {
|
||||
throw new RuntimeException(
|
||||
__('Does not contain status.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
}
|
||||
|
||||
return new Authorization(
|
||||
$data->id,
|
||||
new AuthorizationStatus($data->status)
|
||||
);
|
||||
}
|
||||
}
|
124
modules.local/ppcp-api-client/src/Factory/ItemFactory.php
Normal file
124
modules.local/ppcp-api-client/src/Factory/ItemFactory.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class ItemFactory
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function fromWcCart(\WC_Cart $cart): array
|
||||
{
|
||||
$currency = get_woocommerce_currency();
|
||||
$items = array_map(
|
||||
static function (array $item) use ($currency): Item {
|
||||
$product = $item['data'];
|
||||
/**
|
||||
* @var \WC_Product $product
|
||||
*/
|
||||
$quantity = (int) $item['quantity'];
|
||||
|
||||
$price = (float) wc_get_price_including_tax($product);
|
||||
$priceWithoutTax = (float) wc_get_price_excluding_tax($product);
|
||||
$priceWithoutTaxRounded = round($priceWithoutTax, 2);
|
||||
$tax = round($price - $priceWithoutTaxRounded, 2);
|
||||
$tax = new Money($tax, $currency);
|
||||
return new Item(
|
||||
mb_substr($product->get_name(), 0, 127),
|
||||
new Money($priceWithoutTaxRounded, $currency),
|
||||
$quantity,
|
||||
mb_substr($product->get_description(), 0, 127),
|
||||
$tax,
|
||||
$product->get_sku(),
|
||||
($product->is_virtual()) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
|
||||
);
|
||||
},
|
||||
$cart->get_cart_contents()
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WC_Order $order
|
||||
* @return Item[]
|
||||
*/
|
||||
public function fromWcOrder(\WC_Order $order): array
|
||||
{
|
||||
return array_map(
|
||||
function (\WC_Order_Item_Product $item) use ($order): Item {
|
||||
return $this->fromWcOrderLineItem($item, $order);
|
||||
},
|
||||
$order->get_items('line_item')
|
||||
);
|
||||
}
|
||||
|
||||
private function fromWcOrderLineItem(\WC_Order_Item_Product $item, \WC_Order $order): Item
|
||||
{
|
||||
$currency = $order->get_currency();
|
||||
$product = $item->get_product();
|
||||
/**
|
||||
* @var \WC_Product $product
|
||||
*/
|
||||
$quantity = $item->get_quantity();
|
||||
|
||||
$price = (float) $order->get_item_subtotal($item, true);
|
||||
$priceWithoutTax = (float) $order->get_item_subtotal($item, false);
|
||||
$priceWithoutTaxRounded = round($priceWithoutTax, 2);
|
||||
$tax = round($price - $priceWithoutTaxRounded, 2);
|
||||
$tax = new Money($tax, $currency);
|
||||
return new Item(
|
||||
mb_substr($product->get_name(), 0, 127),
|
||||
new Money($priceWithoutTaxRounded, $currency),
|
||||
$quantity,
|
||||
mb_substr($product->get_description(), 0, 127),
|
||||
$tax,
|
||||
$product->get_sku(),
|
||||
($product->is_virtual()) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
|
||||
);
|
||||
}
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): Item
|
||||
{
|
||||
if (! isset($data->name)) {
|
||||
throw new RuntimeException(
|
||||
__("No name for item given", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
if (! isset($data->quantity) || ! is_numeric($data->quantity)) {
|
||||
throw new RuntimeException(
|
||||
__("No quantity for item given", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
if (! isset($data->unit_amount->value) || ! isset($data->unit_amount->currency_code)) {
|
||||
throw new RuntimeException(
|
||||
__("No money values for item given", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
|
||||
$unitAmount = new Money((float) $data->unit_amount->value, $data->unit_amount->currency_code);
|
||||
$description = (isset($data->description)) ? $data->description : '';
|
||||
$tax = (isset($data->tax)) ?
|
||||
new Money((float) $data->tax->value, $data->tax->currency_code)
|
||||
: null;
|
||||
$sku = (isset($data->sku)) ? $data->sku : '';
|
||||
$category = (isset($data->category)) ? $data->category : 'PHYSICAL_GOODS';
|
||||
|
||||
return new Item(
|
||||
$data->name,
|
||||
$unitAmount,
|
||||
(int) $data->quantity,
|
||||
$description,
|
||||
$tax,
|
||||
$sku,
|
||||
$category
|
||||
);
|
||||
}
|
||||
}
|
113
modules.local/ppcp-api-client/src/Factory/OrderFactory.php
Normal file
113
modules.local/ppcp-api-client/src/Factory/OrderFactory.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
|
||||
|
||||
class OrderFactory
|
||||
{
|
||||
|
||||
private $purchaseUnitFactory;
|
||||
private $payerFactory;
|
||||
private $applicationContextRepository;
|
||||
private $applicationContextFactory;
|
||||
private $paymentSourceFactory;
|
||||
public function __construct(
|
||||
PurchaseUnitFactory $purchaseUnitFactory,
|
||||
PayerFactory $payerFactory,
|
||||
ApplicationContextRepository $applicationContextRepository,
|
||||
ApplicationContextFactory $applicationContextFactory,
|
||||
PaymentSourceFactory $paymentSourceFactory
|
||||
) {
|
||||
|
||||
$this->purchaseUnitFactory = $purchaseUnitFactory;
|
||||
$this->payerFactory = $payerFactory;
|
||||
$this->applicationContextRepository = $applicationContextRepository;
|
||||
$this->applicationContextFactory = $applicationContextFactory;
|
||||
$this->paymentSourceFactory = $paymentSourceFactory;
|
||||
}
|
||||
|
||||
public function fromWcOrder(\WC_Order $wcOrder, Order $order): Order
|
||||
{
|
||||
$purchaseUnits = [$this->purchaseUnitFactory->fromWcOrder($wcOrder)];
|
||||
|
||||
return new Order(
|
||||
$order->id(),
|
||||
$purchaseUnits,
|
||||
$order->status(),
|
||||
$order->applicationContext(),
|
||||
$order->paymentSource(),
|
||||
$order->payer(),
|
||||
$order->intent(),
|
||||
$order->createTime(),
|
||||
$order->updateTime()
|
||||
);
|
||||
}
|
||||
|
||||
// phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
|
||||
public function fromPayPalResponse(\stdClass $orderData): Order
|
||||
{
|
||||
if (! isset($orderData->id)) {
|
||||
throw new RuntimeException(
|
||||
__('Order does not contain an id.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
}
|
||||
if (! isset($orderData->purchase_units) || !is_array($orderData->purchase_units)) {
|
||||
throw new RuntimeException(
|
||||
__('Order does not contain items.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
}
|
||||
if (! isset($orderData->status)) {
|
||||
throw new RuntimeException(
|
||||
__('Order does not contain status.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
}
|
||||
if (! isset($orderData->intent)) {
|
||||
throw new RuntimeException(
|
||||
__('Order does not contain intent.', 'woocommerce-paypal-commerce-gateway')
|
||||
);
|
||||
}
|
||||
|
||||
$purchaseUnits = array_map(
|
||||
function (\stdClass $data): PurchaseUnit {
|
||||
return $this->purchaseUnitFactory->fromPayPalResponse($data);
|
||||
},
|
||||
$orderData->purchase_units
|
||||
);
|
||||
|
||||
$createTime = (isset($orderData->create_time)) ?
|
||||
\DateTime::createFromFormat(\DateTime::ISO8601, $orderData->create_time)
|
||||
: null;
|
||||
$updateTime = (isset($orderData->update_time)) ?
|
||||
\DateTime::createFromFormat(\DateTime::ISO8601, $orderData->update_time)
|
||||
: null;
|
||||
$payer = (isset($orderData->payer)) ?
|
||||
$this->payerFactory->fromPayPalResponse($orderData->payer)
|
||||
: null;
|
||||
$applicationContext = (isset($orderData->application_context)) ?
|
||||
$this->applicationContextFactory->fromPayPalResponse($orderData->application_context)
|
||||
: null;
|
||||
$paymentSource = (isset($orderData->payment_source)) ?
|
||||
$this->paymentSourceFactory->fromPayPalResponse($orderData->payment_source) :
|
||||
null;
|
||||
|
||||
return new Order(
|
||||
$orderData->id,
|
||||
$purchaseUnits,
|
||||
new OrderStatus($orderData->status),
|
||||
$applicationContext,
|
||||
$paymentSource,
|
||||
$payer,
|
||||
$orderData->intent,
|
||||
$createTime,
|
||||
$updateTime
|
||||
);
|
||||
}
|
||||
// phpcs:enable Inpsyde.CodeQuality.FunctionLength.TooLong
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Patch;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PatchCollection;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
|
||||
class PatchCollectionFactory
|
||||
{
|
||||
|
||||
public function fromOrders(Order $from, Order $to): PatchCollection
|
||||
{
|
||||
$allPatches = [];
|
||||
$allPatches += $this->purchaseUnits($from->purchaseUnits(), $to->purchaseUnits());
|
||||
|
||||
return new PatchCollection(...$allPatches);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PurchaseUnit[] $from
|
||||
* @param PurchaseUnit[] $to
|
||||
* @return Patch[]
|
||||
*/
|
||||
private function purchaseUnits(array $from, array $to): array
|
||||
{
|
||||
$patches = [];
|
||||
|
||||
$path = '/purchase_units';
|
||||
foreach ($to as $purchaseUnitTo) {
|
||||
$needsUpdate = ! count(
|
||||
array_filter(
|
||||
$from,
|
||||
static function (PurchaseUnit $unit) use ($purchaseUnitTo): bool {
|
||||
//phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
|
||||
// Loose comparison needed to compare two objects.
|
||||
return $unit == $purchaseUnitTo;
|
||||
//phpcs:enable WordPress.PHP.StrictComparisons.LooseComparison
|
||||
}
|
||||
)
|
||||
);
|
||||
$needsUpdate = true;
|
||||
if (!$needsUpdate) {
|
||||
continue;
|
||||
}
|
||||
$purchaseUnitFrom = current(array_filter(
|
||||
$from,
|
||||
static function (PurchaseUnit $unit) use ($purchaseUnitTo): bool {
|
||||
return $purchaseUnitTo->referenceId() === $unit->referenceId();
|
||||
}
|
||||
));
|
||||
$operation = $purchaseUnitFrom ? 'replace' : 'add';
|
||||
$value = $purchaseUnitTo->toArray();
|
||||
$patches[] = new Patch(
|
||||
$operation,
|
||||
$path . "/@reference_id=='" . $purchaseUnitTo->referenceId() . "'",
|
||||
$value
|
||||
);
|
||||
}
|
||||
|
||||
return $patches;
|
||||
}
|
||||
}
|
24
modules.local/ppcp-api-client/src/Factory/PayeeFactory.php
Normal file
24
modules.local/ppcp-api-client/src/Factory/PayeeFactory.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payee;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class PayeeFactory
|
||||
{
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): ?Payee
|
||||
{
|
||||
if (! isset($data->email_address)) {
|
||||
throw new RuntimeException(
|
||||
__("No email for payee given.", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
|
||||
$merchantId = (isset($data->merchant_id)) ? $data->merchant_id : '';
|
||||
return new Payee($data->email_address, $merchantId);
|
||||
}
|
||||
}
|
82
modules.local/ppcp-api-client/src/Factory/PayerFactory.php
Normal file
82
modules.local/ppcp-api-client/src/Factory/PayerFactory.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PayerName;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PayerTaxInfo;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Phone;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PhoneWithType;
|
||||
|
||||
class PayerFactory
|
||||
{
|
||||
|
||||
private $addressFactory;
|
||||
public function __construct(AddressFactory $addressFactory)
|
||||
{
|
||||
$this->addressFactory = $addressFactory;
|
||||
}
|
||||
|
||||
public function fromCustomer(\WC_Customer $customer): Payer
|
||||
{
|
||||
$payerId = '';
|
||||
$birthdate = null;
|
||||
|
||||
$phone = null;
|
||||
if ($customer->get_billing_phone()) {
|
||||
// make sure the phone number contains only numbers and is max 14. chars long.
|
||||
$nationalNumber = $customer->get_billing_phone();
|
||||
$nationalNumber = preg_replace("/[^0-9]/", "", $nationalNumber);
|
||||
$nationalNumber = substr($nationalNumber, 0, 14);
|
||||
|
||||
$phone = new PhoneWithType(
|
||||
'HOME',
|
||||
new Phone($nationalNumber)
|
||||
);
|
||||
}
|
||||
return new Payer(
|
||||
new PayerName(
|
||||
$customer->get_billing_first_name(),
|
||||
$customer->get_billing_last_name()
|
||||
),
|
||||
$customer->get_billing_email(),
|
||||
$payerId,
|
||||
$this->addressFactory->fromWcCustomer($customer, 'billing'),
|
||||
$birthdate,
|
||||
$phone
|
||||
);
|
||||
}
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): Payer
|
||||
{
|
||||
$address = $this->addressFactory->fromPayPalRequest($data->address);
|
||||
$payerName = new PayerName(
|
||||
isset($data->name->given_name) ? (string) $data->name->given_name : '',
|
||||
isset($data->name->surname) ? (string) $data->name->surname : ''
|
||||
);
|
||||
// TODO deal with phones without type instead of passing a invalid type
|
||||
$phone = (isset($data->phone)) ? new PhoneWithType(
|
||||
(isset($data->phone->phone_type)) ? $data->phone->phone_type : 'undefined',
|
||||
new Phone(
|
||||
$data->phone->phone_number->national_number
|
||||
)
|
||||
) : null;
|
||||
$taxInfo = (isset($data->tax_info)) ?
|
||||
new PayerTaxInfo($data->tax_info->tax_id, $data->tax_info->tax_id_type)
|
||||
: null;
|
||||
$birthDate = (isset($data->birth_date)) ?
|
||||
\DateTime::createFromFormat('Y-m-d', $data->birth_date)
|
||||
: null;
|
||||
return new Payer(
|
||||
$payerName,
|
||||
isset($data->email_address) ? $data->email_address : '',
|
||||
(isset($data->payer_id)) ? $data->payer_id : '',
|
||||
$address,
|
||||
$birthDate,
|
||||
$phone,
|
||||
$taxInfo
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\CardAuthenticationResult;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentSourceCard;
|
||||
|
||||
class PaymentSourceFactory
|
||||
{
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): PaymentSource
|
||||
{
|
||||
|
||||
$card = null;
|
||||
$wallet = null;
|
||||
if (isset($data->card)) {
|
||||
$authenticationResult = null;
|
||||
if (isset($data->card->authentication_result)) {
|
||||
$authenticationResult = new CardAuthenticationResult(
|
||||
isset($data->card->authentication_result->liability_shift) ?
|
||||
(string) $data->card->authentication_result->liability_shift : '',
|
||||
isset($data->card->authentication_result->three_d_secure->enrollment_status) ?
|
||||
(string) $data->card->authentication_result->three_d_secure->enrollment_status : '',
|
||||
isset($data->card->authentication_result->three_d_secure->authentication_result) ?
|
||||
(string) $data->card->authentication_result->three_d_secure->authentication_result : ''
|
||||
);
|
||||
}
|
||||
$card = new PaymentSourceCard(
|
||||
isset($data->card->last_digits) ? (string) $data->card->last_digits : '',
|
||||
isset($data->card->brand) ? (string) $data->card->brand : '',
|
||||
isset($data->card->type) ? (string) $data->card->type : '',
|
||||
$authenticationResult
|
||||
);
|
||||
}
|
||||
return new PaymentSource($card, $wallet);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class PaymentTokenFactory
|
||||
{
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): PaymentToken
|
||||
{
|
||||
if (! isset($data->id)) {
|
||||
throw new RuntimeException(
|
||||
__("No id for payment token given", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
return new PaymentToken(
|
||||
$data->id,
|
||||
(isset($data->type)) ? $data->type : PaymentToken::TYPE_PAYMENT_METHOD_TOKEN
|
||||
);
|
||||
}
|
||||
|
||||
public function fromArray(array $data): PaymentToken
|
||||
{
|
||||
return $this->fromPayPalResponse((object) $data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payments;
|
||||
|
||||
class PaymentsFactory
|
||||
{
|
||||
private $authorizationsFactory;
|
||||
|
||||
public function __construct(
|
||||
AuthorizationFactory $authorizationsFactory
|
||||
) {
|
||||
|
||||
$this->authorizationsFactory = $authorizationsFactory;
|
||||
}
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): Payments
|
||||
{
|
||||
$authorizations = array_map(
|
||||
function (\stdClass $authorization): Authorization {
|
||||
return $this->authorizationsFactory->fromPayPalRequest($authorization);
|
||||
},
|
||||
isset($data->authorizations) ? $data->authorizations : []
|
||||
);
|
||||
$payments = new Payments(...$authorizations);
|
||||
return $payments;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
||||
|
||||
class PurchaseUnitFactory
|
||||
{
|
||||
|
||||
private $amountFactory;
|
||||
private $payeeRepository;
|
||||
private $payeeFactory;
|
||||
private $itemFactory;
|
||||
private $shippingFactory;
|
||||
private $paymentsFactory;
|
||||
private $prefix;
|
||||
|
||||
public function __construct(
|
||||
AmountFactory $amountFactory,
|
||||
PayeeRepository $payeeRepository,
|
||||
PayeeFactory $payeeFactory,
|
||||
ItemFactory $itemFactory,
|
||||
ShippingFactory $shippingFactory,
|
||||
PaymentsFactory $paymentsFactory,
|
||||
string $prefix = 'WC-'
|
||||
) {
|
||||
|
||||
$this->amountFactory = $amountFactory;
|
||||
$this->payeeRepository = $payeeRepository;
|
||||
$this->payeeFactory = $payeeFactory;
|
||||
$this->itemFactory = $itemFactory;
|
||||
$this->shippingFactory = $shippingFactory;
|
||||
$this->paymentsFactory = $paymentsFactory;
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
public function fromWcOrder(\WC_Order $order): PurchaseUnit
|
||||
{
|
||||
$amount = $this->amountFactory->fromWcOrder($order);
|
||||
$items = $this->itemFactory->fromWcOrder($order);
|
||||
$shipping = $this->shippingFactory->fromWcOrder($order);
|
||||
if (
|
||||
empty($shipping->address()->countryCode()) ||
|
||||
($shipping->address()->countryCode() && !$shipping->address()->postalCode())
|
||||
) {
|
||||
$shipping = null;
|
||||
}
|
||||
$referenceId = 'default';
|
||||
$description = '';
|
||||
$payee = $this->payeeRepository->payee();
|
||||
$wcOrderId = $order->get_id();
|
||||
$customId = $this->prefix . $wcOrderId;
|
||||
$invoiceId = $this->prefix . $wcOrderId;
|
||||
$softDescriptor = '';
|
||||
$purchaseUnit = new PurchaseUnit(
|
||||
$amount,
|
||||
$items,
|
||||
$shipping,
|
||||
$referenceId,
|
||||
$description,
|
||||
$payee,
|
||||
$customId,
|
||||
$invoiceId,
|
||||
$softDescriptor
|
||||
);
|
||||
return $purchaseUnit;
|
||||
}
|
||||
|
||||
public function fromWcCart(\WC_Cart $cart): PurchaseUnit
|
||||
{
|
||||
$amount = $this->amountFactory->fromWcCart($cart);
|
||||
$items = $this->itemFactory->fromWcCart($cart);
|
||||
|
||||
$shipping = null;
|
||||
$customer = \WC()->customer;
|
||||
if (is_a($customer, \WC_Customer::class)) {
|
||||
$shipping = $this->shippingFactory->fromWcCustomer(\WC()->customer);
|
||||
if (
|
||||
! $shipping->address()->countryCode()
|
||||
|| ($shipping->address()->countryCode() && !$shipping->address()->postalCode())
|
||||
) {
|
||||
$shipping = null;
|
||||
}
|
||||
}
|
||||
|
||||
$referenceId = 'default';
|
||||
$description = '';
|
||||
|
||||
$payee = $this->payeeRepository->payee();
|
||||
|
||||
$customId = '';
|
||||
$invoiceId = '';
|
||||
$softDescriptor = '';
|
||||
$purchaseUnit = new PurchaseUnit(
|
||||
$amount,
|
||||
$items,
|
||||
$shipping,
|
||||
$referenceId,
|
||||
$description,
|
||||
$payee,
|
||||
$customId,
|
||||
$invoiceId,
|
||||
$softDescriptor
|
||||
);
|
||||
|
||||
return $purchaseUnit;
|
||||
}
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): PurchaseUnit
|
||||
{
|
||||
if (! isset($data->reference_id) || ! is_string($data->reference_id)) {
|
||||
throw new RuntimeException(
|
||||
__("No reference ID given.", "woocommercepaypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
|
||||
$amount = $this->amountFactory->fromPayPalResponse($data->amount);
|
||||
$description = (isset($data->description)) ? $data->description : '';
|
||||
$customId = (isset($data->custom_id)) ? $data->custom_id : '';
|
||||
$invoiceId = (isset($data->invoice_id)) ? $data->invoice_id : '';
|
||||
$softDescriptor = (isset($data->soft_descriptor)) ? $data->soft_descriptor : '';
|
||||
$items = [];
|
||||
if (isset($data->items) && is_array($data->items)) {
|
||||
$items = array_map(
|
||||
function (\stdClass $item): Item {
|
||||
return $this->itemFactory->fromPayPalResponse($item);
|
||||
},
|
||||
$data->items
|
||||
);
|
||||
}
|
||||
$payee = isset($data->payee) ? $this->payeeFactory->fromPayPalResponse($data->payee) : null;
|
||||
$shipping = null;
|
||||
try {
|
||||
if (isset($data->shipping)) {
|
||||
$shipping = $this->shippingFactory->fromPayPalResponse($data->shipping);
|
||||
}
|
||||
} catch (RuntimeException $error) {
|
||||
}
|
||||
$payments = null;
|
||||
try {
|
||||
if (isset($data->payments)) {
|
||||
$payments = $this->paymentsFactory->fromPayPalResponse($data->payments);
|
||||
}
|
||||
} catch (RuntimeException $error) {
|
||||
}
|
||||
|
||||
$purchaseUnit = new PurchaseUnit(
|
||||
$amount,
|
||||
$items,
|
||||
$shipping,
|
||||
$data->reference_id,
|
||||
$description,
|
||||
$payee,
|
||||
$customId,
|
||||
$invoiceId,
|
||||
$softDescriptor,
|
||||
$payments
|
||||
);
|
||||
return $purchaseUnit;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Shipping;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class ShippingFactory
|
||||
{
|
||||
|
||||
private $addressFactory;
|
||||
public function __construct(AddressFactory $addressFactory)
|
||||
{
|
||||
$this->addressFactory = $addressFactory;
|
||||
}
|
||||
|
||||
public function fromWcCustomer(\WC_Customer $customer): Shipping
|
||||
{
|
||||
// Replicates the Behavior of \WC_Order::get_formatted_shipping_full_name()
|
||||
$fullName = sprintf(
|
||||
// translators: %1$s is the first name and %2$s is the second name. wc translation.
|
||||
_x('%1$s %2$s', 'full name', 'woocommerce'),
|
||||
$customer->get_shipping_first_name(),
|
||||
$customer->get_shipping_last_name()
|
||||
);
|
||||
$address = $this->addressFactory->fromWcCustomer($customer);
|
||||
return new Shipping(
|
||||
$fullName,
|
||||
$address
|
||||
);
|
||||
}
|
||||
|
||||
public function fromWcOrder(\WC_Order $order): Shipping
|
||||
{
|
||||
$fullName = $order->get_formatted_shipping_full_name();
|
||||
$address = $this->addressFactory->fromWcOrder($order);
|
||||
return new Shipping(
|
||||
$fullName,
|
||||
$address
|
||||
);
|
||||
}
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): Shipping
|
||||
{
|
||||
if (! isset($data->name->full_name)) {
|
||||
throw new RuntimeException(
|
||||
__("No name was given for shipping.", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
if (! isset($data->address)) {
|
||||
throw new RuntimeException(
|
||||
__("No address was given for shipping.", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
$address = $this->addressFactory->fromPayPalRequest($data->address);
|
||||
return new Shipping(
|
||||
$data->name->full_name,
|
||||
$address
|
||||
);
|
||||
}
|
||||
}
|
56
modules.local/ppcp-api-client/src/Factory/WebhookFactory.php
Normal file
56
modules.local/ppcp-api-client/src/Factory/WebhookFactory.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Webhook;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
class WebhookFactory
|
||||
{
|
||||
|
||||
public function forUrlAndEvents(string $url, array $eventTypes): Webhook
|
||||
{
|
||||
$eventTypes = array_map(
|
||||
static function (string $type): array {
|
||||
return ["name" => $type];
|
||||
},
|
||||
$eventTypes
|
||||
);
|
||||
return new Webhook(
|
||||
$url,
|
||||
$eventTypes
|
||||
);
|
||||
}
|
||||
|
||||
public function fromArray(array $data): Webhook
|
||||
{
|
||||
return $this->fromPayPalResponse((object) $data);
|
||||
}
|
||||
|
||||
public function fromPayPalResponse(\stdClass $data): Webhook
|
||||
{
|
||||
if (! isset($data->id)) {
|
||||
throw new RuntimeException(
|
||||
__("No id for webhook given.", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
if (! isset($data->url)) {
|
||||
throw new RuntimeException(
|
||||
__("No URL for webhook given.", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
if (! isset($data->event_types)) {
|
||||
throw new RuntimeException(
|
||||
__("No event types for webhook given.", "woocommerce-paypal-commerce-gateway")
|
||||
);
|
||||
}
|
||||
|
||||
return new Webhook(
|
||||
(string) $data->url,
|
||||
(array) $data->event_types,
|
||||
(string) $data->id
|
||||
);
|
||||
}
|
||||
}
|
136
modules.local/ppcp-api-client/src/Helper/DccApplies.php
Normal file
136
modules.local/ppcp-api-client/src/Helper/DccApplies.php
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Helper;
|
||||
|
||||
class DccApplies
|
||||
{
|
||||
|
||||
private $allowedCountryCurrencyMatrix = [
|
||||
'AU' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'BE' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'BG' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'CY' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'CZ' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'DK' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'EE' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'FI' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'FR' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'GR' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'HU' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'IT' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'LV' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'LI' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'LT' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'LU' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'MT' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'NL' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'NO' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'PL' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'PT' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'RO' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'SK' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'SI' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'ES' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'SE' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
'US' => [
|
||||
'AUD', 'CAD', 'EUR', 'GBP', 'JPY', 'USD',
|
||||
],
|
||||
'GB' => [
|
||||
'AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD',
|
||||
'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD',
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
public function forCountryCurrency(): bool
|
||||
{
|
||||
$region = wc_get_base_location();
|
||||
$country = $region['country'];
|
||||
$currency = get_woocommerce_currency();
|
||||
if (!in_array($country, array_keys($this->allowedCountryCurrencyMatrix), true)) {
|
||||
return false;
|
||||
}
|
||||
$applies = in_array($currency, $this->allowedCountryCurrencyMatrix[$country], true);
|
||||
return $applies;
|
||||
}
|
||||
}
|
114
modules.local/ppcp-api-client/src/Helper/ErrorResponse.php
Normal file
114
modules.local/ppcp-api-client/src/Helper/ErrorResponse.php
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Helper;
|
||||
|
||||
class ErrorResponse
|
||||
{
|
||||
public const UNKNOWN = 'UNKNOWN';
|
||||
|
||||
// phpcs:disable Inpsyde.CodeQuality.LineLength.TooLong
|
||||
/* Order error codes */
|
||||
public const ACTION_DOES_NOT_MATCH_INTENT = 'ACTION_DOES_NOT_MATCH_INTENT';
|
||||
public const AGREEMENT_ALREADY_CANCELLED = 'AGREEMENT_ALREADY_CANCELLED';
|
||||
public const AMOUNT_CANNOT_BE_SPECIFIED = 'AMOUNT_CANNOT_BE_SPECIFIED';
|
||||
public const AMOUNT_MISMATCH = 'AMOUNT_MISMATCH';
|
||||
public const AMOUNT_NOT_PATCHABLE = 'AMOUNT_NOT_PATCHABLE';
|
||||
public const AUTH_CAPTURE_NOT_ENABLED = 'AUTH_CAPTURE_NOT_ENABLED';
|
||||
public const AUTHENTICATION_FAILURE = 'AUTHENTICATION_FAILURE';
|
||||
public const AUTHORIZATION_AMOUNT_EXCEEDED = 'AUTHORIZATION_AMOUNT_EXCEEDED';
|
||||
public const AUTHORIZATION_CURRENCY_MISMATCH = 'AUTHORIZATION_CURRENCY_MISMATCH';
|
||||
public const BILLING_AGREEMENT_NOT_FOUND = 'BILLING_AGREEMENT_NOT_FOUND';
|
||||
public const CANNOT_BE_NEGATIVE = 'CANNOT_BE_NEGATIVE';
|
||||
public const CANNOT_BE_ZERO_OR_NEGATIVE = 'CANNOT_BE_ZERO_OR_NEGATIVE';
|
||||
public const CARD_TYPE_NOT_SUPPORTED = 'CARD_TYPE_NOT_SUPPORTED';
|
||||
public const INVALID_SECURITY_CODE_LENGTH = 'INVALID_SECURITY_CODE_LENGTH';
|
||||
public const CITY_REQUIRED = 'CITY_REQUIRED';
|
||||
public const COMPLIANCE_VIOLATION = 'COMPLIANCE_VIOLATION';
|
||||
public const CONSENT_NEEDED = 'CONSENT_NEEDED';
|
||||
public const CURRENCY_NOT_SUPPORTED_FOR_CARD_TYPE = 'CURRENCY_NOT_SUPPORTED_FOR_CARD_TYPE';
|
||||
public const CURRENCY_NOT_SUPPORTED_FOR_COUNTRY = 'CURRENCY_NOT_SUPPORTED_FOR_COUNTRY';
|
||||
public const DECIMAL_PRECISION = 'DECIMAL_PRECISION';
|
||||
public const DOMESTIC_TRANSACTION_REQUIRED = 'DOMESTIC_TRANSACTION_REQUIRED';
|
||||
public const DUPLICATE_INVOICE_ID = 'DUPLICATE_INVOICE_ID';
|
||||
public const DUPLICATE_REQUEST_ID = 'DUPLICATE_REQUEST_ID';
|
||||
public const FIELD_NOT_PATCHABLE = 'FIELD_NOT_PATCHABLE';
|
||||
public const INSTRUMENT_DECLINED = 'INSTRUMENT_DECLINED';
|
||||
public const INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR';
|
||||
public const INTERNAL_SERVICE_ERROR = 'INTERNAL_SERVICE_ERROR';
|
||||
public const INVALID_ACCOUNT_STATUS = 'INVALID_ACCOUNT_STATUS';
|
||||
public const INVALID_ARRAY_MAX_ITEMS = 'INVALID_ARRAY_MAX_ITEMS';
|
||||
public const INVALID_ARRAY_MIN_ITEMS = 'INVALID_ARRAY_MIN_ITEMS';
|
||||
public const INVALID_COUNTRY_CODE = 'INVALID_COUNTRY_CODE';
|
||||
public const INVALID_CURRENCY_CODE = 'INVALID_CURRENCY_CODE';
|
||||
public const INVALID_JSON_POINTER_FORMAT = 'INVALID_JSON_POINTER_FORMAT';
|
||||
public const INVALID_PARAMETER_SYNTAX = 'INVALID_PARAMETER_SYNTAX';
|
||||
public const INVALID_PARAMETER_VALUE = 'INVALID_PARAMETER_VALUE';
|
||||
public const INVALID_PARAMETER = 'INVALID_PARAMETER';
|
||||
public const INVALID_PATCH_OPERATION = 'INVALID_PATCH_OPERATION';
|
||||
public const INVALID_PAYER_ID = 'INVALID_PAYER_ID';
|
||||
public const INVALID_RESOURCE_ID = 'INVALID_RESOURCE_ID';
|
||||
public const INVALID_STRING_LENGTH = 'INVALID_STRING_LENGTH';
|
||||
public const ITEM_TOTAL_MISMATCH = 'ITEM_TOTAL_MISMATCH';
|
||||
public const ITEM_TOTAL_REQUIRED = 'ITEM_TOTAL_REQUIRED';
|
||||
public const MAX_AUTHORIZATION_COUNT_EXCEEDED = 'MAX_AUTHORIZATION_COUNT_EXCEEDED';
|
||||
public const MAX_NUMBER_OF_PAYMENT_ATTEMPTS_EXCEEDED = 'MAX_NUMBER_OF_PAYMENT_ATTEMPTS_EXCEEDED';
|
||||
public const MAX_VALUE_EXCEEDED = 'MAX_VALUE_EXCEEDED';
|
||||
public const MISSING_REQUIRED_PARAMETER = 'MISSING_REQUIRED_PARAMETER';
|
||||
public const MISSING_SHIPPING_ADDRESS = 'MISSING_SHIPPING_ADDRESS';
|
||||
public const MULTI_CURRENCY_ORDER = 'MULTI_CURRENCY_ORDER';
|
||||
public const MULTIPLE_SHIPPING_ADDRESS_NOT_SUPPORTED = 'MULTIPLE_SHIPPING_ADDRESS_NOT_SUPPORTED';
|
||||
public const MULTIPLE_SHIPPING_OPTION_SELECTED = 'MULTIPLE_SHIPPING_OPTION_SELECTED';
|
||||
public const INVALID_PICKUP_ADDRESS = 'INVALID_PICKUP_ADDRESS';
|
||||
public const NOT_AUTHORIZED = 'NOT_AUTHORIZED';
|
||||
public const NOT_ENABLED_FOR_CARD_PROCESSING = 'NOT_ENABLED_FOR_CARD_PROCESSING';
|
||||
public const NOT_PATCHABLE = 'NOT_PATCHABLE';
|
||||
public const NOT_SUPPORTED = 'NOT_SUPPORTED';
|
||||
public const ORDER_ALREADY_AUTHORIZED = 'ORDER_ALREADY_AUTHORIZED';
|
||||
public const ORDER_ALREADY_CAPTURED = 'ORDER_ALREADY_CAPTURED';
|
||||
public const ORDER_ALREADY_COMPLETED = 'ORDER_ALREADY_COMPLETED';
|
||||
public const ORDER_CANNOT_BE_SAVED = 'ORDER_CANNOT_BE_SAVED';
|
||||
public const ORDER_COMPLETED_OR_VOIDED = 'ORDER_COMPLETED_OR_VOIDED';
|
||||
public const ORDER_EXPIRED = 'ORDER_EXPIRED';
|
||||
public const ORDER_NOT_APPROVED = 'ORDER_NOT_APPROVED';
|
||||
public const ORDER_NOT_SAVED = 'ORDER_NOT_SAVED';
|
||||
public const ORDER_PREVIOUSLY_VOIDED = 'ORDER_PREVIOUSLY_VOIDED';
|
||||
public const PARAMETER_VALUE_NOT_SUPPORTED = 'PARAMETER_VALUE_NOT_SUPPORTED';
|
||||
public const PATCH_PATH_REQUIRED = 'PATCH_PATH_REQUIRED';
|
||||
public const PATCH_VALUE_REQUIRED = 'PATCH_VALUE_REQUIRED';
|
||||
public const PAYEE_ACCOUNT_INVALID = 'PAYEE_ACCOUNT_INVALID';
|
||||
public const PAYEE_ACCOUNT_LOCKED_OR_CLOSED = 'PAYEE_ACCOUNT_LOCKED_OR_CLOSED';
|
||||
public const PAYEE_ACCOUNT_RESTRICTED = 'PAYEE_ACCOUNT_RESTRICTED';
|
||||
public const PAYEE_BLOCKED_TRANSACTION = 'PAYEE_BLOCKED_TRANSACTION';
|
||||
public const PAYER_ACCOUNT_LOCKED_OR_CLOSED = 'PAYER_ACCOUNT_LOCKED_OR_CLOSED';
|
||||
public const PAYER_ACCOUNT_RESTRICTED = 'PAYER_ACCOUNT_RESTRICTED';
|
||||
public const PAYER_CANNOT_PAY = 'PAYER_CANNOT_PAY';
|
||||
public const PAYER_CONSENT_REQUIRED = 'PAYER_CONSENT_REQUIRED';
|
||||
public const PAYER_COUNTRY_NOT_SUPPORTED = 'PAYER_COUNTRY_NOT_SUPPORTED';
|
||||
public const PAYEE_NOT_ENABLED_FOR_CARD_PROCESSING = 'PAYEE_NOT_ENABLED_FOR_CARD_PROCESSING';
|
||||
public const PAYMENT_INSTRUCTION_REQUIRED = 'PAYMENT_INSTRUCTION_REQUIRED';
|
||||
public const PERMISSION_DENIED = 'PERMISSION_DENIED';
|
||||
public const POSTAL_CODE_REQUIRED = 'POSTAL_CODE_REQUIRED';
|
||||
public const PREFERRED_SHIPPING_OPTION_AMOUNT_MISMATCH = 'PREFERRED_SHIPPING_OPTION_AMOUNT_MISMATCH';
|
||||
public const REDIRECT_PAYER_FOR_ALTERNATE_FUNDING = 'REDIRECT_PAYER_FOR_ALTERNATE_FUNDING';
|
||||
public const REFERENCE_ID_NOT_FOUND = 'REFERENCE_ID_NOT_FOUND';
|
||||
public const REFERENCE_ID_REQUIRED = 'REFERENCE_ID_REQUIRED';
|
||||
public const DUPLICATE_REFERENCE_ID = 'DUPLICATE_REFERENCE_ID';
|
||||
public const SHIPPING_ADDRESS_INVALID = 'SHIPPING_ADDRESS_INVALID';
|
||||
public const SHIPPING_OPTION_NOT_SELECTED = 'SHIPPING_OPTION_NOT_SELECTED';
|
||||
public const SHIPPING_OPTIONS_NOT_SUPPORTED = 'SHIPPING_OPTIONS_NOT_SUPPORTED';
|
||||
public const TAX_TOTAL_MISMATCH = 'TAX_TOTAL_MISMATCH';
|
||||
public const TAX_TOTAL_REQUIRED = 'TAX_TOTAL_REQUIRED';
|
||||
public const TRANSACTION_AMOUNT_EXCEEDS_MONTHLY_MAX_LIMIT = 'TRANSACTION_AMOUNT_EXCEEDS_MONTHLY_MAX_LIMIT';
|
||||
public const TRANSACTION_BLOCKED_BY_PAYEE = 'TRANSACTION_BLOCKED_BY_PAYEE';
|
||||
public const TRANSACTION_LIMIT_EXCEEDED = 'TRANSACTION_LIMIT_EXCEEDED';
|
||||
public const TRANSACTION_RECEIVING_LIMIT_EXCEEDED = 'TRANSACTION_RECEIVING_LIMIT_EXCEEDED';
|
||||
public const TRANSACTION_REFUSED = 'TRANSACTION_REFUSED';
|
||||
public const UNSUPPORTED_INTENT = 'UNSUPPORTED_INTENT';
|
||||
public const UNSUPPORTED_PATCH_PARAMETER_VALUE = 'UNSUPPORTED_PATCH_PARAMETER_VALUE';
|
||||
public const UNSUPPORTED_PAYMENT_INSTRUCTION = 'UNSUPPORTED_PAYMENT_INSTRUCTION';
|
||||
public const PAYEE_ACCOUNT_NOT_SUPPORTED = 'PAYEE_ACCOUNT_NOT_SUPPORTED';
|
||||
public const PAYEE_ACCOUNT_NOT_VERIFIED = 'PAYEE_ACCOUNT_NOT_VERIFIED';
|
||||
public const PAYEE_NOT_CONSENTED = 'PAYEE_NOT_CONSENTED';
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
||||
use Inpsyde\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class ApplicationContextRepository
|
||||
{
|
||||
|
||||
private $settings;
|
||||
public function __construct(ContainerInterface $settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function currentContext(
|
||||
string $shippingPreference = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING
|
||||
): ApplicationContext {
|
||||
|
||||
$brandName = $this->settings->has('brand_name') ? $this->settings->get('brand_name') : '';
|
||||
// Todo: Put user_locale in container as well?
|
||||
$locale = str_replace('_', '-', get_user_locale());
|
||||
$landingpage = $this->settings->has('landing_page') ?
|
||||
$this->settings->get('landing_page') : ApplicationContext::LANDING_PAGE_NO_PREFERENCE;
|
||||
$context = new ApplicationContext(
|
||||
(string) home_url(\WC_AJAX::get_endpoint(ReturnUrlEndpoint::ENDPOINT)),
|
||||
(string) wc_get_checkout_url(),
|
||||
(string) $brandName,
|
||||
$locale,
|
||||
(string) $landingpage,
|
||||
$shippingPreference
|
||||
);
|
||||
return $context;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
||||
|
||||
class CartRepository implements PurchaseUnitRepositoryInterface
|
||||
{
|
||||
private $factory;
|
||||
public function __construct(PurchaseUnitFactory $factory)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Pur of the Woocommerce cart.
|
||||
*
|
||||
* @return PurchaseUnit[]
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
$cart = WC()->cart ?? new \WC_Cart();
|
||||
return [$this->factory->fromWcCart($cart)];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
|
||||
class PartnerReferralsData
|
||||
{
|
||||
|
||||
private $merchantEmail;
|
||||
private $dccApplies;
|
||||
public function __construct(
|
||||
string $merchantEmail,
|
||||
DccApplies $dccApplies
|
||||
) {
|
||||
|
||||
$this->merchantEmail = $merchantEmail;
|
||||
$this->dccApplies = $dccApplies;
|
||||
}
|
||||
|
||||
public function nonce(): string
|
||||
{
|
||||
return 'a1233wtergfsdt4365tzrshgfbaewa36AGa1233wtergfsdt4365tzrshgfbaewa36AG';
|
||||
}
|
||||
|
||||
public function data(): array
|
||||
{
|
||||
$data = $this->defaultData();
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function defaultData(): array
|
||||
{
|
||||
|
||||
return [
|
||||
"email" => $this->merchantEmail,
|
||||
"partner_config_override" => [
|
||||
"partner_logo_url" => "https://connect.woocommerce.com/images/woocommerce_logo.png",
|
||||
"return_url" => admin_url(
|
||||
'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway'
|
||||
),
|
||||
"return_url_description" => __(
|
||||
'Return to your shop.',
|
||||
'woocommerce-paypal-commerce-gateway'
|
||||
),
|
||||
"show_add_credit_card" => true,
|
||||
],
|
||||
"products" => [
|
||||
$this->dccApplies->forCountryCurrency() ? "PPCP" : "EXPRESS_CHECKOUT",
|
||||
],
|
||||
"legal_consents" => [
|
||||
[
|
||||
"type" => "SHARE_DATA_CONSENT",
|
||||
"granted" => true,
|
||||
],
|
||||
],
|
||||
"operations" => [
|
||||
[
|
||||
"operation" => "API_INTEGRATION",
|
||||
"api_integration_preference" => [
|
||||
"rest_api_integration" => [
|
||||
"integration_method" => "PAYPAL",
|
||||
"integration_type" => "FIRST_PARTY",
|
||||
"first_party_details" => [
|
||||
"features" => [
|
||||
"PAYMENT",
|
||||
"FUTURE_PAYMENT",
|
||||
"REFUND",
|
||||
"ADVANCED_TRANSACTIONS_SEARCH",
|
||||
],
|
||||
"seller_nonce" => $this->nonce(),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
|
||||
//phpcs:disable Inpsyde.CodeQuality.NoAccessors.NoSetter
|
||||
//phpcs:disable Inpsyde.CodeQuality.NoAccessors.NoGetter
|
||||
class PayPalRequestIdRepository
|
||||
{
|
||||
public const KEY = 'ppcp-request-ids';
|
||||
public function getForOrderId(string $orderId): string
|
||||
{
|
||||
$all = $this->all();
|
||||
return isset($all[$orderId]) ? (string) $all[$orderId]['id'] : '';
|
||||
}
|
||||
|
||||
public function getForOrder(Order $order): string
|
||||
{
|
||||
return $this->getForOrderId($order->id());
|
||||
}
|
||||
|
||||
public function setForOrder(Order $order, string $requestId): bool
|
||||
{
|
||||
$all = $this->all();
|
||||
$all[$order->id()] = [
|
||||
'id' => $requestId,
|
||||
'expiration' => time() + 10 * DAY_IN_SECONDS,
|
||||
];
|
||||
$all = $this->cleanup($all);
|
||||
update_option(self::KEY, $all);
|
||||
return true;
|
||||
}
|
||||
|
||||
private function all(): array
|
||||
{
|
||||
|
||||
return (array) get_option('ppcp-request-ids', []);
|
||||
}
|
||||
|
||||
private function cleanup(array $all): array
|
||||
{
|
||||
|
||||
foreach ($all as $orderId => $value) {
|
||||
if (time() < $value['expiration']) {
|
||||
continue;
|
||||
}
|
||||
unset($all[$orderId]);
|
||||
}
|
||||
return $all;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Config\Config;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payee;
|
||||
|
||||
class PayeeRepository
|
||||
{
|
||||
|
||||
private $merchantEmail;
|
||||
private $merchantId;
|
||||
public function __construct(string $merchantEmail, string $merchantId)
|
||||
{
|
||||
$this->merchantEmail = $merchantEmail;
|
||||
$this->merchantId = $merchantId;
|
||||
}
|
||||
|
||||
public function payee(): Payee
|
||||
{
|
||||
return new Payee(
|
||||
$this->merchantEmail,
|
||||
$this->merchantId
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
|
||||
interface PurchaseUnitRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return PurchaseUnit[]
|
||||
*/
|
||||
public function all(): array;
|
||||
}
|
220
tests/PHPUnit/ApiClient/Authentication/PayPalBearerTest.php
Normal file
220
tests/PHPUnit/ApiClient/Authentication/PayPalBearerTest.php
Normal file
|
@ -0,0 +1,220 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Authentication;
|
||||
|
||||
use Brain\Monkey\Expectation\Exception\ExpectationArgsRequired;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Mockery;
|
||||
use function Brain\Monkey\Functions\expect;
|
||||
|
||||
class PayPalBearerTest extends TestCase
|
||||
{
|
||||
|
||||
public function testDefault()
|
||||
{
|
||||
$json = '{"access_token":"abc","expires_in":100, "created":' . time() . '}';
|
||||
$cache = Mockery::mock(CacheInterface::class);
|
||||
$cache
|
||||
->expects('get')
|
||||
->andReturn('{"access_token":"abc","expires_in":100, "created":100}');
|
||||
$cache
|
||||
->expects('set');
|
||||
$host = 'https://example.com';
|
||||
$key = 'key';
|
||||
$secret = 'secret';
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldNotReceive('log');
|
||||
|
||||
$bearer = new PayPalBearer($cache, $host, $key, $secret, $logger);
|
||||
|
||||
expect('trailingslashit')
|
||||
->with($host)
|
||||
->andReturn($host . '/');
|
||||
expect('wp_remote_get')
|
||||
->andReturnUsing(
|
||||
function ($url, $args) use ($json, $key, $secret, $host) {
|
||||
if ($url !== $host . '/v1/oauth2/token?grant_type=client_credentials') {
|
||||
return false;
|
||||
}
|
||||
if ($args['method'] !== 'POST') {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Authorization'] !== 'Basic ' . base64_encode($key . ':' . $secret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return [
|
||||
'body' => $json,
|
||||
];
|
||||
}
|
||||
);
|
||||
expect('is_wp_error')
|
||||
->andReturn(false);
|
||||
expect('wp_remote_retrieve_response_code')
|
||||
->andReturn(200);
|
||||
|
||||
$token = $bearer->bearer();
|
||||
$this->assertEquals("abc", $token->token());
|
||||
$this->assertTrue($token->isValid());
|
||||
}
|
||||
|
||||
public function testNoTokenCached()
|
||||
{
|
||||
$json = '{"access_token":"abc","expires_in":100, "created":' . time() . '}';
|
||||
$cache = Mockery::mock(CacheInterface::class);
|
||||
$cache
|
||||
->expects('get')
|
||||
->andReturn('');
|
||||
$cache
|
||||
->expects('set');
|
||||
$host = 'https://example.com';
|
||||
$key = 'key';
|
||||
$secret = 'secret';
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldNotReceive('log');
|
||||
|
||||
$bearer = new PayPalBearer($cache, $host, $key, $secret, $logger);
|
||||
|
||||
expect('trailingslashit')
|
||||
->with($host)
|
||||
->andReturn($host . '/');
|
||||
expect('wp_remote_get')
|
||||
->andReturnUsing(
|
||||
function ($url, $args) use ($json, $key, $secret, $host) {
|
||||
if ($url !== $host . '/v1/oauth2/token?grant_type=client_credentials') {
|
||||
return false;
|
||||
}
|
||||
if ($args['method'] !== 'POST') {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Authorization'] !== 'Basic ' . base64_encode($key . ':' . $secret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return [
|
||||
'body' => $json,
|
||||
];
|
||||
}
|
||||
);
|
||||
expect('is_wp_error')
|
||||
->andReturn(false);
|
||||
expect('wp_remote_retrieve_response_code')
|
||||
->andReturn(200);
|
||||
|
||||
$token = $bearer->bearer();
|
||||
$this->assertEquals("abc", $token->token());
|
||||
$this->assertTrue($token->isValid());
|
||||
}
|
||||
|
||||
public function testCachedTokenIsStillValid()
|
||||
{
|
||||
$json = '{"access_token":"abc","expires_in":100, "created":' . time() . '}';
|
||||
$cache = Mockery::mock(CacheInterface::class);
|
||||
$cache
|
||||
->expects('get')
|
||||
->andReturn($json);
|
||||
$host = 'https://example.com';
|
||||
$key = 'key';
|
||||
$secret = 'secret';
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldNotReceive('log');
|
||||
|
||||
$bearer = new PayPalBearer($cache, $host, $key, $secret, $logger);
|
||||
|
||||
$token = $bearer->bearer();
|
||||
$this->assertEquals("abc", $token->token());
|
||||
$this->assertTrue($token->isValid());
|
||||
}
|
||||
|
||||
public function testExceptionThrownOnError()
|
||||
{
|
||||
$json = '{"access_token":"abc","expires_in":100, "created":' . time() . '}';
|
||||
$cache = Mockery::mock(CacheInterface::class);
|
||||
$cache
|
||||
->expects('get')
|
||||
->andReturn('');
|
||||
$host = 'https://example.com';
|
||||
$key = 'key';
|
||||
$secret = 'secret';
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldReceive('log');
|
||||
|
||||
$bearer = new PayPalBearer($cache, $host, $key, $secret, $logger);
|
||||
|
||||
expect('trailingslashit')
|
||||
->with($host)
|
||||
->andReturn($host . '/');
|
||||
expect('wp_remote_get')
|
||||
->andReturnUsing(
|
||||
function ($url, $args) use ($json, $key, $secret, $host) {
|
||||
if ($url !== $host . '/v1/oauth2/token?grant_type=client_credentials') {
|
||||
return false;
|
||||
}
|
||||
if ($args['method'] !== 'POST') {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Authorization'] !== 'Basic ' . base64_encode($key . ':' . $secret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return [
|
||||
'body' => $json,
|
||||
];
|
||||
}
|
||||
);
|
||||
expect('is_wp_error')
|
||||
->andReturn(true);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$bearer->bearer();
|
||||
}
|
||||
|
||||
public function testExceptionThrownBecauseOfHttpStatusCode()
|
||||
{
|
||||
$json = '{"access_token":"abc","expires_in":100, "created":' . time() . '}';
|
||||
$cache = Mockery::mock(CacheInterface::class);
|
||||
$cache
|
||||
->expects('get')
|
||||
->andReturn('');
|
||||
$host = 'https://example.com';
|
||||
$key = 'key';
|
||||
$secret = 'secret';
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldReceive('log');
|
||||
|
||||
$bearer = new PayPalBearer($cache, $host, $key, $secret, $logger);
|
||||
|
||||
expect('trailingslashit')
|
||||
->with($host)
|
||||
->andReturn($host . '/');
|
||||
expect('wp_remote_get')
|
||||
->andReturnUsing(
|
||||
function ($url, $args) use ($json, $key, $secret, $host) {
|
||||
if ($url !== $host . '/v1/oauth2/token?grant_type=client_credentials') {
|
||||
return false;
|
||||
}
|
||||
if ($args['method'] !== 'POST') {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Authorization'] !== 'Basic ' . base64_encode($key . ':' . $secret)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return [
|
||||
'body' => $json,
|
||||
];
|
||||
}
|
||||
);
|
||||
expect('is_wp_error')
|
||||
->andReturn(false);
|
||||
expect('wp_remote_retrieve_response_code')
|
||||
->andReturn(500);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$bearer->bearer();
|
||||
}
|
||||
}
|
1051
tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php
Normal file
1051
tests/PHPUnit/ApiClient/Endpoint/OrderEndpointTest.php
Normal file
File diff suppressed because it is too large
Load diff
100
tests/PHPUnit/ApiClient/Endpoint/OrderTest.php
Normal file
100
tests/PHPUnit/ApiClient/Endpoint/OrderTest.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class OrderTest extends TestCase
|
||||
{
|
||||
|
||||
public function testOrder()
|
||||
{
|
||||
$id = 'id';
|
||||
$createTime = new \DateTime();
|
||||
$updateTime = new \DateTime();
|
||||
$unit = Mockery::mock(PurchaseUnit::class);
|
||||
$unit->expects('toArray')->andReturn([1]);
|
||||
$status = Mockery::mock(OrderStatus::class);
|
||||
$status->expects('name')->andReturn('CREATED');
|
||||
$payer = Mockery::mock(Payer::class);
|
||||
$payer
|
||||
->expects('toArray')->andReturn(['payer']);
|
||||
$intent = 'AUTHORIZE';
|
||||
$applicationContext = Mockery::mock(ApplicationContext::class);
|
||||
$applicationContext
|
||||
->expects('toArray')
|
||||
->andReturn(['applicationContext']);
|
||||
$paymentSource = Mockery::mock(PaymentSource::class);
|
||||
$paymentSource
|
||||
->expects('toArray')
|
||||
->andReturn(['paymentSource']);
|
||||
|
||||
$testee = new Order(
|
||||
$id,
|
||||
[$unit],
|
||||
$status,
|
||||
$applicationContext,
|
||||
$paymentSource,
|
||||
$payer,
|
||||
$intent,
|
||||
$createTime,
|
||||
$updateTime
|
||||
);
|
||||
|
||||
$this->assertEquals($id, $testee->id());
|
||||
$this->assertEquals($createTime, $testee->createTime());
|
||||
$this->assertEquals($updateTime, $testee->updateTime());
|
||||
$this->assertEquals([$unit], $testee->purchaseUnits());
|
||||
$this->assertEquals($payer, $testee->payer());
|
||||
$this->assertEquals($intent, $testee->intent());
|
||||
$this->assertEquals($status, $testee->status());
|
||||
|
||||
$expected = [
|
||||
'id' => $id,
|
||||
'intent' => $intent,
|
||||
'status' => 'CREATED',
|
||||
'purchase_units' => [
|
||||
[1],
|
||||
],
|
||||
'create_time' => $createTime->format(\DateTimeInterface::ISO8601),
|
||||
'update_time' => $updateTime->format(\DateTimeInterface::ISO8601),
|
||||
'payer' => ['payer'],
|
||||
'application_context' => ['applicationContext'],
|
||||
'payment_source' => ['paymentSource']
|
||||
];
|
||||
$this->assertEquals($expected, $testee->toArray());
|
||||
}
|
||||
|
||||
public function testOrderNoDatesOrPayer()
|
||||
{
|
||||
$id = 'id';
|
||||
$unit = Mockery::mock(PurchaseUnit::class);
|
||||
$unit->expects('toArray')->andReturn([1]);
|
||||
$status = Mockery::mock(OrderStatus::class);
|
||||
$status->expects('name')->andReturn('CREATED');
|
||||
|
||||
$testee = new Order(
|
||||
$id,
|
||||
[$unit],
|
||||
$status
|
||||
);
|
||||
|
||||
$this->assertEquals(null, $testee->createTime());
|
||||
$this->assertEquals(null, $testee->updateTime());
|
||||
$this->assertEquals(null, $testee->payer());
|
||||
$this->assertEquals('CAPTURE', $testee->intent());
|
||||
|
||||
$array = $testee->toArray();
|
||||
$this->assertFalse(array_key_exists('payer', $array));
|
||||
$this->assertFalse(array_key_exists('create_time', $array));
|
||||
$this->assertFalse(array_key_exists('update_time', $array));
|
||||
}
|
||||
}
|
259
tests/PHPUnit/ApiClient/Endpoint/PaymentsEndpointTest.php
Normal file
259
tests/PHPUnit/ApiClient/Endpoint/PaymentsEndpointTest.php
Normal file
|
@ -0,0 +1,259 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\ErrorResponseCollection;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Token;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Factory\ErrorResponseCollectionFactory;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use function Brain\Monkey\Functions\expect;
|
||||
|
||||
class PaymentsEndpointTest extends TestCase
|
||||
{
|
||||
public function testAuthorizationDefault()
|
||||
{
|
||||
$host = 'https://example.com/';
|
||||
$authorizationId = 'somekindofid';
|
||||
|
||||
$bearer = Mockery::mock(Bearer::class);
|
||||
$token = Mockery::mock(Token::class);
|
||||
$token
|
||||
->expects('token')->andReturn('bearer');
|
||||
$bearer
|
||||
->expects('bearer')->andReturn($token);
|
||||
|
||||
$authorization = Mockery::mock(Authorization::class);
|
||||
$authorizationFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
$authorizationFactory
|
||||
->expects('fromPayPalRequest')
|
||||
->andReturn($authorization);
|
||||
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldNotReceive('log');
|
||||
|
||||
$rawResponse = ['body' => '{"is_correct":true}'];
|
||||
|
||||
$testee = new PaymentsEndpoint(
|
||||
$host,
|
||||
$bearer,
|
||||
$authorizationFactory,
|
||||
$logger
|
||||
);
|
||||
|
||||
expect('wp_remote_get')->andReturnUsing(
|
||||
function ($url, $args) use ($rawResponse, $host, $authorizationId) {
|
||||
if ($url !== $host . 'v2/payments/authorizations/' . $authorizationId) {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Authorization'] !== 'Bearer bearer') {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Content-Type'] !== 'application/json') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $rawResponse;
|
||||
}
|
||||
);
|
||||
expect('is_wp_error')->with($rawResponse)->andReturn(false);
|
||||
expect('wp_remote_retrieve_response_code')->with($rawResponse)->andReturn(200);
|
||||
|
||||
$result = $testee->authorization($authorizationId);
|
||||
$this->assertEquals($authorization, $result);
|
||||
}
|
||||
|
||||
public function testAuthorizationWpError()
|
||||
{
|
||||
$host = 'https://example.com/';
|
||||
$authorizationId = 'somekindofid';
|
||||
|
||||
$token = Mockery::mock(Token::class);
|
||||
$token
|
||||
->expects('token')->andReturn('bearer');
|
||||
$bearer = Mockery::mock(Bearer::class);
|
||||
$bearer->expects('bearer')->andReturn($token);
|
||||
|
||||
$authorizationFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldReceive('log');
|
||||
|
||||
$rawResponse = ['body' => '{"is_correct":true}'];
|
||||
|
||||
$testee = new PaymentsEndpoint(
|
||||
$host,
|
||||
$bearer,
|
||||
$authorizationFactory,
|
||||
$logger
|
||||
);
|
||||
|
||||
expect('wp_remote_get')->andReturn($rawResponse);
|
||||
expect('is_wp_error')->with($rawResponse)->andReturn(true);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->authorization($authorizationId);
|
||||
}
|
||||
|
||||
public function testAuthorizationIsNot200()
|
||||
{
|
||||
$host = 'https://example.com/';
|
||||
$authorizationId = 'somekindofid';
|
||||
|
||||
$token = Mockery::mock(Token::class);
|
||||
$token
|
||||
->expects('token')->andReturn('bearer');
|
||||
$bearer = Mockery::mock(Bearer::class);
|
||||
$bearer->expects('bearer')->andReturn($token);
|
||||
|
||||
$authorizationFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
|
||||
$rawResponse = ['body' => '{"some_error":true}'];
|
||||
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldReceive('log');
|
||||
|
||||
$testee = new PaymentsEndpoint(
|
||||
$host,
|
||||
$bearer,
|
||||
$authorizationFactory,
|
||||
$logger
|
||||
);
|
||||
|
||||
expect('wp_remote_get')->andReturn($rawResponse);
|
||||
expect('is_wp_error')->with($rawResponse)->andReturn(false);
|
||||
expect('wp_remote_retrieve_response_code')->with($rawResponse)->andReturn(500);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->authorization($authorizationId);
|
||||
}
|
||||
|
||||
public function testCaptureDefault()
|
||||
{
|
||||
$host = 'https://example.com/';
|
||||
$authorizationId = 'somekindofid';
|
||||
|
||||
$token = Mockery::mock(Token::class);
|
||||
$token
|
||||
->expects('token')->andReturn('bearer');
|
||||
$bearer = Mockery::mock(Bearer::class);
|
||||
$bearer
|
||||
->expects('bearer')->andReturn($token);
|
||||
|
||||
$authorization = Mockery::mock(Authorization::class);
|
||||
$authorizationFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
$authorizationFactory
|
||||
->expects('fromPayPalRequest')
|
||||
->andReturn($authorization);
|
||||
|
||||
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->shouldNotReceive('log');
|
||||
|
||||
$rawResponse = ['body' => '{"is_correct":true}'];
|
||||
|
||||
$testee = new PaymentsEndpoint(
|
||||
$host,
|
||||
$bearer,
|
||||
$authorizationFactory,
|
||||
$logger
|
||||
);
|
||||
|
||||
expect('wp_remote_get')->andReturnUsing(
|
||||
function ($url, $args) use ($rawResponse, $host, $authorizationId) {
|
||||
if ($url !== $host . 'v2/payments/authorizations/' . $authorizationId . '/capture') {
|
||||
return false;
|
||||
}
|
||||
if ($args['method'] !== 'POST') {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Authorization'] !== 'Bearer bearer') {
|
||||
return false;
|
||||
}
|
||||
if ($args['headers']['Content-Type'] !== 'application/json') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $rawResponse;
|
||||
}
|
||||
);
|
||||
expect('is_wp_error')->with($rawResponse)->andReturn(false);
|
||||
expect('wp_remote_retrieve_response_code')->with($rawResponse)->andReturn(201);
|
||||
|
||||
$result = $testee->capture($authorizationId);
|
||||
$this->assertEquals($authorization, $result);
|
||||
}
|
||||
|
||||
public function testCaptureIsWpError()
|
||||
{
|
||||
$host = 'https://example.com/';
|
||||
$authorizationId = 'somekindofid';
|
||||
|
||||
$token = Mockery::mock(Token::class);
|
||||
$token
|
||||
->expects('token')->andReturn('bearer');
|
||||
$bearer = Mockery::mock(Bearer::class);
|
||||
$bearer->expects('bearer')->andReturn($token);
|
||||
|
||||
$authorizationFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->expects('log');
|
||||
|
||||
$rawResponse = ['body' => '{"is_correct":true}'];
|
||||
|
||||
$testee = new PaymentsEndpoint(
|
||||
$host,
|
||||
$bearer,
|
||||
$authorizationFactory,
|
||||
$logger
|
||||
);
|
||||
|
||||
expect('wp_remote_get')->andReturn($rawResponse);
|
||||
expect('is_wp_error')->with($rawResponse)->andReturn(true);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->capture($authorizationId);
|
||||
}
|
||||
|
||||
public function testAuthorizationIsNot201()
|
||||
{
|
||||
$host = 'https://example.com/';
|
||||
$authorizationId = 'somekindofid';
|
||||
|
||||
$token = Mockery::mock(Token::class);
|
||||
$token
|
||||
->expects('token')->andReturn('bearer');
|
||||
$bearer = Mockery::mock(Bearer::class);
|
||||
$bearer->expects('bearer')->andReturn($token);
|
||||
|
||||
$authorizationFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
|
||||
$rawResponse = ['body' => '{"some_error":true}'];
|
||||
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$logger->expects('log');
|
||||
|
||||
$testee = new PaymentsEndpoint(
|
||||
$host,
|
||||
$bearer,
|
||||
$authorizationFactory,
|
||||
$logger
|
||||
);
|
||||
|
||||
expect('wp_remote_get')->andReturn($rawResponse);
|
||||
expect('is_wp_error')->with($rawResponse)->andReturn(false);
|
||||
expect('wp_remote_retrieve_response_code')->with($rawResponse)->andReturn(500);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->capture($authorizationId);
|
||||
}
|
||||
}
|
53
tests/PHPUnit/ApiClient/Entity/AddressTest.php
Normal file
53
tests/PHPUnit/ApiClient/Entity/AddressTest.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
|
||||
class AddressTest extends TestCase
|
||||
{
|
||||
|
||||
public function test()
|
||||
{
|
||||
$testee = new Address(
|
||||
'countryCode',
|
||||
'addressLine1',
|
||||
'addressLine2',
|
||||
'adminArea1',
|
||||
'adminArea2',
|
||||
'postalCode'
|
||||
);
|
||||
|
||||
$this->assertEquals('countryCode', $testee->countryCode());
|
||||
$this->assertEquals('addressLine1', $testee->addressLine1());
|
||||
$this->assertEquals('addressLine2', $testee->addressLine2());
|
||||
$this->assertEquals('adminArea1', $testee->adminArea1());
|
||||
$this->assertEquals('adminArea2', $testee->adminArea2());
|
||||
$this->assertEquals('postalCode', $testee->postalCode());
|
||||
}
|
||||
|
||||
public function testToArray()
|
||||
{
|
||||
$testee = new Address(
|
||||
'countryCode',
|
||||
'addressLine1',
|
||||
'addressLine2',
|
||||
'adminArea1',
|
||||
'adminArea2',
|
||||
'postalCode'
|
||||
);
|
||||
|
||||
$expected = [
|
||||
'country_code' => 'countryCode',
|
||||
'address_line_1' => 'addressLine1',
|
||||
'address_line_2' => 'addressLine2',
|
||||
'admin_area_1' => 'adminArea1',
|
||||
'admin_area_2' => 'adminArea2',
|
||||
'postal_code' => 'postalCode',
|
||||
];
|
||||
|
||||
$actual = $testee->toArray();
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
}
|
123
tests/PHPUnit/ApiClient/Entity/AmountBreakdownTest.php
Normal file
123
tests/PHPUnit/ApiClient/Entity/AmountBreakdownTest.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class AmountBreakdownTest extends TestCase
|
||||
{
|
||||
|
||||
public function test()
|
||||
{
|
||||
$itemTotal = Mockery::mock(Money::class);
|
||||
$itemTotal
|
||||
->expects('toArray')->andReturn(['itemTotal']);
|
||||
$shipping = Mockery::mock(Money::class);
|
||||
$shipping
|
||||
->expects('toArray')->andReturn(['shipping']);
|
||||
$taxTotal = Mockery::mock(Money::class);
|
||||
$taxTotal
|
||||
->expects('toArray')->andReturn(['taxTotal']);
|
||||
$handling = Mockery::mock(Money::class);
|
||||
$handling
|
||||
->expects('toArray')->andReturn(['handling']);
|
||||
$insurance = Mockery::mock(Money::class);
|
||||
$insurance
|
||||
->expects('toArray')->andReturn(['insurance']);
|
||||
$shippingDiscount = Mockery::mock(Money::class);
|
||||
$shippingDiscount
|
||||
->expects('toArray')->andReturn(['shippingDiscount']);
|
||||
$discount = Mockery::mock(Money::class);
|
||||
$discount
|
||||
->expects('toArray')->andReturn(['discount']);
|
||||
$testee = new AmountBreakdown(
|
||||
$itemTotal,
|
||||
$shipping,
|
||||
$taxTotal,
|
||||
$handling,
|
||||
$insurance,
|
||||
$shippingDiscount,
|
||||
$discount
|
||||
);
|
||||
|
||||
$this->assertEquals($itemTotal, $testee->itemTotal());
|
||||
$this->assertEquals($shipping, $testee->shipping());
|
||||
$this->assertEquals($taxTotal, $testee->taxTotal());
|
||||
$this->assertEquals($handling, $testee->handling());
|
||||
$this->assertEquals($insurance, $testee->insurance());
|
||||
$this->assertEquals($shippingDiscount, $testee->shippingDiscount());
|
||||
$this->assertEquals($discount, $testee->discount());
|
||||
|
||||
$expected = [
|
||||
'item_total' => ['itemTotal'],
|
||||
'shipping' => ['shipping'],
|
||||
'tax_total' => ['taxTotal'],
|
||||
'handling' => ['handling'],
|
||||
'insurance' => ['insurance'],
|
||||
'shipping_discount' => ['shippingDiscount'],
|
||||
'discount' => ['discount'],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $testee->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataDropArrayKeyIfNoValueGiven
|
||||
*/
|
||||
public function testDropArrayKeyIfNoValueGiven($keyMissing, $methodName)
|
||||
{
|
||||
$itemTotal = Mockery::mock(Money::class);
|
||||
$itemTotal
|
||||
->shouldReceive('toArray')->zeroOrMoreTimes()->andReturn(['itemTotal']);
|
||||
$shipping = Mockery::mock(Money::class);
|
||||
$shipping
|
||||
->shouldReceive('toArray')->zeroOrMoreTimes()->andReturn(['shipping']);
|
||||
$taxTotal = Mockery::mock(Money::class);
|
||||
$taxTotal
|
||||
->shouldReceive('toArray')->zeroOrMoreTimes()->andReturn(['taxTotal']);
|
||||
$handling = Mockery::mock(Money::class);
|
||||
$handling
|
||||
->shouldReceive('toArray')->zeroOrMoreTimes()->andReturn(['handling']);
|
||||
$insurance = Mockery::mock(Money::class);
|
||||
$insurance
|
||||
->shouldReceive('toArray')->zeroOrMoreTimes()->andReturn(['insurance']);
|
||||
$shippingDiscount = Mockery::mock(Money::class);
|
||||
$shippingDiscount
|
||||
->shouldReceive('toArray')->zeroOrMoreTimes()->andReturn(['shippingDiscount']);
|
||||
$discount = Mockery::mock(Money::class);
|
||||
$discount
|
||||
->shouldReceive('toArray')->zeroOrMoreTimes()->andReturn(['discount']);
|
||||
|
||||
$items = [
|
||||
'item_total' => $itemTotal,
|
||||
'shipping' => $shipping,
|
||||
'tax_total' => $taxTotal,
|
||||
'handling' => $handling,
|
||||
'insurance' => $insurance,
|
||||
'shipping_discount' => $shippingDiscount,
|
||||
'discount' => $discount,
|
||||
];
|
||||
$items[$keyMissing] = null;
|
||||
|
||||
$testee = new AmountBreakdown(...array_values($items));
|
||||
$array = $testee->toArray();
|
||||
$result = ! array_key_exists($keyMissing, $array);
|
||||
$this->assertTrue($result);
|
||||
$this->assertNull($testee->{$methodName}(), "$methodName should return null");
|
||||
}
|
||||
|
||||
public function dataDropArrayKeyIfNoValueGiven() : array
|
||||
{
|
||||
return [
|
||||
['item_total', 'itemTotal'],
|
||||
['shipping', 'shipping'],
|
||||
['tax_total', 'taxTotal'],
|
||||
['handling', 'handling'],
|
||||
['insurance', 'insurance'],
|
||||
['shipping_discount', 'shippingDiscount'],
|
||||
['discount', 'discount'],
|
||||
];
|
||||
}
|
||||
}
|
57
tests/PHPUnit/ApiClient/Entity/AmountTest.php
Normal file
57
tests/PHPUnit/ApiClient/Entity/AmountTest.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class AmountTest extends TestCase
|
||||
{
|
||||
|
||||
public function test()
|
||||
{
|
||||
$money = Mockery::mock(Money::class);
|
||||
$money->shouldReceive('currencyCode')->andReturn('currencyCode');
|
||||
$money->shouldReceive('value')->andReturn(1.10);
|
||||
$testee = new Amount($money);
|
||||
|
||||
$this->assertEquals('currencyCode', $testee->currencyCode());
|
||||
$this->assertEquals(1.10, $testee->value());
|
||||
}
|
||||
|
||||
public function testBreakdownIsNull()
|
||||
{
|
||||
$money = Mockery::mock(Money::class);
|
||||
$money->shouldReceive('currencyCode')->andReturn('currencyCode');
|
||||
$money->shouldReceive('value')->andReturn(1.10);
|
||||
$testee = new Amount($money);
|
||||
|
||||
$this->assertNull($testee->breakdown());
|
||||
|
||||
$expectedArray = [
|
||||
'currency_code' => 'currencyCode',
|
||||
'value' => 1.10,
|
||||
];
|
||||
$this->assertEquals($expectedArray, $testee->toArray());
|
||||
}
|
||||
|
||||
public function testBreakdown()
|
||||
{
|
||||
$money = Mockery::mock(Money::class);
|
||||
$money->shouldReceive('currencyCode')->andReturn('currencyCode');
|
||||
$money->shouldReceive('value')->andReturn(1.10);
|
||||
$breakdown = Mockery::mock(AmountBreakdown::class);
|
||||
$breakdown->shouldReceive('toArray')->andReturn([1]);
|
||||
$testee = new Amount($money, $breakdown);
|
||||
|
||||
$this->assertEquals($breakdown, $testee->breakdown());
|
||||
|
||||
$expectedArray = [
|
||||
'currency_code' => 'currencyCode',
|
||||
'value' => 1.10,
|
||||
'breakdown' => [1],
|
||||
];
|
||||
$this->assertEquals($expectedArray, $testee->toArray());
|
||||
}
|
||||
}
|
51
tests/PHPUnit/ApiClient/Entity/AuthorizationStatusTest.php
Normal file
51
tests/PHPUnit/ApiClient/Entity/AuthorizationStatusTest.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
|
||||
class AuthorizationStatusTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider statusDataProvider
|
||||
* @param $status
|
||||
*/
|
||||
public function testValidStatusProvided($status)
|
||||
{
|
||||
$authorizationStatus = new AuthorizationStatus($status);
|
||||
|
||||
$this->assertEquals($authorizationStatus->name(), $status);
|
||||
}
|
||||
|
||||
public function testInvalidStatusProvided()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
new AuthorizationStatus('invalid');
|
||||
}
|
||||
|
||||
public function testStatusComparision()
|
||||
{
|
||||
$authorizationStatus = new AuthorizationStatus('CREATED');
|
||||
|
||||
$this->assertTrue($authorizationStatus->is('CREATED'));
|
||||
$this->assertFalse($authorizationStatus->is('NOT_CREATED'));
|
||||
}
|
||||
|
||||
public function statusDataProvider(): array
|
||||
{
|
||||
return [
|
||||
['INTERNAL'],
|
||||
['CREATED'],
|
||||
['CAPTURED'],
|
||||
['DENIED'],
|
||||
['EXPIRED'],
|
||||
['PARTIALLY_CAPTURED'],
|
||||
['VOIDED'],
|
||||
['PENDING'],
|
||||
];
|
||||
}
|
||||
}
|
33
tests/PHPUnit/ApiClient/Entity/AuthorizationTest.php
Normal file
33
tests/PHPUnit/ApiClient/Entity/AuthorizationTest.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
|
||||
class AuthorizationTest extends TestCase
|
||||
{
|
||||
public function testIdAndStatus()
|
||||
{
|
||||
$authorizationStatus = \Mockery::mock(AuthorizationStatus::class);
|
||||
$testee = new Authorization('foo', $authorizationStatus);
|
||||
|
||||
$this->assertEquals('foo', $testee->id());
|
||||
$this->assertEquals($authorizationStatus, $testee->status());
|
||||
}
|
||||
|
||||
public function testToArray()
|
||||
{
|
||||
$authorizationStatus = \Mockery::mock(AuthorizationStatus::class);
|
||||
$authorizationStatus->expects('name')->andReturn('CAPTURED');
|
||||
|
||||
$testee = new Authorization('foo', $authorizationStatus);
|
||||
|
||||
$expected = [
|
||||
'id' => 'foo',
|
||||
'status' => 'CAPTURED',
|
||||
];
|
||||
$this->assertEquals($expected, $testee->toArray());
|
||||
}
|
||||
}
|
84
tests/PHPUnit/ApiClient/Entity/ItemTest.php
Normal file
84
tests/PHPUnit/ApiClient/Entity/ItemTest.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class ItemTest extends TestCase
|
||||
{
|
||||
|
||||
public function test()
|
||||
{
|
||||
$unitAmount = Mockery::mock(Money::class);
|
||||
$tax = Mockery::mock(Money::class);
|
||||
$testee = new Item(
|
||||
'name',
|
||||
$unitAmount,
|
||||
1,
|
||||
'description',
|
||||
$tax,
|
||||
'sku',
|
||||
'PHYSICAL_GOODS'
|
||||
);
|
||||
|
||||
$this->assertEquals('name', $testee->name());
|
||||
$this->assertEquals($unitAmount, $testee->unitAmount());
|
||||
$this->assertEquals(1, $testee->quantity());
|
||||
$this->assertEquals('description', $testee->description());
|
||||
$this->assertEquals($tax, $testee->tax());
|
||||
$this->assertEquals('sku', $testee->sku());
|
||||
$this->assertEquals('PHYSICAL_GOODS', $testee->category());
|
||||
}
|
||||
|
||||
public function testDigitalGoodsCategory()
|
||||
{
|
||||
$unitAmount = Mockery::mock(Money::class);
|
||||
$tax = Mockery::mock(Money::class);
|
||||
$testee = new Item(
|
||||
'name',
|
||||
$unitAmount,
|
||||
1,
|
||||
'description',
|
||||
$tax,
|
||||
'sku',
|
||||
'DIGITAL_GOODS'
|
||||
);
|
||||
|
||||
$this->assertEquals('DIGITAL_GOODS', $testee->category());
|
||||
}
|
||||
|
||||
public function testToArray()
|
||||
{
|
||||
$unitAmount = Mockery::mock(Money::class);
|
||||
$unitAmount
|
||||
->expects('toArray')
|
||||
->andReturn([1]);
|
||||
$tax = Mockery::mock(Money::class);
|
||||
$tax
|
||||
->expects('toArray')
|
||||
->andReturn([2]);
|
||||
$testee = new Item(
|
||||
'name',
|
||||
$unitAmount,
|
||||
1,
|
||||
'description',
|
||||
$tax,
|
||||
'sku',
|
||||
'PHYSICAL_GOODS'
|
||||
);
|
||||
|
||||
$expected = [
|
||||
'name' => 'name',
|
||||
'unit_amount' => [1],
|
||||
'quantity' => 1,
|
||||
'description' => 'description',
|
||||
'sku' => 'sku',
|
||||
'category' => 'PHYSICAL_GOODS',
|
||||
'tax' => [2],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $testee->toArray());
|
||||
}
|
||||
}
|
23
tests/PHPUnit/ApiClient/Entity/MoneyTest.php
Normal file
23
tests/PHPUnit/ApiClient/Entity/MoneyTest.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
|
||||
class MoneyTest extends TestCase
|
||||
{
|
||||
|
||||
public function test()
|
||||
{
|
||||
$testee = new Money(1.10, 'currencyCode');
|
||||
$this->assertEquals(1.10, $testee->value());
|
||||
$this->assertEquals('currencyCode', $testee->currencyCode());
|
||||
|
||||
$expected = [
|
||||
'currency_code' => 'currencyCode',
|
||||
'value' => 1.10,
|
||||
];
|
||||
$this->assertEquals($expected, $testee->toArray());
|
||||
}
|
||||
}
|
202
tests/PHPUnit/ApiClient/Entity/PayerTest.php
Normal file
202
tests/PHPUnit/ApiClient/Entity/PayerTest.php
Normal file
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class PayerTest extends TestCase
|
||||
{
|
||||
|
||||
public function testPayer()
|
||||
{
|
||||
$birthday = new \DateTime();
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->expects('toArray')
|
||||
->andReturn(['address']);
|
||||
$phone = Mockery::mock(PhoneWithType::class);
|
||||
$phone
|
||||
->expects('toArray')
|
||||
->andReturn(['phone']);
|
||||
$taxInfo = Mockery::mock(PayerTaxInfo::class);
|
||||
$taxInfo
|
||||
->expects('toArray')
|
||||
->andReturn(['taxInfo']);
|
||||
$payerName = Mockery::mock(PayerName::class);
|
||||
$payerName
|
||||
->expects('toArray')
|
||||
->andReturn(['payerName']);
|
||||
$email = 'email@example.com';
|
||||
$payerId = 'payerId';
|
||||
$payer = new Payer(
|
||||
$payerName,
|
||||
$email,
|
||||
$payerId,
|
||||
$address,
|
||||
$birthday,
|
||||
$phone,
|
||||
$taxInfo
|
||||
);
|
||||
|
||||
$this->assertEquals($payerName, $payer->name());
|
||||
$this->assertEquals($email, $payer->emailAddress());
|
||||
$this->assertEquals($payerId, $payer->payerId());
|
||||
$this->assertEquals($address, $payer->address());
|
||||
$this->assertEquals($birthday, $payer->birthDate());
|
||||
$this->assertEquals($phone, $payer->phone());
|
||||
$this->assertEquals($taxInfo, $payer->taxInfo());
|
||||
|
||||
$array = $payer->toArray();
|
||||
$this->assertEquals($birthday->format('Y-m-d'), $array['birth_date']);
|
||||
$this->assertEquals(['payerName'], $array['name']);
|
||||
$this->assertEquals($email, $array['email_address']);
|
||||
$this->assertEquals(['address'], $array['address']);
|
||||
$this->assertEquals($payerId, $array['payer_id']);
|
||||
$this->assertEquals(['phone'], $array['phone']);
|
||||
$this->assertEquals(['taxInfo'], $array['tax_info']);
|
||||
}
|
||||
|
||||
public function testPayerNoId()
|
||||
{
|
||||
$birthday = new \DateTime();
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->expects('toArray')
|
||||
->andReturn(['address']);
|
||||
$phone = Mockery::mock(PhoneWithType::class);
|
||||
$phone
|
||||
->expects('toArray')
|
||||
->andReturn(['phone']);
|
||||
$taxInfo = Mockery::mock(PayerTaxInfo::class);
|
||||
$taxInfo
|
||||
->expects('toArray')
|
||||
->andReturn(['taxInfo']);
|
||||
$payerName = Mockery::mock(PayerName::class);
|
||||
$payerName
|
||||
->expects('toArray')
|
||||
->andReturn(['payerName']);
|
||||
$email = 'email@example.com';
|
||||
$payerId = '';
|
||||
$payer = new Payer(
|
||||
$payerName,
|
||||
$email,
|
||||
$payerId,
|
||||
$address,
|
||||
$birthday,
|
||||
$phone,
|
||||
$taxInfo
|
||||
);
|
||||
|
||||
$this->assertEquals($payerId, $payer->payerId());
|
||||
|
||||
$array = $payer->toArray();
|
||||
$this->assertArrayNotHasKey('payer_id', $array);
|
||||
}
|
||||
|
||||
public function testPayerNoPhone()
|
||||
{
|
||||
$birthday = new \DateTime();
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->expects('toArray')
|
||||
->andReturn(['address']);
|
||||
$phone = null;
|
||||
$taxInfo = Mockery::mock(PayerTaxInfo::class);
|
||||
$taxInfo
|
||||
->expects('toArray')
|
||||
->andReturn(['taxInfo']);
|
||||
$payerName = Mockery::mock(PayerName::class);
|
||||
$payerName
|
||||
->expects('toArray')
|
||||
->andReturn(['payerName']);
|
||||
$email = 'email@example.com';
|
||||
$payerId = 'payerId';
|
||||
$payer = new Payer(
|
||||
$payerName,
|
||||
$email,
|
||||
$payerId,
|
||||
$address,
|
||||
$birthday,
|
||||
$phone,
|
||||
$taxInfo
|
||||
);
|
||||
|
||||
$this->assertEquals($phone, $payer->phone());
|
||||
|
||||
$array = $payer->toArray();
|
||||
$this->assertArrayNotHasKey('phone', $array);
|
||||
}
|
||||
|
||||
public function testPayerNoTaxInfo()
|
||||
{
|
||||
$birthday = new \DateTime();
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->expects('toArray')
|
||||
->andReturn(['address']);
|
||||
$phone = Mockery::mock(PhoneWithType::class);
|
||||
$phone
|
||||
->expects('toArray')
|
||||
->andReturn(['phone']);
|
||||
$taxInfo = null;
|
||||
$payerName = Mockery::mock(PayerName::class);
|
||||
$payerName
|
||||
->expects('toArray')
|
||||
->andReturn(['payerName']);
|
||||
$email = 'email@example.com';
|
||||
$payerId = 'payerId';
|
||||
$payer = new Payer(
|
||||
$payerName,
|
||||
$email,
|
||||
$payerId,
|
||||
$address,
|
||||
$birthday,
|
||||
$phone,
|
||||
$taxInfo
|
||||
);
|
||||
|
||||
$this->assertEquals($taxInfo, $payer->taxInfo());
|
||||
|
||||
$array = $payer->toArray();
|
||||
$this->assertArrayNotHasKey('tax_info', $array);
|
||||
}
|
||||
|
||||
public function testPayerNoBirthDate()
|
||||
{
|
||||
$birthday = null;
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->expects('toArray')
|
||||
->andReturn(['address']);
|
||||
$phone = Mockery::mock(PhoneWithType::class);
|
||||
$phone
|
||||
->expects('toArray')
|
||||
->andReturn(['phone']);
|
||||
$taxInfo = Mockery::mock(PayerTaxInfo::class);
|
||||
$taxInfo
|
||||
->expects('toArray')
|
||||
->andReturn(['taxInfo']);
|
||||
$payerName = Mockery::mock(PayerName::class);
|
||||
$payerName
|
||||
->expects('toArray')
|
||||
->andReturn(['payerName']);
|
||||
$email = 'email@example.com';
|
||||
$payerId = 'payerId';
|
||||
$payer = new Payer(
|
||||
$payerName,
|
||||
$email,
|
||||
$payerId,
|
||||
$address,
|
||||
$birthday,
|
||||
$phone,
|
||||
$taxInfo
|
||||
);
|
||||
|
||||
$this->assertEquals($birthday, $payer->birthDate());
|
||||
|
||||
$array = $payer->toArray();
|
||||
$this->assertArrayNotHasKey('birth_date', $array);
|
||||
}
|
||||
}
|
46
tests/PHPUnit/ApiClient/Entity/PaymentsTest.php
Normal file
46
tests/PHPUnit/ApiClient/Entity/PaymentsTest.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
|
||||
class PaymentsTest extends TestCase
|
||||
{
|
||||
public function testAuthorizations()
|
||||
{
|
||||
$authorization = \Mockery::mock(Authorization::class);
|
||||
$authorizations = [$authorization];
|
||||
|
||||
$testee = new Payments(...$authorizations);
|
||||
|
||||
$this->assertEquals($authorizations, $testee->authorizations());
|
||||
}
|
||||
|
||||
public function testToArray()
|
||||
{
|
||||
$authorization = \Mockery::mock(Authorization::class);
|
||||
$authorization->shouldReceive('toArray')->andReturn(
|
||||
[
|
||||
'id' => 'foo',
|
||||
'status' => 'CREATED',
|
||||
]
|
||||
);
|
||||
$authorizations = [$authorization];
|
||||
|
||||
$testee = new Payments(...$authorizations);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'authorizations' => [
|
||||
[
|
||||
'id' => 'foo',
|
||||
'status' => 'CREATED',
|
||||
],
|
||||
],
|
||||
],
|
||||
$testee->toArray()
|
||||
);
|
||||
}
|
||||
}
|
502
tests/PHPUnit/ApiClient/Entity/PurchaseUnitTest.php
Normal file
502
tests/PHPUnit/ApiClient/Entity/PurchaseUnitTest.php
Normal file
|
@ -0,0 +1,502 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class PurchaseUnitTest extends TestCase
|
||||
{
|
||||
|
||||
public function test()
|
||||
{
|
||||
|
||||
$amount = Mockery::mock(
|
||||
Amount::class,
|
||||
[
|
||||
'breakdown' => null,
|
||||
'toArray' => ['amount'],
|
||||
]
|
||||
);
|
||||
|
||||
$item1 = Mockery::mock(
|
||||
Item::class,
|
||||
[
|
||||
'toArray' => ['item1'],
|
||||
'category' => Item::DIGITAL_GOODS,
|
||||
]
|
||||
);
|
||||
|
||||
$item2 = Mockery::mock(
|
||||
Item::class,
|
||||
[
|
||||
'toArray' => ['item2'],
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
]
|
||||
);
|
||||
|
||||
$shipping = Mockery::mock(Shipping::class, ['toArray' => ['shipping']]);
|
||||
|
||||
$testee = new PurchaseUnit(
|
||||
$amount,
|
||||
[$item1, $item2],
|
||||
$shipping,
|
||||
'referenceId',
|
||||
'description',
|
||||
null,
|
||||
'customId',
|
||||
'invoiceId',
|
||||
'softDescriptor'
|
||||
);
|
||||
|
||||
$this->assertEquals($amount, $testee->amount());
|
||||
$this->assertEquals('referenceId', $testee->referenceId());
|
||||
$this->assertEquals('description', $testee->description());
|
||||
$this->assertNull($testee->payee());
|
||||
$this->assertEquals('customId', $testee->customId());
|
||||
$this->assertEquals('invoiceId', $testee->invoiceId());
|
||||
$this->assertEquals('softDescriptor', $testee->softDescriptor());
|
||||
$this->assertEquals($shipping, $testee->shipping());
|
||||
$this->assertEquals([$item1, $item2], $testee->items());
|
||||
self::assertTrue($testee->containsPhysicalGoodsItems());
|
||||
|
||||
$expected = [
|
||||
'reference_id' => 'referenceId',
|
||||
'amount' => ['amount'],
|
||||
'description' => 'description',
|
||||
'items' => [['item1'], ['item2']],
|
||||
'shipping' => ['shipping'],
|
||||
'custom_id' => 'customId',
|
||||
'invoice_id' => 'invoiceId',
|
||||
'soft_descriptor' => 'softDescriptor',
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $testee->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForDitchTests
|
||||
* @param array $items
|
||||
* @param Amount $amount
|
||||
* @param bool $doDitch
|
||||
*/
|
||||
public function testDitchMethod(array $items, Amount $amount, bool $doDitch, string $message)
|
||||
{
|
||||
$testee = new PurchaseUnit(
|
||||
$amount,
|
||||
$items
|
||||
);
|
||||
|
||||
$array = $testee->toArray();
|
||||
$resultItems = $doDitch === ! array_key_exists('items', $array);
|
||||
$resultBreakdown = $doDitch === ! array_key_exists('breakdown', $array['amount']);
|
||||
$this->assertTrue($resultItems, $message);
|
||||
$this->assertTrue($resultBreakdown, $message);
|
||||
}
|
||||
|
||||
public function dataForDitchTests() : array
|
||||
{
|
||||
$data = [
|
||||
'default' => [
|
||||
'message' => 'Items should not be ditched.',
|
||||
'ditch' => false,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 26,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'dont_ditch_with_discount' => [
|
||||
'message' => 'Items should not be ditched.',
|
||||
'ditch' => false,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 23,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => 3,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_with_discount' => [
|
||||
'message' => 'Items should be ditched because of discount.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 25,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => 3,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'dont_ditch_with_shipping_discount' => [
|
||||
'message' => 'Items should not be ditched.',
|
||||
'ditch' => false,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 23,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => 3,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_with_handling' => [
|
||||
'message' => 'Items should be ditched because of handling.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 26,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => 3,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'dont_ditch_with_handling' => [
|
||||
'message' => 'Items should not be ditched.',
|
||||
'ditch' => false,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 29,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => 3,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_with_insurance' => [
|
||||
'message' => 'Items should be ditched because of insurance.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 26,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => 3,
|
||||
],
|
||||
],
|
||||
'dont_ditch_with_insurance' => [
|
||||
'message' => 'Items should not be ditched.',
|
||||
'ditch' => false,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 29,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => 3,
|
||||
],
|
||||
],
|
||||
'ditch_with_shipping_discount' => [
|
||||
'message' => 'Items should be ditched because of shipping discount.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 25,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => 3,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'dont_ditch_with_shipping' => [
|
||||
'message' => 'Items should not be ditched.',
|
||||
'ditch' => false,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 29,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => 3,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_because_shipping' => [
|
||||
'message' => 'Items should be ditched because of shipping.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 28,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => 3,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_items_total' => [
|
||||
'message' => 'Items should be ditched because the item total does not add up.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 26,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 11,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_tax_total' => [
|
||||
'message' => 'Items should be ditched because the tax total does not add up.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 26,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 5,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
'ditch_total_amount' => [
|
||||
'message' => 'Items should be ditched because the total amount is way out of order.',
|
||||
'ditch' => true,
|
||||
'items' => [
|
||||
[
|
||||
'value' => 10,
|
||||
'quantity' => 2,
|
||||
'tax' => 3,
|
||||
'category' => Item::PHYSICAL_GOODS,
|
||||
],
|
||||
],
|
||||
'amount' => 260,
|
||||
'breakdown' => [
|
||||
'itemTotal' => 20,
|
||||
'taxTotal' => 6,
|
||||
'shipping' => null,
|
||||
'discount' => null,
|
||||
'shippingDiscount' => null,
|
||||
'handling' => null,
|
||||
'insurance' => null,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$values = [];
|
||||
foreach ($data as $testKey => $test) {
|
||||
$items = [];
|
||||
foreach ($test['items'] as $key => $item) {
|
||||
$unitAmount = Mockery::mock(Money::class);
|
||||
$unitAmount->shouldReceive('value')->andReturn($item['value']);
|
||||
$tax = Mockery::mock(Money::class);
|
||||
$tax->shouldReceive('value')->andReturn($item['tax']);
|
||||
$items[$key] = Mockery::mock(
|
||||
Item::class,
|
||||
[
|
||||
'unitAmount' => $unitAmount,
|
||||
'tax' => $tax,
|
||||
'quantity'=> $item['quantity'],
|
||||
'category' => $item['category'],
|
||||
'toArray' => [],
|
||||
]
|
||||
);
|
||||
}
|
||||
$breakdown = null;
|
||||
if ($test['breakdown']) {
|
||||
$breakdown = Mockery::mock(AmountBreakdown::class);
|
||||
foreach ($test['breakdown'] as $method => $value) {
|
||||
$breakdown->shouldReceive($method)->andReturnUsing(function () use ($value) {
|
||||
if (! is_numeric($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$money = Mockery::mock(Money::class);
|
||||
$money->shouldReceive('value')->andReturn($value);
|
||||
return $money;
|
||||
});
|
||||
}
|
||||
}
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amount->shouldReceive('toArray')->andReturn(['value' => [], 'breakdown' => []]);
|
||||
$amount->shouldReceive('value')->andReturn($test['amount']);
|
||||
$amount->shouldReceive('breakdown')->andReturn($breakdown);
|
||||
|
||||
$values[$testKey] = [
|
||||
$items,
|
||||
$amount,
|
||||
$test['ditch'],
|
||||
$test['message'],
|
||||
];
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
public function testPayee()
|
||||
{
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amount->shouldReceive('breakdown')->andReturnNull();
|
||||
$amount->shouldReceive('toArray')->andReturn(['amount']);
|
||||
$item1 = Mockery::mock(Item::class);
|
||||
$item1->shouldReceive('toArray')->andReturn(['item1']);
|
||||
$item2 = Mockery::mock(Item::class);
|
||||
$item2->shouldReceive('toArray')->andReturn(['item2']);
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping->shouldReceive('toArray')->andReturn(['shipping']);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payee->shouldReceive('toArray')->andReturn(['payee']);
|
||||
$testee = new PurchaseUnit(
|
||||
$amount,
|
||||
[],
|
||||
$shipping,
|
||||
'referenceId',
|
||||
'description',
|
||||
$payee,
|
||||
'customId',
|
||||
'invoiceId',
|
||||
'softDescriptor'
|
||||
);
|
||||
|
||||
$this->assertEquals($payee, $testee->payee());
|
||||
|
||||
$expected = [
|
||||
'reference_id' => 'referenceId',
|
||||
'amount' => ['amount'],
|
||||
'description' => 'description',
|
||||
'items' => [],
|
||||
'shipping' => ['shipping'],
|
||||
'custom_id' => 'customId',
|
||||
'invoice_id' => 'invoiceId',
|
||||
'soft_descriptor' => 'softDescriptor',
|
||||
'payee' => ['payee'],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $testee->toArray());
|
||||
}
|
||||
}
|
137
tests/PHPUnit/ApiClient/Entity/TokenTest.php
Normal file
137
tests/PHPUnit/ApiClient/Entity/TokenTest.php
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
|
||||
class TokenTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestDefault
|
||||
* @param \stdClass $data
|
||||
*/
|
||||
public function testDefault(\stdClass $data)
|
||||
{
|
||||
$token = new Token($data);
|
||||
$this->assertEquals($data->token, $token->token());
|
||||
$this->assertTrue($token->isValid());
|
||||
}
|
||||
|
||||
public function dataForTestDefault() : array
|
||||
{
|
||||
return [
|
||||
'default' => [
|
||||
(object)[
|
||||
'created' => time(),
|
||||
'expires_in' => 100,
|
||||
'token' => 'abc',
|
||||
],
|
||||
],
|
||||
'created_not_needed' => [
|
||||
(object)[
|
||||
'expires_in' => 100,
|
||||
'token' => 'abc',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testIsValid()
|
||||
{
|
||||
$data = (object) [
|
||||
'created' => time() - 100,
|
||||
'expires_in' => 99,
|
||||
'token' => 'abc',
|
||||
];
|
||||
|
||||
$token = new Token($data);
|
||||
$this->assertFalse($token->isValid());
|
||||
}
|
||||
|
||||
public function testFromBearerJson()
|
||||
{
|
||||
$data = json_encode([
|
||||
'expires_in' => 100,
|
||||
'access_token' => 'abc',
|
||||
]);
|
||||
|
||||
$token = Token::fromJson($data);
|
||||
$this->assertEquals('abc', $token->token());
|
||||
$this->assertTrue($token->isValid());
|
||||
}
|
||||
|
||||
public function testFromIdentityJson()
|
||||
{
|
||||
$data = json_encode([
|
||||
'expires_in' => 100,
|
||||
'client_token' => 'abc',
|
||||
]);
|
||||
|
||||
$token = Token::fromJson($data);
|
||||
$this->assertEquals('abc', $token->token());
|
||||
$this->assertTrue($token->isValid());
|
||||
}
|
||||
|
||||
public function testAsJson()
|
||||
{
|
||||
$data = (object) [
|
||||
'created' => 100,
|
||||
'expires_in' => 100,
|
||||
'token' => 'abc',
|
||||
];
|
||||
|
||||
$token = new Token($data);
|
||||
$json = json_decode($token->asJson());
|
||||
$this->assertEquals($data->token, $json->token);
|
||||
$this->assertEquals($data->created, $json->created);
|
||||
$this->assertEquals($data->expires_in, $json->expires_in);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestExceptions
|
||||
* @param \stdClass $data
|
||||
*/
|
||||
public function testExceptions(\stdClass $data)
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
new Token($data);
|
||||
}
|
||||
|
||||
public function dataForTestExceptions() : array
|
||||
{
|
||||
return [
|
||||
'created_is_not_integer' => [
|
||||
(object) [
|
||||
'created' => 'abc',
|
||||
'expires_in' => 123,
|
||||
'token' => 'abc',
|
||||
],
|
||||
],
|
||||
'expires_in_is_not_integer' => [
|
||||
(object) [
|
||||
'expires_in' => 'abc',
|
||||
'token' => 'abc',
|
||||
],
|
||||
],
|
||||
'access_token_is_not_string' => [
|
||||
(object) [
|
||||
'expires_in' => 123,
|
||||
'token' => ['abc'],
|
||||
],
|
||||
],
|
||||
'access_token_does_not_exist' => [
|
||||
(object) [
|
||||
'expires_in' => 123,
|
||||
],
|
||||
],
|
||||
'expires_in_does_not_exist' => [
|
||||
(object) [
|
||||
'token' => 'abc',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
205
tests/PHPUnit/ApiClient/Factory/AddressFactoryTest.php
Normal file
205
tests/PHPUnit/ApiClient/Factory/AddressFactoryTest.php
Normal file
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class AddressFactoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testFromWcCustomer()
|
||||
{
|
||||
$testee = new AddressFactory();
|
||||
$customer = Mockery::mock(\WC_Customer::class);
|
||||
$customer
|
||||
->expects('get_shipping_country')
|
||||
->andReturn('shipping_country');
|
||||
$customer
|
||||
->expects('get_shipping_address_1')
|
||||
->andReturn('shipping_address_1');
|
||||
$customer
|
||||
->expects('get_shipping_address_2')
|
||||
->andReturn('shipping_address_2');
|
||||
$customer
|
||||
->expects('get_shipping_state')
|
||||
->andReturn('shipping_state');
|
||||
$customer
|
||||
->expects('get_shipping_city')
|
||||
->andReturn('shipping_city');
|
||||
$customer
|
||||
->expects('get_shipping_postcode')
|
||||
->andReturn('shipping_postcode');
|
||||
|
||||
$result = $testee->fromWcCustomer($customer);
|
||||
$this->assertEquals('shipping_country', $result->countryCode());
|
||||
$this->assertEquals('shipping_address_1', $result->addressLine1());
|
||||
$this->assertEquals('shipping_address_2', $result->addressLine2());
|
||||
$this->assertEquals('shipping_state', $result->adminArea1());
|
||||
$this->assertEquals('shipping_city', $result->adminArea2());
|
||||
$this->assertEquals('shipping_postcode', $result->postalCode());
|
||||
}
|
||||
|
||||
public function testFromWcCustomersBillingAddress()
|
||||
{
|
||||
$testee = new AddressFactory();
|
||||
$customer = Mockery::mock(\WC_Customer::class);
|
||||
$customer
|
||||
->expects('get_billing_country')
|
||||
->andReturn('billing_country');
|
||||
$customer
|
||||
->expects('get_billing_address_1')
|
||||
->andReturn('billing_address_1');
|
||||
$customer
|
||||
->expects('get_billing_address_2')
|
||||
->andReturn('billing_address_2');
|
||||
$customer
|
||||
->expects('get_billing_state')
|
||||
->andReturn('billing_state');
|
||||
$customer
|
||||
->expects('get_billing_city')
|
||||
->andReturn('billing_city');
|
||||
$customer
|
||||
->expects('get_billing_postcode')
|
||||
->andReturn('billing_postcode');
|
||||
|
||||
$result = $testee->fromWcCustomer($customer, 'billing');
|
||||
$this->assertEquals('billing_country', $result->countryCode());
|
||||
$this->assertEquals('billing_address_1', $result->addressLine1());
|
||||
$this->assertEquals('billing_address_2', $result->addressLine2());
|
||||
$this->assertEquals('billing_state', $result->adminArea1());
|
||||
$this->assertEquals('billing_city', $result->adminArea2());
|
||||
$this->assertEquals('billing_postcode', $result->postalCode());
|
||||
}
|
||||
|
||||
public function testFromWcOrder()
|
||||
{
|
||||
$testee = new AddressFactory();
|
||||
$order = Mockery::mock(\WC_Order::class);
|
||||
$order
|
||||
->expects('get_shipping_country')
|
||||
->andReturn('shipping_country');
|
||||
$order
|
||||
->expects('get_shipping_address_1')
|
||||
->andReturn('shipping_address_1');
|
||||
$order
|
||||
->expects('get_shipping_address_2')
|
||||
->andReturn('shipping_address_2');
|
||||
$order
|
||||
->expects('get_shipping_state')
|
||||
->andReturn('shipping_state');
|
||||
$order
|
||||
->expects('get_shipping_city')
|
||||
->andReturn('shipping_city');
|
||||
$order
|
||||
->expects('get_shipping_postcode')
|
||||
->andReturn('shipping_postcode');
|
||||
|
||||
$result = $testee->fromWcOrder($order);
|
||||
$this->assertEquals('shipping_country', $result->countryCode());
|
||||
$this->assertEquals('shipping_address_1', $result->addressLine1());
|
||||
$this->assertEquals('shipping_address_2', $result->addressLine2());
|
||||
$this->assertEquals('shipping_state', $result->adminArea1());
|
||||
$this->assertEquals('shipping_city', $result->adminArea2());
|
||||
$this->assertEquals('shipping_postcode', $result->postalCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataFromPayPalRequest
|
||||
*/
|
||||
public function testFromPayPalRequest($data)
|
||||
{
|
||||
$testee = new AddressFactory();
|
||||
|
||||
$result = $testee->fromPayPalRequest($data);
|
||||
$expectedAddressLine1 = (isset($data->address_line_1)) ? $data->address_line_1 : '';
|
||||
$expectedAddressLine2 = (isset($data->address_line_2)) ? $data->address_line_2 : '';
|
||||
$expectedAdminArea1 = (isset($data->admin_area_1)) ? $data->admin_area_1 : '';
|
||||
$expectedAdminArea2 = (isset($data->admin_area_2)) ? $data->admin_area_2 : '';
|
||||
$expectedPostalCode = (isset($data->postal_code)) ? $data->postal_code : '';
|
||||
$this->assertEquals($data->country_code, $result->countryCode());
|
||||
$this->assertEquals($expectedAddressLine1, $result->addressLine1());
|
||||
$this->assertEquals($expectedAddressLine2, $result->addressLine2());
|
||||
$this->assertEquals($expectedAdminArea1, $result->adminArea1());
|
||||
$this->assertEquals($expectedAdminArea2, $result->adminArea2());
|
||||
$this->assertEquals($expectedPostalCode, $result->postalCode());
|
||||
}
|
||||
|
||||
public function testFromPayPalRequestThrowsError()
|
||||
{
|
||||
$testee = new AddressFactory();
|
||||
|
||||
$data = (object) [
|
||||
'address_line_1' => 'shipping_address_1',
|
||||
'address_line_2' => 'shipping_address_2',
|
||||
'admin_area_1' => 'shipping_admin_area_1',
|
||||
'admin_area_2' => 'shipping_admin_area_2',
|
||||
'postal_code' => 'shipping_postcode',
|
||||
];
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->fromPayPalRequest($data);
|
||||
}
|
||||
|
||||
public function dataFromPayPalRequest() : array
|
||||
{
|
||||
return [
|
||||
'default' => [
|
||||
(object) [
|
||||
'country_code' => 'shipping_country',
|
||||
'address_line_1' => 'shipping_address_1',
|
||||
'address_line_2' => 'shipping_address_2',
|
||||
'admin_area_1' => 'shipping_admin_area_1',
|
||||
'admin_area_2' => 'shipping_admin_area_2',
|
||||
'postal_code' => 'shipping_postcode',
|
||||
],
|
||||
],
|
||||
'no_admin_area_2' => [
|
||||
(object) [
|
||||
'country_code' => 'shipping_country',
|
||||
'address_line_1' => 'shipping_address_1',
|
||||
'address_line_2' => 'shipping_address_2',
|
||||
'admin_area_1' => 'shipping_admin_area_1',
|
||||
'postal_code' => 'shipping_postcode',
|
||||
],
|
||||
],
|
||||
'no_postal_code' => [
|
||||
(object) [
|
||||
'country_code' => 'shipping_country',
|
||||
'address_line_1' => 'shipping_address_1',
|
||||
'address_line_2' => 'shipping_address_2',
|
||||
'admin_area_1' => 'shipping_admin_area_1',
|
||||
'admin_area_2' => 'shipping_admin_area_2',
|
||||
],
|
||||
],
|
||||
'no_admin_area_1' => [
|
||||
(object) [
|
||||
'country_code' => 'shipping_country',
|
||||
'address_line_1' => 'shipping_address_1',
|
||||
'address_line_2' => 'shipping_address_2',
|
||||
'admin_area_2' => 'shipping_admin_area_2',
|
||||
'postal_code' => 'shipping_postcode',
|
||||
],
|
||||
],
|
||||
'no_address_line_1' => [
|
||||
(object) [
|
||||
'country_code' => 'shipping_country',
|
||||
'address_line_2' => 'shipping_address_2',
|
||||
'admin_area_1' => 'shipping_admin_area_1',
|
||||
'admin_area_2' => 'shipping_admin_area_2',
|
||||
'postal_code' => 'shipping_postcode',
|
||||
],
|
||||
],
|
||||
'no_address_line_2' => [
|
||||
(object) [
|
||||
'country_code' => 'shipping_country',
|
||||
'address_line_1' => 'shipping_address_1',
|
||||
'admin_area_1' => 'shipping_admin_area_1',
|
||||
'admin_area_2' => 'shipping_admin_area_2',
|
||||
'postal_code' => 'shipping_postcode',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
581
tests/PHPUnit/ApiClient/Factory/AmountFactoryTest.php
Normal file
581
tests/PHPUnit/ApiClient/Factory/AmountFactoryTest.php
Normal file
|
@ -0,0 +1,581 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Amount;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
use function Brain\Monkey\Functions\expect;
|
||||
|
||||
class AmountFactoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testFromWcCartDefault()
|
||||
{
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$testee = new AmountFactory($itemFactory);
|
||||
|
||||
$expectedCurrency = 'EUR';
|
||||
$cart = Mockery::mock(\WC_Cart::class);
|
||||
$cart
|
||||
->shouldReceive('get_total')
|
||||
->withAnyArgs()
|
||||
->andReturn(1);
|
||||
$cart
|
||||
->shouldReceive('get_cart_contents_total')
|
||||
->andReturn(2);
|
||||
$cart
|
||||
->shouldReceive('get_discount_total')
|
||||
->andReturn(3);
|
||||
$cart
|
||||
->shouldReceive('get_shipping_total')
|
||||
->andReturn(4);
|
||||
$cart
|
||||
->shouldReceive('get_shipping_tax')
|
||||
->andReturn(5);
|
||||
$cart
|
||||
->shouldReceive('get_cart_contents_tax')
|
||||
->andReturn(6);
|
||||
$cart
|
||||
->shouldReceive('get_discount_tax')
|
||||
->andReturn(7);
|
||||
|
||||
expect('get_woocommerce_currency')->andReturn($expectedCurrency);
|
||||
$result = $testee->fromWcCart($cart);
|
||||
$this->assertEquals($expectedCurrency, $result->currencyCode());
|
||||
$this->assertEquals((float) 1, $result->value());
|
||||
$this->assertEquals((float) 10, $result->breakdown()->discount()->value());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->discount()->currencyCode());
|
||||
$this->assertEquals((float) 9, $result->breakdown()->shipping()->value());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->shipping()->currencyCode());
|
||||
$this->assertEquals((float) 5, $result->breakdown()->itemTotal()->value());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->itemTotal()->currencyCode());
|
||||
$this->assertEquals((float) 13, $result->breakdown()->taxTotal()->value());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->taxTotal()->currencyCode());
|
||||
}
|
||||
|
||||
public function testFromWcCartNoDiscount()
|
||||
{
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$testee = new AmountFactory($itemFactory);
|
||||
|
||||
$expectedCurrency = 'EUR';
|
||||
$expectedTotal = 1;
|
||||
$cart = Mockery::mock(\WC_Cart::class);
|
||||
$cart
|
||||
->shouldReceive('get_total')
|
||||
->withAnyArgs()
|
||||
->andReturn($expectedTotal);
|
||||
$cart
|
||||
->shouldReceive('get_cart_contents_total')
|
||||
->andReturn(2);
|
||||
$cart
|
||||
->shouldReceive('get_discount_total')
|
||||
->andReturn(0);
|
||||
$cart
|
||||
->shouldReceive('get_shipping_total')
|
||||
->andReturn(4);
|
||||
$cart
|
||||
->shouldReceive('get_shipping_tax')
|
||||
->andReturn(5);
|
||||
$cart
|
||||
->shouldReceive('get_cart_contents_tax')
|
||||
->andReturn(6);
|
||||
$cart
|
||||
->shouldReceive('get_discount_tax')
|
||||
->andReturn(0);
|
||||
|
||||
expect('get_woocommerce_currency')->andReturn($expectedCurrency);
|
||||
$result = $testee->fromWcCart($cart);
|
||||
$this->assertNull($result->breakdown()->discount());
|
||||
}
|
||||
|
||||
public function testFromWcOrderDefault()
|
||||
{
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$order = Mockery::mock(\WC_Order::class);
|
||||
$unitAmount = Mockery::mock(Money::class);
|
||||
$unitAmount
|
||||
->shouldReceive('value')
|
||||
->andReturn(3);
|
||||
$tax = Mockery::mock(Money::class);
|
||||
$tax
|
||||
->shouldReceive('value')
|
||||
->andReturn(1);
|
||||
$item = Mockery::mock(Item::class);
|
||||
$item
|
||||
->shouldReceive('quantity')
|
||||
->andReturn(2);
|
||||
$item
|
||||
->shouldReceive('unitAmount')
|
||||
->andReturn($unitAmount);
|
||||
$item
|
||||
->shouldReceive('tax')
|
||||
->andReturn($tax);
|
||||
$itemFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($order)
|
||||
->andReturn([$item]);
|
||||
$testee = new AmountFactory($itemFactory);
|
||||
|
||||
$expectedCurrency = 'EUR';
|
||||
$order
|
||||
->shouldReceive('get_total')
|
||||
->andReturn(100);
|
||||
$order
|
||||
->shouldReceive('get_currency')
|
||||
->andReturn($expectedCurrency);
|
||||
$order
|
||||
->shouldReceive('get_shipping_total')
|
||||
->andReturn(1);
|
||||
$order
|
||||
->shouldReceive('get_shipping_tax')
|
||||
->andReturn(.5);
|
||||
$order
|
||||
->shouldReceive('get_total_discount')
|
||||
->with(false)
|
||||
->andReturn(3);
|
||||
|
||||
$result = $testee->fromWcOrder($order);
|
||||
$this->assertEquals((float) 3, $result->breakdown()->discount()->value());
|
||||
$this->assertEquals((float) 6, $result->breakdown()->itemTotal()->value());
|
||||
$this->assertEquals((float) 1.5, $result->breakdown()->shipping()->value());
|
||||
$this->assertEquals((float) 100, $result->value());
|
||||
$this->assertEquals((float) 2, $result->breakdown()->taxTotal()->value());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->discount()->currencyCode());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->itemTotal()->currencyCode());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->shipping()->currencyCode());
|
||||
$this->assertEquals($expectedCurrency, $result->breakdown()->taxTotal()->currencyCode());
|
||||
$this->assertEquals($expectedCurrency, $result->currencyCode());
|
||||
}
|
||||
|
||||
public function testFromWcOrderDiscountIsNull()
|
||||
{
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$order = Mockery::mock(\WC_Order::class);
|
||||
$unitAmount = Mockery::mock(Money::class);
|
||||
$unitAmount
|
||||
->shouldReceive('value')
|
||||
->andReturn(3);
|
||||
$tax = Mockery::mock(Money::class);
|
||||
$tax
|
||||
->shouldReceive('value')
|
||||
->andReturn(1);
|
||||
$item = Mockery::mock(Item::class);
|
||||
$item
|
||||
->shouldReceive('quantity')
|
||||
->andReturn(2);
|
||||
$item
|
||||
->shouldReceive('unitAmount')
|
||||
->andReturn($unitAmount);
|
||||
$item
|
||||
->shouldReceive('tax')
|
||||
->andReturn($tax);
|
||||
$itemFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($order)
|
||||
->andReturn([$item]);
|
||||
$testee = new AmountFactory($itemFactory);
|
||||
|
||||
$expectedCurrency = 'EUR';
|
||||
$order
|
||||
->shouldReceive('get_total')
|
||||
->andReturn(100);
|
||||
$order
|
||||
->shouldReceive('get_currency')
|
||||
->andReturn($expectedCurrency);
|
||||
$order
|
||||
->shouldReceive('get_shipping_total')
|
||||
->andReturn(1);
|
||||
$order
|
||||
->shouldReceive('get_shipping_tax')
|
||||
->andReturn(.5);
|
||||
$order
|
||||
->shouldReceive('get_total_discount')
|
||||
->with(false)
|
||||
->andReturn(0);
|
||||
|
||||
$result = $testee->fromWcOrder($order);
|
||||
$this->assertNull($result->breakdown()->discount());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataFromPayPalResponse
|
||||
* @param $response
|
||||
*/
|
||||
public function testFromPayPalResponse($response, $expectsException)
|
||||
{
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$testee = new AmountFactory($itemFactory);
|
||||
if ($expectsException) {
|
||||
$this->expectException(RuntimeException::class);
|
||||
}
|
||||
$result = $testee->fromPayPalResponse($response);
|
||||
if ($expectsException) {
|
||||
return;
|
||||
}
|
||||
$this->assertEquals($response->value, $result->value());
|
||||
$this->assertEquals($response->currency_code, $result->currencyCode());
|
||||
$breakdown = $result->breakdown();
|
||||
if (! isset($response->breakdown)) {
|
||||
$this->assertNull($breakdown);
|
||||
return;
|
||||
}
|
||||
if ($breakdown->shipping()) {
|
||||
$this->assertEquals($response->breakdown->shipping->value, $breakdown->shipping()->value());
|
||||
$this->assertEquals($response->breakdown->shipping->currency_code, $breakdown->shipping()->currencyCode());
|
||||
} else {
|
||||
$this->assertTrue(! isset($response->breakdown->shipping));
|
||||
}
|
||||
if ($breakdown->itemTotal()) {
|
||||
$this->assertEquals($response->breakdown->item_total->value, $breakdown->itemTotal()->value());
|
||||
$this->assertEquals($response->breakdown->item_total->currency_code, $breakdown->itemTotal()->currencyCode());
|
||||
} else {
|
||||
$this->assertTrue(! isset($response->breakdown->item_total));
|
||||
}
|
||||
if ($breakdown->taxTotal()) {
|
||||
$this->assertEquals($response->breakdown->tax_total->value, $breakdown->taxTotal()->value());
|
||||
$this->assertEquals($response->breakdown->tax_total->currency_code, $breakdown->taxTotal()->currencyCode());
|
||||
} else {
|
||||
$this->assertTrue(! isset($response->breakdown->tax_total));
|
||||
}
|
||||
if ($breakdown->handling()) {
|
||||
$this->assertEquals($response->breakdown->handling->value, $breakdown->handling()->value());
|
||||
$this->assertEquals($response->breakdown->handling->currency_code, $breakdown->handling()->currencyCode());
|
||||
} else {
|
||||
$this->assertTrue(! isset($response->breakdown->handling));
|
||||
}
|
||||
if ($breakdown->insurance()) {
|
||||
$this->assertEquals($response->breakdown->insurance->value, $breakdown->insurance()->value());
|
||||
$this->assertEquals($response->breakdown->insurance->currency_code, $breakdown->insurance()->currencyCode());
|
||||
} else {
|
||||
$this->assertTrue(! isset($response->breakdown->insurance));
|
||||
}
|
||||
if ($breakdown->shippingDiscount()) {
|
||||
$this->assertEquals($response->breakdown->shipping_discount->value, $breakdown->shippingDiscount()->value());
|
||||
$this->assertEquals($response->breakdown->shipping_discount->currency_code, $breakdown->shippingDiscount()->currencyCode());
|
||||
} else {
|
||||
$this->assertTrue(! isset($response->breakdown->shipping_discount));
|
||||
}
|
||||
if ($breakdown->discount()) {
|
||||
$this->assertEquals($response->breakdown->discount->value, $breakdown->discount()->value());
|
||||
$this->assertEquals($response->breakdown->discount->currency_code, $breakdown->discount()->currencyCode());
|
||||
} else {
|
||||
$this->assertTrue(! isset($response->breakdown->discount));
|
||||
}
|
||||
}
|
||||
|
||||
public function dataFromPayPalResponse() : array
|
||||
{
|
||||
return [
|
||||
'no_value' => [
|
||||
(object) [
|
||||
"currency_code" => "A",
|
||||
],
|
||||
true,
|
||||
],
|
||||
'no_currency_code' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
],
|
||||
true,
|
||||
],
|
||||
'no_value_in_breakdown' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"currency_code" => "B",
|
||||
],
|
||||
],
|
||||
],
|
||||
true,
|
||||
],
|
||||
'no_currency_code_in_breakdown' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
],
|
||||
],
|
||||
],
|
||||
true,
|
||||
],
|
||||
'default' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
"currency_code" => "B",
|
||||
],
|
||||
"shipping_discount" => (object) [
|
||||
"value" => (float) 3,
|
||||
"currency_code" => "C",
|
||||
],
|
||||
"insurance" => (object) [
|
||||
"value" => (float) 4,
|
||||
"currency_code" => "D",
|
||||
],
|
||||
"handling" => (object) [
|
||||
"value" => (float) 5,
|
||||
"currency_code" => "E",
|
||||
],
|
||||
"tax_total" => (object) [
|
||||
"value" => (float) 6,
|
||||
"currency_code" => "F",
|
||||
],
|
||||
"shipping" => (object) [
|
||||
"value" => (float) 7,
|
||||
"currency_code" => "G",
|
||||
],
|
||||
"item_total" => (object) [
|
||||
"value" => (float) 8,
|
||||
"currency_code" => "H",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
'no_item_total' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
"currency_code" => "B",
|
||||
],
|
||||
"shipping_discount" => (object) [
|
||||
"value" => (float) 3,
|
||||
"currency_code" => "C",
|
||||
],
|
||||
"insurance" => (object) [
|
||||
"value" => (float) 4,
|
||||
"currency_code" => "D",
|
||||
],
|
||||
"handling" => (object) [
|
||||
"value" => (float) 5,
|
||||
"currency_code" => "E",
|
||||
],
|
||||
"tax_total" => (object) [
|
||||
"value" => (float) 6,
|
||||
"currency_code" => "F",
|
||||
],
|
||||
"shipping" => (object) [
|
||||
"value" => (float) 7,
|
||||
"currency_code" => "G",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
'no_tax_total' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
"currency_code" => "B",
|
||||
],
|
||||
"shipping_discount" => (object) [
|
||||
"value" => (float) 3,
|
||||
"currency_code" => "C",
|
||||
],
|
||||
"insurance" => (object) [
|
||||
"value" => (float) 4,
|
||||
"currency_code" => "D",
|
||||
],
|
||||
"handling" => (object) [
|
||||
"value" => (float) 5,
|
||||
"currency_code" => "E",
|
||||
],
|
||||
"shipping" => (object) [
|
||||
"value" => (float) 7,
|
||||
"currency_code" => "G",
|
||||
],
|
||||
"item_total" => (object) [
|
||||
"value" => (float) 8,
|
||||
"currency_code" => "H",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
'no_handling' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
"currency_code" => "B",
|
||||
],
|
||||
"shipping_discount" => (object) [
|
||||
"value" => (float) 3,
|
||||
"currency_code" => "C",
|
||||
],
|
||||
"insurance" => (object) [
|
||||
"value" => (float) 4,
|
||||
"currency_code" => "D",
|
||||
],
|
||||
"tax_total" => (object) [
|
||||
"value" => (float) 6,
|
||||
"currency_code" => "F",
|
||||
],
|
||||
"shipping" => (object) [
|
||||
"value" => (float) 7,
|
||||
"currency_code" => "G",
|
||||
],
|
||||
"item_total" => (object) [
|
||||
"value" => (float) 8,
|
||||
"currency_code" => "H",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
'no_insurance' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
"currency_code" => "B",
|
||||
],
|
||||
"shipping_discount" => (object) [
|
||||
"value" => (float) 3,
|
||||
"currency_code" => "C",
|
||||
],
|
||||
"handling" => (object) [
|
||||
"value" => (float) 5,
|
||||
"currency_code" => "E",
|
||||
],
|
||||
"tax_total" => (object) [
|
||||
"value" => (float) 6,
|
||||
"currency_code" => "F",
|
||||
],
|
||||
"shipping" => (object) [
|
||||
"value" => (float) 7,
|
||||
"currency_code" => "G",
|
||||
],
|
||||
"item_total" => (object) [
|
||||
"value" => (float) 8,
|
||||
"currency_code" => "H",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
'no_shipping_discount' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
"currency_code" => "B",
|
||||
],
|
||||
"insurance" => (object) [
|
||||
"value" => (float) 4,
|
||||
"currency_code" => "D",
|
||||
],
|
||||
"handling" => (object) [
|
||||
"value" => (float) 5,
|
||||
"currency_code" => "E",
|
||||
],
|
||||
"tax_total" => (object) [
|
||||
"value" => (float) 6,
|
||||
"currency_code" => "F",
|
||||
],
|
||||
"shipping" => (object) [
|
||||
"value" => (float) 7,
|
||||
"currency_code" => "G",
|
||||
],
|
||||
"item_total" => (object) [
|
||||
"value" => (float) 8,
|
||||
"currency_code" => "H",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
'no_discount' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"shipping_discount" => (object) [
|
||||
"value" => (float) 3,
|
||||
"currency_code" => "C",
|
||||
],
|
||||
"insurance" => (object) [
|
||||
"value" => (float) 4,
|
||||
"currency_code" => "D",
|
||||
],
|
||||
"handling" => (object) [
|
||||
"value" => (float) 5,
|
||||
"currency_code" => "E",
|
||||
],
|
||||
"tax_total" => (object) [
|
||||
"value" => (float) 6,
|
||||
"currency_code" => "F",
|
||||
],
|
||||
"shipping" => (object) [
|
||||
"value" => (float) 7,
|
||||
"currency_code" => "G",
|
||||
],
|
||||
"item_total" => (object) [
|
||||
"value" => (float) 8,
|
||||
"currency_code" => "H",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
'no_shipping' => [
|
||||
(object) [
|
||||
"value" => (float) 1,
|
||||
"currency_code" => "A",
|
||||
"breakdown" => (object) [
|
||||
"discount" => (object) [
|
||||
"value" => (float) 2,
|
||||
"currency_code" => "B",
|
||||
],
|
||||
"shipping_discount" => (object) [
|
||||
"value" => (float) 3,
|
||||
"currency_code" => "C",
|
||||
],
|
||||
"insurance" => (object) [
|
||||
"value" => (float) 4,
|
||||
"currency_code" => "D",
|
||||
],
|
||||
"handling" => (object) [
|
||||
"value" => (float) 5,
|
||||
"currency_code" => "E",
|
||||
],
|
||||
"tax_total" => (object) [
|
||||
"value" => (float) 6,
|
||||
"currency_code" => "F",
|
||||
],
|
||||
"item_total" => (object) [
|
||||
"value" => (float) 8,
|
||||
"currency_code" => "H",
|
||||
],
|
||||
],
|
||||
],
|
||||
false,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
53
tests/PHPUnit/ApiClient/Factory/AuthorizationFactoryTest.php
Normal file
53
tests/PHPUnit/ApiClient/Factory/AuthorizationFactoryTest.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
|
||||
class AuthorizationFactoryTest extends TestCase
|
||||
{
|
||||
public function testFromPayPalRequestDefault()
|
||||
{
|
||||
$response = (object)[
|
||||
'id' => 'foo',
|
||||
'status' => 'CAPTURED',
|
||||
];
|
||||
|
||||
$testee = new AuthorizationFactory();
|
||||
$result = $testee->fromPayPalRequest($response);
|
||||
|
||||
$this->assertInstanceOf(Authorization::class, $result);
|
||||
|
||||
$this->assertEquals('foo', $result->id());
|
||||
$this->assertInstanceOf(AuthorizationStatus::class, $result->status());
|
||||
|
||||
$this->assertEquals('CAPTURED', $result->status()->name());
|
||||
}
|
||||
|
||||
public function testReturnExceptionIdIsMissing()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
$response = (object)[
|
||||
'status' => 'CAPTURED',
|
||||
];
|
||||
|
||||
$testee = new AuthorizationFactory();
|
||||
$testee->fromPayPalRequest($response);
|
||||
}
|
||||
|
||||
public function testReturnExceptionStatusIsMissing()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
$response = (object)[
|
||||
'id' => 'foo',
|
||||
];
|
||||
|
||||
$testee = new AuthorizationFactory();
|
||||
$testee->fromPayPalRequest($response);
|
||||
}
|
||||
}
|
420
tests/PHPUnit/ApiClient/Factory/ItemFactoryTest.php
Normal file
420
tests/PHPUnit/ApiClient/Factory/ItemFactoryTest.php
Normal file
|
@ -0,0 +1,420 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use function Brain\Monkey\Functions\expect;
|
||||
use Mockery;
|
||||
|
||||
class ItemFactoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testFromCartDefault()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$product = Mockery::mock(\WC_Product_Simple::class);
|
||||
$product
|
||||
->expects('get_name')
|
||||
->andReturn('name');
|
||||
$product
|
||||
->expects('get_description')
|
||||
->andReturn('description');
|
||||
$product
|
||||
->expects('get_sku')
|
||||
->andReturn('sku');
|
||||
$product
|
||||
->expects('is_virtual')
|
||||
->andReturn(false);
|
||||
$items = [
|
||||
[
|
||||
'data' => $product,
|
||||
'quantity' => 1,
|
||||
],
|
||||
];
|
||||
$cart = Mockery::mock(\WC_Cart::class);
|
||||
$cart
|
||||
->expects('get_cart_contents')
|
||||
->andReturn($items);
|
||||
|
||||
expect('get_woocommerce_currency')
|
||||
->andReturn('EUR');
|
||||
expect('wc_get_price_including_tax')
|
||||
->with($product)
|
||||
->andReturn(2.995);
|
||||
expect('wc_get_price_excluding_tax')
|
||||
->with($product)
|
||||
->andReturn(1);
|
||||
|
||||
$result = $testee->fromWcCart($cart);
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
$item = current($result);
|
||||
$this->assertInstanceOf(Item::class, $item);
|
||||
/**
|
||||
* @var Item $item
|
||||
*/
|
||||
$this->assertEquals(Item::PHYSICAL_GOODS, $item->category());
|
||||
$this->assertEquals('description', $item->description());
|
||||
$this->assertEquals(1, $item->quantity());
|
||||
$this->assertEquals('name', $item->name());
|
||||
$this->assertEquals('sku', $item->sku());
|
||||
$this->assertEquals(1, $item->unitAmount()->value());
|
||||
$this->assertEquals(2, $item->tax()->value());
|
||||
}
|
||||
|
||||
public function testFromCartDigitalGood()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$product = Mockery::mock(\WC_Product_Simple::class);
|
||||
$product
|
||||
->expects('get_name')
|
||||
->andReturn('name');
|
||||
$product
|
||||
->expects('get_description')
|
||||
->andReturn('description');
|
||||
$product
|
||||
->expects('get_sku')
|
||||
->andReturn('sku');
|
||||
$product
|
||||
->expects('is_virtual')
|
||||
->andReturn(true);
|
||||
$items = [
|
||||
[
|
||||
'data' => $product,
|
||||
'quantity' => 1,
|
||||
],
|
||||
];
|
||||
$cart = Mockery::mock(\WC_Cart::class);
|
||||
$cart
|
||||
->expects('get_cart_contents')
|
||||
->andReturn($items);
|
||||
|
||||
expect('get_woocommerce_currency')
|
||||
->andReturn('EUR');
|
||||
expect('wc_get_price_including_tax')
|
||||
->with($product)
|
||||
->andReturn(2.995);
|
||||
expect('wc_get_price_excluding_tax')
|
||||
->with($product)
|
||||
->andReturn(1);
|
||||
|
||||
$result = $testee->fromWcCart($cart);
|
||||
|
||||
$item = current($result);
|
||||
$this->assertEquals(Item::DIGITAL_GOODS, $item->category());
|
||||
}
|
||||
|
||||
public function testFromWcOrderDefault()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$product = Mockery::mock(\WC_Product::class);
|
||||
$product
|
||||
->expects('get_name')
|
||||
->andReturn('name');
|
||||
$product
|
||||
->expects('get_description')
|
||||
->andReturn('description');
|
||||
$product
|
||||
->expects('get_sku')
|
||||
->andReturn('sku');
|
||||
$product
|
||||
->expects('is_virtual')
|
||||
->andReturn(false);
|
||||
|
||||
$item = Mockery::mock(\WC_Order_Item_Product::class);
|
||||
$item
|
||||
->expects('get_product')
|
||||
->andReturn($product);
|
||||
$item
|
||||
->expects('get_quantity')
|
||||
->andReturn(1);
|
||||
|
||||
$order = Mockery::mock(\WC_Order::class);
|
||||
$order
|
||||
->expects('get_currency')
|
||||
->andReturn('EUR');
|
||||
$order
|
||||
->expects('get_items')
|
||||
->andReturn([$item]);
|
||||
$order
|
||||
->expects('get_item_subtotal')
|
||||
->with($item, true)
|
||||
->andReturn(3);
|
||||
$order
|
||||
->expects('get_item_subtotal')
|
||||
->with($item, false)
|
||||
->andReturn(1);
|
||||
|
||||
$result = $testee->fromWcOrder($order);
|
||||
$this->assertCount(1, $result);
|
||||
$item = current($result);
|
||||
/**
|
||||
* @var Item $item
|
||||
*/
|
||||
$this->assertInstanceOf(Item::class, $item);
|
||||
$this->assertEquals('name', $item->name());
|
||||
$this->assertEquals('description', $item->description());
|
||||
$this->assertEquals(1, $item->quantity());
|
||||
$this->assertEquals(Item::PHYSICAL_GOODS, $item->category());
|
||||
$this->assertEquals(1, $item->unitAmount()->value());
|
||||
$this->assertEquals(2, $item->tax()->value());
|
||||
}
|
||||
|
||||
public function testFromWcOrderDigitalGood()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$product = Mockery::mock(\WC_Product::class);
|
||||
$product
|
||||
->expects('get_name')
|
||||
->andReturn('name');
|
||||
$product
|
||||
->expects('get_description')
|
||||
->andReturn('description');
|
||||
$product
|
||||
->expects('get_sku')
|
||||
->andReturn('sku');
|
||||
$product
|
||||
->expects('is_virtual')
|
||||
->andReturn(true);
|
||||
|
||||
$item = Mockery::mock(\WC_Order_Item_Product::class);
|
||||
$item
|
||||
->expects('get_product')
|
||||
->andReturn($product);
|
||||
$item
|
||||
->expects('get_quantity')
|
||||
->andReturn(1);
|
||||
|
||||
$order = Mockery::mock(\WC_Order::class);
|
||||
$order
|
||||
->expects('get_currency')
|
||||
->andReturn('EUR');
|
||||
$order
|
||||
->expects('get_items')
|
||||
->andReturn([$item]);
|
||||
$order
|
||||
->expects('get_item_subtotal')
|
||||
->with($item, true)
|
||||
->andReturn(3);
|
||||
$order
|
||||
->expects('get_item_subtotal')
|
||||
->with($item, false)
|
||||
->andReturn(1);
|
||||
|
||||
$result = $testee->fromWcOrder($order);
|
||||
$item = current($result);
|
||||
/**
|
||||
* @var Item $item
|
||||
*/
|
||||
$this->assertEquals(Item::DIGITAL_GOODS, $item->category());
|
||||
}
|
||||
|
||||
public function testFromWcOrderMaxStringLength()
|
||||
{
|
||||
$name = 'öawjetöagrjjaglörjötairgjaflkögjöalfdgjöalfdjblköajtlkfjdbljslkgjfklösdgjalkerjtlrajglkfdajblköajflköbjsdgjadfgjaöfgjaölkgjkladjgfköajgjaflgöjafdlgjafdögjdsflkgjö4jwegjfsdbvxj öskögjtaeröjtrgt';
|
||||
$description = 'öawjetöagrjjaglörjötairgjaflkögjöalfdgjöalfdjblköajtlkfjdbljslkgjfklösdgjalkerjtlrajglkfdajblköajflköbjsdgjadfgjaöfgjaölkgjkladjgfköajgjaflgöjafdlgjafdögjdsflkgjö4jwegjfsdbvxj öskögjtaeröjtrgt';
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$product = Mockery::mock(\WC_Product::class);
|
||||
$product
|
||||
->expects('get_name')
|
||||
->andReturn($name);
|
||||
$product
|
||||
->expects('get_description')
|
||||
->andReturn($description);
|
||||
$product
|
||||
->expects('get_sku')
|
||||
->andReturn('sku');
|
||||
$product
|
||||
->expects('is_virtual')
|
||||
->andReturn(true);
|
||||
|
||||
$item = Mockery::mock(\WC_Order_Item_Product::class);
|
||||
$item
|
||||
->expects('get_product')
|
||||
->andReturn($product);
|
||||
$item
|
||||
->expects('get_quantity')
|
||||
->andReturn(1);
|
||||
|
||||
$order = Mockery::mock(\WC_Order::class);
|
||||
$order
|
||||
->expects('get_currency')
|
||||
->andReturn('EUR');
|
||||
$order
|
||||
->expects('get_items')
|
||||
->andReturn([$item]);
|
||||
$order
|
||||
->expects('get_item_subtotal')
|
||||
->with($item, true)
|
||||
->andReturn(3);
|
||||
$order
|
||||
->expects('get_item_subtotal')
|
||||
->with($item, false)
|
||||
->andReturn(1);
|
||||
|
||||
$result = $testee->fromWcOrder($order);
|
||||
$item = current($result);
|
||||
/**
|
||||
* @var Item $item
|
||||
*/
|
||||
$this->assertEquals(mb_substr($name, 0, 127), $item->name());
|
||||
$this->assertEquals(mb_substr($description, 0, 127), $item->description());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponse()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$response = (object) [
|
||||
'name' => 'name',
|
||||
'description' => 'description',
|
||||
'quantity' => 1,
|
||||
'unit_amount' => (object) [
|
||||
'value' => 1,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
];
|
||||
$item = $testee->fromPayPalResponse($response);
|
||||
$this->assertInstanceOf(Item::class, $item);
|
||||
/**
|
||||
* @var Item $item
|
||||
*/
|
||||
$this->assertInstanceOf(Item::class, $item);
|
||||
$this->assertEquals('name', $item->name());
|
||||
$this->assertEquals('description', $item->description());
|
||||
$this->assertEquals(1, $item->quantity());
|
||||
$this->assertEquals(Item::PHYSICAL_GOODS, $item->category());
|
||||
$this->assertEquals(1, $item->unitAmount()->value());
|
||||
$this->assertNull($item->tax());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseDigitalGood()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$response = (object) [
|
||||
'name' => 'name',
|
||||
'description' => 'description',
|
||||
'quantity' => 1,
|
||||
'unit_amount' => (object) [
|
||||
'value' => 1,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
'category' => Item::DIGITAL_GOODS,
|
||||
];
|
||||
$item = $testee->fromPayPalResponse($response);
|
||||
/**
|
||||
* @var Item $item
|
||||
*/
|
||||
$this->assertEquals(Item::DIGITAL_GOODS, $item->category());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseHasTax()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$response = (object) [
|
||||
'name' => 'name',
|
||||
'description' => 'description',
|
||||
'quantity' => 1,
|
||||
'unit_amount' => (object) [
|
||||
'value' => 1,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
'tax' => (object) [
|
||||
'value' => 100,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
];
|
||||
$item = $testee->fromPayPalResponse($response);
|
||||
$this->assertEquals(100, $item->tax()->value());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseThrowsWithoutName()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$response = (object) [
|
||||
'description' => 'description',
|
||||
'quantity' => 1,
|
||||
'unit_amount' => (object) [
|
||||
'value' => 1,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
'tax' => (object) [
|
||||
'value' => 100,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
];
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->fromPayPalResponse($response);
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseThrowsWithoutQuantity()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$response = (object) [
|
||||
'name' => 'name',
|
||||
'description' => 'description',
|
||||
'unit_amount' => (object) [
|
||||
'value' => 1,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
'tax' => (object) [
|
||||
'value' => 100,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
];
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->fromPayPalResponse($response);
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseThrowsWithStringInQuantity()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$response = (object) [
|
||||
'name' => 'name',
|
||||
'description' => 'description',
|
||||
'quantity' => 'should-not-be-a-string',
|
||||
'unit_amount' => (object) [
|
||||
'value' => 1,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
'tax' => (object) [
|
||||
'value' => 100,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
];
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->fromPayPalResponse($response);
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseThrowsWithWrongUnitAmount()
|
||||
{
|
||||
$testee = new ItemFactory();
|
||||
|
||||
$response = (object) [
|
||||
'name' => 'name',
|
||||
'description' => 'description',
|
||||
'quantity' => 1,
|
||||
'unit_amount' => (object) [
|
||||
],
|
||||
'tax' => (object) [
|
||||
'value' => 100,
|
||||
'currency_code' => 'EUR',
|
||||
],
|
||||
];
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->fromPayPalResponse($response);
|
||||
}
|
||||
}
|
221
tests/PHPUnit/ApiClient/Factory/OrderFactoryTest.php
Normal file
221
tests/PHPUnit/ApiClient/Factory/OrderFactoryTest.php
Normal file
|
@ -0,0 +1,221 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payer;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class OrderFactoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testFromWcOrder()
|
||||
{
|
||||
$createTime = new \DateTime();
|
||||
$updateTime = new \DateTime();
|
||||
$payer = Mockery::mock(Payer::class);
|
||||
$status = Mockery::mock(OrderStatus::class);
|
||||
$order = Mockery::mock(Order::class);
|
||||
$order->expects('id')->andReturn('id');
|
||||
$order->expects('status')->andReturn($status);
|
||||
$order->expects('payer')->andReturn($payer);
|
||||
$order->expects('intent')->andReturn('intent');
|
||||
$order->expects('createTime')->andReturn($createTime);
|
||||
$order->expects('updateTime')->andReturn($updateTime);
|
||||
$order->expects('applicationContext')->andReturnNull();
|
||||
$order->expects('paymentSource')->andReturnNull();
|
||||
$wcOrder = Mockery::mock(\WC_Order::class);
|
||||
$purchaseUnitFactory = Mockery::mock(PurchaseUnitFactory::class);
|
||||
$purchaseUnit = Mockery::mock(PurchaseUnit::class);
|
||||
$purchaseUnitFactory->expects('fromWcOrder')->with($wcOrder)->andReturn($purchaseUnit);
|
||||
$payerFactory = Mockery::mock(PayerFactory::class);
|
||||
$applicationRepository = Mockery::mock(ApplicationContextRepository::class);
|
||||
$applicationFactory = Mockery::mock(ApplicationContextFactory::class);
|
||||
$paymentSourceFactory = Mockery::mock(PaymentSourceFactory::class);
|
||||
|
||||
|
||||
$testee = new OrderFactory(
|
||||
$purchaseUnitFactory,
|
||||
$payerFactory,
|
||||
$applicationRepository,
|
||||
$applicationFactory,
|
||||
$paymentSourceFactory
|
||||
);
|
||||
$result = $testee->fromWcOrder($wcOrder, $order);
|
||||
$resultPurchaseUnit = current($result->purchaseUnits());
|
||||
$this->assertEquals($purchaseUnit, $resultPurchaseUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestFromPayPalResponseTest
|
||||
* @param $orderData
|
||||
*/
|
||||
public function testFromPayPalResponse($orderData)
|
||||
{
|
||||
$purchaseUnitFactory = Mockery::mock(PurchaseUnitFactory::class);
|
||||
if (count($orderData->purchase_units)) {
|
||||
$purchaseUnitFactory
|
||||
->expects('fromPayPalResponse')
|
||||
->times(count($orderData->purchase_units))
|
||||
->andReturn(Mockery::mock(PurchaseUnit::class));
|
||||
}
|
||||
$payerFactory = Mockery::mock(PayerFactory::class);
|
||||
if (isset($orderData->payer)) {
|
||||
$payerFactory
|
||||
->expects('fromPayPalResponse')
|
||||
->andReturn(Mockery::mock(Payer::class));
|
||||
}
|
||||
$applicationRepository = Mockery::mock(ApplicationContextRepository::class);
|
||||
$applicationFactory = Mockery::mock(ApplicationContextFactory::class);
|
||||
$paymentSourceFactory = Mockery::mock(PaymentSourceFactory::class);
|
||||
|
||||
$testee = new OrderFactory(
|
||||
$purchaseUnitFactory,
|
||||
$payerFactory,
|
||||
$applicationRepository,
|
||||
$applicationFactory,
|
||||
$paymentSourceFactory
|
||||
);
|
||||
$order = $testee->fromPayPalResponse($orderData);
|
||||
|
||||
$this->assertCount(count($orderData->purchase_units), $order->purchaseUnits());
|
||||
$this->assertEquals($orderData->id, $order->id());
|
||||
$this->assertEquals($orderData->status, $order->status()->name());
|
||||
$this->assertEquals($orderData->intent, $order->intent());
|
||||
if (! isset($orderData->create_time)) {
|
||||
$this->assertNull($order->createTime());
|
||||
} else {
|
||||
$this->assertEquals($orderData->create_time, $order->createTime()->format(\DateTime::ISO8601));
|
||||
}
|
||||
if (! isset($orderData->payer)) {
|
||||
$this->assertNull($order->payer());
|
||||
} else {
|
||||
$this->assertInstanceOf(Payer::class, $order->payer());
|
||||
}
|
||||
if (! isset($orderData->update_time)) {
|
||||
$this->assertNull($order->updateTime());
|
||||
} else {
|
||||
$this->assertEquals($orderData->update_time, $order->updateTime()->format(\DateTime::ISO8601));
|
||||
}
|
||||
}
|
||||
|
||||
public function dataForTestFromPayPalResponseTest() : array
|
||||
{
|
||||
return [
|
||||
'default' => [
|
||||
(object) [
|
||||
'id' => 'id',
|
||||
'purchase_units' => [new \stdClass(), new \stdClass()],
|
||||
'status' => OrderStatus::APPROVED,
|
||||
'intent' => 'CAPTURE',
|
||||
'create_time' => '2005-08-15T15:52:01+0000',
|
||||
'update_time' => '2005-09-15T15:52:01+0000',
|
||||
'payer' => new \stdClass(),
|
||||
],
|
||||
],
|
||||
'no_update_time' => [
|
||||
(object) [
|
||||
'id' => 'id',
|
||||
'purchase_units' => [new \stdClass(), new \stdClass()],
|
||||
'status' => OrderStatus::APPROVED,
|
||||
'intent' => 'CAPTURE',
|
||||
'create_time' => '2005-08-15T15:52:01+0000',
|
||||
'payer' => new \stdClass(),
|
||||
],
|
||||
],
|
||||
'no_create_time' => [
|
||||
(object) [
|
||||
'id' => 'id',
|
||||
'purchase_units' => [new \stdClass(), new \stdClass()],
|
||||
'status' => OrderStatus::APPROVED,
|
||||
'intent' => 'CAPTURE',
|
||||
'update_time' => '2005-09-15T15:52:01+0000',
|
||||
'payer' => new \stdClass(),
|
||||
],
|
||||
],
|
||||
'no_payer' => [
|
||||
(object) [
|
||||
'id' => 'id',
|
||||
'purchase_units' => [new \stdClass(), new \stdClass()],
|
||||
'status' => OrderStatus::APPROVED,
|
||||
'intent' => 'CAPTURE',
|
||||
'create_time' => '2005-08-15T15:52:01+0000',
|
||||
'update_time' => '2005-09-15T15:52:01+0000',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestFromPayPalResponseExceptionsTest
|
||||
* @param $orderData
|
||||
*/
|
||||
public function testFromPayPalResponseExceptions($orderData)
|
||||
{
|
||||
$purchaseUnitFactory = Mockery::mock(PurchaseUnitFactory::class);
|
||||
$payerFactory = Mockery::mock(PayerFactory::class);
|
||||
$applicationRepository = Mockery::mock(ApplicationContextRepository::class);
|
||||
$applicationFactory = Mockery::mock(ApplicationContextFactory::class);
|
||||
$paymentSourceFactory = Mockery::mock(PaymentSourceFactory::class);
|
||||
|
||||
$testee = new OrderFactory(
|
||||
$purchaseUnitFactory,
|
||||
$payerFactory,
|
||||
$applicationRepository,
|
||||
$applicationFactory,
|
||||
$paymentSourceFactory
|
||||
);
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
$testee->fromPayPalResponse($orderData);
|
||||
}
|
||||
|
||||
public function dataForTestFromPayPalResponseExceptionsTest() : array
|
||||
{
|
||||
return [
|
||||
'no_id' => [
|
||||
(object) [
|
||||
'purchase_units' => [],
|
||||
'status' => '',
|
||||
'intent' => '',
|
||||
],
|
||||
],
|
||||
'no_purchase_units' => [
|
||||
(object) [
|
||||
'id' => '',
|
||||
'status' => '',
|
||||
'intent' => '',
|
||||
],
|
||||
],
|
||||
'purchase_units_is_not_array' => [
|
||||
(object) [
|
||||
'id' => '',
|
||||
'purchase_units' => 1,
|
||||
'status' => '',
|
||||
'intent' => '',
|
||||
],
|
||||
],
|
||||
'no_status' => [
|
||||
(object) [
|
||||
'id' => '',
|
||||
'purchase_units' => [],
|
||||
'intent' => '',
|
||||
],
|
||||
],
|
||||
'no_intent' => [
|
||||
(object) [
|
||||
'id' => '',
|
||||
'purchase_units' => [],
|
||||
'status' => '',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
269
tests/PHPUnit/ApiClient/Factory/PayerFactoryTest.php
Normal file
269
tests/PHPUnit/ApiClient/Factory/PayerFactoryTest.php
Normal file
|
@ -0,0 +1,269 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Address;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class PayerFactoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testFromWcCustomer()
|
||||
{
|
||||
$expectedPhone = '012345678901';
|
||||
$expectedEmail = 'test@example.com';
|
||||
$expectedFirstName = 'John';
|
||||
$expectedLastName = 'Locke';
|
||||
$address = Mockery::mock(Address::class);
|
||||
$customer = Mockery::mock(\WC_Customer::class);
|
||||
$customer
|
||||
->shouldReceive('get_billing_phone')
|
||||
->andReturn($expectedPhone);
|
||||
$customer
|
||||
->shouldReceive('get_billing_email')
|
||||
->andReturn($expectedEmail);
|
||||
$customer
|
||||
->shouldReceive('get_billing_last_name')
|
||||
->andReturn($expectedLastName);
|
||||
$customer
|
||||
->shouldReceive('get_billing_first_name')
|
||||
->andReturn($expectedFirstName);
|
||||
$addressFactory = Mockery::mock(AddressFactory::class);
|
||||
$addressFactory
|
||||
->expects('fromWcCustomer')
|
||||
->with($customer, 'billing')
|
||||
->andReturn($address);
|
||||
$testee = new PayerFactory($addressFactory);
|
||||
$result = $testee->fromCustomer($customer);
|
||||
|
||||
$this->assertEquals($expectedEmail, $result->emailAddress());
|
||||
$this->assertEquals($expectedLastName, $result->name()->surname());
|
||||
$this->assertEquals($expectedFirstName, $result->name()->givenName());
|
||||
$this->assertEquals($address, $result->address());
|
||||
$this->assertEquals($expectedPhone, $result->phone()->phone()->nationalNumber());
|
||||
$this->assertNull($result->birthDate());
|
||||
$this->assertEmpty($result->payerId());
|
||||
}
|
||||
|
||||
/**
|
||||
* The phone number is only allowed to contain numbers.
|
||||
* The WC_Customer get_billing_phone can contain other characters, which need to
|
||||
* get stripped.
|
||||
*/
|
||||
public function testFromWcCustomerStringsFromNumberAreRemoved()
|
||||
{
|
||||
$expectedPhone = '012345678901';
|
||||
$expectedEmail = 'test@example.com';
|
||||
$expectedFirstName = 'John';
|
||||
$expectedLastName = 'Locke';
|
||||
$address = Mockery::mock(Address::class);
|
||||
$customer = Mockery::mock(\WC_Customer::class);
|
||||
$customer
|
||||
->shouldReceive('get_billing_phone')
|
||||
->andReturn($expectedPhone . 'abcdefg');
|
||||
$customer
|
||||
->shouldReceive('get_billing_email')
|
||||
->andReturn($expectedEmail);
|
||||
$customer
|
||||
->shouldReceive('get_billing_last_name')
|
||||
->andReturn($expectedLastName);
|
||||
$customer
|
||||
->shouldReceive('get_billing_first_name')
|
||||
->andReturn($expectedFirstName);
|
||||
$addressFactory = Mockery::mock(AddressFactory::class);
|
||||
$addressFactory
|
||||
->expects('fromWcCustomer')
|
||||
->with($customer, 'billing')
|
||||
->andReturn($address);
|
||||
$testee = new PayerFactory($addressFactory);
|
||||
$result = $testee->fromCustomer($customer);
|
||||
|
||||
$this->assertEquals($expectedPhone, $result->phone()->phone()->nationalNumber());
|
||||
}
|
||||
|
||||
public function testFromWcCustomerNoNumber()
|
||||
{
|
||||
$expectedEmail = 'test@example.com';
|
||||
$expectedFirstName = 'John';
|
||||
$expectedLastName = 'Locke';
|
||||
$address = Mockery::mock(Address::class);
|
||||
$customer = Mockery::mock(\WC_Customer::class);
|
||||
$customer
|
||||
->shouldReceive('get_billing_phone')
|
||||
->andReturn('');
|
||||
$customer
|
||||
->shouldReceive('get_billing_email')
|
||||
->andReturn($expectedEmail);
|
||||
$customer
|
||||
->shouldReceive('get_billing_last_name')
|
||||
->andReturn($expectedLastName);
|
||||
$customer
|
||||
->shouldReceive('get_billing_first_name')
|
||||
->andReturn($expectedFirstName);
|
||||
$addressFactory = Mockery::mock(AddressFactory::class);
|
||||
$addressFactory
|
||||
->expects('fromWcCustomer')
|
||||
->with($customer, 'billing')
|
||||
->andReturn($address);
|
||||
$testee = new PayerFactory($addressFactory);
|
||||
$result = $testee->fromCustomer($customer);
|
||||
|
||||
$this->assertNull($result->phone());
|
||||
}
|
||||
|
||||
/**
|
||||
* The phone number is not allowed to be longer than 14 characters.
|
||||
* We need to make sure, we strip the number if longer.
|
||||
*/
|
||||
public function testFromWcCustomerTooLongNumberGetsStripped()
|
||||
{
|
||||
$expectedPhone = '01234567890123';
|
||||
$expectedEmail = 'test@example.com';
|
||||
$expectedFirstName = 'John';
|
||||
$expectedLastName = 'Locke';
|
||||
$address = Mockery::mock(Address::class);
|
||||
$customer = Mockery::mock(\WC_Customer::class);
|
||||
$customer
|
||||
->shouldReceive('get_billing_phone')
|
||||
->andReturn($expectedPhone . '456789');
|
||||
$customer
|
||||
->shouldReceive('get_billing_email')
|
||||
->andReturn($expectedEmail);
|
||||
$customer
|
||||
->shouldReceive('get_billing_last_name')
|
||||
->andReturn($expectedLastName);
|
||||
$customer
|
||||
->shouldReceive('get_billing_first_name')
|
||||
->andReturn($expectedFirstName);
|
||||
$addressFactory = Mockery::mock(AddressFactory::class);
|
||||
$addressFactory
|
||||
->expects('fromWcCustomer')
|
||||
->with($customer, 'billing')
|
||||
->andReturn($address);
|
||||
$testee = new PayerFactory($addressFactory);
|
||||
$result = $testee->fromCustomer($customer);
|
||||
|
||||
$this->assertEquals($expectedPhone, $result->phone()->phone()->nationalNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForTestFromPayPalResponse
|
||||
*/
|
||||
public function testFromPayPalResponse($data)
|
||||
{
|
||||
$addressFactory = Mockery::mock(AddressFactory::class);
|
||||
$addressFactory
|
||||
->expects('fromPayPalRequest')
|
||||
->with($data->address)
|
||||
->andReturn(Mockery::mock(Address::class));
|
||||
$testee = new PayerFactory($addressFactory);
|
||||
$payer = $testee->fromPayPalResponse($data);
|
||||
$this->assertEquals($data->email_address, $payer->emailAddress());
|
||||
$this->assertEquals($data->payer_id, $payer->payerId());
|
||||
$this->assertEquals($data->name->given_name, $payer->name()->givenName());
|
||||
$this->assertEquals($data->name->surname, $payer->name()->surname());
|
||||
if (isset($data->phone)) {
|
||||
$this->assertEquals($data->phone->phone_type, $payer->phone()->type());
|
||||
$this->assertEquals($data->phone->phone_number->national_number, $payer->phone()->phone()->nationalNumber());
|
||||
} else {
|
||||
$this->assertNull($payer->phone());
|
||||
}
|
||||
$this->assertInstanceOf(Address::class, $payer->address());
|
||||
if (isset($data->tax_info)) {
|
||||
$this->assertEquals($data->tax_info->tax_id, $payer->taxInfo()->taxId());
|
||||
$this->assertEquals($data->tax_info->tax_id_type, $payer->taxInfo()->type());
|
||||
} else {
|
||||
$this->assertNull($payer->taxInfo());
|
||||
}
|
||||
if (isset($data->birth_date)) {
|
||||
$this->assertEquals($data->birth_date, $payer->birthDate()->format('Y-m-d'));
|
||||
} else {
|
||||
$this->assertNull($payer->birthDate());
|
||||
}
|
||||
}
|
||||
|
||||
public function dataForTestFromPayPalResponse() : array
|
||||
{
|
||||
return [
|
||||
'default' => [
|
||||
(object)[
|
||||
'address' => new \stdClass(),
|
||||
'name' => (object)[
|
||||
'given_name' => 'given_name',
|
||||
'surname' => 'surname',
|
||||
],
|
||||
'phone' => (object)[
|
||||
'phone_type' => 'HOME',
|
||||
'phone_number' => (object)[
|
||||
'national_number' => '1234567890',
|
||||
],
|
||||
],
|
||||
'tax_info' => (object)[
|
||||
'tax_id' => 'tax_id',
|
||||
'tax_id_type' => 'BR_CPF',
|
||||
],
|
||||
'birth_date' => '1970-01-01',
|
||||
'email_address' => 'email_address',
|
||||
'payer_id' => 'payer_id',
|
||||
],
|
||||
],
|
||||
'no_phone' => [
|
||||
(object)[
|
||||
'address' => new \stdClass(),
|
||||
'name' => (object)[
|
||||
'given_name' => 'given_name',
|
||||
'surname' => 'surname',
|
||||
],
|
||||
'tax_info' => (object)[
|
||||
'tax_id' => 'tax_id',
|
||||
'tax_id_type' => 'BR_CPF',
|
||||
],
|
||||
'birth_date' => '1970-01-01',
|
||||
'email_address' => 'email_address',
|
||||
'payer_id' => 'payer_id',
|
||||
],
|
||||
],
|
||||
'no_tax_info' => [
|
||||
(object)[
|
||||
'address' => new \stdClass(),
|
||||
'name' => (object)[
|
||||
'given_name' => 'given_name',
|
||||
'surname' => 'surname',
|
||||
],
|
||||
'phone' => (object)[
|
||||
'phone_type' => 'HOME',
|
||||
'phone_number' => (object)[
|
||||
'national_number' => '1234567890',
|
||||
],
|
||||
],
|
||||
'birth_date' => '1970-01-01',
|
||||
'email_address' => 'email_address',
|
||||
'payer_id' => 'payer_id',
|
||||
],
|
||||
],
|
||||
'no_birth_date' => [
|
||||
(object)[
|
||||
'address' => new \stdClass(),
|
||||
'name' => (object)[
|
||||
'given_name' => 'given_name',
|
||||
'surname' => 'surname',
|
||||
],
|
||||
'phone' => (object)[
|
||||
'phone_type' => 'HOME',
|
||||
'phone_number' => (object)[
|
||||
'national_number' => '1234567890',
|
||||
],
|
||||
],
|
||||
'tax_info' => (object)[
|
||||
'tax_id' => 'tax_id',
|
||||
'tax_id_type' => 'BR_CPF',
|
||||
],
|
||||
'email_address' => 'email_address',
|
||||
'payer_id' => 'payer_id',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
40
tests/PHPUnit/ApiClient/Factory/PaymentsFactoryTest.php
Normal file
40
tests/PHPUnit/ApiClient/Factory/PaymentsFactoryTest.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payments;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class PaymentsFactoryTest extends TestCase
|
||||
{
|
||||
public function testFromPayPalResponse()
|
||||
{
|
||||
$authorization = Mockery::mock(Authorization::class);
|
||||
$authorization->shouldReceive('toArray')->andReturn(['id' => 'foo', 'status' => 'CREATED']);
|
||||
|
||||
$authorizationsFactory = Mockery::mock(AuthorizationFactory::class);
|
||||
$authorizationsFactory->shouldReceive('fromPayPalRequest')->andReturn($authorization);
|
||||
|
||||
$response = (object)[
|
||||
'authorizations' => [
|
||||
(object)['id' => 'foo', 'status' => 'CREATED'],
|
||||
],
|
||||
];
|
||||
|
||||
$testee = new PaymentsFactory($authorizationsFactory);
|
||||
$result = $testee->fromPayPalResponse($response);
|
||||
|
||||
$this->assertInstanceOf(Payments::class, $result);
|
||||
|
||||
$expectedToArray = [
|
||||
'authorizations' => [
|
||||
['id' => 'foo', 'status' => 'CREATED'],
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expectedToArray, $result->toArray());
|
||||
}
|
||||
}
|
659
tests/PHPUnit/ApiClient/Factory/PurchaseUnitFactoryTest.php
Normal file
659
tests/PHPUnit/ApiClient/Factory/PurchaseUnitFactoryTest.php
Normal file
|
@ -0,0 +1,659 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Address;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Amount;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payee;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Payments;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Entity\Shipping;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
use function Brain\Monkey\Functions\expect;
|
||||
|
||||
class PurchaseUnitFactoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testWcOrderDefault()
|
||||
{
|
||||
$wcOrderId = 1;
|
||||
$wcOrder = Mockery::mock(\WC_Order::class);
|
||||
$wcOrder
|
||||
->expects('get_id')->andReturn($wcOrderId);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amountFactory
|
||||
->shouldReceive('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->shouldReceive('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->shouldReceive('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn([]);
|
||||
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->shouldReceive('countryCode')
|
||||
->twice()
|
||||
->andReturn('DE');
|
||||
$address
|
||||
->shouldReceive('postalCode')
|
||||
->andReturn('12345');
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping
|
||||
->shouldReceive('address')
|
||||
->andReturn($address);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shippingFactory
|
||||
->shouldReceive('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$unit = $testee->fromWcOrder($wcOrder);
|
||||
$this->assertTrue(is_a($unit, PurchaseUnit::class));
|
||||
$this->assertEquals($payee, $unit->payee());
|
||||
$this->assertEquals('', $unit->description());
|
||||
$this->assertEquals('default', $unit->referenceId());
|
||||
$this->assertEquals('WC-' . $wcOrderId, $unit->customId());
|
||||
$this->assertEquals('', $unit->softDescriptor());
|
||||
$this->assertEquals('WC-' . $wcOrderId, $unit->invoiceId());
|
||||
$this->assertEquals([], $unit->items());
|
||||
$this->assertEquals($amount, $unit->amount());
|
||||
$this->assertEquals($shipping, $unit->shipping());
|
||||
}
|
||||
|
||||
public function testWcOrderShippingGetsDroppedWhenNoPostalCode()
|
||||
{
|
||||
$wcOrder = Mockery::mock(\WC_Order::class);
|
||||
$wcOrder
|
||||
->expects('get_id')->andReturn(1);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amountFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn([]);
|
||||
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->expects('countryCode')
|
||||
->twice()
|
||||
->andReturn('DE');
|
||||
$address
|
||||
->expects('postalCode')
|
||||
->andReturn('');
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping
|
||||
->expects('address')
|
||||
->times(3)
|
||||
->andReturn($address);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shippingFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$unit = $testee->fromWcOrder($wcOrder);
|
||||
$this->assertEquals(null, $unit->shipping());
|
||||
}
|
||||
|
||||
public function testWcOrderShippingGetsDroppedWhenNoCountryCode()
|
||||
{
|
||||
$wcOrder = Mockery::mock(\WC_Order::class);
|
||||
$wcOrder
|
||||
->expects('get_id')->andReturn(1);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amountFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn([]);
|
||||
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->expects('countryCode')
|
||||
->andReturn('');
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping
|
||||
->expects('address')
|
||||
->andReturn($address);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shippingFactory
|
||||
->expects('fromWcOrder')
|
||||
->with($wcOrder)
|
||||
->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$unit = $testee->fromWcOrder($wcOrder);
|
||||
$this->assertEquals(null, $unit->shipping());
|
||||
}
|
||||
|
||||
public function testWcCartDefault()
|
||||
{
|
||||
$wcCustomer = Mockery::mock(\WC_Customer::class);
|
||||
expect('WC')
|
||||
->andReturn((object) ['customer' => $wcCustomer]);
|
||||
|
||||
$wcCart = Mockery::mock(\WC_Cart::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amountFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn([]);
|
||||
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->shouldReceive('countryCode')
|
||||
->andReturn('DE');
|
||||
$address
|
||||
->shouldReceive('postalCode')
|
||||
->andReturn('12345');
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping
|
||||
->shouldReceive('address')
|
||||
->zeroOrMoreTimes()
|
||||
->andReturn($address);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shippingFactory
|
||||
->expects('fromWcCustomer')
|
||||
->with($wcCustomer)
|
||||
->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$unit = $testee->fromWcCart($wcCart);
|
||||
$this->assertTrue(is_a($unit, PurchaseUnit::class));
|
||||
$this->assertEquals($payee, $unit->payee());
|
||||
$this->assertEquals('', $unit->description());
|
||||
$this->assertEquals('default', $unit->referenceId());
|
||||
$this->assertEquals('', $unit->customId());
|
||||
$this->assertEquals('', $unit->softDescriptor());
|
||||
$this->assertEquals('', $unit->invoiceId());
|
||||
$this->assertEquals([], $unit->items());
|
||||
$this->assertEquals($amount, $unit->amount());
|
||||
$this->assertEquals($shipping, $unit->shipping());
|
||||
}
|
||||
|
||||
public function testWcCartShippingGetsDroppendWhenNoCustomer()
|
||||
{
|
||||
expect('WC')
|
||||
->andReturn((object) ['customer' => null]);
|
||||
|
||||
$wcCart = Mockery::mock(\WC_Cart::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amountFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn([]);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$unit = $testee->fromWcCart($wcCart);
|
||||
$this->assertNull($unit->shipping());
|
||||
}
|
||||
|
||||
public function testWcCartShippingGetsDroppendWhenNoPostalCode()
|
||||
{
|
||||
expect('WC')
|
||||
->andReturn((object) ['customer' => Mockery::mock(\WC_Customer::class)]);
|
||||
|
||||
$wcCart = Mockery::mock(\WC_Cart::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amountFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn([]);
|
||||
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->shouldReceive('countryCode')
|
||||
->andReturn('DE');
|
||||
$address
|
||||
->shouldReceive('postalCode')
|
||||
->andReturn('');
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping
|
||||
->shouldReceive('address')
|
||||
->andReturn($address);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shippingFactory
|
||||
->expects('fromWcCustomer')
|
||||
->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$unit = $testee->fromWcCart($wcCart);
|
||||
$this->assertNull($unit->shipping());
|
||||
}
|
||||
|
||||
public function testWcCartShippingGetsDroppendWhenNoCountryCode()
|
||||
{
|
||||
expect('WC')
|
||||
->andReturn((object) ['customer' => Mockery::mock(\WC_Customer::class)]);
|
||||
|
||||
$wcCart = Mockery::mock(\WC_Cart::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amountFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeRepository
|
||||
->expects('payee')->andReturn($payee);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$itemFactory
|
||||
->expects('fromWcCart')
|
||||
->with($wcCart)
|
||||
->andReturn([]);
|
||||
|
||||
$address = Mockery::mock(Address::class);
|
||||
$address
|
||||
->shouldReceive('countryCode')
|
||||
->andReturn('');
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shipping
|
||||
->shouldReceive('address')
|
||||
->andReturn($address);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shippingFactory
|
||||
->expects('fromWcCustomer')
|
||||
->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$unit = $testee->fromWcCart($wcCart);
|
||||
$this->assertNull($unit->shipping());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseDefault()
|
||||
{
|
||||
$rawItem = (object) ['items' => 1];
|
||||
$rawAmount = (object) ['amount' => 1];
|
||||
$rawPayee = (object) ['payee' => 1];
|
||||
$rawShipping = (object) ['shipping' => 1];
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('fromPayPalResponse')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('fromPayPalResponse')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$item = Mockery::mock(Item::class, ['category' => Item::PHYSICAL_GOODS]);
|
||||
$itemFactory->expects('fromPayPalResponse')->with($rawItem)->andReturn($item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shippingFactory->expects('fromPayPalResponse')->with($rawShipping)->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$response = (object) [
|
||||
'reference_id' => 'default',
|
||||
'description' => 'description',
|
||||
'custom_id' => 'customId',
|
||||
'invoice_id' => 'invoiceId',
|
||||
'soft_descriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
'shipping' => $rawShipping,
|
||||
];
|
||||
|
||||
$unit = $testee->fromPayPalResponse($response);
|
||||
$this->assertTrue(is_a($unit, PurchaseUnit::class));
|
||||
$this->assertEquals($payee, $unit->payee());
|
||||
$this->assertEquals('description', $unit->description());
|
||||
$this->assertEquals('default', $unit->referenceId());
|
||||
$this->assertEquals('customId', $unit->customId());
|
||||
$this->assertEquals('softDescriptor', $unit->softDescriptor());
|
||||
$this->assertEquals('invoiceId', $unit->invoiceId());
|
||||
$this->assertEquals([$item], $unit->items());
|
||||
$this->assertEquals($amount, $unit->amount());
|
||||
$this->assertEquals($shipping, $unit->shipping());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponsePayeeIsNull()
|
||||
{
|
||||
$rawItem = (object) ['items' => 1];
|
||||
$rawAmount = (object) ['amount' => 1];
|
||||
$rawPayee = (object) ['payee' => 1];
|
||||
$rawShipping = (object) ['shipping' => 1];
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('fromPayPalResponse')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$item = Mockery::mock(Item::class, ['category' => Item::PHYSICAL_GOODS]);
|
||||
$itemFactory->expects('fromPayPalResponse')->with($rawItem)->andReturn($item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shippingFactory->expects('fromPayPalResponse')->with($rawShipping)->andReturn($shipping);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$response = (object) [
|
||||
'reference_id' => 'default',
|
||||
'description' => 'description',
|
||||
'customId' => 'customId',
|
||||
'invoiceId' => 'invoiceId',
|
||||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'shipping' => $rawShipping,
|
||||
];
|
||||
|
||||
$unit = $testee->fromPayPalResponse($response);
|
||||
$this->assertNull($unit->payee());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseShippingIsNull()
|
||||
{
|
||||
$rawItem = (object) ['items' => 1];
|
||||
$rawAmount = (object) ['amount' => 1];
|
||||
$rawPayee = (object) ['payee' => 1];
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('fromPayPalResponse')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('fromPayPalResponse')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$item = Mockery::mock(Item::class, ['category' => Item::PHYSICAL_GOODS]);
|
||||
$itemFactory->expects('fromPayPalResponse')->with($rawItem)->andReturn($item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$response = (object) [
|
||||
'reference_id' => 'default',
|
||||
'description' => 'description',
|
||||
'customId' => 'customId',
|
||||
'invoiceId' => 'invoiceId',
|
||||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
];
|
||||
|
||||
$unit = $testee->fromPayPalResponse($response);
|
||||
$this->assertNull($unit->shipping());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponseNeedsReferenceId()
|
||||
{
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$paymentsFacory = Mockery::mock(PaymentsFactory::class);
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFacory
|
||||
);
|
||||
|
||||
$response = (object) [
|
||||
'description' => 'description',
|
||||
'customId' => 'customId',
|
||||
'invoiceId' => 'invoiceId',
|
||||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => '',
|
||||
'items' => [],
|
||||
'payee' => '',
|
||||
'shipping' => '',
|
||||
];
|
||||
|
||||
$this->expectException(\Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException::class);
|
||||
$testee->fromPayPalResponse($response);
|
||||
}
|
||||
|
||||
public function testFromPayPalResponsePaymentsGetAppended()
|
||||
{
|
||||
$rawItem = (object)['items' => 1];
|
||||
$rawAmount = (object)['amount' => 1];
|
||||
$rawPayee = (object)['payee' => 1];
|
||||
$rawShipping = (object)['shipping' => 1];
|
||||
$rawPayments = (object)['payments' => 1];
|
||||
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('fromPayPalResponse')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('fromPayPalResponse')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$item = Mockery::mock(Item::class, ['category' => Item::PHYSICAL_GOODS]);
|
||||
$itemFactory->expects('fromPayPalResponse')->with($rawItem)->andReturn($item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shippingFactory->expects('fromPayPalResponse')->with($rawShipping)->andReturn($shipping);
|
||||
|
||||
$paymentsFactory = Mockery::mock(PaymentsFactory::class);
|
||||
$payments = Mockery::mock(Payments::class);
|
||||
$paymentsFactory->expects('fromPayPalResponse')->with($rawPayments)->andReturn($payments);
|
||||
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFactory
|
||||
);
|
||||
|
||||
$response = (object)[
|
||||
'reference_id' => 'default',
|
||||
'description' => 'description',
|
||||
'customId' => 'customId',
|
||||
'invoiceId' => 'invoiceId',
|
||||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
'shipping' => $rawShipping,
|
||||
'payments' => $rawPayments,
|
||||
];
|
||||
|
||||
$unit = $testee->fromPayPalResponse($response);
|
||||
$this->assertEquals($payments, $unit->payments());
|
||||
}
|
||||
|
||||
public function testFromPayPalResponsePaymentsIsNull()
|
||||
{
|
||||
$rawItem = (object)['items' => 1];
|
||||
$rawAmount = (object)['amount' => 1];
|
||||
$rawPayee = (object)['payee' => 1];
|
||||
$rawShipping = (object)['shipping' => 1];
|
||||
$rawPayments = (object)['payments' => 1];
|
||||
|
||||
$amountFactory = Mockery::mock(AmountFactory::class);
|
||||
$amount = Mockery::mock(Amount::class);
|
||||
$amountFactory->expects('fromPayPalResponse')->with($rawAmount)->andReturn($amount);
|
||||
$payeeFactory = Mockery::mock(PayeeFactory::class);
|
||||
$payee = Mockery::mock(Payee::class);
|
||||
$payeeFactory->expects('fromPayPalResponse')->with($rawPayee)->andReturn($payee);
|
||||
$payeeRepository = Mockery::mock(PayeeRepository::class);
|
||||
$itemFactory = Mockery::mock(ItemFactory::class);
|
||||
$item = Mockery::mock(Item::class, ['category' => Item::PHYSICAL_GOODS]);
|
||||
$itemFactory->expects('fromPayPalResponse')->with($rawItem)->andReturn($item);
|
||||
$shippingFactory = Mockery::mock(ShippingFactory::class);
|
||||
$shipping = Mockery::mock(Shipping::class);
|
||||
$shippingFactory->expects('fromPayPalResponse')->with($rawShipping)->andReturn($shipping);
|
||||
|
||||
$paymentsFactory = Mockery::mock(PaymentsFactory::class);
|
||||
|
||||
$testee = new PurchaseUnitFactory(
|
||||
$amountFactory,
|
||||
$payeeRepository,
|
||||
$payeeFactory,
|
||||
$itemFactory,
|
||||
$shippingFactory,
|
||||
$paymentsFactory
|
||||
);
|
||||
|
||||
$response = (object)[
|
||||
'reference_id' => 'default',
|
||||
'description' => 'description',
|
||||
'customId' => 'customId',
|
||||
'invoiceId' => 'invoiceId',
|
||||
'softDescriptor' => 'softDescriptor',
|
||||
'amount' => $rawAmount,
|
||||
'items' => [$rawItem],
|
||||
'payee' => $rawPayee,
|
||||
'shipping' => $rawShipping,
|
||||
];
|
||||
|
||||
$unit = $testee->fromPayPalResponse($response);
|
||||
$this->assertNull($unit->payments());
|
||||
}
|
||||
}
|
22
tests/PHPUnit/ApiClient/Repository/PayeeRepositoryTest.php
Normal file
22
tests/PHPUnit/ApiClient/Repository/PayeeRepositoryTest.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use Inpsyde\PayPalCommerce\ApiClient\Config\Config;
|
||||
use Inpsyde\PayPalCommerce\ApiClient\TestCase;
|
||||
use Mockery;
|
||||
|
||||
class PayeeRepositoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testDefault()
|
||||
{
|
||||
$merchantEmail = 'merchant_email';
|
||||
$merchantId = 'merchant_id';
|
||||
$testee = new PayeeRepository($merchantEmail, $merchantId);
|
||||
$payee = $testee->payee();
|
||||
$this->assertEquals($merchantId, $payee->merchantId());
|
||||
$this->assertEquals($merchantEmail, $payee->email());
|
||||
}
|
||||
}
|
28
tests/PHPUnit/ApiClient/TestCase.php
Normal file
28
tests/PHPUnit/ApiClient/TestCase.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Inpsyde\PayPalCommerce\ApiClient;
|
||||
|
||||
use function Brain\Monkey\setUp;
|
||||
use function Brain\Monkey\tearDown;
|
||||
use function Brain\Monkey\Functions\expect;
|
||||
use Mockery;
|
||||
|
||||
class TestCase extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
expect('__')->andReturnUsing(function (string $text) {
|
||||
return $text;
|
||||
});
|
||||
setUp();
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
tearDown();
|
||||
Mockery::close();
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue