Problem/Motivation
The commerce_order.order.paid event is used by commerce_registration/src/EventSubscriber/OrderSubscriber.php to update the registration status to complete.
However, this event is a little odd, in that it actually fires inside the presave logic of the Order entity. Because of this it's possible to get an error in this code as the registration is being saved inside the order presave:
Drupal\Core\Entity\EntityStorageException: Update existing 'registration' entity while changing the ID is not supported. in
Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 817 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 806)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object) (Line: 352)
Drupal\Core\Entity\EntityBase->save() (Line: 75)
Drupal\commerce_registration\EventSubscriber\OrderSubscriber->onOrderPaid(Object, 'commerce_order.order.paid', Object)
call_user_func(Array, Object, 'commerce_order.order.paid', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'commerce_order.order.paid') (Line: 100)
Drupal\commerce_order\OrderStorage->doOrderPreSave(Object) (Line: 61)
Drupal\commerce_order\OrderStorage->invokeHook('presave', Object) (Line: 529)
Drupal\Core\Entity\EntityStorageBase->doPreSave(Object) (Line: 753)
Drupal\Core\Entity\ContentEntityStorageBase->doPreSave(Object) (Line: 483)
Drupal\Core\Entity\EntityStorageBase->save(Object) (Line: 806)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object) (Line: 352)
Drupal\Core\Entity\EntityBase->save() (Line: 312)
Drupal\commerce_stripe\Plugin\Commerce\PaymentGateway\Stripe->createPayment(Object, 1) (Line: 68)
Drupal\ahs_commerce\Plugin\Commerce\PaymentGateway\Stripe->tryGatewayMethod('createPayment', Array, Object) (Line: 130)
Drupal\ahs_commerce\Plugin\Commerce\PaymentGateway\Stripe->createPayment(Object, 1) (Line: 179)
Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentProcess->buildPaneForm(Array, Object, Array) (Line: 545)
Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowWithPanesBase->buildForm(Array, Object, 'payment')
call_user_func_array(Array, Array) (Line: 536)
Drupal\Core\Form\FormBuilder->retrieveForm('commerce_checkout_flow_ahs_registration_registration', Object) (Line: 283)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 224)
Drupal\Core\Form\FormBuilder->getForm(Object, 'payment') (Line: 143)
Drupal\commerce_checkout\Controller\CheckoutController->formPage(Object) (Line: 47)
Steps to reproduce
I'm not able to reproduce this easily, as even in my setup I don't understand why it occurs in some circumstances and not others. And my checkout flow and panes are heavily custom.
Proposed resolution
Use the commerce_order.commerce_order.update event instead of the commerce_order.order.paid event.
This lacks the strong guarantee that it's only triggered once that order.paid has, but arguably that's a feature not a bug.
Remaining tasks
User interface changes
None.
API changes
None.
Data model changes
None.