onNitify is called asynchronized and OnReturn is called synchronized so youYou are right about race condition, but onReturn does not modify order at all
This is what happens in the background:
- the
commerce_payment.checkout.return
route on commerce payment module is called which at first it let order payment gateway plugin to create an payment for order - then if no exceptions thrown bymatter what happens in the onReturn method of plugin, it will transit order checkout
to next flow will be redirected on another stage which is
completed
(if onReturn throws exception it will be redirected to previous stage by defaultelse it will be redirect to next stage) - in this situation the method
onStepChangeredirectToStep
in theDrupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowBase
will apply place transation on order,modify and thatsave order which is where the problem happens happens.
this is the implementation of redirectToStep
:
/**
* {@inheritdoc}
*/
public function redirectToStep($step_id) {
if (!$this->isStepVisible($step_id)) {
throw new \InvalidArgumentException(sprintf('Invalid step ID "%s" passed to redirectToStep().', $step_id));
}
$this->order->set('checkout_step', $step_id);
$this->onStepChange($step_id);
$this->order->save();
throw new NeedsRedirectException(Url::fromRoute('commerce_checkout.form', [
'commerce_order' => $this->order->id(),
'step' => $step_id,
])->toString());
}
so to solve the problem in your onReturn method you can simplyshould stand for onNotify changes to be done crate another checkout flow(a while loop which has a thanks for buying
stage after payment and your problem will solvewaits until changes on order are set)
hopes it helps.