Right now the SupportsStoredPaymentMethods interface is onsite only, and the payment_information pane doesn't even check if payment methods exist if the selected gateway is offsite.
We can easily fix the payment_information pane to always check for payment methods, but we need to figure out how to restructure the interfaces. Offsite has two ways of supporting payment methods:
1) onReturn / onNotify() can return both a payment and a payment method, and the payment method can be used on next purchase
2) In rare cases, the user can also create payment methods through their own user pages (Zuora iFrame, for example)
So we need to distinguish between offsite "I can have payment methods" and "the user can create payment methods"
| Comment | File | Size | Author |
|---|---|---|---|
| #81 | Updated-version-of-238380-81-allow-offsite-payment.patch | 28.85 KB | florisg |
| #74 | meta_allow_offsite-2838380-74.patch | 57.9 KB | mglaman |
| #72 | meta_allow_offsite-2838380-72.patch | 62.72 KB | mglaman |
| #72 | interdiff-2838380-70-72.txt | 28.98 KB | mglaman |
| #70 | interdiff-2838380-64-70.txt | 14.38 KB | mglaman |
Comments
Comment #2
maciej.zgadzaj commentedI had a quick look at the interfaces last Friday, and have come up with this as a possible way forward?
Essentially, next to existing
SupportsStoredPaymentMethodsInterfaceit adds newSupportsCreatingStoredPaymentMethodsInterface, moving thecreatePaymentMethod()method declaration there.The idea is:
1) payment gateways that support creating new credit card tokens only during the checkout (together with order payment) would implement
SupportsStoredPaymentMethodsInterfaceonly,2) additionally, gateways that support "stand-alone" cc token creation as well (outside of checkout) would also implement
SupportsCreatingStoredPaymentMethodsInterface,3) gateways not supporting tokenization at all wouldn't implement any of these interfaces.
This applies to both onsite and offsite gateways, as I imagine we could have an onsite gateway not supporting cc tokenization.
Mind that the llinked commit is just a very rough and incomplete draft.
Thoughts?
Comment #3
mglamanI think we should just keep
SupportsStoredPaymentMethodsInterfaceand the payment gateway properly sets the payment method as not being reusable. Otherwise I would say aSupportsReusablePaymentMethodsInterfaceto identify the reusable flag can be TRUE.With the linked commit I'd rather keep the OffSiteInterface lean, not extending anything with stored payments. The problem is it feels cumbersome to add a new interface just to make sure a flag is TRUE or FALSE. I'd rather leave this to developer documentation.
Comment #4
maciej.zgadzaj commentedBojan said he wanted to rewrite these stored interfaces - see our Slack from 09/01 - the linked commit is just my take on it.
Setting the payment method as being reusable or not is a different thing. Here in both cases - both for
SupportsStoredPaymentMethodsInterfaceas well as forSupportsCreatingStoredPaymentMethodsInterfacethe payment method is always reusable. (Well, actually, there is also a 3rd case, when a payment method is not reusable, and then the gateway should not implement any of the "stored" interfaces.)The issue here is separating the 2 use cases from Bojan's issue description - 1) payment gateways that support creating payment methods only during the checkout process and 2) gateways that support "stand-alone" creation of payment methods (from user's "Payment methods" page, without checkout). The 2nd case is what
SupportsCreatingStoredPaymentMethodsInterfaceis supposed to be used for - though perhaps a different name might fit it better.It's just that when a payment gateway doesn't support "stand-alone" payment method creation, the
createPaymentMethod()method doesn't make any sense, and actually should not be called at all - that's why I have moved it to a separate interface, and did other subsequent changes.Re keeping the OffSiteInterface lean - no problem with that, I will update the commit accordingly.
Comment #5
harings_rob commentedWork on this was done here: https://github.com/drupalcommerce/commerce/pull/613
Comment #6
harings_rob commentedWouldn't it be ok for the "first" version to just store the payment address and name for a given method.
Let's say I pay with "bankcontact", a single use off-site payment method.
I enter my address and continue to the payment page.
The next time I get to the payment selection page, I select "bankcontact" again, and my address is pre-filled.
The rest of the process goes as usual.
Comment #7
zaporylieI've been looking into proposed changes and issue summary (both made a long time ago and partially outdated) and I have some doubts in relation to PaymentMethodTypes.
All that makes me wonder:
I know this issue has a high priority on the #2913801: Commerce 2.x roadmap, hence I hope we can make some progress in the following weeks. I'll be working on this issue for the next 2 weeks with the hope that @bojanz or @mglaman will find time to brainstorm with me on the direction this issue should follow.
Comment #8
zaporylie☝ Kinda answering myself 👇
I believe it would be best to reuse SupportsStoredPaymentMethod interface even though it is not the perfect fit here. The one and the only issue I see is that we must create PaymentMethod entity before we even take the user offsite, so that we can collect and sustain payment method data between checkout steps - billing profile, and for some providers, payment-method-type-specific fields, ex. telephone number (Vipps).
A solution could be to create the payment method stub - payment method entity flagged as not yet ready to be paid with and needing offsite finalizing before becoming fully-featured payment method. As far as I'm concerned even though such stubs can easily bloat the database I see it as the easiest and the least time-demanding solution, featuring all perks we get with the Commerce payment architecture.
Nevertheless, for every OffsitePaymentGateway implementing SupportsStoredPaymentMethod we would need an extra method - similar to OnsitePaymentGatewayInterface::createPayment() - that will handle payments for already stored payment methods.
Any objections or could I just try to code it?
Comment #9
zaporylie@bojanz answered on Slack that he doesn't like the idea of stub.
In that case, we're most likely won't be able to have a payment method form of any kind for payment methods using offsite gateways - at least I can't think of any other way. The only thing we can do is to re-use the approach we have for one-time off-site gateways, so show the billing profile form element in payment details, which will be later referenced in
$this->order->setBillingProfile(...)(@see Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentInformation::submitPaneForm()).But that means we won't be able to create off-site payment methods outside the checkout flow (-> user page)? We need a billing profile to be stored on the payment method and if we cannot use the order as temp storage then there is no (easy way) of solving it. It sounds like a big tradeoff to me, because the possibility of managing payment methods using user page was something our customers were looking for.
So another idea, which once again isn't perfect by any means but imho still something to be considered is to use TempStore for payment method stub (yes, the stub again) in a similar way we do the node previews. With this approach we don't actually allow $payment_method->save() - that should throw an exception - before the order comes back from the offsite gateway. But TempStore, or at least PrivateTempStore, won't be available for the anonymous user who deals with SupportsNotificationsInterface::onNotify which puts us back to square one...
Comment #10
zaporylieOne more idea before I 🤐. I think this is doable even though we won't support `add-payment-method` form this way. But maybe that's ok? I haven't heard many complaints from offsite-payment-gateway-developers that billing address is not enough for them. And the whole point of offsite gateways is that we won't process data in Drupal.
To the point:
As much as I believe that creating payment methods outside the order context (user pages) is just must-have, I would rather do it in the follow-up, limiting the scope for this issue to the workable minimum. Related challenges - createPaymentMethod has now different signature (missing order context), billing profile form needs to be temporarily stored somewhere because the payment method cannot be created before user returns from the offsite gateway.
I should have patch ready tomorrow.
Comment #11
zaporylieSo here's a PoC to #10. There was some refactoring needed but overall I am happy with the results. Needs tests of course - manual and automated but I'd like to get some feedback first. Setting "Needs review" to see which tests fail - I have run only Unit and Kernel locally.
Comment #12
zaporylie... and the patch :facepalm:
Comment #14
zaporylieInteresting enough the only failing test is not related to this patch - #3009728: Product translation tests are failing for 8.6.x-dev - which theoretically means the patch in #12 doesn't cause any regression.
^ #3009860: Support creating reusable payment method for off-site payment gateways from user page
Comment #15
zaporylieThe reroll of #12, but it requires some changes now that we validate step id and throw NeedsRedirectException early in the returnPage route callback . Perhaps we should give up on createPaymentMethod whatsoever and give the module developer freedom to create payment method via onReturn/onNotify if desired? But that would require them to modify Order object - set the payment_method and save - and the order, according to #2930789-6: Expand code documentation for off-site payment gateways, should not be touched.
In spite of all the above, I'm changing status to "Needs Review" to get some feedback about the patch from both the DrupalCI and developers.
Comment #16
abramm+1 vote for this issue.
Required for PayFast, the South African payment processor.
Comment #17
josebc commentedre-rollin
Comment #18
josebc commentedI noticed that setting state to 'completed' on return it will trigger commerce_order.place.post_transition twice in checkout resulting in things like duplicate order emails.
Comment #19
bojanz commented@josebc
That is fixed in -dev, see #3011667: Saving the order before its payment in PaymentGateway::onReturn() can cause data loss.
Comment #20
josebc commentedYes, issue stopped happening after update
there is something else im wondering about, should we save the payment method for anonymous users? I handled that by returning NULL from the createPaymentMethod in the PaymentGateway plugin implementation in case of anonymous orders but I’m not sure this should be the solution.
Comment #21
abu-zakham commentedAfter applying the patch on the latest version of commerce, I got this error "Error: Call to a member function getPaymentMethodId() on null in Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentInformation->buildPaneForm() (line 184 of modules/contrib/commerce/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentInformation.php)."
I've removed the following code from the patch, I don't know if $default_option was defined before.
Comment #22
milosr commentedChanged wrong class of file StoredOffsiteRedirectWithPurchase.
Comment #24
czigor commentedIf I understand the patch correctly
1.
SupportsCreatingOffsitePaymentMethodsWithPurchaseInterface::createPaymentMethod()would be called on checkout after redirecting back from the gateway site but just before onReturn().2.
SupportsStoredPaymentMethodsInterface::createPaymentMethod()is called on the payment information checkout pane. It has another use on the user payment method management pages for onsite gateways.1. and 2. are mutually exclusive. (We create payment methods differently for onsite and offsite on checkout.) However, we want to make user payment method management pages available for offsite gateways too.
A use case would be Elavon's XML API that supports payment method creation on both checkout and user pages.
My suggestion is introducing a third interface
SupportsCreatingOffsitePaymentMethodsOnUserPageInterfacewith methodcreatePaymentMethodOnUserPage(PaymentMethodInterface $payment_method, array $payment_details). We should also rename SupportsCreatingOffsitePaymentMethodsWithPurchaseInterface to SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface for consistency and clarity. So that's what we would end up with:SupportsStoredPaymentMethodsInterface::createPaymentMethod(PaymentMethodInterface $payment_method, array $payment_details)SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface::createPaymentMethod(PaymentMethodInterface $paymentMethod, OrderInterface $order, Request $request)SupportsCreatingOffsitePaymentMethodsOnUserPageInterface::createPaymentMethodOnUserPage(PaymentMethodInterface $payment_method, array $payment_details)Comment #25
init90Thanks for the great work here. I just start using the patch and noticed that the payment method always attaches to the order as
NULL.It's because of that
SupportsCreatingOffsitePaymentMethodsWithPurchaseInterface::createPaymentMethodnot require to return any value, but inPaymentCheckoutController.phpwe have next code:So in most cases
$payment_methodwill be equal to theNULL.Comment #26
init90Changed status.
Comment #28
czigor commentedThis patch:
\Drupal::.StoredOffsiteRedirectgateway to commerce_payment_example.StoredOffsiteRedirectexample gatewayTests are still to be added. Setting to "Needs review" just to make the bot run tests.
Comment #30
czigor commentedRetry.
Comment #31
czigor commentedComment #33
czigor commentedRetry #2. (Tests are still needed.)
Comment #34
czigor commentedAnd the tests.
Comment #36
czigor commentedSetting the payment's payment method.
Comment #38
czigor commentedComment #39
czigor commentedComment #41
czigor commentedFurther test fixes.
Comment #43
czigor commentedYet another testfix.
Comment #44
mglamanGiving this a look over 👀
Comment #45
mglamanI have got to run for a call. Here are some initial items. I definitely think we're going to need to split out some of this work into other issues to help focus on some of the API improvements of the payment module. Unless we can reconcile them here. This is a great start, @czigor! With passing tests it's time to tighten it up.
Unassigning for now.
Is there a reason we renamed this class? It was changed in #28 but I don't know why. It doesn't seem required and reduces some diff noise.
I'm not against it with good reasoning, but I'm also for not changing it to just change it (keeps diff easier to read, changes more succint
Missing phpdoc for $current_user
Declared dynamically.
Missing return tag
Since these are defined in the route with proper
options.parametersvalues, we can just place them in the method parameters for injection. We don't need to fetch them from the route match.There is no return statement here and Drupal will crash since the controller did not return a render array or response.
If there is an exception, how should this be handled?
Missing @return in phpdoc
Again, let's add this to method params for injection versus manually pulling from the route match
This would not allow an admin to create a payment method for a user.
I'm fine keeping this restriction to start. We'll just want to open a follow up to document it's not supported for admins to create offsite payment methods for other users.
missing param name
Why do we need a specific interface for creating offsite payment methods on checkout?
If it's supported, it should support both instances since it is the same form.
At a quick glance, the main difference is the User interface expects a less completed payment method object. I think we should reconcile this so that we don't need more interfaces.
This is where the interface name feels weird. All payment gateways can create payments. But the Payment API assumes the createPayment method is provided a payment with a populate payment method.
This is code smell which, to me, means we need to reconcile SupportsStoredPaymentMethodsInterface, SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface, and SupportsCreatingOffsitePaymentMethodsOnUserPageInterface
Why did we make an interface for creating payments? Oh, because it only existed on the OnSitePaymentGatewayInterface.
This makes sense. But needs to be worked on some more, further comments to follow.
Any reason we split out deleting? The only reason we added a "SupportsUpdating" is because we missed that functionality in the first API pass and had to add it as a new interface to support backwards compatability.
EDIT:
As soon as I commented, I realized the
createPaymentmethod problem is because it was on OnSitePaymentGatewayInterface and has a dependency on payment methods. The method name really meanscreatePaymentWithPaymentMethod, but that's ugly. But that makes me feel the method really belongs in SupportsStoredPaymentMethodsInterface. But that can also feel weird. But it highlights needing to reconcile SupportsStoredPaymentMethodsInterface, SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface, and SupportsCreatingOffsitePaymentMethodsOnUserPageInterface from the patch.Comment #46
czigor commented1. It had to do something with the js getting triggered on forms it was not supposed to. I can't remember exactly. Let's undo the rename and see if the tests pass for now.
2. Fixed.
3.
We don't need it, removed.Added the string translation trait which declares it.4. Fixed.
5. Fixed.
6. Right, so this is the case when the payment method creation fails. I think we should display a message and still redirect to the user's payment methods collection page. Implemented this.
7-10. Fixed.
11. It's because the process is different for creating a payment method on checkout and one on the user pages. For example, they need to have different return controllers. Or the gateway might not even support creating payment methods on the user pages. See Bojan's issue description and
\Drupal\commerce_payment_example\Plugin\Commerce\PaymentGateway\StoredOffsiteRedirect.12-14 I agree that there would be room for improvements on naming, but changing the name of
SupportsStoredPaymentMethodsInterfaceorcreatePayment()would break BC. ForSupportsCreatingOffsitePaymentMethodsOnCheckoutInterfaceandSupportsCreatingOffsitePaymentMethodsOnUserPageInterfaceI tried to choose descriptive names even if they might not be in line with existing patterns. We could try to make up for the name calamity in the interfaces' comments.We can't put
createPayment()intoSupportsStoredPaymentMethodsInterfacesinceSupportsStoredPaymentMethodsInterfaceis only for onsite andcreatePayment()is needed on both onsite and offsite. (Note thatSupportsStoredPaymentMethodsInterfaceandSupportsCreatingOffsitePaymentMethodsOnCheckoutInterfaceare mutually exclusive as they both havecreatePaymentMethod()but with different arguments.)Comment #47
andypostThe route
entity.commerce_payment_method.collectionis personalized but access check\Drupal\commerce_payment\Access\PaymentMethodAccessCheck::checkAccess()does not use administer commerce_payment_method permission, so why that access check extended for new routes?Return(cancel) page using to pass User via route, but it used only in checkAccess() and "hacky way" for administrator to masquerade as a user
Is this behavior intended? Then it needs extra test coverage
Comment #48
czigor commentedThanks for noticing, I was not aware of
\Drupal\commerce_payment\Access\PaymentMethodAccessCheck::checkAccess(). Removing the custom access check. (I think they checked the same thing though.)Comment #49
mglaman🙏 thanks, @czigor for the updates and @andypost for catching that access check.
Assigning to myself for another round of review. The patch is just under 70kb, partially because of all of the new files. I'd like to see if we can find ways to spin out any succinct changes into other issues. This touched on a lot of required improvements for the Payment API.
Comment #50
mglamanThis is in regards to my comment about why do we need SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface and SupportsCreatingOffsitePaymentMethodsOnUserPageInterface.
I can see why we need SupportsCreatingOffsitePaymentMethodsOnUserPageInterface. But maybe we can reconcile SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface and SupportsStoredPaymentMethodsInterface
The offsite interface provides
The onsite provides
The
array $payment_detailsparameter has no limitations to what it may contain. For onsite payment gateways, it pulls from (typically) hidden HTML inputs.The \Drupal\commerce_payment\Controller\PaymentCheckoutController::returnPage method could very well provide the request in that payment details array, or just the entire request's
requestparameters (since that would be the true replacement of hidden input values. It might be a GET and might be POST, so use$request->request->all()).The example in \Drupal\commerce_payment_example\Plugin\Commerce\PaymentGateway\StoredOffsiteRedirect::createPaymentMethod works all of the time, and creating a payment method was intended to work without the context of an order. When working on Zuora and other offiste iframes that support creating the payment method, we never needed items in the order.
Comment #51
czigor commentedAs per Matt's comment this patch update is removing SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface.
Comment #53
mglamanError is due to the test gateway still implementing SupportsDeletingPaymentMethodsInterface when SupportsCreatingPaymentInterface implements it as well
Comment #54
mglamanSo, I was thinking:
We split out SupportsDeletingPaymentMethodsInterface before because we had custom SupportsPaymentMethods. This makes sense, because we have "Supports" which allows creation, then SupportsEdit and we can do SupportsDelete. I consider payment methods as either reusable or non-reusable payment instruments.
So what I'm proposing is we split SupportsDeletingPaymentMethodsInterface out into a new issue, since I don't think it's required here anymore.
Then, with the current patch we don't have a Checkout specific interface anymore. So maybe we should split SupportsCreatingOffsitePaymentMethodsOnUserPageInterface into its own issue. With the latest patch we can support payment methods with offsite gateways – then a follow up could allow creation from user pages.
That could help split things out a lot.
To make it more feasible, we could turn this issue into a META/PLAN and then the following child issues:
I think this route could make it more feasible to commit and grok.
Thoughts?
Comment #55
mglamanDiscussed with @czigor my thoughts in #54. I'm going to take the work done here and chunk it out into more manageable pieces.
Comment #56
mglamanI found a bug in #51 after my idea of removing SupportsCreatingOffsitePaymentMethodsOnCheckoutInterface. The AddPaymentMethodForm is rendered in checkout, when it shouldn't be. For off-site gateways the payment method is not created before the payment transaction, it is a result of that process.
Comment #57
mglamanThis should fix the test failures, however
Comment #58
mglamanHere's a second revision. This removes the changes to SupportsStoredPaymentMethodsInterface and creation of SupportsDeletingPaymentMethodsInterface. I don't think we need to make this explicit change, especially since we never type hint for it.
Comment #59
mglamanOkay, new iteration. SupportsCreatingOffsitePaymentMethodsOnUserPageInterface extends SupportsStoredPaymentMethodsInterface. This removes onReturnOffsitePaymentMethodOnUserPage in favor of createPaymentMethod.
We consume the query or request parameters and pass those is in as the payment details for offsite gateways.
Comment #60
mglaman🤦♂️ wrong interdiff before.
Comment #61
mglamanIn two places we create a payment method stub with this patch. \Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentInformation::buildPaymentMethodForm does something similar.
I want to see if there is a way to reuse some of the code here.
In our offsite code we use the payment gateway and plugin directly whereas the PaymentInformation pane uses a PaymentOption value object.
Comment #63
mglamanThis patch removes the introduced SupportsCreatingPaymentInterface interface. The
createPaymentmethod was moved to SupportsStoredPaymentMethods, as that was the intent of the method when attached to OnsitePaymentGatewayInterface.This helps reduce the number of API changes and keeps some assumptions, but makes it easy for an off-site gateway to implement stored payment methods. This should also fix the situation where off-site still went off-site when reusing a payment method.
Next steps:
createFromCustomermethod on the payment method storage (naming thanks to lisastreeter)Have off-site payment gateways render their add_payment_method form in checkout without crashing, so we properly collect billing information and don't display the collection when reusing a stored payment methodWe don't want any payment method entities created, just the capture of billing information if configuredComment #64
mglamanOne more before heading out. This is a little clean up.
We can't let off-site payment gateways render add-payment-method forms, as it'd create a bogus payment method entity. This patch ensures the
billing_informationelement renders if the gateway collects billing information, but not if we're using an existing stored off-site payment method.For the checkout flow and reusing payment methods, things seem all right. I want to revisit the sample payment gateway based on my experience with Zuora, which used an iframe as the off-site method and returned a payment token from that process. I also want to review PayPal Checkout's process for stored payment methods.
-----
For Zuora's payment pages, the iframe posts a redirect/callback that contains either an error code or refId. The refId represents the payment method, which allows you to perform charges.
With our currently flow, the offsite gateway would create the payment method and then be able to utilize is in the
onReturn, instead of processing it directly in theonReturncallback.That's the one awkward part. The \Drupal\commerce_payment\Controller\PaymentCheckoutController::returnPage controller is invoking
createPaymentMethodand thenonReturn. It's a helper that we're calling that for off-site gateways. But maybe they should be responsible for creating the payment method within onReturn? That might be difficult from a developer experience perspective.---
TBD: PayPal
Comment #65
mglamanComment #66
mglamanGoing back to #2, and as I have worked on this: I wonder if we should make SupportsCreatingStoredPaymentMethodsInterface. The naming feels weird though because you support stored payment methods and maybe don't support creating? But the idea of creating goes for creation not as a side effect of payment.
For instance, Authorize.net has off-site hosted payment forms. You can then take the transaction ID and convert it into a customer profile and payment profile.
Part of the awakwardness is that we have all of this logic before the onReturn method.
If an on-site supports stored payment methods, they should be responsible for generating them in onReturn.
And if they implement SupportsCreatingStoredPaymentMethodsInterface it means they can be added from the user page.
Maybe.
EDIT: if we made the onReturn responsible, it'd help make the case for a payment method storage method for creating the initialized payment method entity.
Comment #67
zaporylieJust a quick note to the
onReturnmethod responsibility for creating payment method, previously mentioned in #15and
see https://www.drupal.org/project/commerce/issues/2930789#comment-12835134
I will post more detailed comment later but please note that #3009860: Support creating reusable payment method for off-site payment gateways from user page has already been created as per #14 and I stick to what I said - this is a good material for a follow up.
Comment #68
mglamanI haven't had a chance yet to update this issue, but here's a summary I wrote up in Notion: https://www.notion.so/Payment-API-improvements-b0c721f615d04a18b5cfc48f0...
Per #67: the idea is to get it "working" here, and then split into relevant issues
Comment #69
mglaman💪 Cleared off my plate to tackle this today.
Comment #70
mglamanUpdated patch leveraging SupportsCreatingPaymentMethodsInterface. Letting the tests run, doing a review after lunch.
Comment #71
mglamanFeedback for myself. I'm tempted to remove everything related to creating off-site payment methods and handling it in #3009860: Support creating reusable payment method for off-site payment gateways from user page after we commit, but I'm afraid it might cause even more disruption, like if we don't get something right here.
I think we should rename this to
PaymentUserControllerlike we havePaymentCheckoutController.The checkout controller handles checkout procedures. So we should have a user controller.
This would pertain to adding payment methods, but other actions as well that could come in the future.
I need to brush off SCA, but we may need callbacks that help with SCA workflows, such as approving a recurring payment or async payment.
It doesn't cost anything to use the name and allows it to have wider scope.
The
createPaymentMethodmethod was removed from this interface. It is on the payment gateway to create a payment method within it'sonReturnmethod.If we don't, we should have
commerce_payment.order_updaterservice sync the payment's payment method to the order. That would help having to manually set the payment method.Clean this up to just SupportsCreating interface
This should just be SupportsStored
This is already added in the
processRedirectFormprocess callback.Comment #72
mglamanOkay, I think this is pretty close.
I created \Drupal\commerce_payment\PaymentMethodStorageInterface::createForCustomer to help with initializing a payment method to be created. #3137107: Provide a storage method to initialize a new payment method for a customer
It's also safe to spin \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsCreatingPaymentMethodsInterface into its own issue and move
createPaymentMethodfrom SupportsStored to this new method.It should also be safe to move
createPaymentfrom the OnSite interface to SupportsStoredPaymentMethodsInterface, as every gateway I saw implements the OnSite interface. #3137116: Move createPayment to SupportsStoredPaymentMethodsInterfaceThat spins a lot of the ground work out of this issue.
Comment #74
mglamanReroll of #72 after the following were committed
Next, I'll create an issue for the
SupportsCreatingPaymentMethodsInterfacechange.Comment #76
mglamanOne thing got missed:
This needs to change to: SupportsCreatingPaymentMethodsInterface
Comment #77
mglaman🥳2.19 released with support for off-site payment gateways to charge stored payment methods.
The remaining task is #3009860: Support creating reusable payment method for off-site payment gateways from user page. Let's close this issue and carry on there with this last patch.
Comment #79
shaldrupal commented@mglaman thanks for creating a patch, I tried your last posted i.e. #70 but sorry to say my requirement is not being achieved.
Actually I'm finding a solution to process the recurring payments/subscriptions with offsite payment-gateways those not giving any payment methods just redirecting to own payment page(gateway).
Could anyone give me a solution or idea please, hoping will have positive reply as quick as possible.
Comment #80
shaldrupal commentedI tried PATCH-70 & PATCH-74 but both failed, giving this error
With #Patch 70 :
With Patch-74:
Comment #81
florisg commentedrerolled 74 against dev from git