SagePay Server - who can help me / the Spree community and earn some money in the process?

190 views
Skip to first unread message

Glenn Mc

unread,
Aug 26, 2010, 8:53:23 AM8/26/10
to Spree
this is a serious request for help!

(ever felt like you've bitten off more than you can chew? read on
(please)...)

Spree does an excellent job of handling "Direct" credit card payments
where it authenticates and fulfils the transaction in a single step.
this is brilliant but sadly i can't use this approach, especially
since it puts a higher demand on clients with regards to PCI DSS.
instead, i have to use the SagePay "Server" (UK based) approach which
breaks up the payment process into lots of bits as you'll see below
and makes the whole payment task, from a developer's perspective, so
much more complicated i think.

i do not have the time (and perhaps even the necessary skills) to get
this solution working on my current project and so i'm shouting out to
anyone interested in helping - some payment can be arranged. it would
then be great to see the new "SagePay Server" gateway option available
in the core for others to benefit from as this has been a huge
headache for me so far and i wouldn't wish it on anyone else. i'm also
convinced that this solution is going to be more and more requested as
PCI digs in its heels so the work done here will be extremely welcomed
by more people than just me.

anyway, here's where i am up to and it doesn't feel very far (i've
been very thorough below by the way to help you get a true grasp of
the work involved):

to date, i have edited the "sage_pay.rb" gateway code in the
"payment_gateway" extension (i can supply via email if requested) to
handle a SagePay Server PAYMENT transaction. i have left the payment
form in the checkout > payment view in place but it is not actually
using the values you type in per se - as long as a single digit is
entered in both the card number and CV2 field to pass the validation
the actions will fire. the plan would be to remove these form fields
later and use the Payment view to inform the user that they will now
be passed to SagePay / they are secure / show a few logos and a link
to other security info etc.

so the user presses the "continue" button...

what actually happens with this code is that it communicates with
SagePay via the URL:

https://test.sagepay.com/gateway/service/vspserver-register.vsp"

and does an authentication routine returning a status of "OK" from
SagePay which is great BUT... as the rest of the core Spree code
stands without any changes as yet, the checkout process happily
completes and stores all the response data as if it has finished -
just as it should because that is how it happens with a "Direct"
solution as stated above i.e. the "purchase" and "commit" methods work
a treat! however, this is not good for a "Server" solution as the
'transaction registration' stage is only the first of many steps:

what should happen with the response in a "Server" scenario is that
the "VPSTxId" value (SagePay's unique reference for this transaction)
and the "SecurityKey" (used to validate the call back from SagePay
later) are stored against the order and the user is immediately
redirected to the value of "NextURL" in the response (supplied by
SagePay) without a blip in the user experience and the user is
confronted with the first payment page on SagePay's servers for this
transaction.

after the user has navigated through about 3-5 screens depending on
whether 3DS is active for the card and in the SagePay account, SagePay
then redirects and POSTs more data back to the "NotificationURL" you
supply in the initial POST to their servers - it has remembered it
from before.

the notification 'page' then needs to use methods to extract the
"VendorTxCode", the "VPSTxId" and "Status" values from the POST which
are then used to decide how to respond to the POST:


1. using the "VPSTxId" and "VendorTxCode" values, we can retrieve the
"SecurityKey" from our database to enable us to validate the POST to
ensure it came from SagePay:

1.a. if we cannot find a record of this order in the database,
something isn't right so to protect the customer, we should send back
an "INVALID" response to SagePay. this will prevent the SagePay server
from settling any authorised transactions. we will also send a
"RedirectURL" that points to our 'order failure page', passing details
of the error to possibly display

1.b. if we DO find the order, we validate the response message:
extract all the key values* and rebuild the POST message, including
our security key, by using the MD5 Hash component which creates a
local signature to compare with the signature sent by SagePay (called
the "VPSSignature").

*the list of key/value pairs required are:

VPSTxId, VendorTxCode, Status, TxAuthNo, VendorName, AVSCV2,
SecurityKey, AddressResult, PostCodeResult, CV2Result, GiftAid,
3DSecureStatus, CAVV, AddressStatus, PayerStatus, CardType,
Last4Digits


2. now we compare our rebuilt POST / signature with the "VPSSignature"

2.a. if the two signatures DON'T match, the order is marked as
"tampered" (for example) in the database and the "Status" of "INVALID"
is sent to SagePay along with a "RedirectURL" (as in point 1.a. above)

2.b. if the two signatures DO match, we can finally process our
payment status which will be one of:

OK (AUTHORISED - The transaction was successfully authorised with the
bank)

NOTAUTHED (DECLINED - The transaction was not authorised by the bank)

ABORT (ABORTED - The customer clicked Cancel on the payment pages, or
the transaction was timed out due to customer inactivity)

REJECTED (REJECTED - The transaction was failed by your 3D-Secure or
AVS/CV2 rule-bases)

AUTHENTICATED (AUTHENTICATED - The transaction was successfully 3D-
Secure Authenticated and can now be Authorised)

REGISTERED (REGISTERED - The transaction was could not be 3D-Secure
Authenticated, but has been registered to be Authorised)

ERROR (ERROR - There was an error during the payment process) ... and
the StatusDetail can be included here


3. we can then update the order (matching the "VendorTxCode") with the
above payment status and other data like: "TxAuthNo", "CardType",
"Last4Digits"


4. next, we send a new reply to SagePay to let the system know we've
received the Notification POST

4.a. always send a "Status" of "OK" if we've read everything correctly

4.b. or send a "Status" of "INVALID" for messages with a "Status" of
"ERROR"


5. finally, either redirect the user or show a flash message on the
final view based on the "Status" of the response

5.a. a "Status" of "OK", "AUTHENTICATED" or "REGISTERED" is a
'Success' message

5.b. any other "Status" is a 'failure' of some kind


the plea: are there any Spree core team members willing to take this
on to completion please? or maybe someone else has the interest and
would like some extra pay this month? honestly, this really needs to
be done within the next 1-2 weeks as without it, the new store can't
open!

please email me or reply here and i'll get back to you very quickly.

thanks for reading, i look forward to hearing from you all.
Reply all
Reply to author
Forward
0 new messages