This commit is contained in:
David Remer 2020-04-06 11:16:18 +03:00
parent 7fd57b9393
commit 005a55c213
62 changed files with 905 additions and 751 deletions

View file

@ -1,7 +1,6 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient;
use Dhii\Modular\Module\ModuleInterface;

View file

@ -20,23 +20,23 @@ use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
return [
'api.host' => function(ContainerInterface $container) : string {
'api.host' => function (ContainerInterface $container) : string {
return 'https://api.sandbox.paypal.com';
},
'api.key' => function(ContainerInterface $container) : string {
'api.key' => function (ContainerInterface $container) : string {
return 'AQB97CzMsd58-It1vxbcDAGvMuXNCXRD9le_XUaMlHB_U7XsU9IiItBwGQOtZv9sEeD6xs2vlIrL4NiD';
},
'api.secret' => function(ContainerInterface $container) : string {
'api.secret' => function (ContainerInterface $container) : string {
return 'EILGMYK_0iiSbja8hT-nCBGl0BvKxEB4riHgyEO7QWDeUzCJ5r42JUEvrI7gpGyw0Qww8AIXxSdCIAny';
},
'api.bearer' => function(ContainerInterface $container) : Bearer {
'api.bearer' => function (ContainerInterface $container) : Bearer {
return new Bearer(
$container->get('api.host'),
$container->get('api.key'),
$container->get('api.secret')
);
},
'api.endpoint.order' => function(ContainerInterface $container) : OrderEndpoint {
'api.endpoint.order' => function (ContainerInterface $container) : OrderEndpoint {
$sessionHandler = $container->get('session.handler');
$orderFactory = $container->get('api.factory.order');
$patchCollectionFactory = $container->get('api.factory.patch-collection-factory');
@ -48,20 +48,24 @@ return [
$patchCollectionFactory
);
},
'api.cart-repository' => function(ContainerInterface $container) : CartRepository {
'api.cart-repository' => function (ContainerInterface $container) : CartRepository {
/*
* ToDo: We need to watch out and see, if we can load the Cart Repository only on specific situations.
* Current problem can be seen here: http://ppc-dev-website.localhost/wp-admin/admin.php?page=wc-settings&tab=tax
* ToDo: We need to watch out and see, if we can load the Cart Repository
* only on specific situations.
* @see http://ppc-dev-website.localhost/wp-admin/admin.php?page=wc-settings&tab=tax
*/
$cart = WC()->cart;
if (! $cart) {
// ToDo: The cart repository gets pulled in the wp-admin, where there is no WC Cart loaded. Rethink.
/**
* ToDo: The cart repository gets pulled in the wp-admin,
* where there is no WC Cart loaded. Rethink.
**/
$cart = new \WC_Cart();
}
$factory = $container->get('api.factory.purchase-unit');
return new CartRepository($cart, $factory);
},
'api.factory.purchase-unit' => function(ContainerInterface $container) : PurchaseUnitFactory {
'api.factory.purchase-unit' => function (ContainerInterface $container) : PurchaseUnitFactory {
$amountFactory = $container->get('api.factory.amount');
$payeeFactory = $container->get('api.factory.payee');
@ -74,30 +78,31 @@ return [
$shippingFactory
);
},
'api.factory.patch-collection-factory' => function(ContainerInterface $container) : PatchCollectionFactory {
'api.factory.patch-collection-factory' => function (ContainerInterface $container)
: PatchCollectionFactory {
return new PatchCollectionFactory();
},
'api.factory.payee' => function(ContainerInterface $container) : PayeeFactory {
'api.factory.payee' => function (ContainerInterface $container) : PayeeFactory {
return new PayeeFactory();
},
'api.factory.item' => function(ContainerInterface $container) : ItemFactory {
'api.factory.item' => function (ContainerInterface $container) : ItemFactory {
return new ItemFactory();
},
'api.factory.shipping' => function(ContainerInterface $container) : ShippingFactory {
'api.factory.shipping' => function (ContainerInterface $container) : ShippingFactory {
$addressFactory = $container->get('api.factory.address');
return new ShippingFactory($addressFactory);
},
'api.factory.amount' => function(ContainerInterface $container) : AmountFactory {
'api.factory.amount' => function (ContainerInterface $container) : AmountFactory {
return new AmountFactory();
},
'api.factory.payer' => function(ContainerInterface $container) : PayerFactory {
'api.factory.payer' => function (ContainerInterface $container) : PayerFactory {
$addressFactory = $container->get('api.factory.address');
return new PayerFactory($addressFactory);
},
'api.factory.address' => function(ContainerInterface $container) : AddressFactory {
'api.factory.address' => function (ContainerInterface $container) : AddressFactory {
return new AddressFactory();
},
'api.factory.order' => function(ContainerInterface $container) : OrderFactory {
'api.factory.order' => function (ContainerInterface $container) : OrderFactory {
$purchaseUnitFactory = $container->get('api.factory.purchase-unit');
$payerFactory = $container->get('api.factory.payer');
return new OrderFactory($purchaseUnitFactory, $payerFactory);

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient;
use Dhii\Container\ServiceProvider;
use Dhii\Modular\Module\Exception\ModuleExceptionInterface;
use Dhii\Modular\Module\ModuleInterface;
@ -21,7 +20,7 @@ class ApiModule implements ModuleInterface
);
}
public function run(ContainerInterface $c)
public function run(ContainerInterface $container)
{
// TODO: Implement run() method.
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Authentication;
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
class Bearer
@ -23,7 +22,7 @@ class Bearer
{
//ToDo: Do not store with wp_cache_get but as transient.
$bearer = wp_cache_get(self::CACHE_KEY);
if ( ! $bearer) {
if (! $bearer) {
return $this->newBearer();
}
return (string) $bearer;

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Endpoint;
use Inpsyde\PayPalCommerce\ApiClient\Authentication\Bearer;
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
@ -35,14 +34,14 @@ class OrderEndpoint
$this->patchCollectionFactory = $patchCollectionFactory;
}
public function createForPurchaseUnits(PurchaseUnit ...$items) : Order {
public function createForPurchaseUnits(PurchaseUnit ...$items) : Order
{
$bearer = $this->bearer->bearer();
$data = [
'intent' => 'CAPTURE',
'purchase_units' => array_map(
function(PurchaseUnit $item) : array {
function (PurchaseUnit $item) : array {
return $item->toArray();
},
$items
@ -63,13 +62,12 @@ class OrderEndpoint
}
$json = json_decode($response['body']);
$order = $this->orderFactory->fromPayPalResponse($json);
$this->sessionHandler->setOrder($order);
$this->sessionHandler->replaceOrder($order);
return $order;
}
public function capture(Order $order) : Order
{
$bearer = $this->bearer->bearer();
$url = trailingslashit($this->host) . 'v2/checkout/orders/' . $order->id() . '/capture';
$args = [
@ -77,7 +75,7 @@ class OrderEndpoint
'Authorization' => 'Bearer ' . $bearer,
'Content-Type' => 'application/json',
'Prefer' => 'return=representation',
]
],
];
$response = wp_remote_post($url, $args);
/**
@ -92,12 +90,12 @@ class OrderEndpoint
}
$json = json_decode($response['body']);
$order = $this->orderFactory->fromPayPalResponse($json);
$this->sessionHandler->setOrder($order);
$this->sessionHandler->replaceOrder($order);
return $order;
}
public function order(string $id) : Order {
public function order(string $id) : Order
{
$bearer = $this->bearer->bearer();
$url = trailingslashit($this->host) . 'v2/checkout/orders/' . $id;
$args = [
@ -114,13 +112,13 @@ class OrderEndpoint
return $this->orderFactory->fromPayPalResponse($json);
}
public function patchOrderWith(Order $orderToUpdate, Order $orderToCompare) : Order {
public function patchOrderWith(Order $orderToUpdate, Order $orderToCompare) : Order
{
$patches = $this->patchCollectionFactory->fromOrders($orderToCompare, $orderToCompare);
if (! count($patches->patches())) {
return $orderToUpdate;
}
$bearer = $this->bearer->bearer();
$url = trailingslashit($this->host) . 'v2/checkout/orders/' . $orderToUpdate->id();
$args = [
@ -138,7 +136,7 @@ class OrderEndpoint
}
$newOrder = $this->order($orderToUpdate->id());
$this->sessionHandler->setOrder($newOrder);
$this->sessionHandler->replaceOrder($newOrder);
return $newOrder;
}
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class Address
{
private $countryCode;
@ -19,8 +18,8 @@ class Address
string $adminArea1 = '',
string $adminArea2 = '',
string $postalCode = ''
)
{
) {
$this->countryCode = $countryCode;
$this->addressLine1 = $addressLine1;
$this->addressLine2 = $addressLine2;
@ -29,22 +28,33 @@ class Address
$this->postalCode = $postalCode;
}
public function countryCode() : string {
public function countryCode() : string
{
return $this->countryCode;
}
public function addressLine1() : string {
public function addressLine1() : string
{
return $this->addressLine1;
}
public function addressLine2() : string {
public function addressLine2() : string
{
return $this->addressLine2;
}
public function adminArea1() : string {
public function adminArea1() : string
{
return $this->adminArea1;
}
public function adminArea2() : string {
public function adminArea2() : string
{
return $this->adminArea2;
}
public function postalCode() : string {
public function postalCode() : string
{
return $this->postalCode;
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class Amount
{

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class AmountBreakdown
{

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class Item
{
@ -30,6 +29,7 @@ class Item
string $sku = '',
string $category = 'PHYSICAL_GOODS'
) {
$this->name = $name;
$this->unitAmount = $unitAmount;
$this->quantity = $quantity;
@ -39,35 +39,43 @@ class Item
$this->category = ($category === self::DIGITAL_GOODS) ? self::DIGITAL_GOODS : self::PHYSICAL_GOODS;
}
public function name() : string {
public function name() : string
{
return $this->name;
}
public function unitAmount() : Money {
public function unitAmount() : Money
{
return $this->unitAmount;
}
public function quantity() : int {
public function quantity() : int
{
return $this->quantity;
}
public function description() : string {
public function description() : string
{
return $this->description;
}
public function tax() : ?Money {
public function tax() : ?Money
{
return $this->tax;
}
public function sku() : string {
public function sku() : string
{
return $this->sku;
}
public function category() : string {
public function category() : string
{
return $this->category;
}
public function toArray() : array {
public function toArray() : array
{
$item = [
'name' => $this->name(),
'unit_amount' => $this->unitAmount()->toArray(),

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class Money
{
@ -25,7 +24,8 @@ class Money
return $this->currencyCode;
}
public function toArray() : array {
public function toArray() : array
{
return [
'currency_code' => $this->currencyCode(),
'value' => $this->value(),

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class Order
{
@ -29,14 +28,17 @@ class Order
string $intent = 'CAPTURE',
\DateTime $updateTime = null
) {
$this->id = $id;
$this->createTime = $createTime;
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
$this->purchaseUnits = array_values(array_filter(
$purchaseUnits,
function($unit) : bool {
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';
@ -44,30 +46,36 @@ class Order
$this->updateTime = $updateTime;
}
public function id() : string {
public function id() : string
{
return $this->id;
}
public function createTime() : \DateTime {
public function createTime() : \DateTime
{
return $this->createTime;
}
public function updateTime() : ?\DateTime {
public function updateTime() : ?\DateTime
{
return $this->updateTime;
}
public function intent() : string {
public function intent() : string
{
return $this->intent;
}
public function payer() : ?Payer {
public function payer() : ?Payer
{
return $this->payer;
}
/**
* @return PurchaseUnit[]
*/
public function purchaseUnits() : array {
public function purchaseUnits() : array
{
return $this->purchaseUnits;
}
@ -76,13 +84,14 @@ class Order
return $this->orderStatus;
}
public function toArray() : array {
public function toArray() : array
{
$order = [
'id' => $this->id(),
'intent' => $this->intent(),
'status' => $this->status()->name(),
'purchase_units' => array_map(
function(PurchaseUnit $unit) : array {
function (PurchaseUnit $unit) : array {
return $unit->toArray();
},
$this->purchaseUnits()

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
class OrderStatus
@ -25,9 +24,11 @@ class OrderStatus
];
private $status;
public function __construct(string $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
));

View file

@ -3,7 +3,7 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
//phpcs:disable Inpsyde.CodeQuality.ElementNameMinimalLength.TooShort
class Patch
{
@ -17,19 +17,25 @@ class Patch
$this->value = $value;
}
public function op() : string {
public function op() : string
{
return $this->op;
}
public function path() : string {
public function path() : string
{
return $this->path;
}
public function value() {
// phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
public function value()
{
return $this->value;
}
// phpcs:enable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
public function toArray() : array {
public function toArray() : array
{
return [
'op' => $this->op(),
'value' => $this->value(),
@ -43,7 +49,8 @@ class Patch
*
* @return string
*/
public function from() : string {
public function from() : string
{
return '';
}
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class PatchCollection
{
@ -24,7 +23,7 @@ class PatchCollection
public function toArray() : array
{
return array_map(
function(Patch $patch) : array {
function (Patch $patch) : array {
return $patch->toArray();
},
$this->patches()

View file

@ -19,19 +19,23 @@ class Payee
string $email,
string $merchantId
) {
$this->email = $email;
$this->merchantId = $merchantId;
}
public function email() : string {
public function email() : string
{
return $this->email;
}
public function merchantId() : string {
public function merchantId() : string
{
return $this->merchantId;
}
public function toArray() : array {
public function toArray() : array
{
return [
'email_address' => $this->email(),
'merchant_id' => $this->merchantId(),

View file

@ -29,6 +29,7 @@ class Payer
PhoneWithType $phone = null,
PayerTaxInfo $taxInfo = null
) {
$this->name = $name;
$this->emailAddress = $emailAddress;
$this->payerId = $payerId;
@ -38,35 +39,43 @@ class Payer
$this->taxInfo = $taxInfo;
}
public function name() : PayerName {
public function name() : PayerName
{
return $this->name;
}
public function emailAddress() : string {
$this->emailAddress;
public function emailAddress() : string
{
return $this->emailAddress;
}
public function payerId() : string {
public function payerId() : string
{
return $this->payerId;
}
public function birthDate() : \DateTime {
public function birthDate() : \DateTime
{
return $this->birthDate;
}
public function address() : Address {
public function address() : Address
{
return $this->address;
}
public function phone() : ?PhoneWithType {
public function phone() : ?PhoneWithType
{
return $this->phone;
}
public function taxInfo() : ?PayerTaxInfo {
public function taxInfo() : ?PayerTaxInfo
{
return $this->taxInfo;
}
public function toArray() : array {
public function toArray() : array
{
$payer = [
'name' => $this->name()->toArray(),
'email_address' => $this->emailAddress(),

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class PayerName
{
@ -13,13 +12,12 @@ class PayerName
public function __construct(
string $givenName,
string $surname
)
{
) {
$this->givenName = $givenName;
$this->surname = $surname;
}
public function givenName() : string
{
return $this->givenName;

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
class PayerTaxInfo
@ -18,10 +17,11 @@ class PayerTaxInfo
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
));
@ -30,14 +30,18 @@ class PayerTaxInfo
$this->type = $type;
}
public function type() : string {
public function type() : string
{
return $this->type;
}
public function taxId() : string {
public function taxId() : string
{
return $this->taxId;
}
public function toArray() : array {
public function toArray() : array
{
return [
'tax_id' => $this->taxId(),
'tax_id_type' => $this->type(),

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class Phone
{

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class PhoneWithType
{
const VALLID_TYPES = [
@ -18,7 +17,6 @@ class PhoneWithType
private $phone;
public function __construct(string $type, Phone $phone)
{
$this->type = in_array($type, self::VALLID_TYPES, true) ? $type : 'OTHER';
$this->phone = $phone;
}
@ -28,15 +26,16 @@ class PhoneWithType
return $this->type;
}
public function phone() : Phone {
public function phone() : Phone
{
return $this->phone;
}
public function toArray() : array {
public function toArray() : array
{
return [
'phone_type' => $this->type(),
'phone_number' => $this->phone()->toArray(),
];
}
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class PurchaseUnit
{
@ -32,25 +31,29 @@ class PurchaseUnit
$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 {
function ($item) : bool {
return is_a($item, Item::class);
}
)
);
//phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
$this->payee = $payee;
$this->customId = $customId;
$this->invoiceId = $invoiceId;
$this->softDescriptor = $softDescriptor;
}
public function amount() : Amount {
public function amount() : Amount
{
return $this->amount;
}
public function shipping() : ?Shipping {
public function shipping() : ?Shipping
{
return $this->shipping;
}
@ -63,13 +66,19 @@ class PurchaseUnit
{
return $this->description;
}
public function customId() : string {
public function customId() : string
{
return $this->customId;
}
public function invoiceId() : string {
public function invoiceId() : string
{
return $this->invoiceId;
}
public function softDescriptor() : string {
public function softDescriptor() : string
{
return $this->softDescriptor;
}
@ -86,13 +95,16 @@ class PurchaseUnit
return $this->items;
}
public function toArray() : array {
public function toArray() : array
{
$purchaseUnit = [
'reference_id' => $this->referenceId(),
'amount' => $this->amount()->toArray(),
'description' => $this->description(),
'items' => array_map(
function(Item $item) : array { return $item->toArray(); },
function (Item $item) : array {
return $item->toArray();
},
$this->items()
),
];

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Entity;
class Shipping
{
@ -15,15 +14,18 @@ class Shipping
$this->address = $address;
}
public function name() : string {
public function name() : string
{
return $this->name;
}
public function address() : Address {
public function address() : Address
{
return $this->address;
}
public function toArray() : array {
public function toArray() : array
{
return [
'name' => [
'full_name' => $this->name(),

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Exception;
class RuntimeException extends \RuntimeException
{

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
use Inpsyde\PayPalCommerce\ApiClient\Entity\Address;
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
@ -14,8 +13,8 @@ class AddressFactory
{
}
public function fromPayPalRequest(\stdClass $data) : Address {
public function fromPayPalRequest(\stdClass $data) : Address
{
if (! isset($data->country_code)) {
new RuntimeException(__('No country given for address.', 'woocommerce-paypal-commerce-gateway'));
}

View file

@ -3,7 +3,6 @@ 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\Money;
@ -16,8 +15,8 @@ class AmountFactory
{
}
public function fromPayPalResponse(\stdClass $data) : 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"));
}
@ -30,7 +29,8 @@ class AmountFactory
return new Amount($money, $breakdown);
}
private function breakDown(\stdClass $data) : AmountBreakdown {
private function breakDown(\stdClass $data) : AmountBreakdown
{
/**
* The order of the keys equals the necessary order of the constructor arguments.
*/
@ -54,12 +54,14 @@ class AmountFactory
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
));

View file

@ -3,7 +3,6 @@ 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;
@ -21,15 +20,21 @@ class ItemFactory
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"));
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"));
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;
$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';

View file

@ -3,7 +3,6 @@ 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;
@ -18,12 +17,13 @@ class OrderFactory
PurchaseUnitFactory $purchaseUnitFactory,
PayerFactory $payerFactory
) {
$this->purchaseUnitFactory = $purchaseUnitFactory;
$this->payerFactory = $payerFactory;
}
public function fromWcOrder(\WC_Order $wcOrder, Order $order) : Order {
public function fromWcOrder(\WC_Order $wcOrder, Order $order) : Order
{
$purchaseUnits = [$this->purchaseUnitFactory->fromWcOrder($wcOrder)];
return new Order(
@ -40,30 +40,44 @@ class OrderFactory
public function fromPayPalResponse(\stdClass $orderData) : Order
{
if (! isset($orderData->id)) {
throw new RuntimeException(__('Order does not contain an id.', 'woocommerce-paypal-commerce-gateway'));
throw new RuntimeException(
__('Order does not contain an id.', 'woocommerce-paypal-commerce-gateway')
);
}
if (! isset($orderData->create_time)) {
throw new RuntimeException(__('Order does not contain a create time.', 'woocommerce-paypal-commerce-gateway'));
throw new RuntimeException(
__('Order does not contain a create time.', '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'));
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'));
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'));
throw new RuntimeException(
__('Order does not contain intent.', 'woocommerce-paypal-commerce-gateway')
);
}
$purchaseUnits = array_map(
function($data) : PurchaseUnit {
function (\stdClass $data) : PurchaseUnit {
return $this->purchaseUnitFactory->fromPayPalResponse($data);
},
$orderData->purchase_units
);
$updateTime = (isset($orderData->update_time)) ? \DateTime::createFromFormat(\DateTime::ISO8601, $orderData->update_time) : null;
$payer = (isset($orderData->payer)) ? $this->payerFactory->fromPayPalResponse($orderData->payer) : null;
$updateTime = (isset($orderData->update_time)) ?
\DateTime::createFromFormat(\DateTime::ISO8601, $orderData->update_time)
: null;
$payer = (isset($orderData->payer)) ?
$this->payerFactory->fromPayPalResponse($orderData->payer)
: null;
return new Order(
$orderData->id,

View file

@ -3,7 +3,6 @@ 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;
@ -12,7 +11,8 @@ use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
class PatchCollectionFactory
{
public function fromOrders(Order $from, Order $to) : PatchCollection {
public function fromOrders(Order $from, Order $to) : PatchCollection
{
$allPatches = [];
$allPatches += $this->purchaseUnits($from->purchaseUnits(), $to->purchaseUnits());
@ -20,14 +20,12 @@ class PatchCollectionFactory
}
/**
* ToDo: This patches the purchaseUnits. The way we do it right now, we simply always patch. This simplifies the
* process but the drawback is, we always have to send a patch request.
*
* @param PurchaseUnit[] $from
* @param PurchaseUnit[] $to
* @return Patch[]
*/
private function purchaseUnits(array $from, array $to) : array {
private function purchaseUnits(array $from, array $to) : array
{
$patches = [];
$path = '/purchase_units';
@ -35,8 +33,11 @@ class PatchCollectionFactory
$needsUpdate = ! count(
array_filter(
$from,
function(PurchaseUnit $unit) use ($purchaseUnitTo) : bool {
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
}
)
);
@ -45,8 +46,7 @@ class PatchCollectionFactory
}
$purchaseUnitFrom = current(array_filter(
$from,
function(PurchaseUnit $unit) use ($purchaseUnitTo) : bool
{
function (PurchaseUnit $unit) use ($purchaseUnitTo) : bool {
return $purchaseUnitTo->referenceId() === $unit->referenceId();
}
));

View file

@ -3,15 +3,14 @@ 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($data) : ?Payee {
public function fromPayPalResponse(\stdClass $data) : ?Payee
{
if (! isset($data->email_address)) {
throw new RuntimeException(__("No email for payee given.", "woocommerce-paypal-commerce-gateway"));
}

View file

@ -3,7 +3,6 @@ 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;
@ -21,7 +20,6 @@ class PayerFactory
public function fromPayPalResponse(\stdClass $data) : Payer
{
$address = $this->addressFactory->fromPayPalRequest($data->address);
$payerName = new PayerName(
$data->name->given_name,
@ -33,8 +31,12 @@ class PayerFactory
$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;
$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,
$data->email_address,

View file

@ -3,7 +3,6 @@ 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;
@ -24,17 +23,19 @@ class PurchaseUnitFactory
ItemFactory $itemFactory,
ShippingFactory $shippingFactory
) {
$this->amountFactory = $amountFactory;
$this->payeeFactory = $payeeFactory;
$this->itemFactory = $itemFactory;
$this->shippingFactory = $shippingFactory;
}
public function fromWcOrder(\WC_Order $order) : PurchaseUnit {
public function fromWcOrder(\WC_Order $order) : PurchaseUnit
{
$currency = get_woocommerce_currency();
$items = array_map(
function(\WC_Order_Item_Product $item) use ($currency, $order): Item {
function (\WC_Order_Item_Product $item) use ($currency, $order): Item {
$product = $item->get_product();
/**
@ -56,7 +57,6 @@ class PurchaseUnitFactory
$product->get_sku(),
($product->is_downloadable()) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
);
},
$order->get_items('line_item')
);
@ -64,15 +64,18 @@ class PurchaseUnitFactory
$total = new Money((float) $order->get_total(), $currency);
$itemsTotal = new Money(array_reduce(
$items,
function(float $total, Item $item) : float {
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);
$shipping = new Money(
(float) $order->get_shipping_total() + (float) $order->get_shipping_tax(),
$currency
);
$taxes = new Money(array_reduce(
$items,
function(float $total, Item $item) : float {
function (float $total, Item $item) : float {
return $total + $item->quantity() * $item->tax()->value();
},
0
@ -119,13 +122,16 @@ class PurchaseUnitFactory
return $purchaseUnit;
}
public function fromWcCart(\WC_Cart $cart) : PurchaseUnit {
public function fromWcCart(\WC_Cart $cart) : PurchaseUnit
{
$currency = get_woocommerce_currency();
$total = new Money((float) $cart->get_total('numeric'), $currency);
$itemsTotal = $cart->get_cart_contents_total();
$itemsTotal = new Money((float) $itemsTotal, $currency);
$shipping = new Money((float) $cart->get_shipping_total() + $cart->get_shipping_tax(), $currency);
$shipping = new Money(
(float) $cart->get_shipping_total() + $cart->get_shipping_tax(),
$currency
);
$taxes = new Money((float) $cart->get_cart_contents_tax(), $currency);
@ -144,7 +150,7 @@ class PurchaseUnitFactory
$breakdown
);
$items = array_map(
function(array $item) use ($currency): Item {
function (array $item) use ($currency): Item {
$product = $item['data'];
/**
* @var \WC_Product $product
@ -165,7 +171,6 @@ class PurchaseUnitFactory
$product->get_sku(),
($product->is_downloadable()) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
);
},
$cart->get_cart_contents()
);
@ -197,8 +202,8 @@ class PurchaseUnitFactory
return $purchaseUnit;
}
public function fromPayPalResponse(\stdClass $data) : 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"));
}
@ -211,14 +216,16 @@ class PurchaseUnitFactory
$items = [];
if (isset($data->items) && is_array($data->items)) {
$items = array_map(
function($item) : Item {
function (\stdClass $item) : Item {
return $this->itemFactory->fromPayPalRequest($item);
},
$data->items
);
}
$payee = isset($data->payee) ? $this->payeeFactory->fromPayPalResponse($data->payee) : null;
$shipping = isset($data->shipping) ? $this->shippingFactory->fromPayPalResponse($data->shipping) : null;
$shipping = isset($data->shipping) ?
$this->shippingFactory->fromPayPalResponse($data->shipping)
: null;
return new PurchaseUnit(
$amount,
$items,

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Factory;
use Inpsyde\PayPalCommerce\ApiClient\Entity\Shipping;
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
@ -16,8 +15,8 @@ class ShippingFactory
$this->addressFactory = $addressFactory;
}
public function fromPayPalResponse(\stdClass $data) : Shipping {
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")

View file

@ -3,7 +3,6 @@ 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;
@ -23,8 +22,8 @@ class CartRepository implements PurchaseUnitRepositoryInterface
*
* @return PurchaseUnit[]
*/
public function all() : array {
public function all() : array
{
return [$this->factory->fromWcCart($this->cart)];
}
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\ApiClient\Repository;
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
interface PurchaseUnitRepositoryInterface

View file

@ -1,12 +1,14 @@
/******/ (function(modules) { // webpackBootstrap
/******/ (function (modules) {
// webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ function __webpack_require__(moduleId)
{
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ if (installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
@ -34,15 +36,15 @@
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ __webpack_require__.d = function (exports, name, getter) {
/******/ if (!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ __webpack_require__.r = function (exports) {
/******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
@ -53,28 +55,44 @@
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ __webpack_require__.t = function (value, mode) {
/******/ if (mode & 1) {
value = __webpack_require__(value);
}
/******/ if (mode & 8) {
return value;
}
/******/ if ((mode & 4) && typeof value === 'object' && value && value.__esModule) {
return value;
}
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ if (mode & 2 && typeof value != 'string') {
for (var key in value) {
__webpack_require__.d(ns, key, function (key) {
return value[key]; }.bind(null, key));
}
}
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ __webpack_require__.n = function (module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ function getDefault()
{
return module['default']; } :
/******/ function getModuleExports()
{
return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/ __webpack_require__.o = function (object, property) {
return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
@ -82,29 +100,27 @@
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./resources/js/button.js");
/******/ })
/************************************************************************/
/******/ ({
/******/ })({
/***/ "./resources/js/button.js":
/*!********************************!*\
/***/ "./resources/js/button.js":
/*!********************************!*\
!*** ./resources/js/button.js ***!
\********************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
/*! no exports provided */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _modules_Renderer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modules/Renderer */ "./resources/js/modules/Renderer.js");
/* harmony import */ var _modules_SingleProductConfig__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/SingleProductConfig */ "./resources/js/modules/SingleProductConfig.js");
/* harmony import */ var _modules_UpdateCart__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modules/UpdateCart */ "./resources/js/modules/UpdateCart.js");
/* harmony import */ var _modules_ErrorHandler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/ErrorHandler */ "./resources/js/modules/ErrorHandler.js");
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _modules_Renderer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modules/Renderer */ "./resources/js/modules/Renderer.js");
/* harmony import */ var _modules_SingleProductConfig__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/SingleProductConfig */ "./resources/js/modules/SingleProductConfig.js");
/* harmony import */ var _modules_UpdateCart__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modules/UpdateCart */ "./resources/js/modules/UpdateCart.js");
/* harmony import */ var _modules_ErrorHandler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/ErrorHandler */ "./resources/js/modules/ErrorHandler.js");
document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('DOMContentLoaded', () => {
if (!typeof PayPalCommerceGateway) {
console.error('PayPal button could not be configured.');
return;
@ -134,33 +150,35 @@ document.addEventListener('DOMContentLoaded', () => {
return;
}
renderer.render(configurator.configuration());
});
});
/***/ }),
/***/ }),
/***/ "./resources/js/modules/ButtonsToggleListener.js":
/*!*******************************************************!*\
/***/ "./resources/js/modules/ButtonsToggleListener.js":
/*!*******************************************************!*\
!*** ./resources/js/modules/ButtonsToggleListener.js ***!
\*******************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/**
"use strict";
__webpack_require__.r(__webpack_exports__);
/**
* When you can't add something to the cart, the PayPal buttons should not show.
* Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.
*/
class ButtonsToggleListener {
constructor(element, showCallback, hideCallback) {
class ButtonsToggleListener {
constructor(element, showCallback, hideCallback)
{
this.element = element;
this.showCallback = showCallback;
this.hideCallback = hideCallback;
this.observer = null;
}
init() {
init()
{
const config = { attributes: true };
const callback = () => {
if (this.element.classList.contains('disabled')) {
@ -173,70 +191,77 @@ class ButtonsToggleListener {
this.observer.observe(this.element, config);
}
disconnect() {
disconnect()
{
this.observer.disconnect();
}
}
}
/* harmony default export */ __webpack_exports__["default"] = (ButtonsToggleListener);
/* harmony default export */ __webpack_exports__["default"] = (ButtonsToggleListener);
/***/ }),
/***/ }),
/***/ "./resources/js/modules/ErrorHandler.js":
/*!**********************************************!*\
/***/ "./resources/js/modules/ErrorHandler.js":
/*!**********************************************!*\
!*** ./resources/js/modules/ErrorHandler.js ***!
\**********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
class ErrorHandler {
"use strict";
__webpack_require__.r(__webpack_exports__);
class ErrorHandler {
constructor() {
constructor()
{
this.wrapper = document.querySelector('.woocommerce-notices-wrapper');
}
message(text) {
message(text)
{
this.wrapper.classList.add('woocommerce-error');
this.wrapper.innerText = this.sanitize(text);
}
sanitize(text) {
sanitize(text)
{
const textarea = document.createElement('textarea');
textarea.innerHTML = text;
return textarea.value;
}
clear() {
clear()
{
if (!this.wrapper.classList.contains('woocommerce-error')) {
return;
}
this.wrapper.classList.remove('woocommerce-error');
this.wrapper.innerText = '';
}
}
}
/* harmony default export */ __webpack_exports__["default"] = (ErrorHandler);
/* harmony default export */ __webpack_exports__["default"] = (ErrorHandler);
/***/ }),
/***/ }),
/***/ "./resources/js/modules/Renderer.js":
/*!******************************************!*\
/***/ "./resources/js/modules/Renderer.js":
/*!******************************************!*\
!*** ./resources/js/modules/Renderer.js ***!
\******************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
class Renderer {
"use strict";
__webpack_require__.r(__webpack_exports__);
class Renderer {
constructor(config) {
constructor(config)
{
this.config = config;
}
render(buttonConfig) {
render(buttonConfig)
{
const script = document.createElement('script');
@ -252,39 +277,43 @@ class Renderer {
this.renderButtons(buttonConfig);
}
renderButtons(buttonConfig) {
renderButtons(buttonConfig)
{
paypal.Buttons(buttonConfig).render(this.config.wrapper);
}
hideButtons() {
hideButtons()
{
document.querySelector(this.config.wrapper).style.display = 'none';
}
showButtons() {
showButtons()
{
document.querySelector(this.config.wrapper).style.display = 'block';
}
}
}
/* harmony default export */ __webpack_exports__["default"] = (Renderer);
/* harmony default export */ __webpack_exports__["default"] = (Renderer);
/***/ }),
/***/ }),
/***/ "./resources/js/modules/SingleProductConfig.js":
/*!*****************************************************!*\
/***/ "./resources/js/modules/SingleProductConfig.js":
/*!*****************************************************!*\
!*** ./resources/js/modules/SingleProductConfig.js ***!
\*****************************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _ButtonsToggleListener__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ButtonsToggleListener */ "./resources/js/modules/ButtonsToggleListener.js");
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _ButtonsToggleListener__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ButtonsToggleListener */ "./resources/js/modules/ButtonsToggleListener.js");
class SingleProductConfig {
class SingleProductConfig {
constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {
constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler)
{
this.config = config;
this.updateCart = updateCart;
this.showButtonCallback = showButtonCallback;
@ -293,7 +322,8 @@ class SingleProductConfig {
this.errorHandler = errorHandler;
}
configuration() {
configuration()
{
if (this.hasVariations()) {
const observer = new _ButtonsToggleListener__WEBPACK_IMPORTED_MODULE_0__["default"](this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);
@ -311,7 +341,8 @@ class SingleProductConfig {
};
}
createOrder() {
createOrder()
{
const createOrder = (data, actions) => {
this.errorHandler.clear();
const product = document.querySelector('[name="add-to-cart"]').value;
@ -342,7 +373,8 @@ class SingleProductConfig {
return createOrder;
}
variations() {
variations()
{
if (!this.hasVariations()) {
return null;
@ -356,32 +388,35 @@ class SingleProductConfig {
return attributes;
}
hasVariations() {
hasVariations()
{
return this.formElement.classList.contains('variations_form');
}
}
}
/* harmony default export */ __webpack_exports__["default"] = (SingleProductConfig);
/* harmony default export */ __webpack_exports__["default"] = (SingleProductConfig);
/***/ }),
/***/ }),
/***/ "./resources/js/modules/UpdateCart.js":
/*!********************************************!*\
/***/ "./resources/js/modules/UpdateCart.js":
/*!********************************************!*\
!*** ./resources/js/modules/UpdateCart.js ***!
\********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
/*! exports provided: default */
/***/ (function (module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
class UpdateCart {
"use strict";
__webpack_require__.r(__webpack_exports__);
class UpdateCart {
constructor(endpoint, nonce) {
constructor(endpoint, nonce)
{
this.endpoint = endpoint;
this.nonce = nonce;
}
update(onResolve, product, qty, variations) {
update(onResolve, product, qty, variations)
{
return new Promise((resolve, reject) => {
fetch(this.endpoint, {
method: 'POST',
@ -404,11 +439,11 @@ class UpdateCart {
});
});
}
}
}
/* harmony default export */ __webpack_exports__["default"] = (UpdateCart);
/* harmony default export */ __webpack_exports__["default"] = (UpdateCart);
/***/ })
/***/ })
/******/ });
//# sourceMappingURL=button.js.map

View file

@ -18,14 +18,11 @@ document.addEventListener(
if (context === 'product' && ! document.querySelector('form.cart') ) {
return;
}
const errorHandler = new ErrorHandler();
const renderer = new Renderer({
url: PayPalCommerceGateway.button.url,
wrapper:PayPalCommerceGateway.button.wrapper
});
const updateCart = new UpdateCart(
PayPalCommerceGateway.ajax.change_cart.endpoint,
PayPalCommerceGateway.ajax.change_cart.nonce
@ -46,6 +43,5 @@ document.addEventListener(
return;
}
renderer.render(configurator.configuration());
}
);

View file

@ -4,14 +4,16 @@
*/
class ButtonsToggleListener {
constructor(element, showCallback, hideCallback) {
constructor(element, showCallback, hideCallback)
{
this.element = element;
this.showCallback = showCallback;
this.hideCallback = hideCallback;
this.observer = null;
}
init() {
init()
{
const config = { attributes : true };
const callback = () => {
if (this.element.classList.contains('disabled')) {
@ -24,7 +26,8 @@ class ButtonsToggleListener {
this.observer.observe(this.element, config);
}
disconnect() {
disconnect()
{
this.observer.disconnect();
}
}

View file

@ -1,21 +1,25 @@
class ErrorHandler {
constructor() {
constructor()
{
this.wrapper = document.querySelector('.woocommerce-notices-wrapper');
}
message(text) {
message(text)
{
this.wrapper.classList.add('woocommerce-error');
this.wrapper.innerText = this.sanitize(text);
}
sanitize(text) {
sanitize(text)
{
const textarea = document.createElement('textarea');
textarea.innerHTML = text;
return textarea.value;
}
clear() {
clear()
{
if (! this.wrapper.classList.contains('woocommerce-error')) {
return;
}

View file

@ -1,10 +1,12 @@
class Renderer {
constructor(config) {
constructor(config)
{
this.config = config;
}
render(buttonConfig) {
render(buttonConfig)
{
const script = document.createElement('script');
@ -20,18 +22,21 @@ class Renderer {
this.renderButtons(buttonConfig);
}
renderButtons(buttonConfig) {
renderButtons(buttonConfig)
{
paypal.Buttons(
buttonConfig
).render(this.config.wrapper);
}
hideButtons() {
hideButtons()
{
document.querySelector(this.config.wrapper).style.display = 'none';
}
showButtons() {
showButtons()
{
document.querySelector(this.config.wrapper).style.display = 'block';
}
}

View file

@ -18,7 +18,8 @@ class SingleProductConfig {
this.errorHandler = errorHandler;
}
configuration() {
configuration()
{
if ( this.hasVariations() ) {
const observer = new ButtonsToggleListener(
@ -40,7 +41,8 @@ class SingleProductConfig {
}
}
createOrder() {
createOrder()
{
const createOrder = (data, actions) => {
this.errorHandler.clear();
const product = document.querySelector('[name="add-to-cart"]').value;
@ -54,9 +56,9 @@ class SingleProductConfig {
nonce:this.config.ajax.create_order.nonce,
purchase_units
})
}).then(function(res) {
}).then(function (res) {
return res.json();
}).then(function(data) {
}).then(function (data) {
if (! data.success) {
//Todo: Error handling
return;
@ -71,7 +73,8 @@ class SingleProductConfig {
return createOrder;
}
variations() {
variations()
{
if (! this.hasVariations()) {
return null;
@ -87,7 +90,8 @@ class SingleProductConfig {
return attributes;
}
hasVariations() {
hasVariations()
{
return this.formElement.classList.contains('variations_form');
}
}

View file

@ -1,12 +1,14 @@
class UpdateCart {
constructor(endpoint, nonce) {
constructor(endpoint, nonce)
{
this.endpoint = endpoint;
this.nonce = nonce;
}
update(onResolve, product, qty, variations) {
return new Promise( (resolve, reject) => {
update(onResolve, product, qty, variations)
{
return new Promise((resolve, reject) => {
fetch(
this.endpoint,
{
@ -22,7 +24,7 @@ class UpdateCart {
(result) => {
return result.json();
}
).then( (result) => {
).then((result) => {
if (! result.success) {
reject(result.data);
return;
@ -30,8 +32,7 @@ class UpdateCart {
const resolved = onResolve(result.data);
resolve(resolved);
}
)
})
});
}
}

View file

@ -11,17 +11,20 @@ use Inpsyde\PayPalCommerce\Button\Endpoint\RequestData;
use Inpsyde\PayPalCommerce\Button\Exception\RuntimeException;
return [
'button.smart-button' => function(ContainerInterface $container) {
'button.smart-button' => function (ContainerInterface $container) : SmartButton {
$isSandbox = true;
return new SmartButton($container->get('button.url'), $isSandbox);
},
'button.url' => function(ContainerInterface $container) : string {
return plugins_url('/modules/ppcp-button/', dirname(__FILE__, 3) . '/woocommerce-paypal-commerce-gateway.php');
'button.url' => function (ContainerInterface $container) : string {
return plugins_url(
'/modules/ppcp-button/',
dirname(__FILE__, 3) . '/woocommerce-paypal-commerce-gateway.php'
);
},
'button.request-data' => function(ContainerInterface $container) : RequestData {
'button.request-data' => function (ContainerInterface $container) : RequestData {
return new RequestData();
},
'button.endpoint.change-cart' => function(ContainerInterface $container) : ChangeCartEndpoint {
'button.endpoint.change-cart' => function (ContainerInterface $container) : ChangeCartEndpoint {
if (! \WC()->cart) {
throw new RuntimeException('cant initialize endpoint at this moment');
}
@ -31,10 +34,10 @@ return [
$repository = $container->get('api.cart-repository');
return new ChangeCartEndpoint($cart, $shipping, $requestData, $repository);
},
'button.endpoint.create-order' => function(ContainerInterface $container) : CreateOrderEndpoint {
'button.endpoint.create-order' => function (ContainerInterface $container) : CreateOrderEndpoint {
$requestData = $container->get('button.request-data');
$repository = $container->get('api.cart-repository');
$apiClient = $container->get('api.endpoint.order');
return new CreateOrderEndpoint($requestData, $repository, $apiClient);
}
},
];

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Button\Assets;
use Inpsyde\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
use Inpsyde\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
@ -16,13 +15,14 @@ class SmartButton
string $moduleUrl,
bool $isSandbox
) {
$this->moduleUrl = $moduleUrl;
$this->isSandbox = $isSandbox;
}
public function renderWrapper() : bool
{
$renderer = function() {
$renderer = function () {
echo '<div id="ppc-button"></div>';
};
if (is_product()) {
@ -51,7 +51,6 @@ class SmartButton
$this->moduleUrl . '/assets/js/button.js'
);
$params = [
'client-id' => 'AcVzowpNCpTxFzLG7onQI4JD0sVcA0BkZv-D42qRZPv_gZ8cNfX9zGL_8bXmSu7cbJ5B2DH7sot8vDpw',
'currency' => get_woocommerce_currency(),
@ -63,18 +62,18 @@ class SmartButton
'context' => $this->context(),
'ajax' => [
'change_cart' => [
'endpoint' => home_url(\WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT )),
'endpoint' => home_url(\WC_AJAX::get_endpoint(ChangeCartEndpoint::ENDPOINT)),
'nonce' => wp_create_nonce(ChangeCartEndpoint::nonce()),
],
'create_order' => [
'endpoint' => home_url(\WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT )),
'endpoint' => home_url(\WC_AJAX::get_endpoint(CreateOrderEndpoint::ENDPOINT)),
'nonce' => wp_create_nonce(CreateOrderEndpoint::nonce()),
],
],
'button' => [
'wrapper' => '#ppc-button',
'url' =>$smartButtonUrl,
]
],
];
wp_localize_script(
'paypal-smart-button',
@ -84,7 +83,8 @@ class SmartButton
return true;
}
private function context() : string {
private function context() : string
{
$context = 'mini-cart';
if (is_product()) {
$context = 'product';

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Button;
use Dhii\Container\ServiceProvider;
use Dhii\Modular\Module\ModuleInterface;
use Inpsyde\PayPalCommerce\Button\Assets\SmartButton;
@ -35,20 +34,20 @@ class ButtonModule implements ModuleInterface
*/
add_action(
'wp',
function() use ($smartButton) {
function () use ($smartButton) {
if (is_admin()) {
return;
}
$smartButton->renderWrapper();
}
);
add_action('wp_enqueue_scripts', function() use ($smartButton) {
add_action('wp_enqueue_scripts', function () use ($smartButton) {
$smartButton->enqueue();
});
add_action(
'wc_ajax_' . ChangeCartEndpoint::ENDPOINT,
function() use ($container) {
function () use ($container) {
$endpoint = $container->get('button.endpoint.change-cart');
/**
* @var ChangeCartEndpoint $endpoint
@ -59,7 +58,7 @@ class ButtonModule implements ModuleInterface
add_action(
'wc_ajax_' . CreateOrderEndpoint::ENDPOINT,
function() use ($container) {
function () use ($container) {
$endpoint = $container->get('button.endpoint.create-order');
/**
* @var ChangeCartEndpoint $endpoint

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Button\Endpoint;
use Inpsyde\PayPalCommerce\ApiClient\Entity\Item;
use Inpsyde\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
@ -24,6 +23,7 @@ class ChangeCartEndpoint implements EndpointInterface
RequestData $requestData,
CartRepository $repository
) {
$this->cart = $cart;
$this->shipping = $shipping;
$this->requestData = $requestData;
@ -40,16 +40,25 @@ class ChangeCartEndpoint implements EndpointInterface
try {
$data = $this->requestData->readRequest($this->nonce());
if (
! isset($data['product'])
if (! isset($data['product'])
|| ! isset($data['qty'])
) {
wp_send_json_error(__('Necessary fields not defined. Action aborted.', 'woocommerce-paypal-commerce-gateway'));
wp_send_json_error(
__(
'Necessary fields not defined. Action aborted.',
'woocommerce-paypal-commerce-gateway'
)
);
return false;
}
$product = wc_get_product((int) $data['product']);
if (! $product) {
wp_send_json_error(__('No product defined. Action aborted.', 'woocommerce-paypal-commerce-gateway'));
wp_send_json_error(
__(
'No product defined. Action aborted.',
'woocommerce-paypal-commerce-gateway'
)
);
return false;
}
@ -60,13 +69,12 @@ class ChangeCartEndpoint implements EndpointInterface
$success = $this->addProduct($product, $quantity)
: $this->addVariableProduct($product, $quantity, $data['variations']);
if (! $success) {
$message = __('Something went wrong. Action aborted', 'woocommerce-paypal-commerce-gateway');
$errors = wc_get_notices('error');
if (count($errors)) {
$message = array_reduce(
$errors,
function(string $add, $error) : string {
function (string $add, array $error) : string {
return $add . $error['notice'] . ' ';
},
''
@ -85,27 +93,32 @@ class ChangeCartEndpoint implements EndpointInterface
}
}
private function addProduct(\WC_Product $product, int $quantity) : bool {
private function addProduct(\WC_Product $product, int $quantity) : bool
{
return false !== $this->cart->add_to_cart($product->get_id(), $quantity);
}
private function addVariableProduct(\WC_Product $product, int $quantity, array $postVariations) : bool {
private function addVariableProduct(
\WC_Product $product,
int $quantity,
array $postVariations
) : bool {
foreach ($postVariations as $key => $value) {
$variations[$value['name']] = $value['value'];
}
$dataStore = \WC_Data_Store::load( 'product' );
$variationId = $dataStore->find_matching_product_variation( $product, $variations );
$dataStore = \WC_Data_Store::load('product');
$variationId = $dataStore->find_matching_product_variation($product, $variations);
//ToDo: Check stock status for variation.
return false !== WC()->cart->add_to_cart( $product->get_id(), $quantity, $variationId, $variations );
return false !== WC()->cart->add_to_cart($product->get_id(), $quantity, $variationId, $variations);
}
private function generatePurchaseUnits() : array {
private function generatePurchaseUnits() : array
{
return array_map(
function(PurchaseUnit $lineItem) : array {
function (PurchaseUnit $lineItem) : array {
return $lineItem->toArray();
},
$this->repository->all()

View file

@ -20,6 +20,7 @@ class CreateOrderEndpoint implements EndpointInterface
CartRepository $repository,
OrderEndpoint $apiEndpoint
) {
$this->requestData = $requestData;
$this->repository = $repository;
$this->apiEndpoint = $apiEndpoint;
@ -32,7 +33,6 @@ class CreateOrderEndpoint implements EndpointInterface
public function handleRequest() : bool
{
try {
$this->requestData->readRequest($this->nonce());
$purchaseUnits = $this->repository->all();
@ -41,10 +41,9 @@ class CreateOrderEndpoint implements EndpointInterface
);
wp_send_json_success($order->toArray());
return false;
} catch (\RuntimeException $error ) {
} catch (\RuntimeException $error) {
wp_send_json_error($error->getMessage());
return false;
}
}
}

View file

@ -3,12 +3,10 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Button\Endpoint;
interface EndpointInterface
{
public static function nonce() : string;
public function handleRequest() : bool;
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Button\Endpoint;
use Inpsyde\PayPalCommerce\Button\Exception\RuntimeException;
class RequestData
@ -11,11 +10,9 @@ class RequestData
public function readRequest(string $nonce) : array
{
$stream = file_get_contents('php://input');
$json = json_decode($stream, true);
if (
! isset($json['nonce'])
if (! isset($json['nonce'])
|| !wp_verify_nonce($json['nonce'], $nonce)
) {
throw new RuntimeException(
@ -26,8 +23,8 @@ class RequestData
return $this->sanitize($json);
}
private function sanitize(array $assocArray) : array {
private function sanitize(array $assocArray) : array
{
$data = [];
foreach ((array) $assocArray as $rawKey => $rawValue) {
if (! is_array($rawValue)) {

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Button\Exception;
class RuntimeException extends \RuntimeException
{

View file

@ -1,4 +1,4 @@
const path = require( 'path' );
const path = require('path');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
@ -6,10 +6,10 @@ module.exports = {
mode: isProduction ? 'production' : 'development',
target: 'web',
entry: {
button: path.resolve( './resources/js/button.js' ),
button: path.resolve('./resources/js/button.js'),
},
output: {
path: path.resolve( __dirname, 'assets/' ),
path: path.resolve(__dirname, 'assets/'),
filename: 'js/[name].js',
},
module: {

View file

@ -6,7 +6,7 @@ namespace Inpsyde\PayPalCommerce\Session;
use Dhii\Data\Container\ContainerInterface;
return [
'session.handler' => function(ContainerInterface $container) : SessionHandler {
'session.handler' => function (ContainerInterface $container) : SessionHandler {
if (is_admin()) {
return new SessionHandler();
@ -18,5 +18,5 @@ return [
$sessionHandler = new SessionHandler();
WC()->session->set(SessionHandler::ID, $sessionHandler);
return $sessionHandler;
}
},
];

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Session;
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
class SessionHandler
@ -11,17 +10,20 @@ class SessionHandler
const ID = 'ppcp';
private $order;
public function order() : ?Order {
public function order() : ?Order
{
return $this->order;
}
public function setOrder(Order $order) : SessionHandler {
public function replaceOrder(Order $order) : SessionHandler
{
$this->order = $order;
$this->storeSession();
return $this;
}
private function storeSession() {
private function storeSession()
{
WC()->session->set(self::ID, $this);
}
}

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Session;
use Dhii\Container\ServiceProvider;
use Dhii\Modular\Module\ModuleInterface;
use Interop\Container\ServiceProviderInterface;
@ -20,12 +19,12 @@ class SessionModule implements ModuleInterface
);
}
public function run(ContainerInterface $c)
public function run(ContainerInterface $container)
{
add_action(
'woocommerce_init',
function() use ($c) {
$c->get('session.handler');
function () use ($container) {
$container->get('session.handler');
}
);
}

View file

@ -8,15 +8,15 @@ use Inpsyde\PayPalCommerce\WcGateway\Checkout\DisableGateways;
use Inpsyde\PayPalCommerce\WcGateway\Gateway\WcGateway;
return [
'wcgateway.gateway' => function(ContainerInterface $container) : WcGateway {
'wcgateway.gateway' => function (ContainerInterface $container) : WcGateway {
$sessionHandler = $container->get('session.handler');
$cartRepository = $container->get('api.cart-repository');
$endpoint = $container->get('api.endpoint.order');
$orderFactory = $container->get('api.factory.order');
return new WcGateway($sessionHandler, $cartRepository, $endpoint, $orderFactory);
},
'wcgateway.disabler' => function(ContainerInterface $container) : DisableGateways {
'wcgateway.disabler' => function (ContainerInterface $container) : DisableGateways {
$sessionHandler = $container->get('session.handler');
return new DisableGateways($sessionHandler);
}
},
];

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Checkout;
use Inpsyde\PayPalCommerce\Session\SessionHandler;
use Inpsyde\PayPalCommerce\WcGateway\Gateway\WcGateway;

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use Inpsyde\PayPalCommerce\ApiClient\Entity\Order;
use Inpsyde\PayPalCommerce\ApiClient\Entity\OrderStatus;
@ -11,6 +10,8 @@ use Inpsyde\PayPalCommerce\ApiClient\Factory\OrderFactory;
use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
use Inpsyde\PayPalCommerce\Session\SessionHandler;
//phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
class WcGateway extends \WC_Payment_Gateway
{
@ -35,68 +36,79 @@ class WcGateway extends \WC_Payment_Gateway
$this->orderFactory = $orderFactory;
$this->id = self::ID;
$this->method_title = __('PayPal Payments', 'woocommerce-paypal-gateway');
$this->method_description = __('Provide your customers with the PayPal payment system', 'woocommerce-paypal-gateway');
$this->method_description = __(
'Provide your customers with the PayPal payment system',
'woocommerce-paypal-gateway'
);
$this->init_form_fields();
$this->init_settings();
$this->isSandbox = $this->get_option( 'sandbox_on', 'yes' ) === 'yes';
$this->isSandbox = $this->get_option('sandbox_on', 'yes') === 'yes';
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action(
'woocommerce_update_options_payment_gateways_' . $this->id,
[
$this,
'process_admin_options',
]
);
}
public function init_form_fields()
{
$this->form_fields = [
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce-paypal-gateway' ),
'enabled' => [
'title' => __('Enable/Disable', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __( 'Enable PayPal Payments', 'woocommerce-paypal-gateway' ),
'default' => 'yes'
),
'sandbox_on' => array(
'title' => __( 'Enable Sandbox', 'woocommerce-paypal-gateway' ),
'label' => __('Enable PayPal Payments', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'sandbox_on' => [
'title' => __('Enable Sandbox', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __( 'For testing your integration, you can enable the sandbox.', 'woocommerce-paypal-gateway' ),
'default' => 'yes'
'label' => __(
'For testing your integration, you can enable the sandbox.',
'woocommerce-paypal-gateway'
),
'default' => 'yes',
],
];
}
function process_payment($orderId) : ?array
public function process_payment($orderId) : ?array
{
global $woocommerce;
$wcOrder = new \WC_Order( $orderId );
$wcOrder = new \WC_Order($orderId);
//ToDo: We need to fetch the order from paypal again to get it with the new status.
$order = $this->sessionHandler->order();
$errorMessage = null;
if (! $order || ! $order->status()->is(OrderStatus::APPROVED)) {
$errorMessage = 'not approve yet';
}
$errorMessage = null;
if ($errorMessage) {
wc_add_notice( __('Payment error:', 'woocommerce-paypal-gateway') . $errorMessage, 'error' );
wc_add_notice(__('Payment error:', 'woocommerce-paypal-gateway') . $errorMessage, 'error');
return null;
}
$order = $this->patchOrder($wcOrder, $order);
$order = $this->endpoint->capture($order);
$wcOrder->update_status('on-hold', __( 'Awaiting payment.', 'woocommerce-paypal-gateway' ));
$wcOrder->update_status('on-hold', __('Awaiting payment.', 'woocommerce-paypal-gateway'));
if ($order->status()->is(OrderStatus::COMPLETED)) {
$wcOrder->update_status('processing', __( 'Payment received.', 'woocommerce-paypal-gateway' ));
$wcOrder->update_status('processing', __('Payment received.', 'woocommerce-paypal-gateway'));
}
$woocommerce->cart->empty_cart();
return array(
return [
'result' => 'success',
'redirect' => $this->get_return_url( $wcOrder )
);
'redirect' => $this->get_return_url($wcOrder),
];
}
private function patchOrder(\WC_Order $wcOrder, Order $order) : Order {
private function patchOrder(\WC_Order $wcOrder, Order $order) : Order
{
$updatedOrder = $this->orderFactory->fromWcOrder($wcOrder, $order);
$order = $this->endpoint->patchOrderWith($order, $updatedOrder);
return $order;

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway;
use Dhii\Container\ServiceProvider;
use Dhii\Modular\Module\Exception\ModuleExceptionInterface;
use Dhii\Modular\Module\ModuleInterface;
@ -22,21 +21,21 @@ class WcGatewayModule implements ModuleInterface
);
}
public function run(ContainerInterface $c)
public function run(ContainerInterface $container)
{
add_filter(
'woocommerce_payment_gateways',
function($methods) use ($c) : array {
function ($methods) use ($container) : array {
$methods[] = $c->get('wcgateway.gateway');
$methods[] = $container->get('wcgateway.gateway');
return (array) $methods;
}
);
add_filter(
'woocommerce_available_payment_gateways',
function($methods) use ($c) : array {
$disabler = $c->get('wcgateway.disabler');
function ($methods) use ($container) : array {
$disabler = $container->get('wcgateway.disabler');
/**
* @var DisableGateways $disabler
*/

View file

@ -2,4 +2,9 @@
<ruleset name="Inpsyde Coding Standard">
<rule ref="Inpsyde"/>
<file>./src</file>
<file>./modules.local</file>
<exclude-pattern>*\.(inc|css|js)$</exclude-pattern>
<exclude-pattern>*\.(inc|css|js)$</exclude-pattern>
</ruleset>

View file

@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce;
use Dhii\Container\ServiceProvider;
use Dhii\Modular\Module\Exception\ModuleExceptionInterface;
use Dhii\Modular\Module\ModuleInterface;
@ -18,7 +17,7 @@ class PluginModule implements ModuleInterface
return new ServiceProvider([], []);
}
public function run(ContainerInterface $c)
public function run(ContainerInterface $container)
{
// TODO: Implement run() method.
}