Closed chrisleversuch closed 5 years ago
Thank you so much for this ❤️
I've been scrabbling around for the last few hours trying to figure out why 3-D Secure randomly stopped working on Thursday last week on Android (after which we turned it off). We could see the empty md and pares but were unsure why. Next step for me was to run in debug mode and capture the HTML it was processing against (which would have highlighted the bug), but you've already solved it. Awesome!
I'll give this a whirl in the next few days.
Testing using release 1.1.2:
👍 Seems like this is the problem.
@chrisleversuch - Can you replicate these same problems on Chrome 70 using this branch?
My Samsung Android phone has Chrome 70 installed by default. To get version 71 I had to install Chrome Beta.
The choice of webview to use is buried in the Developer Options on Android.
I tested using our commercial app (development version) and used the payments test platform provided by our PSP.
I've been testing a bit more ... on this branch, on Chrome 70 it maybe works 1 in 5 times, which seems to indicate some sort of race condition.
Yeah I'm getting the same problem, not sure how I didn't see it earlier. I'd guess onPageStarted for the Google request is being called before onPageFinished for the previous request. I'll see what I can do
FYI I think I'll try moving the processing to onPageFinished - as soon as there's an html page with MD and PaRes inputs, trigger the completion handler. That's the html we're interested in and I don't think there's any reason to wait for the form to submit itself
Cool. I'm now in a bit of a quandary as to what to do. Ideally I'd like to have this fixed this week, with a gradual app rollout over the next 7 days, in time for the Christmas period (I really don't want to be deploying new versions of apps while having Christmas dinner etc).
You are much more familiar with this code than I am and have already made good progress to solving the issue, however I've got a work related deadline. So, if this isn't a high priority for you / you stop work on it, then give me a shout and I'll have a crack at it (no guarantees that I'll actually manage to fix it though). Conversely, if you do manage to fabricate a fix, give me a shout and I'll give it another test to validate it, after which we can try to get the attention of the repository maintainer to deploy a new release (as otherwise this library is dead in the water imminently).
FYI I think I'll try moving the processing to onPageFinished - as soon as there's an html page with MD and PaRes inputs, trigger the completion handler. That's the html we're interested in and I don't think there's any reason to wait for the form to submit itself
I've been looking at how this library works under the hood. What you propose makes sense, however it seems a pretty fairly fundamental change to this library. I'm worried about breaking the spaghetti code around "stacked mode" which I'm not using (and I've no idea what that is - There is only a cryptic comment to go on and the commit history for those lines aren't very useful). I found https://github.com/LivotovLabs/3DSView/commit/71de5aa3b60136ce2a3a8ff359e851331cbcb0c2 but I still have little idea why this was introduced. Otherwise, your proposed changes look fairly straightforward.
I'm pretty sure this library could be a lot simpler than it currently is at the moment. I guess I/we could put together a fix in the manner that you suggest and ditch stacked mode, and perhaps someone else who is using that can figure out how to fix it, if it's important to them?
FYI I'm merely using the basic D3SView
- no frills.
I've updated the code with another attempt. I've tried it on Chrome 70 and I think Chrome 71 (I installed the beta and changed the WebView setting in Developer Options). I have the same concern as you with stacked mode, I've tried to keep the changes as minimal as possible. It now runs the processing in both onPageStarted and onPageFinished, using a boolean to track when it's been done so the completion handler is only called once.
Right, I've tested this 10 times on both Chrome 70 and 71 and it works. Good job. 👍
The only niggle I have is a 4-5 second delay before I can enter information on the ACS form (The ACS form is shown, for ages, I can see it, but I can't press on the text entry fields for what feels like ages). The issue seems to be on both Chrome 70 and 71.
I rolled back to 1.1.2, and I can press on text fields immediately (i.e feels rapid in comparison) on both versions of Chrome (albeit 71 fails with the issue we are trying to fix here).
Video of responsiveness issue using this branch: https://drive.google.com/file/d/1I8ImPRULPQAyyhwCzmhzRi-FxgUul8ez/view?usp=sharing
I'm not sure what would cause the delay and I don't think I'm seeing the same issue - normally I just tap submit when the form loads but I can interact with the text entry and drop down (I assume the form I see is different to yours - I'm not sure who the payment provider is in this project, we're just using our client's API)
Video of 1.1.2 https://drive.google.com/open?id=1Rb0UZtMlytsl_6nARul3J9OnHvQ_5oRc
I've rebuilt and tested both versions multiple times with same consistent behaviour (1.1.2 = fast, this branch = slow, same ACS etc) ... not sure what's going on.
I notice there is some other stuff on master
since 1.1.2 was released.
What I might try doing is branching from 1.1.2 and cherry-picking your changes on top, to see if it's your changes, or the other stuff that's causing the issue.
Actually, I'll just build master
, that's easier 🤦♂️
Ok ... master
version doesn't appear to exhibit the issue, so it must be caused by these changes.
👍
@livotov - would you be able to review this PR? It fixes this library on the latest version of Chrome (71)
I need this fix
hey, what are we waiting for?
@chrisleversuch I've ran into an issue, I'm not 100% sure if it's related to these changes however a few of our customers have ran into the following error:
We have a 3-D Secure success rate of 91-92% on Android, and on our other platforms they are all solidly around 95% (this is on a volume of around 20,000 transactions since I made the change in the Android app).
I suspect it might be an issue confined to certain banks. The cards affected seem to be Co-op, Nationwide, Clydesdale and perhaps Capital One 🙀
Interestingly, some of the IINs involved were processed successfully before I chucked in this branch update. Might just be coincidence though.
Here are a few IINs that seem to be affected: 498824, 557351, 454313
I'll update if I manage to replicate the issue.
Hello, @sandyscoffable have you found a solution yet? I am also experiencing the same issue with capital one cards.
I have had a successful transaction with 454313 btw.
@rihantvx - 454313 (Nationwide) is possibly a red-herring ... it's quite difficult to get a definitive list as consumers can legitimately abandon the payment process at that point.
Clutching at straws, but I wonder if the issue is with the regex this library uses? That's typically the cause of issues and looks like the weak point in this library.
I've not got a card to hand that I can try so I've not managed to replicate the issue myself yet (I've been embroiled in other stuff and the employee that has a co-op card has gone home). I've got a branch of this that spits out the resulting HTML for inspection, I just need a card that I can test with 🥃
Pretty close to just signing up to a co-op bank account just to test this TBH!
I hate 3-D Secure ... it's a nightmare to test as the HTML returned by these ACS providers possibly differs in some way. Such a cludge.
We also experienced continuing issues even after adopting this change, about 30% of payments still did not complete successfully from 3DSecure screen. We're now moving to a more elaborate solution involving back-end callbacks and no longer using this library.
@markomeara-whitbread - I assume you mean you have a dedicated endpoint in your server side stack that the consumer is redirected to and the PaRes
is extracted? Makes sense I guess.. I could totally do that too..
I'm going to continue to try and debug / fix this issue.
I've been able to reproduce the issue here. When the library loads it seems to fairly quickly show the above Google page in the screenshot (without any sort of intervention required).
The code that extracts the PaRes from the HTML doesn't appear to be called (as I had debug code to spit out the HTML if that was hit). There are the following cryptic log lines though which might offer a clue:
2019-01-11 12:55:07.033 10790-12869/com.scoffable W/chromium: [WARNING:spdy_session.cc(2876)] Received RST for invalid stream1
2019-01-11 12:55:07.079 10790-10790/com.scoffable I/chromium: [INFO:CONSOLE(1)] "Uncaught TypeError: Cannot read property 'innerHTML' of undefined", source: https://www.google.com/ (1)
So, still not sure why this is happening, but it's definitely an issue. The employee who has the affected card is now off until Monday, so I can't reproduce again until then.
Ok, so the issue is clearly with this line:
view.loadUrl(String.format("javascript:window.%s.processHTML(document.getElementsByTagName('html')[0].innerHTML);", JavaScriptNS));
Hopefully I'll get a better idea of why on Monday.
@sandyscoffable Did you manage to reproduce this with Co-op card?
I am yet to find someone in our company who has a co-op card :-(
Thank you guys for awesome discussion and PR! Sorry for delayed merge, was quite hard and busy year, especially end of it.
@rihantvx - Sorry I've been embroiled in other high priority projects. I do have this on my list to pick up in the near future.
I've created https://github.com/LivotovLabs/3DSView/issues/23 to track the issue
We've noticed that in the last few days (we think since Chrome 71 has started rolling out to Android devices), the processHTML method is being called too late so it's running against the HTML from the request to www.google.com rather than the HTML form that it should be running against. The result is that onAuthorizationCompleted is called with empty strings for md and pares.
This PR uses onPageFinished to capture the HTML from each request (except the one to www.google.com) so that the reqex can be run against the correct HTML.