Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving the synchronisation status appears to overwrite payment provider webhook #85

Open
LauHypershop opened this issue Nov 28, 2024 · 0 comments

Comments

@LauHypershop
Copy link

One of our clients is experiencing intermittent problems where order payment details are not getting saved correctly. We suspect this happens as follows:

  • Customer places an order.
  • Payment is handled with Mollie (PSP)
  • ActiveCampaign OrderSync observer responds to event checkout_onepage_controller_success_action, loads the order from the database, and triggers a call to \ActiveCampaign\Order\Model\OrderData\OrderDataSend::orderDataSend. This method takes a bit of time because it sends data back and forth to the ActiveCampaign API.
  • Meanwhile, Mollie sends back a webhook with further payment details. The Mollie module also loads the order form the database, registers their information, and saves the order.
  • ActiveCampaign API call finishes and the orderDataSend method saves that the order was sync'ed:
                $order->setData("ac_order_sync_status", $syncStatus)
                        ->setData("ac_order_sync_id", $acOrderId)
                        ->save();

As a result, the changes the Mollie webhook made are overwritten. As you can imagine, this is problematic for our client because orders that have been paid are incorrectly marked as pending payment, and after a while they're automatically cancelled for being open for too long. So customers paid, but their orders get cancelled.

This doesn't happen all the time, it's a race condition depending on when the Mollie webhook fires and how long your CURL call takes here:

                    if($AcOrderId > 0){
                        $result = $this->curl->orderDataSend(
                            self::UPDATE_METHOD,
                            self::URL_ENDPOINT . '/' . (int) $AcOrderId,
                            $data
                        );
                    }else{
                        $result = $this->curl->orderDataSend(
                            self::METHOD,
                            self::URL_ENDPOINT,
                            $data
                        );
                    }

I think a possible solution would be to reload the order from the database before saving ac_order_sync_status and ac_order_sync_id, to make sure you don't overwrite any changes that happened during your CURL call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant