Sylius: Payment events are not triggered

Created on 8 Mar 2017  路  10Comments  路  Source: Sylius/Sylius

In the payment events docs there are two events mentioned sylius.payment.pre_complete and sylius.payment.post_complete but even we are listening to them they are never triggered.

Didn't find anything in the code about them and I guess they are triggered somehow inside thee ResourceBundle.

Don't now if the issues is with the code or with the docs. Some insight would be helpful.

Potential Bug

Most helpful comment

@gorkalaucirica Wait wait, don't rollback it yet! You are right, this even should be called in admin, on the order summary. So it's a bug on our side. And it would be correct to use an listener to send out an e-mail there. The problem with sending e-mail on state machine callbacks is that while callback will work, then can be exception later, before the flush. So the e-mail will go to spool and go out after termination, but because of race conditions the action won't go through. That's why we moved them.

All 10 comments

It's bug with the docs. The events like these are used for actions taken directly by user via UI/API. What is your use case? Maybe you should use state machine's callbacks?

Yes, we were using the state machine in beta1 to send an email when payment was completed. But after updated to master we thought the best practice was to use event listeners to send emails (see order listeners).

We will rollback that, thanks @pjedrzejewski!!!

I will keep this issue open as I guess some action needs to be taken in docs. Feel fee to close when you consider

@gorkalaucirica Wait wait, don't rollback it yet! You are right, this even should be called in admin, on the order summary. So it's a bug on our side. And it would be correct to use an listener to send out an e-mail there. The problem with sending e-mail on state machine callbacks is that while callback will work, then can be exception later, before the flush. So the e-mail will go to spool and go out after termination, but because of race conditions the action won't go through. That's why we moved them.

@gorkalaucirica @pjedrzejewski

As the documentation is written based on the master branch, and the events in question are already present there, it definitely is not a blocker for the next release, moreover it's resolved automatically upon release, so that's something.

That said, if someone would like to have this feature while pre-beta, I can think of at least two ways to make it work:

  1. Override the troubled part of order's routing to:
sylius_admin_order_payment_complete:
    path: /orders/{orderId}/payments/{id}/complete
    methods: [PUT]
    defaults:
        _controller: sylius.controller.payment:applyStateMachineTransitionAction
        _sylius:
            event: complete
            repository:
                method: findOneByOrderId
                arguments:
                    id: $id
                    orderId: $orderId
            state_machine:
                graph: sylius_payment
                transition: complete
            redirect: referer

Does the trick with minimum effort.

  1. Change the version of sylius under composer to dev-master
    Sounds easy, but most likely won't be, as You'd need to resolve all Upgrade.md entries to make it work the way you intended or at all, depending how much stuff You've overwritten. Big upside being it'll let You migrate to the semi-stable second Beta far more easily.

Of course another possibility is to wait for the next beta (which's right 'round the corner), but it'd pose same problems as point 2.

@NeverResponse So right now in master payment events are triggered? When I opened the issue we were working on master, moving events callback for sending mails from state machine to event subscribers. The issue is also discussed in #7763. Basically we do not want emails until payment is completed.

It's not very clear (at least for me) how to make the events work. Maybe more insight in this topic would be helpful. Internals for events are quite "magic" so to understand the them is not straightforward.

@gorkalaucirica Rechecked it a few times, and yeah, they are.
And as for how the events work, there's this doc with the sole basics; etc. how resource based events work, or at least what to listen to and such.

I couldn't find anything more advanced, etc. the one You are referring to, or frankly, any reference to ::applyStateMachineTransitionAction events (which are same as for ::updateAction). So I guess we'd need a more thorough doc about those, and explaining how to declare custom, route specific events such as complete or ship for instance.

And for a swift explanation:
If you define event in sylius parameters, within the route configuration. The basic event for that route gets overwritten by the one you specified.

So for a simple update action there are:

    sylius.resource.pre_update
    sylius.resource.post_update

but with, lets say

...
    _sylius:
        event: waltzing_matilda

you'll get those:

    sylius.resource.pre_waltzing_matilda
    sylius.resource.post_waltzing_matilda

The resource depends on the controller which route you've overridden, but other than that (besides being not documented) it's pretty straightforward.

Checking the EventDispatcher might also give You some insight, especially ::dispatchPreEvent and ::dispatchPostEvent.

Hope this will somewhat help.

Thanks @NeverResponse, I was missing that events can be triggered by declaring them in routing. I can't find though where sylius.payment.pre_complete and sylius.payment.post_complete are triggered after completing the payment using one of the Payum gateways. I guess that this is handled inside Sylius/PayumBundle. State transition is applied but no events are triggered.

Ok, i wasn't taking Payum into account. In which case, scratch all I wrote above.

Payum-based payments seem to go a completely different route, disregarding ResourceController and going through UpdatePaymentStateExtension of the PayumBundle.
And since the extension uses only state machine, there is no event dispatched. And I don't think changing the route will do anything at all. So this is indeed a bug, and quite severe at that.
Gonna investigate further and hopefully fix asap.

It's not a bug! :)

Events are for user interactions, modifying the responses, etc. For business logic, you should use state machine callbacks, which will be triggered no matter if you click in backend or pay via PayPal, etc. We have updated the docs to highlight that difference: http://docs.sylius.org/en/latest/book/architecture/events.html

Please reopen if still unclear. :)

Was this page helpful?
0 / 5 - 0 ratings