[API] Add Payment request#15502
Conversation
83ebb5d to
da5d3c1
Compare
Bunnyshell Preview Environment deletedAvailable commands:
|
ec4f275 to
487ba19
Compare
487ba19 to
2d43682
Compare
5d54f31 to
cd679fc
Compare
cd679fc to
74c252a
Compare
162906d to
f2c46d1
Compare
4a52858 to
2de795b
Compare
f054ae6 to
77e2207
Compare
3e9e391 to
5d8c23b
Compare
src/Sylius/Bundle/ApiBundle/Applicator/PaymentStateMachineTransitionApplicator.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/ApiBundle/CommandHandler/Payment/AddPaymentRequestHandler.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/ApiBundle/CommandHandler/Payment/AddPaymentRequestHandler.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/ApiBundle/CommandHandler/Payment/UpdatePaymentRequestHandler.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/ApiBundle/CommandHandler/Payment/UpdatePaymentRequestHandler.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/CommandHandler/ModelPaymentRequestHandler.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/CommandHandler/ModelPaymentRequestHandler.php
Outdated
Show resolved
Hide resolved
NoResponseMate
left a comment
There was a problem hiding this comment.
The graph is not necessarily true since you can technically immediately finalize the payment via the create request endpoint.
Now the question is whether we should allow that or force using the post endpoint for initializing/validating/handshake only. It'd then require using the payments API at least twice but might be easier to manage, at least the responsibilities of each would be clearer. Food for thought.
src/Sylius/Bundle/PaymentBundle/Resources/config/doctrine/model/PaymentRequest.orm.xml
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/Resources/config/services/integrations/payum/stripe.xml
Outdated
Show resolved
Hide resolved
| $stateMachine = $this->stateMachineFactory->get($payment, PaymentTransitions::GRAPH); | ||
| if ($paymentRequest->getResponseData()['paid']) { | ||
| $stateMachine->apply(PaymentTransitions::TRANSITION_COMPLETE); | ||
| } else { | ||
| $stateMachine->apply(PaymentTransitions::TRANSITION_PROCESS); | ||
| } |
There was a problem hiding this comment.
The fact that we need to manually trigger a transition cascade to payment is annoying, but I don't really have any good idea ATM how to abstract it out, or if it's even possible given the multiple request types.
There was a problem hiding this comment.
Yes, but keep in mind that this is required only for non Payum gateways, Payum is doing this transition too.
There was a problem hiding this comment.
What you've wrote, makes me think about a way to setup a state machine on the payment request which can cascade status to the payment.
I can imagine it clearly for this Offline gateway: transition from new|processing to completed (if the type === "capture|authorize"), cascade state to completed on the related payment.
WDTY?
There was a problem hiding this comment.
The main problem I see with that is you'd need a matrix of paymentRequest state machines for every factory and paymentRequest type within, which might get messy fast.
Let's say we have 3 factories, each having 4 steps per payment (4 different types of requests), I'd assume you'd need 12 state machines to process the payment's state correctly since each factory can change the state of payment differently per type.
Having to set it manually is maybe annoying, but at least the person implementing it can be sure what state will be the result and there is no internal magic that can be potentially buggy.
...ius/Bundle/CoreBundle/PaymentRequest/CommandHandler/Offline/CapturePaymentRequestHandler.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/Migrations/Version20240203222417.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/ApiBundle/Resources/config/validation/AddPaymentRequest.xml
Show resolved
Hide resolved
src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml
Show resolved
Hide resolved
be9dc0a to
a3fa5a7
Compare
ad38580 to
dccffa8
Compare
2187db3 to
9e03e1d
Compare
There was a problem hiding this comment.
Request changes is due PaymentRequest/Payum/Checker/PayumRequirementsChecker, looks like this system needs to be refactored. (#15502 (comment))
src/Sylius/Bundle/PayumBundle/Resources/config/integrations/payum/paypal.xml
Show resolved
Hide resolved
src/Sylius/Bundle/PayumBundle/Resources/config/integrations/payum/stripe.xml
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/Factory/PayumTokenFactory.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/Factory/PayumTokenFactory.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/Checker/PayumRequirementsChecker.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/Checker/PayumRequirementsChecker.php
Outdated
Show resolved
Hide resolved
...e/CoreBundle/PaymentRequest/CommandProvider/ServiceProviderAwareCommandProviderInterface.php
Outdated
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/Checker/PayumRequirementsChecker.php
Show resolved
Hide resolved
I refactored it, thank you very much for your review @diimpp ! |
| count: 1 | ||
| path: src/Sylius/Bundle/ApiBundle/CommandHandler/Checkout/UpdateCartHandler.php | ||
|
|
||
| - |
There was a problem hiding this comment.
In general it would be good to apply rule that we can only remove from the baseline, not add to it. We can either fix it (preferable option) or write ignore for some type of problem
There was a problem hiding this comment.
I totally agree, I only add what other existing rules were doing like the one for the repositories for example, the rest are needed exclusion for mixed data.
| $response = $this->client->show(Resources::ORDERS, $this->sharedStorage->get('cart_token')); | ||
| Assert::same($this->client->getLastResponse()->getStatusCode(), 200); | ||
|
|
||
| // If the payment is canceled we won't be able to retrieve it because only new one are retrievable |
There was a problem hiding this comment.
shouldn't we eventaully change it and just return cancelled payments as well. Or allow to fetch them with filtration
There was a problem hiding this comment.
If the payment state of the Order is canceled then it's a final state (sylius_order_payment graph):
We don't need to retrieve payment when the order itself is canceled.
Having a way to get access to all payments related to an order can be something that developers will want, but the current behaviour is fine IMHO.
| ) { | ||
| } | ||
|
|
||
| public function check(PaymentRequestHashAwareInterface $command): PaymentRequestInterface |
There was a problem hiding this comment.
I'm not convinced about naming of this service. It should check something, but it mostly asserts and provides request from command
There was a problem hiding this comment.
I agree, since it mainly retrieve a PaymentRequest it can be named "Provider".
@lchrusciel What about PaymentRequestProvider and divide the actual method to 2 methods : provideFromCommand and provideFromHash ?
|
|
||
| public function add(PaymentRequestInterface $paymentRequest): void | ||
| { | ||
| $this->paymentRequestRepository->add($paymentRequest); |
There was a problem hiding this comment.
this logic will persist new object and commit transaction. Do we really want to do it at this stage? Shouldn't we rather just persist it and depend on flushing around command bus?
All in all, maybe this logic should be based more on commands?
There was a problem hiding this comment.
To some extend logic in this class could be simplify to one function, where we will always persist() on object manager
There was a problem hiding this comment.
Reading the code of promotion catalog, I see how to solve this.
Lets just make the same as here : https://github.com/Sylius/Sylius/blob/1.13/src/Sylius/Bundle/ApiBundle/CommandHandler/Catalog/AddProductReviewHandler.php#L68
And then I will add an event subscriber like this one dispatching the commands :
https://github.com/Sylius/Sylius/blob/1.13/src/Sylius/Bundle/ApiBundle/EventSubscriber/CatalogPromotionEventSubscriber.php#L47
|
|
||
| $command = $this->paymentRequestCommandProvider->provide($paymentRequest); | ||
|
|
||
| $this->commandBus->dispatch($command); |
There was a problem hiding this comment.
We should dispatch command after flushing the transaction as we are processing it on async queue
There was a problem hiding this comment.
Resolved by comment above
| use Sylius\Component\Payment\Repository\PaymentRequestRepositoryInterface; | ||
| use Symfony\Component\Messenger\MessageBusInterface; | ||
|
|
||
| final class PaymentRequestCommandDispatcher implements PaymentRequestCommandDispatcherInterface |
There was a problem hiding this comment.
I would like to rethink this class name. Maybe some saver or something like that?
There was a problem hiding this comment.
Catalog promotion called this kind of class "Announcer" WDYT ?
...ius/Bundle/CoreBundle/PaymentRequest/CommandHandler/Offline/CapturePaymentRequestHandler.php
Show resolved
Hide resolved
src/Sylius/Bundle/CoreBundle/PaymentRequest/Payum/Checker/DoctrineProxyObjectResolver.php
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| $paymentRequest->setResponseData($responseData); | ||
| $paymentRequest->setState(PaymentRequestInterface::STATE_COMPLETED); |
There was a problem hiding this comment.
maybe therefore we should change function to somethin like $paymentRequest->complete()?
| use Sylius\Component\Payment\Model\PaymentRequestInterface; | ||
| use Sylius\Component\Payment\PaymentTransitions; | ||
|
|
||
| final class AfterCaptureProcessor implements AfterCaptureProcessorInterface |
There was a problem hiding this comment.
What is the main idea behind splitting capture into normal and after? If I see correctly, we always trigger both of them
There was a problem hiding this comment.
You are right, I wanted to split those two but it's not required.
|
Before someone asks why was it closed. |
This PR was merged into the payment-request branch. Discussion ---------- | Q | A | |-----------------|--------------------------------------------------------------| | Branch? | payment-request | | Bug fix? | no | | New feature? | yes | | BC breaks? | no | | Deprecations? | no | | Related tickets | #15502 | | License | MIT | Commits ------- Add Payment request model Add API resource Add first step of a PAYUM Capture request Finalise Payum POC and 1st try with no Payum using Offline payment method Rename data to payload Rename input/output data to requestPayload/responseData Move Payum stuff to PayumBundle Move services from ApiBundle to PaymentBundle Move services from ApiBundle to PayumBundle Update field in migration Add validation on adding payment request Behat api scenario for PayPal Attempt to get a real object instead of proxy one Pay with PayPal via authorize working Refactor some repeated processes and fix ECS 3/5 behat tests ok Behat ecs fix @paying_for_order&&@api fully working Fix PHPStan real issue and regenrate baseline for the rest Fix service definition and use state machine absctraction Move Payum related integrations to a dedicated folder Fix composer require checker missing new usages Regenerate baseline for PHP8.2 and Sf 6.4 Fix baseline Add missing deps Fix old ignore Use Sylius abstract doctrine migration to allow PostgreSQL Create migration for PostgreSQL Add missing messenger buses Refactor to use CoreBundle instead of SyliusPay(um|ment)Bundle
First PR to handle payments via requests.
