Add InPost Pay integration to admin templates
- Created a new template for the cart rule form with custom label, switch, and choice widgets. - Implemented the InPost Pay block in the order details template for displaying delivery method, APM, and VAT invoice request. - Added legacy support for the order details template to maintain compatibility with older PrestaShop versions.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp;
|
||||
|
||||
use izi\prestashop\Http\Client\Factory\ClientFactoryInterface;
|
||||
use izi\prestashop\Http\Client\Factory\GuzzleClientFactory;
|
||||
use izi\prestashop\OAuth2\Authentication\ClientCredentialsInterface;
|
||||
use izi\prestashop\OAuth2\Authentication\ClientSecretPost;
|
||||
use izi\prestashop\OAuth2\AuthorizationProvider;
|
||||
use izi\prestashop\OAuth2\AuthorizationProviderFactoryInterface;
|
||||
use izi\prestashop\OAuth2\AuthorizationProviderInterface;
|
||||
use izi\prestashop\OAuth2\AuthorizationServerClient;
|
||||
use izi\prestashop\OAuth2\AuthorizationServerClientInterface;
|
||||
use izi\prestashop\OAuth2\Grant\ClientCredentialsGrant;
|
||||
use izi\prestashop\OAuth2\Token\AccessTokenRepositoryInterface;
|
||||
use izi\prestashop\OAuth2\UriCollectionInterface;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use Psr\Http\Message\StreamFactoryInterface;
|
||||
|
||||
final class AuthorizationProviderFactory implements AuthorizationProviderFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @var RequestFactoryInterface
|
||||
*/
|
||||
private $requestFactory;
|
||||
|
||||
/**
|
||||
* @var StreamFactoryInterface
|
||||
*/
|
||||
private $streamFactory;
|
||||
|
||||
/**
|
||||
* @var ClientFactoryInterface
|
||||
*/
|
||||
private $clientFactory;
|
||||
|
||||
public function __construct(RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, ?ClientFactoryInterface $clientFactory = null)
|
||||
{
|
||||
$this->requestFactory = $requestFactory;
|
||||
$this->streamFactory = $streamFactory;
|
||||
$this->clientFactory = $clientFactory ?? new GuzzleClientFactory();
|
||||
}
|
||||
|
||||
public function create(UriCollectionInterface $uriCollection, ClientCredentialsInterface $credentials, ?AccessTokenRepositoryInterface $tokenRepository = null): AuthorizationProviderInterface
|
||||
{
|
||||
$authSeverClient = $this->createAuthServerClient($uriCollection);
|
||||
|
||||
return new AuthorizationProvider(
|
||||
$authSeverClient,
|
||||
new ClientCredentialsGrant(),
|
||||
$credentials,
|
||||
$tokenRepository
|
||||
);
|
||||
}
|
||||
|
||||
private function createAuthServerClient(UriCollectionInterface $uriCollection): AuthorizationServerClientInterface
|
||||
{
|
||||
$httpClient = $this->clientFactory->create();
|
||||
|
||||
return new AuthorizationServerClient(
|
||||
$httpClient,
|
||||
$this->requestFactory,
|
||||
$this->streamFactory,
|
||||
$uriCollection,
|
||||
new ClientSecretPost()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Basket;
|
||||
|
||||
use izi\prestashop\BasketApp\Basket\Request\Basket;
|
||||
use izi\prestashop\BasketApp\Basket\Response\BasketBindingKeyResponse;
|
||||
use izi\prestashop\BasketApp\Basket\Response\BasketBindingResponse;
|
||||
use izi\prestashop\BasketApp\Basket\Response\UpdateBasketResponse;
|
||||
use izi\prestashop\BasketApp\Exception\BasketExpiredException;
|
||||
use izi\prestashop\BasketApp\Exception\BasketNotBoundException;
|
||||
use izi\prestashop\BasketApp\Exception\BasketNotFoundException;
|
||||
|
||||
interface BasketsApiClientInterface
|
||||
{
|
||||
/**
|
||||
* @throws BasketNotFoundException
|
||||
* @throws BasketExpiredException
|
||||
* @throws BasketNotBoundException
|
||||
*/
|
||||
public function deleteBasketBinding(string $basketId, bool $orderCompleted = false): void;
|
||||
|
||||
/**
|
||||
* @throws BasketExpiredException
|
||||
*/
|
||||
public function getBasketBinding(string $basketId, ?string $browserId = null): BasketBindingResponse;
|
||||
|
||||
public function initializeBasketBinding(string $basketId): BasketBindingKeyResponse;
|
||||
|
||||
/**
|
||||
* @throws BasketNotFoundException
|
||||
* @throws BasketExpiredException
|
||||
*/
|
||||
public function updateBasket(string $basketId, Basket $basket): UpdateBasketResponse;
|
||||
}
|
||||
130
modules/inpostizi/src/BasketApp/Basket/Request/Basket.php
Normal file
130
modules/inpostizi/src/BasketApp/Basket/Request/Basket.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Basket\Request;
|
||||
|
||||
use izi\prestashop\Common\Basket\AvailablePromotion;
|
||||
use izi\prestashop\Common\Basket\Consent;
|
||||
use izi\prestashop\Common\Basket\DeliveryOption;
|
||||
use izi\prestashop\Common\Basket\Product;
|
||||
use izi\prestashop\Common\Basket\Summary;
|
||||
use izi\prestashop\Common\PromoCode;
|
||||
|
||||
final class Basket implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var Summary
|
||||
*/
|
||||
private $summary;
|
||||
|
||||
/**
|
||||
* @var DeliveryOption[]
|
||||
*/
|
||||
private $delivery;
|
||||
|
||||
/**
|
||||
* @var PromoCode[]
|
||||
*/
|
||||
private $promo_codes;
|
||||
|
||||
/**
|
||||
* @var Product[]
|
||||
*/
|
||||
private $products;
|
||||
|
||||
/**
|
||||
* @var Product[]
|
||||
*/
|
||||
private $related_products;
|
||||
|
||||
/**
|
||||
* @var Consent[]
|
||||
*/
|
||||
private $consents;
|
||||
|
||||
/**
|
||||
* @var AvailablePromotion[]
|
||||
*/
|
||||
private $promotions_available;
|
||||
|
||||
/**
|
||||
* @param DeliveryOption[] $delivery
|
||||
* @param PromoCode[] $promo_codes
|
||||
* @param Product[] $products
|
||||
* @param Product[] $related_products
|
||||
* @param Consent[] $consents
|
||||
* @param AvailablePromotion[] $promotions_available
|
||||
*/
|
||||
public function __construct(Summary $summary, array $delivery, array $products, array $consents, array $promo_codes = [], array $related_products = [], array $promotions_available = [])
|
||||
{
|
||||
$this->summary = $summary;
|
||||
$this->delivery = $delivery;
|
||||
$this->promo_codes = $promo_codes;
|
||||
$this->products = $products;
|
||||
$this->related_products = $related_products;
|
||||
$this->consents = $consents;
|
||||
$this->promotions_available = $promotions_available;
|
||||
}
|
||||
|
||||
public function getSummary(): Summary
|
||||
{
|
||||
return $this->summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DeliveryOption[]
|
||||
*/
|
||||
public function getDelivery(): array
|
||||
{
|
||||
return $this->delivery;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PromoCode[]
|
||||
*/
|
||||
public function getPromoCodes(): array
|
||||
{
|
||||
return $this->promo_codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Product[]
|
||||
*/
|
||||
public function getProducts(): array
|
||||
{
|
||||
return $this->products;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Product[]
|
||||
*/
|
||||
public function getRelatedProducts(): array
|
||||
{
|
||||
return $this->related_products;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Consent[]
|
||||
*/
|
||||
public function getConsents(): array
|
||||
{
|
||||
return $this->consents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AvailablePromotion[]
|
||||
*/
|
||||
public function getPromotionsAvailable(): array
|
||||
{
|
||||
return $this->promotions_available;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Basket\Response;
|
||||
|
||||
final class BasketBindingKeyResponse implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $basket_binding_api_key;
|
||||
|
||||
public function __construct(string $basket_binding_api_key)
|
||||
{
|
||||
$this->basket_binding_api_key = $basket_binding_api_key;
|
||||
}
|
||||
|
||||
public function getBindingKey(): string
|
||||
{
|
||||
return $this->basket_binding_api_key;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Basket\Response;
|
||||
|
||||
final class BasketBindingResponse implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $basket_linked;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $browser_trusted;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $inpost_basket_id;
|
||||
|
||||
/**
|
||||
* @var ClientDetails|null
|
||||
*/
|
||||
private $client_details;
|
||||
|
||||
public function __construct(bool $basket_linked, bool $browser_trusted, ?string $inpost_basket_id = null, ?ClientDetails $client_details = null)
|
||||
{
|
||||
$this->basket_linked = $basket_linked;
|
||||
$this->browser_trusted = $browser_trusted;
|
||||
$this->inpost_basket_id = $inpost_basket_id;
|
||||
$this->client_details = $client_details;
|
||||
}
|
||||
|
||||
public function isBasketLinked(): bool
|
||||
{
|
||||
return $this->basket_linked;
|
||||
}
|
||||
|
||||
public function isBrowserTrusted(): bool
|
||||
{
|
||||
return $this->browser_trusted;
|
||||
}
|
||||
|
||||
public function getInPostBasketId(): ?string
|
||||
{
|
||||
return $this->inpost_basket_id;
|
||||
}
|
||||
|
||||
public function getClientDetails(): ?ClientDetails
|
||||
{
|
||||
return $this->client_details;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Basket\Response;
|
||||
|
||||
use izi\prestashop\Common\PhoneNumber;
|
||||
|
||||
final class ClientDetails implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var PhoneNumber
|
||||
*/
|
||||
private $phone_number;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $masked_phone_number;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $surname;
|
||||
|
||||
public function __construct(PhoneNumber $phone_number, string $masked_phone_number, string $name, string $surname)
|
||||
{
|
||||
$this->phone_number = $phone_number;
|
||||
$this->masked_phone_number = $masked_phone_number;
|
||||
$this->name = $name;
|
||||
$this->surname = $surname;
|
||||
}
|
||||
|
||||
public function getPhoneNumber(): PhoneNumber
|
||||
{
|
||||
return $this->phone_number;
|
||||
}
|
||||
|
||||
public function getMaskedPhoneNumber(): string
|
||||
{
|
||||
return $this->masked_phone_number;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getSurname(): string
|
||||
{
|
||||
return $this->surname;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Basket\Response;
|
||||
|
||||
final class UpdateBasketResponse implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $inpost_basket_id;
|
||||
|
||||
public function __construct(string $inpost_basket_id)
|
||||
{
|
||||
$this->inpost_basket_id = $inpost_basket_id;
|
||||
}
|
||||
|
||||
public function getInPostBasketId(): string
|
||||
{
|
||||
return $this->inpost_basket_id;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
298
modules/inpostizi/src/BasketApp/BasketAppClient.php
Normal file
298
modules/inpostizi/src/BasketApp/BasketAppClient.php
Normal file
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp;
|
||||
|
||||
use izi\prestashop\BasketApp\Basket\Request\Basket;
|
||||
use izi\prestashop\BasketApp\Basket\Response\BasketBindingKeyResponse;
|
||||
use izi\prestashop\BasketApp\Basket\Response\BasketBindingResponse;
|
||||
use izi\prestashop\BasketApp\Basket\Response\UpdateBasketResponse;
|
||||
use izi\prestashop\BasketApp\Exception\BasketAppException;
|
||||
use izi\prestashop\BasketApp\Order\Request\OrderEvent;
|
||||
use izi\prestashop\BasketApp\Payment\Response\AvailablePaymentOptions;
|
||||
use izi\prestashop\BasketApp\Product\ProductsApiClientInterface;
|
||||
use izi\prestashop\BasketApp\Product\Request\CreateProductsRequest;
|
||||
use izi\prestashop\BasketApp\Product\Response\CreateProductsResponse;
|
||||
use izi\prestashop\BasketApp\Product\Response\Product as ResponseProduct;
|
||||
use izi\prestashop\BasketApp\Signature\Response\SigningKey;
|
||||
use izi\prestashop\BasketApp\Signature\Response\SigningKeys;
|
||||
use izi\prestashop\Common\Error\Error;
|
||||
use izi\prestashop\Common\HotProduct\Product;
|
||||
use izi\prestashop\Environment\ProductionEnvironment;
|
||||
use izi\prestashop\Http\Exception\ClientException;
|
||||
use izi\prestashop\Http\Exception\RedirectionException;
|
||||
use izi\prestashop\Http\Exception\ServerException;
|
||||
use izi\prestashop\Http\Util\UriResolver;
|
||||
use izi\prestashop\Serializer\Normalizer\BasketAppPaginationPageDenormalizer;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamFactoryInterface;
|
||||
use Symfony\Component\Serializer\Exception\ExceptionInterface;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
final class BasketAppClient implements BasketAppClientInterface, ProductsApiClientInterface
|
||||
{
|
||||
/**
|
||||
* @var ClientInterface
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @var RequestFactoryInterface
|
||||
*/
|
||||
private $requestFactory;
|
||||
|
||||
/**
|
||||
* @var StreamFactoryInterface
|
||||
*/
|
||||
private $streamFactory;
|
||||
|
||||
/**
|
||||
* @var SerializerInterface
|
||||
*/
|
||||
private $serializer;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $baseUri;
|
||||
|
||||
public function __construct(ClientInterface $client, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, SerializerInterface $serializer, ?string $baseUri = null)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->requestFactory = $requestFactory;
|
||||
$this->streamFactory = $streamFactory;
|
||||
$this->serializer = $serializer;
|
||||
$this->baseUri = $baseUri ?? (new ProductionEnvironment())->getBasketAppApiUri();
|
||||
}
|
||||
|
||||
public function updateBasket(string $basketId, Basket $basket): UpdateBasketResponse
|
||||
{
|
||||
$request = $this->createRequest('PUT', sprintf('/v2/izi/basket/%s', $basketId), $basket);
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, UpdateBasketResponse::class);
|
||||
}
|
||||
|
||||
public function initializeBasketBinding(string $basketId): BasketBindingKeyResponse
|
||||
{
|
||||
$request = $this->createRequest('PUT', sprintf('/v2/izi/basket/%s/binding', $basketId));
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, BasketBindingKeyResponse::class);
|
||||
}
|
||||
|
||||
public function deleteBasketBinding(string $basketId, bool $orderCompleted = false): void
|
||||
{
|
||||
$uri = sprintf('/v1/izi/basket/%s/binding', $basketId);
|
||||
if ($orderCompleted) {
|
||||
$uri .= '?' . self::buildQuery(['if_basket_realized' => (int) $orderCompleted]);
|
||||
}
|
||||
|
||||
$request = $this->createRequest('DELETE', $uri);
|
||||
$this->sendRequest($request, 204);
|
||||
}
|
||||
|
||||
public function getBasketBinding(string $basketId, ?string $browserId = null): BasketBindingResponse
|
||||
{
|
||||
$uri = sprintf('/v1/izi/basket/%s/binding', $basketId);
|
||||
if (null !== $browserId) {
|
||||
$uri .= '?' . self::buildQuery(['browser_id' => $browserId]);
|
||||
}
|
||||
|
||||
$request = $this->createRequest('GET', $uri);
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, BasketBindingResponse::class);
|
||||
}
|
||||
|
||||
public function updateOrder(string $orderId, OrderEvent $event): void
|
||||
{
|
||||
$request = $this->createRequest('POST', sprintf('/v1/izi/order/%s/event', $orderId), $event);
|
||||
// currently the API returns 201 on success instead of 200 given in the documentation
|
||||
$this->sendRequest($request, 200, 201);
|
||||
}
|
||||
|
||||
public function getSigningKey(string $version): SigningKey
|
||||
{
|
||||
$request = $this->createRequest('GET', sprintf('/v1/izi/signing-keys/public/%s', $version));
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, SigningKey::class);
|
||||
}
|
||||
|
||||
public function getSigningKeys(): SigningKeys
|
||||
{
|
||||
$request = $this->createRequest('GET', '/v1/izi/signing-keys/public');
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, SigningKeys::class);
|
||||
}
|
||||
|
||||
public function getAvailablePaymentOptions(): AvailablePaymentOptions
|
||||
{
|
||||
$request = $this->createRequest('GET', '/v1/izi/payment-methods');
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, AvailablePaymentOptions::class);
|
||||
}
|
||||
|
||||
public function createProducts(CreateProductsRequest $products): CreateProductsResponse
|
||||
{
|
||||
$request = $this->createRequest('POST', '/v1/izi/products', $products);
|
||||
$response = $this->sendRequest($request, 201);
|
||||
|
||||
return $this->deserialize($response, CreateProductsResponse::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $productIds
|
||||
*
|
||||
* @return PaginationPage<ResponseProduct>
|
||||
*/
|
||||
public function getProductsPage(array $productIds = [], ?int $pageSize = null, ?int $pageIndex = null): PaginationPage
|
||||
{
|
||||
$params = [];
|
||||
|
||||
if (null !== $pageIndex) {
|
||||
$params['page_index'] = $pageIndex;
|
||||
}
|
||||
|
||||
if (null !== $pageSize) {
|
||||
$params['page_size'] = $pageSize;
|
||||
}
|
||||
|
||||
if ([] !== $productIds) {
|
||||
$params['product_ids'] = implode(',', $productIds);
|
||||
}
|
||||
|
||||
$uri = '/v1/izi/products';
|
||||
if ([] !== $params) {
|
||||
$uri .= '?' . self::buildQuery($params);
|
||||
}
|
||||
|
||||
$request = $this->createRequest('GET', $uri);
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, PaginationPage::class, [
|
||||
BasketAppPaginationPageDenormalizer::ITEM_TYPE_KEY => ResponseProduct::class,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $productIds
|
||||
*
|
||||
* @return \Generator<ResponseProduct>
|
||||
*/
|
||||
public function getProducts(array $productIds = [], ?int $pageSize = null): \Traversable
|
||||
{
|
||||
$pageIndex = 0;
|
||||
|
||||
do {
|
||||
$page = $this->getProductsPage($productIds, $pageSize, $pageIndex++);
|
||||
$pageSize = $page->getPageSize();
|
||||
$totalCount = $page->getTotalCount();
|
||||
|
||||
foreach ($page as $product) {
|
||||
yield $product;
|
||||
}
|
||||
} while ($totalCount > $pageSize * $pageIndex);
|
||||
}
|
||||
|
||||
public function updateProduct(string $productId, Product $product): ResponseProduct
|
||||
{
|
||||
$request = $this->createRequest('PUT', sprintf('/v1/izi/product/%s', $productId), $product);
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return $this->deserialize($response, ResponseProduct::class);
|
||||
}
|
||||
|
||||
public function deleteProduct(string $productId): void
|
||||
{
|
||||
$request = $this->createRequest('DELETE', sprintf('/v1/izi/product/%s', $productId));
|
||||
$this->sendRequest($request, 204);
|
||||
}
|
||||
|
||||
private function createRequest(string $method, string $uri, $payload = null): RequestInterface
|
||||
{
|
||||
$uri = UriResolver::resolve($uri, $this->baseUri);
|
||||
|
||||
$request = $this->requestFactory
|
||||
->createRequest($method, $uri)
|
||||
->withHeader('Accept', 'application/json');
|
||||
|
||||
if (null === $payload) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
$payload = $this->serializer->serialize($payload, 'json', [
|
||||
'datetime_format' => self::DATETIME_FORMAT,
|
||||
'datetime_timezone' => self::DATETIME_ZONE,
|
||||
]);
|
||||
|
||||
$body = $this->streamFactory->createStream($payload);
|
||||
|
||||
return $request
|
||||
->withBody($body)
|
||||
->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
private function sendRequest(RequestInterface $request, int $expectedStatusCode = 200, int ...$allowedStatusCodes): ResponseInterface
|
||||
{
|
||||
$response = $this->client->sendRequest($request);
|
||||
$statusCode = $response->getStatusCode();
|
||||
|
||||
if (300 <= $statusCode) {
|
||||
$this->handleUnsuccessfulResponse($request, $response);
|
||||
}
|
||||
|
||||
if ($expectedStatusCode === $statusCode || in_array($statusCode, $allowedStatusCodes, true)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException(sprintf('Unexpected server response code: %d', $statusCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*
|
||||
* @param class-string<T> $class
|
||||
*
|
||||
* @return T
|
||||
*/
|
||||
private function deserialize(ResponseInterface $response, string $class, array $context = [])
|
||||
{
|
||||
return $this->serializer->deserialize((string) $response->getBody(), $class, 'json', $context);
|
||||
}
|
||||
|
||||
private function handleUnsuccessfulResponse(RequestInterface $request, ResponseInterface $response): void
|
||||
{
|
||||
$statusCode = $response->getStatusCode();
|
||||
|
||||
try {
|
||||
$error = $this->deserialize($response, Error::class);
|
||||
|
||||
throw BasketAppException::create($request, $error, $statusCode); // TODO? replace with exception factory service
|
||||
} catch (ExceptionInterface $e) {
|
||||
// ignore deserialization errors
|
||||
}
|
||||
|
||||
if (500 <= $statusCode) {
|
||||
throw new ServerException($request, $response);
|
||||
}
|
||||
|
||||
if (400 <= $statusCode) {
|
||||
throw new ClientException($request, $response);
|
||||
}
|
||||
|
||||
throw new RedirectionException($request, $response);
|
||||
}
|
||||
|
||||
private static function buildQuery(array $params): string
|
||||
{
|
||||
return http_build_query($params, '', '&', PHP_QUERY_RFC3986);
|
||||
}
|
||||
}
|
||||
74
modules/inpostizi/src/BasketApp/BasketAppClientFactory.php
Normal file
74
modules/inpostizi/src/BasketApp/BasketAppClientFactory.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp;
|
||||
|
||||
use izi\prestashop\Configuration\ApiConfigurationInterface;
|
||||
use izi\prestashop\Environment\AuthServerUriCollection;
|
||||
use izi\prestashop\Http\Client\AuthorizingClient;
|
||||
use izi\prestashop\Http\Client\Factory\ClientFactoryInterface;
|
||||
use izi\prestashop\Http\Client\Factory\GuzzleClientFactory;
|
||||
use izi\prestashop\OAuth2\AuthorizationProviderFactoryInterface;
|
||||
use Psr\Http\Client\ClientInterface;
|
||||
use Psr\Http\Message\RequestFactoryInterface;
|
||||
use Psr\Http\Message\StreamFactoryInterface;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
final class BasketAppClientFactory
|
||||
{
|
||||
/**
|
||||
* @var RequestFactoryInterface
|
||||
*/
|
||||
private $requestFactory;
|
||||
|
||||
/**
|
||||
* @var StreamFactoryInterface
|
||||
*/
|
||||
private $streamFactory;
|
||||
|
||||
/**
|
||||
* @var SerializerInterface
|
||||
*/
|
||||
private $serializer;
|
||||
|
||||
/**
|
||||
* @var ClientFactoryInterface
|
||||
*/
|
||||
private $clientFactory;
|
||||
|
||||
/**
|
||||
* @var AuthorizationProviderFactoryInterface
|
||||
*/
|
||||
private $authorizationProviderFactory;
|
||||
|
||||
public function __construct(RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, SerializerInterface $serializer, ?ClientFactoryInterface $clientFactory = null, ?AuthorizationProviderFactoryInterface $authorizationProviderFactory = null)
|
||||
{
|
||||
$this->requestFactory = $requestFactory;
|
||||
$this->streamFactory = $streamFactory;
|
||||
$this->serializer = $serializer;
|
||||
$this->clientFactory = $clientFactory ?? new GuzzleClientFactory();
|
||||
$this->authorizationProviderFactory = $authorizationProviderFactory ?? new AuthorizationProviderFactory($requestFactory, $streamFactory, $this->clientFactory);
|
||||
}
|
||||
|
||||
public function create(ApiConfigurationInterface $configuration): BasketAppClient
|
||||
{
|
||||
$httpClient = $this->createHttpClient($configuration);
|
||||
$baseUri = $configuration->getEnvironment()->getBasketAppApiUri();
|
||||
|
||||
return new BasketAppClient($httpClient, $this->requestFactory, $this->streamFactory, $this->serializer, $baseUri);
|
||||
}
|
||||
|
||||
private function createHttpClient(ApiConfigurationInterface $configuration): ClientInterface
|
||||
{
|
||||
if (null === $credentials = $configuration->getClientCredentials()) {
|
||||
throw new \RuntimeException('Client credentials are not available.');
|
||||
}
|
||||
|
||||
$uriCollection = new AuthServerUriCollection($configuration->getEnvironment());
|
||||
$authorizationProvider = $this->authorizationProviderFactory->create($uriCollection, $credentials);
|
||||
$client = $this->clientFactory->create();
|
||||
|
||||
return new AuthorizingClient($client, $authorizationProvider);
|
||||
}
|
||||
}
|
||||
20
modules/inpostizi/src/BasketApp/BasketAppClientInterface.php
Normal file
20
modules/inpostizi/src/BasketApp/BasketAppClientInterface.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp;
|
||||
|
||||
use izi\prestashop\BasketApp\Basket\BasketsApiClientInterface;
|
||||
use izi\prestashop\BasketApp\Order\OrdersApiClientInterface;
|
||||
use izi\prestashop\BasketApp\Payment\PaymentsApiClientInterface;
|
||||
use izi\prestashop\BasketApp\Product\ProductsApiClientInterface;
|
||||
use izi\prestashop\BasketApp\Signature\SigningKeysApiClientInterface;
|
||||
|
||||
/**
|
||||
* @extends ProductsApiClientInterface
|
||||
*/
|
||||
interface BasketAppClientInterface extends BasketsApiClientInterface, OrdersApiClientInterface, SigningKeysApiClientInterface, PaymentsApiClientInterface
|
||||
{
|
||||
public const DATETIME_FORMAT = 'Y-m-d\TH:i:s.u\Z'; // format character "p" is not available before PHP 8.0
|
||||
public const DATETIME_ZONE = 'UTC';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
class BadRequestException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'BAD_REQUEST';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class BasketAlreadyBoundException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'BASKET_IS_BINDED';
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
use izi\prestashop\BasketApp\Product\Exception as Product;
|
||||
use izi\prestashop\Common\Error\Error;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
class BasketAppException extends \RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var array<string, class-string<self>> exception class names by error codes
|
||||
*/
|
||||
private const CLASS_MAP = [
|
||||
BadRequestException::ERROR_CODE => BadRequestException::class,
|
||||
MalformedRequestException::ERROR_CODE => MalformedRequestException::class,
|
||||
UnauthorizedException::ERROR_CODE => UnauthorizedException::class,
|
||||
ForbiddenException::ERROR_CODE => ForbiddenException::class,
|
||||
ResourceNotFoundException::ERROR_CODE => ResourceNotFoundException::class,
|
||||
BasketNotFoundException::ERROR_CODE => BasketNotFoundException::class,
|
||||
PublicKeyNotFoundException::ERROR_CODE => PublicKeyNotFoundException::class,
|
||||
OrderNotFoundException::ERROR_CODE => OrderNotFoundException::class,
|
||||
MerchantDisabledException::ERROR_CODE => MerchantDisabledException::class,
|
||||
BasketAlreadyBoundException::ERROR_CODE => BasketAlreadyBoundException::class,
|
||||
PhoneBindingUnavailableException::ERROR_CODE => PhoneBindingUnavailableException::class,
|
||||
BasketNotBoundException::ERROR_CODE => BasketNotBoundException::class,
|
||||
BasketExpiredException::ERROR_CODE => BasketExpiredException::class,
|
||||
CannotChangeOrderStatusException::ERROR_CODE => CannotChangeOrderStatusException::class,
|
||||
InternalServerErrorException::ERROR_CODE => InternalServerErrorException::class,
|
||||
Product\ProductNotFoundException::ERROR_CODE => Product\ProductNotFoundException::class,
|
||||
Product\ProductExistsException::ERROR_CODE => Product\ProductExistsException::class,
|
||||
Product\MaxProductLimitReachedException::ERROR_CODE => Product\MaxProductLimitReachedException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var RequestInterface
|
||||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* @var Error
|
||||
*/
|
||||
private $error;
|
||||
|
||||
public function __construct(RequestInterface $request, Error $error, int $statusCode)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->error = $error;
|
||||
|
||||
parent::__construct($error->getMessage(), $statusCode);
|
||||
}
|
||||
|
||||
public static function create(RequestInterface $request, Error $error, int $statusCode): self
|
||||
{
|
||||
$class = self::CLASS_MAP[$error->getCode()] ?? self::class;
|
||||
|
||||
return new $class($request, $error, $statusCode);
|
||||
}
|
||||
|
||||
public function getRequest(): RequestInterface
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
public function getError(): Error
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class BasketExpiredException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'BASKET_EXPIRED';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class BasketNotBoundException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'BASKET_NOT_BOUND';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class BasketNotFoundException extends ResourceNotFoundException
|
||||
{
|
||||
public const ERROR_CODE = 'BASKET_NOT_FOUND';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class CannotChangeOrderStatusException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'STATUS_ORDER_ERROR';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class ForbiddenException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'FORBIDDEN';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class InternalServerErrorException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'INTERNAL_SERVER_ERROR';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class MalformedRequestException extends BadRequestException
|
||||
{
|
||||
public const ERROR_CODE = 'MALFORMED_REQUEST';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class MerchantDisabledException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'MERCHANT_DISABLE';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class OrderNotFoundException extends ResourceNotFoundException
|
||||
{
|
||||
public const ERROR_CODE = 'ORDER_NOT_FOUND';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class PhoneBindingUnavailableException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'PHONE_BINDING_METHOD_UNAVAILABLE';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class PublicKeyNotFoundException extends ResourceNotFoundException
|
||||
{
|
||||
public const ERROR_CODE = 'PUBLIC_KEY_NOT_FOUND';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
class ResourceNotFoundException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'NOT_FOUND';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Exception;
|
||||
|
||||
final class UnauthorizedException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'UNAUTHORIZED';
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Order;
|
||||
|
||||
use izi\prestashop\BasketApp\Exception\CannotChangeOrderStatusException;
|
||||
use izi\prestashop\BasketApp\Exception\OrderNotFoundException;
|
||||
use izi\prestashop\BasketApp\Order\Request\OrderEvent;
|
||||
|
||||
interface OrdersApiClientInterface
|
||||
{
|
||||
/**
|
||||
* @throws OrderNotFoundException
|
||||
* @throws CannotChangeOrderStatusException
|
||||
*/
|
||||
public function updateOrder(string $orderId, OrderEvent $event): void;
|
||||
}
|
||||
86
modules/inpostizi/src/BasketApp/Order/Request/Delivery.php
Normal file
86
modules/inpostizi/src/BasketApp/Order/Request/Delivery.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Order\Request;
|
||||
|
||||
use izi\prestashop\Common\Order\DeliveryAddress;
|
||||
use izi\prestashop\Common\PhoneNumber;
|
||||
|
||||
final class Delivery implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var \DateTimeImmutable|null
|
||||
*/
|
||||
private $delivery_date;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $mail;
|
||||
|
||||
/**
|
||||
* @var PhoneNumber|null
|
||||
*/
|
||||
private $phone_number;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $delivery_point;
|
||||
|
||||
/**
|
||||
* @var DeliveryAddress|null
|
||||
*/
|
||||
private $delivery_address;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $courier_note;
|
||||
|
||||
public function __construct(?\DateTimeImmutable $delivery_date = null, ?string $mail = null, ?PhoneNumber $phone_number = null, ?string $delivery_point = null, ?DeliveryAddress $delivery_address = null, ?string $courier_note = null)
|
||||
{
|
||||
$this->delivery_date = $delivery_date;
|
||||
$this->mail = $mail;
|
||||
$this->phone_number = $phone_number;
|
||||
$this->delivery_point = $delivery_point;
|
||||
$this->delivery_address = $delivery_address;
|
||||
$this->courier_note = $courier_note;
|
||||
}
|
||||
|
||||
public function getDeliveryDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->delivery_date;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->mail;
|
||||
}
|
||||
|
||||
public function getPhoneNumber(): ?PhoneNumber
|
||||
{
|
||||
return $this->phone_number;
|
||||
}
|
||||
|
||||
public function getPoint(): ?string
|
||||
{
|
||||
return $this->delivery_point;
|
||||
}
|
||||
|
||||
public function getAddress(): ?DeliveryAddress
|
||||
{
|
||||
return $this->delivery_address;
|
||||
}
|
||||
|
||||
public function getCourierNote(): ?string
|
||||
{
|
||||
return $this->courier_note;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
63
modules/inpostizi/src/BasketApp/Order/Request/OrderEvent.php
Normal file
63
modules/inpostizi/src/BasketApp/Order/Request/OrderEvent.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Order\Request;
|
||||
|
||||
use izi\prestashop\Common\PhoneNumber;
|
||||
|
||||
final class OrderEvent implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $event_id;
|
||||
|
||||
/**
|
||||
* @var \DateTimeImmutable
|
||||
*/
|
||||
private $event_data_time;
|
||||
|
||||
/**
|
||||
* @var PhoneNumber|null
|
||||
*/
|
||||
private $phone_number;
|
||||
|
||||
/**
|
||||
* @var OrderEventData
|
||||
*/
|
||||
private $event_data;
|
||||
|
||||
public function __construct(string $event_id, \DateTimeImmutable $event_data_time, OrderEventData $event_data, ?PhoneNumber $phone_number = null)
|
||||
{
|
||||
$this->event_id = $event_id;
|
||||
$this->event_data_time = $event_data_time;
|
||||
$this->phone_number = $phone_number;
|
||||
$this->event_data = $event_data;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->event_id;
|
||||
}
|
||||
|
||||
public function getDateTime(): \DateTimeImmutable
|
||||
{
|
||||
return $this->event_data_time;
|
||||
}
|
||||
|
||||
public function getPhoneNumber(): ?PhoneNumber
|
||||
{
|
||||
return $this->phone_number;
|
||||
}
|
||||
|
||||
public function getData(): OrderEventData
|
||||
{
|
||||
return $this->event_data;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Order\Request;
|
||||
|
||||
use izi\prestashop\Common\Order\MerchantOrderStatus;
|
||||
|
||||
final class OrderEventData implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var MerchantOrderStatus|null
|
||||
*/
|
||||
private $order_status;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $order_merchant_status_description;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
private $delivery_references_list;
|
||||
|
||||
/**
|
||||
* @var Delivery|null
|
||||
*/
|
||||
private $delivery;
|
||||
|
||||
/**
|
||||
* @param string[]|null $delivery_references_list
|
||||
*/
|
||||
public function __construct(?MerchantOrderStatus $order_status = null, ?string $order_merchant_status_description = null, ?array $delivery_references_list = null, ?Delivery $delivery = null)
|
||||
{
|
||||
$this->order_status = $order_status;
|
||||
$this->order_merchant_status_description = $order_merchant_status_description;
|
||||
$this->delivery_references_list = $delivery_references_list;
|
||||
$this->delivery = $delivery;
|
||||
}
|
||||
|
||||
public function getStatus(): ?MerchantOrderStatus
|
||||
{
|
||||
return $this->order_status;
|
||||
}
|
||||
|
||||
public function getStatusDescription(): ?string
|
||||
{
|
||||
return $this->order_merchant_status_description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]|null
|
||||
*/
|
||||
public function getDeliveryReferencesList(): ?array
|
||||
{
|
||||
return $this->delivery_references_list;
|
||||
}
|
||||
|
||||
public function getDelivery(): ?Delivery
|
||||
{
|
||||
return $this->delivery;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
83
modules/inpostizi/src/BasketApp/PaginationPage.php
Normal file
83
modules/inpostizi/src/BasketApp/PaginationPage.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
*
|
||||
* @template-implements \IteratorAggregate<int, T>
|
||||
*/
|
||||
final class PaginationPage implements \IteratorAggregate, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var T[]
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $total_items;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $page_index;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $page_size;
|
||||
|
||||
/**
|
||||
* @param T[] $content
|
||||
*/
|
||||
public function __construct(array $content, int $total_items, int $page_index, int $page_size)
|
||||
{
|
||||
$this->content = $content;
|
||||
$this->total_items = $total_items;
|
||||
$this->page_index = $page_index;
|
||||
$this->page_size = $page_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return T[]
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getTotalCount(): int
|
||||
{
|
||||
return $this->total_items;
|
||||
}
|
||||
|
||||
public function getPageIndex(): int
|
||||
{
|
||||
return $this->page_index;
|
||||
}
|
||||
|
||||
public function getPageSize(): int
|
||||
{
|
||||
return $this->page_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Traversable<int, T>
|
||||
*/
|
||||
public function getIterator(): \Traversable
|
||||
{
|
||||
return new \ArrayIterator($this->content);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Payment;
|
||||
|
||||
use izi\prestashop\BasketApp\Payment\Response\AvailablePaymentOptions;
|
||||
|
||||
interface PaymentsApiClientInterface
|
||||
{
|
||||
public function getAvailablePaymentOptions(): AvailablePaymentOptions;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Payment\Response;
|
||||
|
||||
use izi\prestashop\Common\PaymentType;
|
||||
|
||||
/**
|
||||
* @implements \IteratorAggregate<PaymentType>
|
||||
*/
|
||||
final class AvailablePaymentOptions implements \JsonSerializable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var PaymentType[]
|
||||
*/
|
||||
private $payment_type;
|
||||
|
||||
/**
|
||||
* @param PaymentType[] $payment_type
|
||||
*/
|
||||
public function __construct(array $payment_type)
|
||||
{
|
||||
$this->payment_type = $payment_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PaymentType[]
|
||||
*/
|
||||
public function getPaymentTypes(): array
|
||||
{
|
||||
return $this->payment_type;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
|
||||
public function getIterator(): \Iterator
|
||||
{
|
||||
return new \ArrayIterator($this->payment_type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Exception;
|
||||
|
||||
use izi\prestashop\BasketApp\Exception\BasketAppException;
|
||||
|
||||
final class MaxProductLimitReachedException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'MAX_LIMIT_PRODUCTS';
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Exception;
|
||||
|
||||
use izi\prestashop\BasketApp\Exception\BasketAppException;
|
||||
|
||||
final class ProductExistsException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'PRODUCT_EXISTS';
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Exception;
|
||||
|
||||
use izi\prestashop\BasketApp\Exception\BasketAppException;
|
||||
|
||||
final class ProductNotFoundException extends BasketAppException
|
||||
{
|
||||
public const ERROR_CODE = 'PRODUCT_NOT_FOUND';
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product;
|
||||
|
||||
use izi\prestashop\BasketApp\PaginationPage;
|
||||
use izi\prestashop\BasketApp\Product\Exception\MaxProductLimitReachedException;
|
||||
use izi\prestashop\BasketApp\Product\Exception\ProductExistsException;
|
||||
use izi\prestashop\BasketApp\Product\Exception\ProductNotFoundException;
|
||||
use izi\prestashop\BasketApp\Product\Request\CreateProductsRequest;
|
||||
use izi\prestashop\BasketApp\Product\Response\CreateProductsResponse;
|
||||
use izi\prestashop\BasketApp\Product\Response\Product as ResponseProduct;
|
||||
use izi\prestashop\Common\HotProduct\Product;
|
||||
|
||||
interface ProductsApiClientInterface
|
||||
{
|
||||
/**
|
||||
* Create products in InPost Pay.
|
||||
*
|
||||
* @throws ProductExistsException
|
||||
* @throws MaxProductLimitReachedException
|
||||
*/
|
||||
public function createProducts(CreateProductsRequest $products): CreateProductsResponse;
|
||||
|
||||
/**
|
||||
* Get paginated list of products from InPost Pay.
|
||||
*
|
||||
* @param string[] $productIds optional list of product IDs to filter by
|
||||
*
|
||||
* @return PaginationPage<ResponseProduct>
|
||||
*/
|
||||
public function getProductsPage(array $productIds = [], ?int $pageSize = null, ?int $pageIndex = null): PaginationPage;
|
||||
|
||||
/**
|
||||
* Get InPost Pay products iterator.
|
||||
*
|
||||
* @param string[] $productIds optional list of product IDs to filter by
|
||||
*
|
||||
* @return \Traversable<ResponseProduct>
|
||||
*/
|
||||
public function getProducts(array $productIds = [], ?int $pageSize = null): \Traversable;
|
||||
|
||||
/**
|
||||
* Update a product in InPost Pay.
|
||||
*
|
||||
* @throws ProductNotFoundException
|
||||
*/
|
||||
public function updateProduct(string $productId, Product $product): ResponseProduct;
|
||||
|
||||
/**
|
||||
* Delete a product from InPost Pay.
|
||||
*
|
||||
* @throws ProductNotFoundException
|
||||
*/
|
||||
public function deleteProduct(string $productId): void;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Request;
|
||||
|
||||
use izi\prestashop\Common\HotProduct\IdentifiableProduct;
|
||||
|
||||
final class CreateProductsRequest implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var IdentifiableProduct[]
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @param IdentifiableProduct[] $content
|
||||
*/
|
||||
public function __construct(array $content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IdentifiableProduct[]
|
||||
*/
|
||||
public function getProducts(): array
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Response;
|
||||
|
||||
final class CreateProductsResponse implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var ProductId[]
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @param ProductId[] $content
|
||||
*/
|
||||
public function __construct(array $content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ProductId[]
|
||||
*/
|
||||
public function getProductIds(): array
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
191
modules/inpostizi/src/BasketApp/Product/Response/Product.php
Normal file
191
modules/inpostizi/src/BasketApp/Product/Response/Product.php
Normal file
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Response;
|
||||
|
||||
use izi\prestashop\Common\Currency;
|
||||
use izi\prestashop\Common\HotProduct\ProductAvailability;
|
||||
use izi\prestashop\Common\HotProduct\Quantity;
|
||||
use izi\prestashop\Common\Price;
|
||||
use izi\prestashop\Common\Product\ProductAttribute;
|
||||
use izi\prestashop\Common\Product\ProductImage;
|
||||
|
||||
final class Product implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $product_id;
|
||||
|
||||
/**
|
||||
* @var Status
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $ean;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $qr_code;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $deep_link;
|
||||
|
||||
/**
|
||||
* @var ProductAvailability|null
|
||||
*/
|
||||
private $product_availability;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $product_name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $product_description;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $product_image;
|
||||
|
||||
/**
|
||||
* @var ProductImage[]
|
||||
*/
|
||||
private $additional_product_images;
|
||||
|
||||
/**
|
||||
* @var Price
|
||||
*/
|
||||
private $price;
|
||||
|
||||
/**
|
||||
* @var Currency
|
||||
*/
|
||||
private $currency;
|
||||
|
||||
/**
|
||||
* @var Quantity
|
||||
*/
|
||||
private $quantity;
|
||||
|
||||
/**
|
||||
* @var ProductAttribute[]
|
||||
*/
|
||||
private $product_attributes;
|
||||
|
||||
/**
|
||||
* @param ProductImage[] $additional_product_images
|
||||
* @param ProductAttribute[] $product_attributes
|
||||
*/
|
||||
public function __construct(string $product_id, Status $status, string $product_name, string $product_description, string $product_image, Price $price, Currency $currency, Quantity $quantity, ?string $ean = null, ?string $qr_code = null, ?string $deep_link = null, ?ProductAvailability $product_availability = null, array $additional_product_images = [], array $product_attributes = [])
|
||||
{
|
||||
$this->product_id = $product_id;
|
||||
$this->status = $status;
|
||||
$this->product_name = $product_name;
|
||||
$this->product_description = $product_description;
|
||||
$this->product_image = $product_image;
|
||||
$this->price = $price;
|
||||
$this->currency = $currency;
|
||||
$this->quantity = $quantity;
|
||||
$this->ean = $ean;
|
||||
$this->qr_code = $qr_code;
|
||||
$this->deep_link = $deep_link;
|
||||
$this->product_availability = $product_availability;
|
||||
$this->additional_product_images = $additional_product_images;
|
||||
$this->product_attributes = $product_attributes;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->product_id;
|
||||
}
|
||||
|
||||
public function getStatus(): Status
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function getEan(): ?string
|
||||
{
|
||||
return $this->ean;
|
||||
}
|
||||
|
||||
public function getQrCode(): ?string
|
||||
{
|
||||
return $this->qr_code;
|
||||
}
|
||||
|
||||
public function getDeepLink(): ?string
|
||||
{
|
||||
return $this->deep_link;
|
||||
}
|
||||
|
||||
public function getAvailability(): ?ProductAvailability
|
||||
{
|
||||
return $this->product_availability;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->product_name;
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->product_description;
|
||||
}
|
||||
|
||||
public function getImageUrl(): string
|
||||
{
|
||||
return $this->product_image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ProductImage[]
|
||||
*/
|
||||
public function getAdditionalImages(): array
|
||||
{
|
||||
return $this->additional_product_images;
|
||||
}
|
||||
|
||||
public function getPrice(): Price
|
||||
{
|
||||
return $this->price;
|
||||
}
|
||||
|
||||
public function getCurrency(): Currency
|
||||
{
|
||||
return $this->currency;
|
||||
}
|
||||
|
||||
public function getQuantity(): Quantity
|
||||
{
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ProductAttribute[]
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return $this->product_attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Response;
|
||||
|
||||
final class ProductId implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $product_id;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $qr_code;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $deep_link;
|
||||
|
||||
public function __construct(string $product_id, ?string $qr_code = null, ?string $deep_link = null)
|
||||
{
|
||||
$this->product_id = $product_id;
|
||||
$this->qr_code = $qr_code;
|
||||
$this->deep_link = $deep_link;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->product_id;
|
||||
}
|
||||
|
||||
public function getQrCode(): ?string
|
||||
{
|
||||
return $this->qr_code;
|
||||
}
|
||||
|
||||
public function getDeepLink(): ?string
|
||||
{
|
||||
return $this->deep_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
17
modules/inpostizi/src/BasketApp/Product/Response/Status.php
Normal file
17
modules/inpostizi/src/BasketApp/Product/Response/Status.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Product\Response;
|
||||
|
||||
use izi\prestashop\Enum\StringEnum;
|
||||
|
||||
/**
|
||||
* @method static self Active()
|
||||
* @method static self Inactive()
|
||||
*/
|
||||
final class Status extends StringEnum
|
||||
{
|
||||
public const ACTIVE = 'ACTIVE';
|
||||
public const INACTIVE = 'INACTIVE';
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Signature\Response;
|
||||
|
||||
use izi\prestashop\Serializer\Normalizer\DenormalizableInterface;
|
||||
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
||||
|
||||
final class PublicKey implements \JsonSerializable, DenormalizableInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $public_key_base64;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $hash;
|
||||
|
||||
public function __construct(string $public_key_base64, string $version)
|
||||
{
|
||||
$this->public_key_base64 = $public_key_base64;
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
public static function denormalize(array $data): self
|
||||
{
|
||||
if (!isset($data['public_key_base64'], $data['version'])) {
|
||||
throw new UnexpectedValueException('Array data does not contain all of the required parameters.');
|
||||
}
|
||||
|
||||
$key = new self($data['public_key_base64'], $data['version']);
|
||||
if (isset($data['hash'])) {
|
||||
$key->hash = $data['hash'];
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
public function getBase64Encoded(): string
|
||||
{
|
||||
return $this->public_key_base64;
|
||||
}
|
||||
|
||||
public function getVersion(): string
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
|
||||
public function getHash(): string
|
||||
{
|
||||
return $this->hash ?? ($this->hash = hash('sha256', $this->public_key_base64));
|
||||
}
|
||||
|
||||
public function getPemFormatted(): string
|
||||
{
|
||||
return "-----BEGIN PUBLIC KEY-----\n" . $this->public_key_base64 . "\n-----END PUBLIC KEY-----";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Signature\Response;
|
||||
|
||||
final class SigningKey implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $merchant_external_id;
|
||||
|
||||
/**
|
||||
* @var PublicKey
|
||||
*/
|
||||
private $public_key;
|
||||
|
||||
public function __construct(string $merchant_external_id, PublicKey $public_key)
|
||||
{
|
||||
$this->merchant_external_id = $merchant_external_id;
|
||||
$this->public_key = $public_key;
|
||||
}
|
||||
|
||||
public function getMerchantId(): string
|
||||
{
|
||||
return $this->merchant_external_id;
|
||||
}
|
||||
|
||||
public function getPublicKey(): PublicKey
|
||||
{
|
||||
return $this->public_key;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Signature\Response;
|
||||
|
||||
/**
|
||||
* @implements \IteratorAggregate<PublicKey>
|
||||
*/
|
||||
final class SigningKeys implements \IteratorAggregate, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $merchant_external_id;
|
||||
|
||||
/**
|
||||
* @var PublicKey[]
|
||||
*/
|
||||
private $public_keys;
|
||||
|
||||
/**
|
||||
* @param PublicKey[] $public_keys
|
||||
*/
|
||||
public function __construct(string $merchant_external_id, array $public_keys)
|
||||
{
|
||||
$this->merchant_external_id = $merchant_external_id;
|
||||
$this->public_keys = $public_keys;
|
||||
}
|
||||
|
||||
public function getMerchantId(): string
|
||||
{
|
||||
return $this->merchant_external_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PublicKey[]
|
||||
*/
|
||||
public function getPublicKeys(): array
|
||||
{
|
||||
return $this->public_keys;
|
||||
}
|
||||
|
||||
public function getIterator(): \Iterator
|
||||
{
|
||||
return new \ArrayIterator($this->public_keys);
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
|
||||
public function getPublicKey(string $version): ?PublicKey
|
||||
{
|
||||
foreach ($this->public_keys as $publicKey) {
|
||||
if ($version === $publicKey->getVersion()) {
|
||||
return $publicKey;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace izi\prestashop\BasketApp\Signature;
|
||||
|
||||
use izi\prestashop\BasketApp\Exception\PublicKeyNotFoundException;
|
||||
use izi\prestashop\BasketApp\Signature\Response\SigningKey;
|
||||
use izi\prestashop\BasketApp\Signature\Response\SigningKeys;
|
||||
|
||||
interface SigningKeysApiClientInterface
|
||||
{
|
||||
/**
|
||||
* @throws PublicKeyNotFoundException
|
||||
*/
|
||||
public function getSigningKey(string $version): SigningKey;
|
||||
|
||||
public function getSigningKeys(): SigningKeys;
|
||||
}
|
||||
Reference in New Issue
Block a user