Long story short, I have a programmer looking into fixing some of the issues for uc_stripe that have directly affected me:
1) comments not working
2) addition of idempotency
3) update to work with the latest php-stripe library (not so much of an issue as a preference. Latest version is 7.28)
What I need to know is the best plan of attack for getting things fixed and included back into the community. I know the normal approach is to create a new issue for each "problem" and submit a patch. Sorry, "ain't nobody got time for that." What I will probably do, is create a new issue tagged as v4.0 and upload the entire zip. I believe the main changes are strictly with uc_stripe.module, however there will probably be enough changes that are all over the place and I just don't have the time to deal with each and every issue, especially when I'm having to relay stuff I don't even fully comprehend...
For some context, according to the programmer there are a few functions under the hood that should seriously consider being fixed. It's over my head so I'll just re-post his comments.
The uc_stripe.module contains these lines:
// When a payment fails, remove the Submit Order button because it will most
// likely fail again. Instead, the customer should hit back to try again.
if(isset($_SESSION['stripe']['payment_failed'])){
$form['actions']['submit']['#type'] = 'hidden';
}I did not like this when I first saw it a few days ago, and I still do not like it. So instead of hiding the button, I would rename it to "Retry". After clicking the Retry a few times, the customer could still click the Back button. What do you think?
---
Unfortunately the module is still plagued by the "charge" and "confirm" naming confusion, if I understand it correctly. For example, the payment may be successful (done via the ajax call, executed in the function called "confirm"), but later when the server checks the payment in the function named "charge", and this checking fails, then the module sets the "payment_failed" value, which will result in the hiding of the "Submit Order" button.
In other words, there is a huge difference between "Stripe server said that Payment Failed" and "Unable to connect to Stripe Server to check payment result", but the module makes no difference.---
I hope that my explanation was clear, but if not: the main thing is that in addition to the idempotency thing, the network errors should be handled better to completely avoid double payments.
I was confused with whether the problem was with Stripe or UC Stripe. His response:
This confusion is in the uc_stripe module.
The reason could be that other payment modules always have a "charge" function that is called when you click the "Submit" button, and uc_stripe also has such a function. However, in the stripe module the actual payment is done via ajax (in function _uc_stripe_confirm_payment), and the usual "charge" function does no charging, only checking.Some other modules as examples:
/**
* Main handler for processing credit card transactions.
*/
function uc_authorizenet_charge($order_id, $amount, $data) {
/**
* Charges card.
*/
function uc_cybersource_charge($order_id, $amount, $data) {
/**
* Processes a credit card payment through Website Payments Pro.
*/
function uc_paypal_wpp_charge($order_id, $amount, $data) {So other modules do indeed charge in their "charge" functions, but uc_stripe does not. It is not bad, just unusual compared to other modules.
So the network error problem I mentioned could be described like this: when charging in _uc_stripe_confirm_payment() is successful via ajax but checking the result later in uc_stripe_charge() fails, the customer is forced to click the "Back" button and pay again, not knowing that the payment was already done.
(the function names look confusing, don't you think?)
This issue is the start of the contributions I am doing, but don't have time to fully deal with in the issue queue of v3.x. I'll keep things posted here, but mainly wanted to share some of the things I'm working on. If the maintainers need this separated out, then I'm going to have to ask someone in the community to reverse engineer what I present and port it back to 3.x branch. Otherwise I suggest we move to a new targeted version which isn't ideal either...
Sorry for being a pain but I'll do what I can to make this go as smooth as possible.
Comments
Comment #2
andraeray commentedHi Philsward, any contributions are welcome. Separating the changes is the most helpful so that each change can be properly tested, but I understand you may not have the time to do this.
1) I haven't looked at the comment issue much, I don't have any recommendation there.
2) For idempotency, you can probably just generate the idempotent key by doing a hash of order id, total, and possibly order created date. (I'm trying to be careful so that it works for users with recurring payments as well)
3) Just look at the stripe change log breaking changes I think it's pretty safe to upgrade since we don't use many stripe functions.
Originally, Charge() used to do the charge, it was straight forward. But after the SCA changes you create a payment intent, then attempt to process the intent, and check the status to see if it succeeded or needs extra authentication. So it doesn't become as straight forward anymore.
Comment #3
andraeray commentedI have implemented the idempotency key in this ticket:
#3074679: Prevent user from making multiple accidental charges. using the order id, payment amount, and payment Id worked out to be a good key.
I removed the code that disables the "Submit Order" and just defaulted to normal UC cart settings. At the time I didn't consider that a network issue could have prevented it and it might succeed on a retry.
If you would like to submit a patch to name it retry please go ahead.
Comment #4
philsward commented@AndraeRay sounds good. I'll have my guy take a look at your changes and compare with his work to see if there's anything more that can be done.
I'll note that he did get the idempotent key working, however I have had one order come through with two charges to stripe. Transactions were approximately 2 min apart from each other so it might be that pesky "network" issue.
Comment #5
philsward commented@AndraeRay on a side note, I looked through some of the other issues that I'm tagged in and the network discussion came up which triggered a conversation I had with my programmer buddy. He mentioned that Stripe is doing some ajax loading under the hood which he felt is kind of un-necessary to getting the transactions to go through.
We discussed getting rid of the ajax, but haven't had a chance to hammer it out yet.
Thought I'd pass it along and put a bug in your ear. See if you had any thoughts on it.
Comment #6
andraeray commentedI believe Ajax is a requirement. I don't know if you can get rid of it entirely. You might be able to add some webhooks in certain places though.
Comment #7
philsward commentedRelayed Thought #1
Comment #8
philsward commentedRelayed Thought #2
Comment #9
philsward commentedRelayed Thought #3
For context, I had a bunch of double charges on the 17th of April (4 or 5 in one day). I am using the coding from my guy which has its own flavor of implementing the idempotency on it, but that hasn't been the problem. The problem has been with the submit button being removed on click and the customer clicking the back button. Hopefully this is enough back-story to help with below.
(That last comment about double emails was in regards to testing the network response of each respective server, using a sandbox of my live site)
Comment #10
philsward commentedReply to Comment #6
I believe Ajax is a requirement. I don't know if you can get rid of it entirely. You might be able to add some webhooks in certain places though.Comment #11
philsward commentedCorrected branch version.