We register and send account activation emails to guest customers after checkout using
registerUserOnOrderComplete. We also want the guest customer to be able to save their payment card during checkout using
savePaymentSource set to
Unfortunately, it seems
savePaymentSource only works if a customer already has a user account and is logged in, prior to completing checkout.
We have reported to Craft as it feels like it should be handled natively, and it has been marked as a potential enhancement: https://github.com/craftcms/commerce/issues/2825
In the meantime, we are trying to come up with a workaround - possible options:
a) TWIG/NATIVE: Registration (or login) form during checkout
Create a registration (or login) form during checkout, and auto-login the user after registration, prior to completing checkout. This is the simplest to implement but has a couple of drawbacks; one, we'd need to disable email verification to auto-login (I think?). Two, it negatively impacts conversion. Three, accounts are created before checkout completion so, if people do not complete, we accrue 'dead' user accounts.
b) MODULE: Register then login during checkout
Custom module that registers a user using the checkout email, then auto-logins. This could either be an "invisible" step during checkout via a controller/action URL or run from an order/payment event (although we haven't found a suitable event that fires at the right time). We have to use a temporary password and send an email with a password reset link. Similar drawbacks to option A).
c) MODULE: After checkout, register user and save order payment source to user
Custom module that registers user after checkout, then retrieves order payment source and saves it to user, using something like Craft's
createPaymentSource method. This is favourable as it mimics what we hope will be native to Craft one day. However, when we use
createPaymentSource, we get an error of
This PaymentMethod was previously used without being attached to a Customer or was detached from a Customer, and may not be used again.
Does anyone have any better approach for this? Or any guidance for
createPaymentSource in option C?