Skip to content

Commit

Permalink
ACP-3507 the APIs to enable projects embed payment elements to headle…
Browse files Browse the repository at this point in the history
…ss frontends (#11043)

ACP-3507 Investigate how the APIs to Enable Projects embed Payment Elements to Yves or in Headless Scenario should be built
  • Loading branch information
stereomon authored Oct 2, 2024
1 parent 5a840d9 commit 3a2cfd0
Show file tree
Hide file tree
Showing 41 changed files with 1,717 additions and 545 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"spryker/checkout-extension": "^1.2.0",
"spryker/guzzle": "^2.2.0",
"spryker/kernel": "^3.30.0",
"spryker/kernel-app": "^1.0.0",
"spryker/locale": "^3.0.0 || ^4.0.0",
"spryker/log": "^3.0.0",
"spryker/message-broker": "^1.0.0",
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ parameters:
level: 7
checkMissingIterableValueType: false
ignoreErrors:
- '#Call to an undefined method Orm\\.+\\SpyWishlistQuery::groupByIdPaymentProvider\(\)#'
- '#Call to an undefined method .+Query::groupByIdPaymentProvider\(\)#'
- '#Call to an undefined method Spryker\\Shared\\Kernel\\Transfer\\AbstractTransfer::toArrayNotRecursiveCamelCased\(\)\.#'
- '#Method .+PaymentToUtilEncodingServiceBridge::decodeJson\(\) should return array\|null but returns array\|object\|null\.#'
- '#Call to an undefined method Spryker\\Shared\\Kernel\\Transfer\\TransferInterface::*.#'
23 changes: 23 additions & 0 deletions resources/api/asyncapi/payment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ channels:
message:
oneOf:
- $ref: '#/components/messages/AddPaymentMethod'
- $ref: '#/components/messages/UpdatePaymentMethod'
- $ref: '#/components/messages/DeletePaymentMethod'

# Deprecated messages
Expand All @@ -46,6 +47,15 @@ components:
$ref: '#/components/schemas/PaymentMethodPayload'
headers:
$ref: '#/components/schemas/message-broker/components/schemas/headers'
UpdatePaymentMethod:
name: UpdatePaymentMethod
x-spryker:
module: Payment
summary: 'Handle an updated Payment method.'
payload:
$ref: '#/components/schemas/PaymentMethodPayload'
headers:
$ref: '#/components/schemas/message-broker/components/schemas/headers'
DeletePaymentMethod:
name: DeletePaymentMethod
x-spryker:
Expand Down Expand Up @@ -237,6 +247,19 @@ components:
example:
- /authorization
- /transfer
checkoutConfiguration:
type: object
description: 'Optional configuration for sophisticated payment methods that support e.g. CheckoutSession or Embedded payment forms.'
properties:
strategy:
type: string
examples:
- embedded
- checkout-session
scripts:
type: array
description: 'List of scripts that should be included in the checkout page.'

PaymentPayload:
type: object
properties:
Expand Down
35 changes: 34 additions & 1 deletion src/Spryker/Client/Payment/PaymentClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

use Generated\Shared\Transfer\PaymentAuthorizeRequestTransfer;
use Generated\Shared\Transfer\PaymentAuthorizeResponseTransfer;
use Generated\Shared\Transfer\PaymentMethodsTransfer;
use Generated\Shared\Transfer\PreOrderPaymentRequestTransfer;
use Generated\Shared\Transfer\PreOrderPaymentResponseTransfer;
use Generated\Shared\Transfer\QuoteTransfer;
use Spryker\Client\Kernel\AbstractClient;

Expand All @@ -34,6 +37,36 @@ public function authorizeForeignPayment(
->authorizeForeignPayment($paymentAuthorizeRequestTransfer);
}

/**
* {@inheritDoc}
*
* @api
*
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function initializePreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer {
return $this->getFactory()->createZedStub()->initializePreOrderPayment($preOrderPaymentRequestTransfer);
}

/**
* {@inheritDoc}
*
* @api
*
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function cancelPreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer {
return $this->getFactory()->createZedStub()->cancelPreOrderPayment($preOrderPaymentRequestTransfer);
}

/**
* {@inheritDoc}
*
Expand All @@ -43,7 +76,7 @@ public function authorizeForeignPayment(
*
* @return \Generated\Shared\Transfer\PaymentMethodsTransfer
*/
public function getAvailableMethods(QuoteTransfer $quoteTransfer)
public function getAvailableMethods(QuoteTransfer $quoteTransfer): PaymentMethodsTransfer
{
return $this->getFactory()->createZedStub()->getAvailableMethods($quoteTransfer);
}
Expand Down
45 changes: 43 additions & 2 deletions src/Spryker/Client/Payment/PaymentClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@

use Generated\Shared\Transfer\PaymentAuthorizeRequestTransfer;
use Generated\Shared\Transfer\PaymentAuthorizeResponseTransfer;
use Generated\Shared\Transfer\PaymentMethodsTransfer;
use Generated\Shared\Transfer\PreOrderPaymentRequestTransfer;
use Generated\Shared\Transfer\PreOrderPaymentResponseTransfer;
use Generated\Shared\Transfer\QuoteTransfer;

interface PaymentClientInterface
{
/**
* Specification:
* - Makes a request from given PaymentAuthorizeRequestTransfer.
* - Adds `Authorization` header to request using `PaymentAuthorizeRequest.authorizaton` if exists.
* - Adds `Authorization` header to request using `PaymentAuthorizeRequest.authorization` if exists.
* - Adds `X-Store-Reference` header to request using `PaymentAuthorizeRequest.storeReference` if exists.
* - Adds `X-Tenant-Identifier` header to request using `PaymentAuthorizeRequest.tenantIdentifier` if exists.
* - Sends a request to a foreign payment service.
* - Returns a PaymentAuthorizeResponseTransfer with the received data.
*
* @api
*
* @deprecated The \Spryker\Zed\Payment\Business\ForeignPayment\ForeignPaymentInterface::initializePayment makes direct use of the KernelApp::makeRequest() method.
*
* @param \Generated\Shared\Transfer\PaymentAuthorizeRequestTransfer $paymentAuthorizeRequestTransfer
*
* @return \Generated\Shared\Transfer\PaymentAuthorizeResponseTransfer
Expand All @@ -32,6 +37,42 @@ public function authorizeForeignPayment(
PaymentAuthorizeRequestTransfer $paymentAuthorizeRequestTransfer
): PaymentAuthorizeResponseTransfer;

/**
* Specification:
* - Makes a request through the KernelApp to a PSP App to initialize a pre-order payment.
* - Requires `PreOrderPaymentRequestTransfer::QUOTE` to be set.
* - Requires `PreOrderPaymentRequestTransfer::PAYMENT_METHOD` to be set.
* - Returns a `PreOrderPaymentResponseTransfer::IS_SUCCESS` with `true` if the request was successful.
* - Returns a `PreOrderPaymentResponseTransfer::PRE_ORDER_PAYMENT_DATA` with specific to the PSP related data (e.g. to initialize a PSP SDK).
*
* @api
*
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function initializePreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer;

/**
* Specification:
* - Makes a request through the KernelApp to a PSP App to cancel a pre-order payment.
* - Requires `PreOrderPaymentRequestTransfer::PAYMENT_METHOD` to be set.
* - Requires `PreOrderPaymentRequestTransfer::PRE_ORDER_PAYMENT_DATA` to be set.
* - Returns a `PreOrderPaymentResponseTransfer::IS_SUCCESS` with `true` if the request was successful.
* - Returns a `PreOrderPaymentResponseTransfer::ERROR` in case of an error.
*
* @api
*
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function cancelPreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer;

/**
* Specification:
* - Requests available payment methods from Zed
Expand All @@ -42,5 +83,5 @@ public function authorizeForeignPayment(
*
* @return \Generated\Shared\Transfer\PaymentMethodsTransfer
*/
public function getAvailableMethods(QuoteTransfer $quoteTransfer);
public function getAvailableMethods(QuoteTransfer $quoteTransfer): PaymentMethodsTransfer;
}
37 changes: 36 additions & 1 deletion src/Spryker/Client/Payment/Zed/PaymentStub.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace Spryker\Client\Payment\Zed;

use Generated\Shared\Transfer\PaymentMethodsTransfer;
use Generated\Shared\Transfer\PreOrderPaymentRequestTransfer;
use Generated\Shared\Transfer\PreOrderPaymentResponseTransfer;
use Generated\Shared\Transfer\QuoteTransfer;
use Spryker\Client\Payment\Dependency\Client\PaymentToZedRequestClientInterface;

Expand All @@ -25,12 +28,44 @@ public function __construct(PaymentToZedRequestClientInterface $zedRequestClient
$this->zedRequestClient = $zedRequestClient;
}

/**
* @uses \Spryker\Zed\Payment\Communication\Controller\GatewayController::initializePreOrderPaymentAction()
*
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function initializePreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer {
/** @var \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer $preOrderPaymentResponseTransfer */
$preOrderPaymentResponseTransfer = $this->zedRequestClient->call('/payment/gateway/initialize-pre-order-payment', $preOrderPaymentRequestTransfer);

return $preOrderPaymentResponseTransfer;
}

/**
* @uses \Spryker\Zed\Payment\Communication\Controller\GatewayController::cancelPreOrderPaymentAction()
*
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function cancelPreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer {
/** @var \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer $preOrderPaymentResponseTransfer */
$preOrderPaymentResponseTransfer = $this->zedRequestClient->call('/payment/gateway/cancel-pre-order-payment', $preOrderPaymentRequestTransfer);

return $preOrderPaymentResponseTransfer;
}

/**
* @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return \Generated\Shared\Transfer\PaymentMethodsTransfer
*/
public function getAvailableMethods(QuoteTransfer $quoteTransfer)
public function getAvailableMethods(QuoteTransfer $quoteTransfer): PaymentMethodsTransfer
{
/** @var \Generated\Shared\Transfer\PaymentMethodsTransfer $paymentMethodsTransfer */
$paymentMethodsTransfer = $this->zedRequestClient->call('/payment/gateway/get-available-methods', $quoteTransfer, null);
Expand Down
23 changes: 22 additions & 1 deletion src/Spryker/Client/Payment/Zed/PaymentStubInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,35 @@

namespace Spryker\Client\Payment\Zed;

use Generated\Shared\Transfer\PaymentMethodsTransfer;
use Generated\Shared\Transfer\PreOrderPaymentRequestTransfer;
use Generated\Shared\Transfer\PreOrderPaymentResponseTransfer;
use Generated\Shared\Transfer\QuoteTransfer;

interface PaymentStubInterface
{
/**
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function initializePreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer;

/**
* @param \Generated\Shared\Transfer\PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
*
* @return \Generated\Shared\Transfer\PreOrderPaymentResponseTransfer
*/
public function cancelPreOrderPayment(
PreOrderPaymentRequestTransfer $preOrderPaymentRequestTransfer
): PreOrderPaymentResponseTransfer;

/**
* @param \Generated\Shared\Transfer\QuoteTransfer $quoteTransfer
*
* @return \Generated\Shared\Transfer\PaymentMethodsTransfer
*/
public function getAvailableMethods(QuoteTransfer $quoteTransfer);
public function getAvailableMethods(QuoteTransfer $quoteTransfer): PaymentMethodsTransfer;
}
52 changes: 45 additions & 7 deletions src/Spryker/Shared/Payment/Transfer/payment.transfer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<property name="shippingAddress" type="Address"/>
<property name="expenses" type="Expense[]" singular="expense"/>
<property name="priceMode" type="string"/>
<property name="preOrderPaymentData" type="array" associative="true" singular="preOrderPaymentDatum"/>
</transfer>

<transfer name="Order">
Expand All @@ -51,12 +52,6 @@
<property name="salesPaymentMethodTypes" singular="salesPaymentMethodType" type="SalesPaymentMethodType[]"/>
</transfer>

<transfer name="PaymentAuthorizeResponse">
<property name="redirectUrl" type="string"/>
<property name="isSuccessful" type="bool"/>
<property name="message" type="string"/>
</transfer>

<transfer name="PaymentAuthorizeRequest">
<property name="requestUrl" type="string"/>
<property name="postData" type="array" associative="true" singular="postValue"/>
Expand All @@ -65,6 +60,13 @@
<property name="tenantIdentifier" type="string"/>
</transfer>

<transfer name="PaymentAuthorizeResponse">
<property name="redirectUrl" type="string"/>
<property name="isSuccessful" type="bool"/>
<property name="preOrderPaymentData" type="array" associative="true" singular="preOrderPaymentDatum"/>
<property name="message" type="string"/>
</transfer>

<transfer name="PaymentMethods">
<property name="methods" singular="method" type="PaymentMethod[]"/>
</transfer>
Expand Down Expand Up @@ -101,13 +103,18 @@
<transfer name="PaymentMethodAppConfiguration" strict="true">
<property name="baseUrl" type="string"/>
<property name="endpoints" type="Endpoint[]" singular="endpoint"/>
<property name="checkoutConfiguration" type="CheckoutConfiguration"/>
</transfer>

<transfer name="Endpoint" strict="true">
<property name="name" type="string"/>
<property name="path" type="string"/>
</transfer>

<transfer name="CheckoutConfiguration" strict="true">
<property name="strategy" type="string"/>
</transfer>

<transfer name="StoreRelation">
<property name="idEntity" type="int"/>
<property name="idStores" type="int[]" singular="idStores"/>
Expand Down Expand Up @@ -278,6 +285,18 @@
<property name="collection" type="array" singular="aclEntityMetadata" associative="true"/>
</transfer>

<transfer name="PreOrderPaymentRequest">
<property name="quote" type="Quote"/>
<property name="preOrderPaymentData" type="array" singular="preOrderPaymentDatum" description="After the first call to initialize the payment this data will be set."/>
<property name="payment" type="Payment"/>
</transfer>

<transfer name="PreOrderPaymentResponse">
<property name="isSuccessful" type="bool"/>
<property name="error" type="string"/>
<property name="preOrderPaymentData" type="array" associative="true" singular="preOrderPaymentDatum"/>
</transfer>

<!-- Asynchronous Messages -->
<transfer name="AddPaymentMethod">
<property name="name" type="string"/>
Expand All @@ -287,10 +306,17 @@
<property name="messageAttributes" type="MessageAttributes"/>
</transfer>

<transfer name="DeletePaymentMethod">
<transfer name="UpdatePaymentMethod">
<property name="name" type="string"/>
<property name="providerName" type="string"/>
<property name="paymentAuthorizationEndpoint" type="string"/>
<property name="paymentMethodAppConfiguration" type="PaymentMethodAppConfiguration"/>
<property name="messageAttributes" type="MessageAttributes"/>
</transfer>

<transfer name="DeletePaymentMethod">
<property name="name" type="string"/>
<property name="providerName" type="string"/>
<property name="messageAttributes" type="MessageAttributes"/>
</transfer>

Expand Down Expand Up @@ -490,5 +516,17 @@
<property name="amount" type="int"/>
<property name="messageAttributes" type="MessageAttributes"/>
</transfer>

<transfer name="AcpHttpRequest" strict="true">
<property name="method" type="string"/>
<property name="uri" type="string"/>
<property name="headers" type="array" associative="true" singular="header"/>
<property name="body" type="string"/>
</transfer>

<transfer name="AcpHttpResponse" strict="true">
<property name="httpStatusCode" type="int"/>
<property name="content" type="string"/>
</transfer>
<!-- EOF deprecated Asynchronous Messages -->
</transfers>
Loading

0 comments on commit 3a2cfd0

Please sign in to comment.