You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current order payment processing is made by Payum: most developers found it hard to get into it. Payum is usually blamed because it is not using already well known concepts and the resulting development of a new Payum gateway can become painful sometime.
However Payum is still the only open source PHP payment library which can bring any payment method to any PHP project.
Sylius needs a new way to handle payments with new ways like :
By making API calls which interact with any existing Payum payment gateways
By having a way to process a payment asynchronously or synchronously depending on the way the payment method is working.
Feature explanation
The Sylius Core team come up with a new concept called "Payment Request", this new feature will allows easier payment processing integration for the UI and the API.
It will supports Payum on the first version it will be shipped, but the goal is to make it optional at the end.
What about the Payum support ?
Since Payum needs an HTTP request and sometime even a session, it's tricky to fully support all the ways the currently available Payum gateways are doing thing.
For example, it's not possible for the PaymentRequest feature to support Payum gateways which are :
Doing weird things like an echo "..."; or making a die; instead of using the RenderTemplate Payum request.
Reading vars like $_REQUEST, $_GET or $_POST instead of requesting GetHttpRequest.
Making a redirection without using the specific Payum way which is to throw an Exception implementing ReplyInterface.
What changes are expected on the PaymentMethod to avoid using Payum ?
The actual Sylius PaymentMethod is relying on a type and it will be used to know if it's a Payum one or not.
The current concept is to define some tagged services to provide custom symfony/messenger messages for each actions the payment handler will have to supports.
For example, for a specific PaymentMethod we can get each supported actions via those service definitions, then when a PaymentRequest is created the action requested will be dispatched into a custom message and consume asynchronously or synchronously depending on the message configuration.
Examples
Synchronous payment processing
This is a diagram explaining how it would work with a synchronous processing:
%%{
init: {
'sequence': {
'noteAlign': 'left',
'noteFontFamily': 'Courier New, monospace'
}
}
}%%
sequenceDiagram
title Sylius - Payment Request
Website->>+Sylius API: POST /shop/payment-request
Note right of Website: {<br> "paymentId": 10,<br> "paymentMethodCode": "offline",<br> "action": "capture",<br> "payload": ...<br>}
Sylius API->>+Payment Method: Dispatch a CAPTURE message
Payment Method-->>-Sylius API: Response
Note left of Payment Method: {'responseData': [...]}
Sylius API->>+Payment Method: Dispatch a STATUS message
Payment Method-->>-Sylius API: Response
Sylius API-->>-Website:
Note left of Sylius API: {<br> "hash": '123456789-1234-123-1234',<br> 'state': 'completed',<br> ...<br> "responseData": [<br> 'redirectUrlOrSomething': 'https://...'<br> ]<br>}
Asynchronous processing
%%{
init: {
'sequence': {
'noteAlign': 'left',
'noteFontFamily': 'Courier New, monospace'
}
}
}%%
sequenceDiagram
title Sylius - Payment Request
Website->>+Sylius API: POST /shop/payment-request
Note right of Website: {<br> "paymentId": 10,<br> "paymentMethodCode": "offline",<br> "action": "capture",<br> "payload": ...<br>}
Sylius API-->>-Website:
Note left of Sylius API: {<br> "hash": '123456789-1234-123-1234',<br> 'state': 'processing',<br> ...,<br> "responseData": []<br>}
par
loop Polling until state change
Website->>+Sylius API: GET /shop/payment-request/{hash}
Sylius API-->>-Website:
Note left of Sylius API: {<br> "hash": '123456789-1234-123-1234',<br> 'state': 'new',<br> ...,<br> "responseData": []<br>}
end
and
Sylius API->>+Payment Method: Dispatch a CAPTURE message
Payment Method-->>-Sylius API: Response
Note left of Payment Method: {'responseData': [...]}
Sylius API->>+Payment Method: Dispatch a STATUS message
Payment Method-->>-Sylius API: Response
and
Website->>+Sylius API: GET /shop/payment-request/{hash}
Sylius API-->>-Website:
Note left of Sylius API: {<br> "hash": '123456789-1234-123-1234',<br> 'state': 'completed',<br> ...,<br> "responseData": [<br> 'redirectUrlOrSomething': 'https://...'<br> ]<br>}
end
More ?
In some cases we need to create a PaymentRequest and update some data along the way. This is typically happening when you need to display a form or redirect the customer to a portal.
For example, let's say you are requesting a PaymentRequest for the action="capture" and the payment method will have first to display a form to the customer before actually capturing the payment.
It means that the payment method have to send a PaymentRequest->responseData even if the PaymentRequest->state is not completed.
Here I choose a synchronous example to make it simpler.
%%{
init: {
'sequence': {
'noteAlign': 'left',
'noteFontFamily': 'Courier New, monospace'
}
}
}%%
sequenceDiagram
title Sylius - Payment Request
Website->>+Sylius API: POST /shop/payment-request
Note right of Website: {<br> "paymentId": 10,<br> "paymentMethodCode": "offline",<br> "action": "capture",<br> "payload": ...<br>}
Sylius API->>+Payment Method: Dispatch a CAPTURE message
Payment Method-->>-Sylius API: Response
Note left of Payment Method: {'responseData': [...]}
Sylius API->>+Payment Method: Dispatch a STATUS message
Payment Method-->>-Sylius API: Response
Sylius API-->>-Website:
Note left of Sylius API: {<br> "hash": '123456789-1234-123-1234',<br> 'state': 'processing',<br> ...<br> "responseData": [<br> 'dataRequiredForAForm': [...]<br> ]<br>}
Website->>+Sylius API: PUT /shop/payment-request/{hash}
Note right of Website: {<br> "payload": {/*data from the submitted form or else*/}<br>}
Sylius API->>+Payment Method: Dispatch a CAPTURE message
Payment Method-->>-Sylius API: Response
Note left of Payment Method: {'responseData': [...]}
Sylius API->>+Payment Method: Dispatch a STATUS message
Payment Method-->>-Sylius API: Response
Sylius API-->>-Website:
Note left of Sylius API: {<br> "hash": '123456789-1234-123-1234',<br> 'state': 'completed',<br> ...<br> "responseData":[...]<br>}
Here is the list of tasks which need to be done to go ahead:
[Component] Design new PaymentRequest models.
[API] Create new front API endpoints.
[Core] Integrate legacy PayPal Payum gateway using PaymentRequest flow (as a POC).
[Core] Integrate legacy Stripe Payum gateway using PaymentRequest flow (as a POC).
[Admin] Copy Payum GatewayConfig model to Payment component (path to the Payum optional requirement).
[API] Refactor duplicate check to a generic service allowing to check if the PaymentReuest should be created or not.
[FRONT UI]Integrate PaymentRequest into the UI flow
The text was updated successfully, but these errors were encountered:
GSadee
added
Feature
New feature proposals.
RFC
Discussions about potential changes or new features.
API
APIs related issues and PRs.
labels
May 17, 2024
State of the art
The current order payment processing is made by Payum: most developers found it hard to get into it. Payum is usually blamed because it is not using already well known concepts and the resulting development of a new Payum gateway can become painful sometime.
However Payum is still the only open source PHP payment library which can bring any payment method to any PHP project.
Sylius needs a new way to handle payments with new ways like :
Feature explanation
The Sylius Core team come up with a new concept called "Payment Request", this new feature will allows easier payment processing integration for the UI and the API.
It will supports Payum on the first version it will be shipped, but the goal is to make it optional at the end.
What about the Payum support ?
Since Payum needs an HTTP request and sometime even a session, it's tricky to fully support all the ways the currently available Payum gateways are doing thing.
For example, it's not possible for the
PaymentRequest
feature to support Payum gateways which are :echo "...";
or making adie;
instead of using theRenderTemplate
Payum request.$_REQUEST
,$_GET
or$_POST
instead of requestingGetHttpRequest
.Exception
implementingReplyInterface
.What changes are expected on the
PaymentMethod
to avoid using Payum ?The actual Sylius
PaymentMethod
is relying on atype
and it will be used to know if it's a Payum one or not.The current concept is to define some tagged services to provide custom
symfony/messenger
messages for each actions the payment handler will have to supports.For example, for a specific
PaymentMethod
we can get each supported actions via those service definitions, then when aPaymentRequest
is created theaction
requested will be dispatched into a custom message and consume asynchronously or synchronously depending on the message configuration.Examples
Synchronous payment processing
This is a diagram explaining how it would work with a synchronous processing:
Asynchronous processing
More ?
In some cases we need to create a
PaymentRequest
and update some data along the way. This is typically happening when you need to display a form or redirect the customer to a portal.For example, let's say you are requesting a
PaymentRequest
for theaction="capture"
and the payment method will have first to display a form to the customer before actually capturing the payment.It means that the payment method have to send a
PaymentRequest->responseData
even if thePaymentRequest->state
is notcompleted
.Task list
We worked on a first PR : #15502 (closed but another PR with the same content has been merged #15943)
Then a new branch was created after this PR to handle all the future work :
https://github.com/Sylius/Sylius/tree/payment-request
Here is the list of tasks which need to be done to go ahead:
GatewayConfig
model to Payment component (path to the Payum optional requirement).The text was updated successfully, but these errors were encountered: