-
-
Notifications
You must be signed in to change notification settings - Fork 825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[REF] Retrieve the token if it is available from the Payment Token ta… #17461
[REF] Retrieve the token if it is available from the Payment Token ta… #17461
Conversation
(Standard links)
|
Thanks @seamuslee001 👍 ping @adixon PS - civicrm_payment_token was created at a YMCA with poor meals in the Colorado mountains specifically for the purpose of storing payment processor tokens so I think we do want them there. |
63eac85
to
d5cf72b
Compare
@seamuslee001 so we have a separate setPaymentToken that is more appropriate than setting the wrong field with it. I'm kinda inclined to think that since we are already setting contribution recur id it makes sense for the processor to use that to get the token. It is in theory an extra query - but the way you are implementing it is an extra query anyway so the downside isn't that clear |
so @eileenmcnaughton my question then is what is the difference between setRecurProcessorID and setPaymentToken ? But also its worth noting that only 1 of the 3 forms seems to be using PropertyBag so far |
@seamuslee001 legacy. We were already setting that & the calling functions were already expecting it |
So these 2 fields are serving the same purpose right? I'm just a bit confused as to what the end point then is and also I'm not looking to dig in and covert the other forms to property bag and they are still relying on getSubscriptionDetails information |
Well fundamentally all the processor needs is the contributionRecurID if everything else is in the DB already. The reason to give it more would be if it were more efficient query-wise or if is already coded to expect something for legacy reasons or if it's not in the DB. If we do decide we should give it more then we should set the correct parameter - ie. paymentToken. I would love to deprecate that silly processor_id field out of existance... |
@artfulrobot might have further thoughts - I could make a case for a propertyBag getter that would load DB-retrievable values if not already loaded. |
@seamuslee001 I'm not fully understanding the link with cancelRecurring here and #17445. But A payment token can be used to initiate a payment using a specific, pre-authorized by the customer, method and does not necessarily need to be tied to a subscription - eg. it could represent a customer credit card. It might help if you rebase this because the link to cancelsubscription no longer goes to the right place and I can't be sure what you mean :-) |
@mattwire the problem is that for IATS and maybe other payment processors (I have not looked our client only uses IATS) the recurring token is stored in the The issue is that when we build the subscriptionDetails object we assume the subscription_id is coming from Eileen is saying that instead of using setPaymentToken for the propertyBag function I think or even not worry about it and assume the processor will get the token from the recur_id but I'm still not 100% sure that is perfect |
…ble if no processor_id is set Update the updateBilling and updateSubscription forms as well
also have now rebased this PR |
d5cf72b
to
02f3e80
Compare
Thanks @seamuslee001 please see #17466 for a cleanup that I think will help. I think I now understand. IATS is using payment tokens in the way I describe (representing a payment method, eg. a credit card, a bank account) and is not directly related to the subscription - ie. you could use that token on multiple subscriptions/recurs. So it doesn't belong in processor_id(subscription_id). Historically we didn't actually pass the recur ID into cancel and relied on looking the recur up via Therefore, I think the fix here should be #17466 and then changing https://github.com/civicrm/civicrm-core/blob/master/CRM/Contribute/Form/CancelSubscription.php#L221 to be optional... but.. What is actually being passed into |
@mattwire my understanding is that the processor_id predates civicrm_payment_token table completely and as such processor_id held the payment token for charging a subscription. Others such as @eileenmcnaughton can probably confirm but that is my understanding |
@seamuslee001 ""Trying to cancel a recurring payment using the self serve link results in an error: InvalidArgumentException: "processorID field has max length of 255""
|
That would explain why I couldn't work out why it would happen when looking at the code! One other difference here is whether the recurring contributions are CiviCRM initiated (IATS and some others) or processor initiated (Stripe, GoCardless, Smartdebit etc). In the CiviCRM initiated case you can generally use the (auto-generated) invoice_id on the recur to represent the subscription ID. On processor initiated that field is generally useless and you have to use the Any payment tokens would be handled separately. In fact, |
Yep - exactly it. I worked on this with a fellow [forgot his name...] back in 2015/CiviCamp Denver Sprint under Eileen's guidance. When Alan and I first started work on iATS Payments we looked at |
Yes - correct In an abstract way isn't your |
I'm closing this as the issue seems to have been an otherwise-fixed error |
@seamuslee001 - fixed how? Perhaps because after Alan ended up playing whack a mole for a bit he ended up adding a hook in the iATS Extension to retrieve the recuring id from the url when on the updatebilling form? |
@KarinG my understanding was the underyling issue is that we changed core such that it was erroring per ""Trying to cancel a recurring payment using the self serve link results in an error: InvalidArgumentException: "processorID field has max length of 255"" In this case the processor has the recurring contribution id & it is an extra query for core or the processor to grab the token from that so it makes sense to do it in the extension as required. |
@KarinG @eileenmcnaughton There was an outstanding issue with So I think it actually is fixed in CiviCRM 5.25 but you'll need to use a workaround if supporting older versions (I support the last security release upwards (ie 5.24) |
Ok that's great, so CancelSubscription.php now does have both mission critical references (recur_id and subscription_id) https://github.com/civicrm/civicrm-core/pull/16741/files ->
So then we can do something similar for -> CRM/Contribute/Form/UpdateBilling.php as well? Currently that form only has the processor_id reference: For the exact same reasons -> that update form also needs: @mattwire - I see you edited that |
@KarinG yes - we should do similar for updateBilling - note the current method name is 'updateSubscriptionBillingInfo' & we should wrap that in a 'do' function - perhaps 'doUpdateRecurring' & then maybe that should be the same wrapper fo ''changeSubscriptionAmount'' |
…ble if no processor_id is set
Overview
Some Payment Processors (notably IATS) do not store the customer token in the civicrm_contribution_recur.processor_id column but rather in the civicrm_payment_token.token column instead see https://github.com/iATSPayments/com.iatspayments.civicrm/blob/3f72337ca0430fc3aaad94c3aba2271c198b2273/CRM/Core/Payment/iATSServiceACHEFT.php#L266
However this causes the cancel form on contribution recur self service to break because the cancel form is assuming the payment token will always be in civicrm_contribution_recur.processor_id https://github.com/civicrm/civicrm-core/blob/master/CRM/Contribute/Form/CancelSubscription.php#L219
Before
Self-Service Cancel form fails or IATS and possibly other payment processors that store the token in the civicrm_payment_token table rather than in the civicrm_contribution_recur table
After
Cancel form works for IATS and similar
ping @mattwire @eileenmcnaughton @KarinG note that this is a partial alternate to @Edzelopez 's #17445 Note this aims to only fix item 1 from that PR