Skip to content
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

PSD2/3DSecure2/Sagepay v4 support #135

Open
jontjs opened this issue Jun 24, 2019 · 60 comments
Open

PSD2/3DSecure2/Sagepay v4 support #135

jontjs opened this issue Jun 24, 2019 · 60 comments

Comments

@jontjs
Copy link

jontjs commented Jun 24, 2019

Sagepay are beginning to publish information on the PSD2/3DSecure2 aspects of their V4 VPSProtocol: https://www.sagepay.co.uk/support/38/psd2-under-direct-integration .

At the time of writing they haven't linked to a new version of the full integration document at https://www.sagepay.co.uk/support/find-an-integration-document/direct-integration-documents, perhaps because v4 doesn't hit their Test environment until July 1st 2019, and their Live environment until "later in July") , but the docs are available at https://www.sagepay.co.uk/library/document/directintegrationandprotocol4guidelinespdf .

@judgej
Copy link
Member

judgej commented Jun 24, 2019

Thank you for the heads' up. We'll jump on this (feel free to help in any way). I'll also follow up the "Sagepay Pi" v1 protocol https://test.sagepay.com/documentation/#3-d-secure API too, with an Omnipay implementation here https://packagist.org/packages/academe/sagepay

@judgej
Copy link
Member

judgej commented Jun 29, 2019

Scanning the docs, the V4 protocol has quite a few changes. The docs are in the usual long-hand form that makes it difficult to find what the changes are without going through every line manually, but I guess that needs to be done. A checklist of individual changes can be put together to work through.

There is a calendar of deadlines. 3DS is mandatory from September 2019. V1 will be supported until teh end of 2020, so having the ability to request V1 only would be good if useful to help client sites move over.

@BigManatee
Copy link

I've been reading into this too, they mention having v1 as a fallback in case v2 fails for any reason but I'm not sure if that fallback will still exist after 2020.
Also from what I've briefly looked at, on page 82/90 from their guidelines they mention that CReq will replace PAReq

@judgej
Copy link
Member

judgej commented Jul 4, 2019

I don't believe the fallback will exist after 2020 (I could be wrong though).

The fallback in the meantime is for banks that don't support v2, so I expect there will be a lot of fallbacks to v1 happening at the start, and they will reduce to zero later as more banks release their v2 support. After 2020 ALL banks must support it, so there is no reason for a fallback.

@judgej
Copy link
Member

judgej commented Jul 9, 2019

I will need to look at this in the next few weeks, but if anyone has any input or branches or code, please post here so we can coordinate effort.

@jontjs
Copy link
Author

jontjs commented Jul 9, 2019

I've had a slightly-deeper look at the V4 protocol docs and, on the face of it, the changes are in one sense fairly small, but in another sense rather tricky...

New fields we need to send at various steps of the 3DS process:

  • BrowserJavascriptEnabled
  • if BrowserJavascriptEnabled, also:
    • BrowserJavaEnabled
    • BrowserColorDepth
    • BrowserScreenHeight
    • BrowserScreenWidth
    • BrowserTZ (timezone)
  • BrowserAcceptHeader (HTTP accept headers as browser sent us)
  • BrowserLanguage
  • BrowserUserAgent
  • ThreeDSNotificationURL - this sounds a lot like the TermUrl we currently send...
  • ChallengeWindowSize - 1 to 5, corresponding to "250x400", "390x400", "500x600", "600x400", & "Full screen"
  • CReq - "This replaces the PAReq", which we currently send
  • CRes - the bank sends this as "cres", we pass it on to Sagepay as "CRes" (note the case difference)
  • VPSTxId - replaces "MD" which we are currently sent and then pass on

I mean "fairly small" in the sense that most are just additional scalar fields. But "rather tricky" in that I'm not sure how a server-side PHP library can be expected to know whether JS is enabled (or the others that depend on it).

@judgej
Copy link
Member

judgej commented Jul 9, 2019

I would think the server would have two entry points for payments, one using JS and one that does not require JS. The browser can redirect the user to whichever endpoint is appropriate to start the payment process.

Great list - very helpful!

@lukrak
Copy link

lukrak commented Jul 26, 2019

Is there an estimated date when this enhancement will be developed and available ?

@judgej
Copy link
Member

judgej commented Jul 26, 2019

No estimated time yet.

Talking to someone who has checked with Sage Pay, they say if you are using Sage Pay Server, there should be no changes needed. Sage Pay Direct there will be, though that one is much less commonly used.

I fully expect Sage Pay Form to be in the same field - because all processing happens off-site, the 3DS handling is all done offsite too.

However, this all needs testing.

@pbh-stu
Copy link

pbh-stu commented Aug 14, 2019

I have just spoken to SagePay who gave me this link which relates to direct integration (which i currently use) https://www.sagepay.co.uk/support/38/psd2-under-direct-integration

However I am planning to switch to server (iframe) based integration to reduce our PCI compliance burden. From what i've read above server integration means sagepay hosted pages and no changes required my end (i hope).

Thanks

@judgej
Copy link
Member

judgej commented Aug 14, 2019

Thanks @pbh-stu If you do find any changes needed for Sage Pay Server, but sure to let us know. From my own research, Sage Pay have not updated documents or SDKs in years, so it's all a bit of a mystery what they expect people to do.

@pbh-stu
Copy link

pbh-stu commented Aug 14, 2019

@judgej

I've just installed a laravel project and tested with

"laravel/framework": "4.2.*",
"league/omnipay": "3.0.2",
"omnipay/sagepay": "3.0"

I can confirm that omnipay sagepay/server does not support sagepay protocol version 4 (required for 3DS 2.0 ) as it's hard coded for version 3 in the omnipay/Message/AbstractRequest.php file and even if that was not the case, version 4.0 requires 5 or so extra fields to be sent and an extra callback handler but nothing too major!

So my hope of server/iframe method just working was a naive dream! I wonder if one of the forks have addressed it yet.

@judgej
Copy link
Member

judgej commented Aug 14, 2019

Just top update, the published Sage Pay specs are still from 2014/2015. That's pretty appalling TBH, considering how close to the go-live date for 3DSv2 we are. I'm guessing there is nothing that can be done at this stage.

@judgej
Copy link
Member

judgej commented Aug 14, 2019

@pbh-stu could you point me at the Sage Pay docs that detail the V4 protocol for Sage Pay Server? All I can find are ancient docs.

@pbh-stu
Copy link

pbh-stu commented Aug 15, 2019

Here you go:

https://www.sagepay.co.uk/support/38/psd2-under-direct-integration
https://www.sagepay.co.uk/library/document/directintegrationandprotocol4guidelinespdf

Ahh sorry that's direct (but gives you an idea) ! I will ring SagePay this morning and get the links for server. I'm actually working to hack the omnipay sagepay (Server) code to work with V4 today, if i get it to work i'll post the minimum required changs to make it work.

Thanks
Stuart

@judgej
Copy link
Member

judgej commented Aug 15, 2019

A few people have said that Server is not affected after ringing Sage Pay themselves. Obviously confirm for yourself, but that's what I'm working to at the moment.

Thanks for the Direct doc (which still seems to be in draft - what are they playing at?) If I understand correctly, it is only table A1 that has changed?

@BigManatee
Copy link

Sagepay and their docs are just not good at all. I'm currently using Sagepay Direct via dwmsw/sagepay but depending what has to be changed I'm thinking of switching to omnipay.

@jontjs
Copy link
Author

jontjs commented Aug 15, 2019

https://www.sagepay.co.uk/support/16/3d-secure-v2-what-do-customers-need-to-do says:

Server integration – There will be no mandatory changes to your current
integration. We will undertake some proactive steps in the coming weeks to
ensure you are ready.

I've seen very little in the way of "proactive steps" from Sagepay, on any matter, for a very long time!

@pbh-stu
Copy link

pbh-stu commented Aug 15, 2019

I've just been on the phone to SagePay, they said they had planned to roll out an update for forms, server and direct (test env) this morning but had to abort, they plan to try again Friday 16th Aug 2019 at 7am

I've been playing with Server v4 this evening , i can complete orders fine with no changes (other than protocol version number) but it only ever shows 3DSv1 not v2. SagePay said this should be sorted tomorrow. I'll be calling them back tomorrow if not.

Hope that helps
Stuart

@pbh-stu
Copy link

pbh-stu commented Aug 16, 2019

Having just tested server integration it's clear that sagepay have updated their systems overnight.

If you enter CHALLENGE in the cardholder name (not in code but above where you enter card number) when placing a test order (with 3ds enabled) you will now see a nice error message !

I just rang Sagepay and a very grumpy Charlotte insisted this was normal and we do not have to test 3DSV2 (server) and they will take care of it. I said this was lame as I need to prove our systems work as well as show stakeholders and sales staff the process for training.

image

Things to note:

You must at present enter STATUS201DS as the cardholder name (above the card number) to get a 3DS V1 challenge else it will just complete with no challenge.

The protocol version does NOT need to be changed to 4.0

I suspect sagepay are cutting corners with SERVER as they are not going to receive the additional fields such as when the customer registered (which is in the spec). I suspect this means more customers will be challenged than with a DIRECT integration where all additional fields are passed along to sagepay.

Hope that helps others struggling with this.

Bollom line, no changes required for 3DSv2 support with SERVER but i suspect that will change once more people realise that sagepay have cut corners.

@judgej
Copy link
Member

judgej commented Aug 16, 2019

Not all heroes wear capes :-) Thank you for doing this thorough research and writing it up. It will be a bit help. And - Charlotte - cheer up, it's Friday!

@judgej
Copy link
Member

judgej commented Aug 24, 2019

Still nothing from Sage Pay but promises. Documentation is dated back to 2015 for direct, 2017 for Pi, and yet there are warnings that we will need to change the integrations, and that all has to be live and working next month. An utter shambles. Never known anything like it.

@Phunky
Copy link

Phunky commented Aug 27, 2019

Looks like we've got some buffer time - https://www.fca.org.uk/news/press-releases/fca-agrees-plan-phased-implementation-strong-customer-authentication

@pbh-stu
Copy link

pbh-stu commented Aug 28, 2019

SagePay how now fixed the 3DS v2 system on test (SERVER)

If you enter CHALLENGE as the card holder name in the IFRAME you'll see the below challenge, enter STATUS201DS to see the old 3DS V1 challenge.

image

3DSv2 Lives !

@BigManatee
Copy link

This whole thing has still left me a bit confused (hopefully I'm not the only one!). I'm currently using the direct integration (without iframe) - is anything/much changing with that or is that a better/easier option?

@judgej
Copy link
Member

judgej commented Sep 2, 2019

@BigManatee Yes it is confusing, because Sage Pay always fail to speak with a unified voice. This means you have to pick up snatches of detail from here and there, and make assumptions about how some things work just by trial and error.

--- end rant ---

Sage Pay Direct involves your site handling the card details forms and sending the users off to the 3DS bank, so this will very much affect you. You will also need to be fully PCI acreditted, which I'm sure you are, but is worth mentioning. The PCI accreditation is the main reason I would recommend Sage Pay Direct to anyone but teh very largest of organisations.

Sage Pay Server hands all the form filling and processing for you offsite. That's what I would recommend, and - for now at least - won't need any immediate changes.

@BigManatee
Copy link

@judgej Thanks for the recommendation, I'll definitely take that into consideration and more than likely switch to this repo and SagePay Server.

My understanding right now is from the 14th of September companies will stop taking non 3DS payments and then will stop taking 3Dsv1 (I don't take any non 3ds payments) at the end of 2020 so I shouldn't have to do anything straight away.
Sagepay are always a dream to deal with.

@lukrak
Copy link

lukrak commented Nov 5, 2020

Is there going to be an update for this package to handle 3DSv2 ? If so, then ? As according to Opayo 2021 Jan 1st is a deadline for Europe

@Sheaffy
Copy link

Sheaffy commented Nov 16, 2020

This deadline is approaching very fast

"European issuers are likely to start declining electronic payment transactions that have no authentication in place. The current 3D Secure implementation [3DSv1] will continue to be supported until end of 2020 (at which time 3DSv2 becomes mandatory worldwide)."

@Sheaffy
Copy link

Sheaffy commented Nov 16, 2020

So as part of work, I have got this fully working now, and it will go through our testing pipelines later tomorrow.
Let me know if anyone wants me to do a PR.

(edit)
Just to be clear, I have got this working for Direct

(**edit)
This code will also fall back to 3dsv1 when necessary as per the documentation.
Please keep in mind, due to some of our other limitations on gateways, this is for omnipay v2.0.
But this can certainly be used to update the 3.0 version. Sorry for any inconvenience.

@lukrak
Copy link

lukrak commented Nov 18, 2020

@Sheaffy @judgej was it already merged or not yet sorry?

@Sheaffy
Copy link

Sheaffy commented Nov 18, 2020

@lukrak
I can see in the master branch on abstractRequest that the version is still
protected $VPSProtocol = '3.00';
and in all the relevant places it has not been updated.

@aidan-ayala
Copy link

Does anyone here have an understanding of where and when we should be sending COFUsage flags?

@lukrak
Copy link

lukrak commented Nov 23, 2020

@judgej are you planning to merge @Sheaffy's update any time this week? I assume there was already a pull request for this? We also need to update our sites to comply with 3DSv2 during this week so wasn't sure if you are planning to merge his changes any time soon? Otherwise we will have to implement this ourselves too

@Sheaffy
Copy link

Sheaffy commented Nov 23, 2020

@lukrak
Haven't had the time to do a PR due to work sorry.
At the same time, what I have done is for version 2.0 of omnipay, so I'm unsure it will be for you if you are on 3.0.

@judgej
Copy link
Member

judgej commented Nov 24, 2020

I came to have a look at this, and have seen the Opayo API documentation for the first time. I must say, what a mess. I haven't been able to find much of any use so far - there seem to be huge chunks missing, diagrams spread over multiple pages with little to help navigate them. Or I'm just looking in the wrong place? Are there any links to decent documentation for upgrading from Sage Pay v3 to Opayo v4 (or is that Opayo v1 aka Sage Pay v4?)

@lukrak
Copy link

lukrak commented Nov 24, 2020

@judgej I'm working on this to add changes as a part of my work too. I'm using the following pdf from Opayo and this blog post. I found blog post useful to better understand all those new required fields that are browser related.

In that PDF it's useful to read pages 12-22 as it mentions any new variables. Whole workflow didn't really change so it should be quite clear for you I think. At the end of this week I should have all commits that I did for this in one place, so I think I can write a quick summary here with the changes I had to do for this over the weekend.

@judgej
Copy link
Member

judgej commented Nov 24, 2020

Brilliant, thank you @lukrak

@Sheaffy
Copy link

Sheaffy commented Nov 24, 2020

@lukrak
Thats funny, that's the same blog post I found too... It's very informative.

@lukrak
Copy link

lukrak commented Nov 30, 2020

Sorry for a delay. So I've tried to create a PR but if you would compare my fork with yours you will see that quite a lot of things are deleted which is not right. I think that's because when I was making changes, I was not on a latest version and now when I tried to upload all files that I modified, it obviously picks up all the stuff missing.

Anyways, I'm attaching a single file which is a single raw commit that I had to do to make this package work with 3DSV2. I'm pretty sure you will be able to copy/paste most of my changes and update this package yourself @judgej .

All in all, I followed that PDF I've mentioned before, pages 12-22. And then I've used javascript from that guy's blog post I've also mentioned.

Bellow I will highlight main changes

src/Message/DirectAuthorizeRequest.php
New mandatory fields:

  • ClientIPAddress - was optional on "3.00", now mandatory with "4.00". SagePay made this mandatory but only supports IPv4 for now, which means they really need to sort this out before actual deadlines. What I have in my own project is that if user request comes from IPv6, I fallback to "3.00" as I can't pass IP with "4.00". (You will see I've added a possibility to say which SagePay API protocol you want to use when creating a payment). Very poor move by SagePay on this...
  • BrowserJavascriptEnabled , BrowserLanguage - you have to pass this from user's browser, so your actual project needs to be updated to pass this as a hidden input. (use javascript example in that blog)
  • ThreeDSNotificationURL - this used to be "returnUrl" I think, essentially a URL to redirect back to
  • BrowserAcceptHeader - just pass $_SERVER['HTTP_ACCEPT']
  • BrowserUserAgent - just pass $_SERVER['HTTP_USER_AGENT']
  • ChallengeWindowSize - see Opayo documentation (same document that I sent before, there is a table at the bottom) to all possible options. Essentially a size of 3DS window

All of the following is only required if BrowserJavascriptEnabled is set to true. All values needs to be passed from customers browser so you will need hidden input fields. Once again, use that javascript example

  • BrowserJavaEnabled
  • BrowserColorDepth
  • BrowserScreenHeight
  • BrowserScreenWidth
  • BrowserTZ

image

src/Message/DirectCompleteAuthorizeRequest.php - Now returns cres and threeDSSessionData when using "4.00". You still need to be compatible with "3.00". Nothing special, you just need to pass different parameters than before

src/Message/Response.php - Very similar to DirectCompleteAuthorizeRequest.php, just new parameters to pass with 3DS request. Note that according to documentation, even if you are using "4.00" API, you might still receive old "3.00" style response since not everyone has migrated to 3DSv2 yet. But simple "if" statement works just fine.

That's essentially all the main changes you need in this package. There is also src/Message/AbstractRequest.php in my commit that I didn't mention but it's self explanatory.

From actual project's point of view that wants to start using this updated package, the way I did mine, I can now pass which VPSProtocol I want to use now ("3.00" or "4.00"). I also double check IP is IPv4 before I say I want to use "4.00" due to that API restriction. If you want to use "4.00" you just need to pass 7 hidden input fields that would be populated by your javascript and that's it, you are good to use 3DSv2.

I've tested both, "3.00" and "4.00" with these changes and seems to be working fine. From testing point of view, just test it the same way you would test "3.00" and you will see that if it's "4.00" that you are using, then 3DS confirmation window looks completely different. That's the only way that I found to tell if it's 3DS v1 or v2 that SagePay is giving to you.

Also it seems that SagePay is ok if you pass all those "Browser..." variables even if you are using "3.00" protocol which is cool because you can see I'm just always passing all those new variables no matter which API version you use.

(Sorry for terrible formatting, don't have too much time)

changes in single commit.txt

@pbh-stu
Copy link

pbh-stu commented Nov 30, 2020

Just to interject: in my test implementation (not using omnipay) we have set:
browserJavascriptEnabled = 'false'
challengeWindowSize ='medium'
seems to work perfectly (for my use case) and negates the need to pass the extra fields server side.

@lukrak
Copy link

lukrak commented Nov 30, 2020

I've also tested with browserJavascriptEnabled = 0, and it seems like SagePay returns exact same 3DS page no matter these settings but I assume it might have impact on a live 3DS site. But yes, I've tested and it works just fine with browserJavascriptEnabled = 0 and you don't need to pass any extra fields that relates to browser that's why I think it's handy if developer can decide if he wants to bother with all this JS part :)

@pbh-stu
Copy link

pbh-stu commented Nov 30, 2020

Just a last note for anyone only concerned about the UK, the deadline is not till the 14th Sept 2021, so plenty of time.

@Sheaffy
Copy link

Sheaffy commented Dec 3, 2020

One thing to note, if you are using stored cards there's two extra fields you now need to pass, if you are using tokens.
those are
initiatedType
COFUsage

They are documented in the direct integration pdf. This caught me off guard because they don't tell you that those fields are required or that migrating from 3.0 to 4.0 effects stored cards.

@Sheaffy
Copy link

Sheaffy commented Dec 3, 2020

I've also tested with browserJavascriptEnabled = 0, and it seems like SagePay returns exact same 3DS page no matter these settings but I assume it might have impact on a live 3DS site. But yes, I've tested and it works just fine with browserJavascriptEnabled = 0 and you don't need to pass any extra fields that relates to browser that's why I think it's handy if developer can decide if he wants to bother with all this JS part :)

If you do have browserJavascriptEnabled=0, I would imagine that would lead to more challenges being issued as they have less information to create a fingerprint with.

@Sheaffy
Copy link

Sheaffy commented Dec 15, 2020

For those implementing this, one more thing that just caught me out. Turns out on a MacBook Pro, on chrome, colorDepth comes out to 30... which Opayo will NOT accept, causing an error on the payment.
they only accept

1,4,8,15,16,24,32,48

which turns out to be very strict.

@nystag
Copy link

nystag commented Jan 6, 2021

I've encountered an issue I thought I should share. If you make use of REPEAT transactions (stored cards) and accept Amex, American Express hasn't yet updated their system to work with 3DSv2 and so with the v4 protocol you won't receive a SchemeTraceID when initiating a Credential On File transaction - so you can't repeat that transaction. Opayo have suggested continuing to use the v3 protocol for Amex cards until they support 3DSv2 :/

@BrockleyJohn
Copy link

@Sheaffy

colorDepth

What did you feed them instead of 30? 24??

@lukrak
Copy link

lukrak commented Jan 26, 2021

@BrockleyJohn I went for 24 because safari returns "24".

See google ticket

@mtjburton
Copy link

For what it's worth I raised this with Sagepay and received this:

The escalations team have advised to have your system hard code the 30 to nearest acceptted value to match the specification laid out by the new 3ds2 process, so that this information can be presented to banks within their specifications.

I've also set it to 24 as this is what other browsers are using and everything has been going through correctly.

@AColes
Copy link

AColes commented Aug 15, 2021

I'm a bit late to the party here - am I missing something?

The latest/current version 3.2.2 does not seem to have any of the 4.00 related changes discussed here - it still puts '3.00' in for VPSProtocol, regardless of what's supplied and ignores all of the new/extra fields required for 4.00.

@benjam-es
Copy link
Contributor

@barryvdh @judgej are there any plans for the package to implement the 4.00 requirements? I believe the deadline from September has been extended, but only until March 2022.

https://www.opayo.co.uk/support/sca-faqs

@lukrak
Copy link

lukrak commented Jan 14, 2022

How did anyone deal with the fact that SagePay requires you to pass customer's IP but you can only pass IPv4 in that field because IPv6 is too long for that field ? I think SagePay returns something like "Max length of 15 for ClientIPAddress"

@benjam-es
Copy link
Contributor

benjam-es commented Jan 14, 2022

How did anyone deal with the fact that SagePay requires you to pass customer's IP but you can only pass IPv4 in that field because IPv6 is too long for that field ? I think SagePay returns something like "Max length of 15 for ClientIPAddress"

When I called Opayo, the result of the conversation was that they didn't have IPv6 in the near future pipeline, so we fake it with 1.1.1.1 if the IP is IPv6 based.

In addition/alternatively, I used a setting within cloudflare to deal with is 'Pseudo IPv4', with overwrite headers.

@jamieburchell
Copy link
Contributor

jamieburchell commented Jan 25, 2022

Is anybody working on/are there any branches/forks for SagePay Server v4? From looking at the changes, there are just some field length changes and new optional fields which must be used in the security key calculations.

Edit: I see this but don't know if it's ready/will be merged?

@bwdgroup
Copy link

How did anyone deal with the fact that SagePay requires you to pass customer's IP but you can only pass IPv4 in that field because IPv6 is too long for that field ? I think SagePay returns something like "Max length of 15 for ClientIPAddress"

When I called Opayo, the result of the conversation was that they didn't have IPv6 in the near future pipeline, so we fake it with 1.1.1.1 if the IP is IPv6 based.

In addition/alternatively, I used a setting within cloudflare to deal with is 'Pseudo IPv4', with overwrite headers.

Where can we find the same setting in CloudFlare ?

@benjam-es
Copy link
Contributor

@bwdgroup Think there should be instructions somewhere here https://blog.cloudflare.com/eliminating-the-last-reasons-to-not-enable-ipv6/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests