Problem/Motivation
Single-step contact/payment/billing is really hard if you need to do anything before Stripe tries to create a payment method and customer.
If, say, you want to identify or create a user matching the order email from a contact information pane on the same step as the payment/billing information pane, that's really difficult, because Stripe has a jquery submit handler on the form, pre-empting other checkout pane submit methods. Stripe::createPaymentMethod() and Stripe::doCreatePaymentMethod() are going to run before any other checkout pane submit method runs.
Proposed resolution
Dispatch a new StripeEvents::PAYMENT_METHOD_CREATE event before a payment method is created.
| Comment | File | Size | Author |
|---|---|---|---|
| #26 | commerce_stripe-payment-method-create-event-3191993-26.patch | 3.84 KB | johnpitcairn |
Comments
Comment #2
johnpitcairn commentedSetting to needs review for testing, but probably warrants a new test to check that the event is dispatched.
Comment #4
johnpitcairn commentedComment #5
jeff veit commentedLooks like it needs
and not
use Drupal\Component\EventDispatcher\Event;I'm going to do some testing to see if I can use this to create a Stripe customer for anonymous users.
Comment #6
johnpitcairn commentedThat is possible I think. I found I needed to stash the order id in private tempstore, because the event doesn't get that handed to it.
For anonymous recurring orders, I still needed to create a real (blocked) user for commerce_recurring to do its thing, but it is possible for checkout to remain anonymous.
Comment #7
johnpitcairn commentedThe Drupal event is a wrapper to work around backwards compatibility for the deprecated/changed Symfony event constructor method signature.
Comment #8
johnpitcairn commentedChange notice for that: https://www.drupal.org/node/3159012
Comment #9
jeff veit commentedJust to note then, for future readers that it should be
use Drupal\Component\EventDispatcher\Event;
on D9.1 and later, as in the patch
and
on D8,
use Symfony\Component\EventDispatcher\Event;
So and you may need to patch the patch to fix this unless D8 introduces transitional code with that mapping, or it is added in Contrib,
John - I am successfully using this for anonymous users. It took a while to get right, and I've added the limitation that once you've set the email address, you can't change it for the order, but it turned out that it isn't much code.
I'll clean it up and probably add it as a different, solved, issue, for others to find. I'm reluctant to make it into a module when it's dependent on a patch.
Comment #10
johnpitcairn commentedThe solution for the deprecation will be to use the old dispatcher and argument order until 8.x support is dropped, or until 10.x support is needed.
Re-rolling.
Comment #11
johnpitcairn commentedUpdated patch using the deprecated
Symfony\Component\EventDispatcher\Eventwith an appropriate todo.Comment #12
johnpitcairn commentedPasses tests, unassigning, please review.
Comment #13
jsacksick commentedCommerce introduced a base event class to facilitate the transition. (EventBase, under commerce namespace).
Comment #14
jsacksick commentedNote we might not need
setPaymentMethod()since objects are always passed by reference, which means getting the payment method and modifying it should be sufficient.Also, not sure why you'd need to set the payment details, and not just access them?
Comment #15
johnpitcairn commentedThanks, I'll use that for this and the transactionData event.
Yes, I'll remove the setter.
Fair enough. If anyone wants it badly enough it's an easy follow-up. I'll remove the setter for that too.
Comment #16
johnpitcairn commentedUsing this will require a minimum commerce version of 8.x-2.25. That's very recent, and there have been no security releases since 8.x-2.18. I'm inclined to leave this as-is for a while yet. Thoughts?
Comment #17
johnpitcairn commentedThis patch removes the setter methods, but does not extend commerce core
EventBase, as per #16, pending discussion.Comment #18
johnpitcairn commentedOK I see we are now requiring commerce 2.25.
I'll re-roll this accordingly.Comment #19
johnpitcairn commentedExtending
EventBasehandles switching theEventclass according to the core/symfony version in use, but it does not handle switching the eventdispatch()parameter order. Right? And the commerce issue handling that is postponed until 8.x support is dropped, with only the base class in place.I don't see any advantage making this change now when it would require parameter-swapping code for both event dispatches, only to remove that anyway when 8.x support is dropped. There are a ton of patches against Stripe.php as it stands, let's not make life harder.
We may as well continue to use the existing deprecated
Symfony\Component\EventDispatcher\Eventclass and parameter order, with todos to change those when commerce core drops support for 8.x.Comment #20
jsacksick commentedIf you extend the base event class now, you won't have to do it later, as the base class knows which event class to extend, so that is one less thing to do, and less deprecation errors, it doesn't hurt to do it, so not sure what you gain by postponing this change as well.
Comment #21
jonathanshawsetPaymentDetails was removed; but it should be included because $paymentDetails is an array and therefore not passed by reference in getPaymentDetails (unlike getPaymentMethod), so it's good to provide an API for anyone wanting to change payment details so they are not exposed to the inner workings of the event construction.
We should follow maintainer guidance in #20.
Comment #22
johnpitcairn commentedFrom @jsacsick in #14:
Which is why the
setPaymentDetailsmethod was removed. Clarification or use-case needed?I will try to attend to #20 soon. I need to look at the implications of #3256552: Allow customising payment intent attributes and metadata and friends first.
Comment #23
johnpitcairn commentedRegarding #20: Correct me if I am wrong - the event should extend Commerce
EventBase, which handles aliasing the new Drupal Event class for core < 9.1. We should follow the Commerce example and switch our event dispatch to use the new argument order (event first, name second). I'll open a separate issue about dropping 8.9 support.This patch
It does not reintroduce the
setPaymentDetailsmethod, pending clarification from @JonathanShaw.Comment #24
johnpitcairn commentedAnd in case anyone else needs it, here's one that applies over:
#3259211: Provide more parameters to createPaymentIntent()
#3259349: Allow for payments without stripe review pane
#3171408: Allow off_session payment intents for recurring payments
#3167261: Lost functionality billing information on anonymous checkout
#3256552: Allow customising payment intent attributes and metadata
In that order.
Comment #25
jonathanshawLooks right to me.
Comment #26
johnpitcairn commentedAs of today all those other issues are committed and included in rc10. So the patch at #24 should be correct.
Renamed and re-uploaded, no changes.
Comment #28
jsacksick commentedCommitted, thanks!