Updated SagePay Server Plugin for 3.10 and 3.20

6 years ago
Don't worry, I managed to copy the correct files out of the Source package ;)
6 years ago
Hi All,

I've got an issue with this plugin... Everything works well up until clicking "submit" on the 3D authentication form at this point sagepay busts out of the iframe into the parent which means when the JS in the ResponsePage.cshtml which is trying to reference the  window.parent.Checkout and window.parent.PaymentInfo objects isn't working as there is no window.parent

Any help appreciated. I have been through the process multiple times to try and work out why if busts out of the iframe into the parent but can't see where!

Thanks in Advance.
6 years ago
Fixed... Changed the profile to "low".
6 years ago
A warning to anyone using this plugin for v3.2

If you are using this with one page checkout and low profile the final stage of the VPS Server process 'acknowledge receipt of the Notification POST' is currently not working and produces no visible error within nopcommerce - it actually appears to have processed the transaction, when in fact it has not.

This is due to the VPS Signature not matching the signature generated within the plugins code of the ValidateTransaction method of SagePageServerWorkflowService

I am currently trying to resolve this and will post again once I have.
6 years ago
To Fix the fact that the plugin does not report any error via the Web UI when card processing fails due to the "ValidateTransaction" function fails modify the function as follows:


public string ValidateTransaction(string strTxAuthNo,string strAvscv2,string strAddressResult,string strPostCodeResult,string strCv2Result,string strGiftAid,string str3DSecureStatus,string strCavv,
            string strAddressStatus,string strPayerStatus,string strCardType,string strLast4Digits,string strVpsTxId,string strVpsSignature,string strStatus,string strStatusDetail,string strVendorTxCode)
        {

            var strVendorName = _sagePayServerPaymentSettings.VendorName.ToLower();

            //Obtain from DB
            var transx = _sagePayServerTransactionService.GetSagePayServerTransactionByVendorTxCode(strVendorTxCode);

            if (transx == null)
            {
                strStatusDetail = "Vendor Transaction code " + strVendorTxCode + " does not exist.";
                transx.Status = "INVALID";
                transx.StatusDetail = strStatusDetail;
                _sagePayServerTransactionService.UpdateSagePayServerTransaction(transx);
                return "Status=INVALID" + Environment.NewLine +
                               "RedirectURL=" + _webHelper.GetStoreLocation() + "Plugins/PaymentSagePayServer/ResponsePage?uid=" + strVendorTxCode + Environment.NewLine +
                               "StatusDetail=" + strStatusDetail;
            }

            if (string.IsNullOrWhiteSpace(transx.SecurityKey))
            {
                strStatusDetail = "Security Key for transaction " + strVendorTxCode + " is empty.";
                transx.Status = "INVALID";
                transx.StatusDetail = strStatusDetail;
                _sagePayServerTransactionService.UpdateSagePayServerTransaction(transx);
                return "Status=INVALID" + Environment.NewLine +
                               "RedirectURL=" + _webHelper.GetStoreLocation() + "Plugins/PaymentSagePayServer/ResponsePage?uid=" + strVendorTxCode + Environment.NewLine +
                               "StatusDetail=" + strStatusDetail;
            }



            //Update DB with what we've got so far
            transx.VpsTxId = strVpsTxId;
            transx.VpsSignature = strVpsSignature;
            transx.Status = strStatus;
            transx.StatusDetail = strStatusDetail;
            transx.TxAuthNo = strTxAuthNo;
            transx.Avscv2 = strAvscv2;
            transx.AddressResult = strAddressResult;
            transx.PostCodeResult = strPostCodeResult;
            transx.Cv2Result = strCv2Result;
            transx.GiftAid = strGiftAid;
            transx.ThreeDSecureStatus = str3DSecureStatus;
            transx.Cavv = strCavv;
            transx.AddressStatus = strAddressStatus;
            transx.PayerStatus = strPayerStatus;
            transx.CardType = strCardType;
            transx.Last4Digits = strLast4Digits;

            //Update DB with what we've got so far
            _sagePayServerTransactionService.UpdateSagePayServerTransaction(transx);

            var strMessage = strVpsTxId + strVendorTxCode + strStatus + strTxAuthNo + strVendorName + strAvscv2 + transx.SecurityKey +
               strAddressResult + strPostCodeResult + strCv2Result + strGiftAid + str3DSecureStatus + strCavv +
               strAddressStatus + strPayerStatus + strCardType + strLast4Digits;

            //Because Sagepay also hashed all these variables, we also need to do the same to verify that they are the same
            var strMySignature = SagePayHelper.HashMd5(strMessage);

            if (strMySignature != strVpsSignature)
            {
                transx.StatusDetail = "Your server was unable to register this transaction with Sage Pay. Cannot match the MD5 Hash. Order might be tampered with: " + strMessage;
                transx.Status = "INVALID";
                _sagePayServerTransactionService.UpdateSagePayServerTransaction(transx);
                
                return "Status=INVALID" + Environment.NewLine +
                               "RedirectURL=" + _webHelper.GetStoreLocation() + "Plugins/PaymentSagePayServer/ResponsePage?uid=" + strVendorTxCode + Environment.NewLine +
                               "StatusDetail=Your server was unable to register this transaction with Sage Pay. Cannot match the MD5 Hash. Order might be tampered with"  + strVendorTxCode ;
            }

            //Always send a Status of OK if we've read everything correctly. Only INVALID for messages with a Status of ERROR
            var responseStatus = strStatus == "ERROR" ? "INVALID" : "OK";

            return "Status=" + responseStatus + Environment.NewLine +
                           "RedirectURL=" + _webHelper.GetStoreLocation() + "Plugins/PaymentSagePayServer/ResponsePage?uid=" + strVendorTxCode;
        }
6 years ago
I should point out, the cause of my original issue with the VPS Signature not matching was due to SagePay.

However I would recommend the code change above to the source.
6 years ago
Hi Carlos
I have been using your plugin version 3.10 with Nop version 3.1, it was all working fine, payments going through and all brilliant. I have now upgraded my site to nop 3.2 and the site works fine, however when I installed the new Sage plugin version 3.2 I cannot get the site to load. I have removed the plugin but could really do with it working. The Log file is:
Stack Trace:
[ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.]
   System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) +0
   System.Reflection.RuntimeModule.GetTypes() +9
   System.Reflection.Assembly.GetTypes() +143
   Nop.Core.Plugins.PluginManager.Initialize() +2057

[Exception: Could not load file or assembly 'EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Could not load file or assembly 'EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Method 'get_SkipPaymentInfo' in type 'Nop.Plugin.Payments.SagePayServer.SagePayServerPaymentPlugin' from assembly 'Nop.Plugin.Payments.SagePayServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
]
   Nop.Core.Plugins.PluginManager.Initialize() +2798

Please could you help us, many thanks.
5 years ago
Hi  Carlos Martinez,

i am getting error while testing with the Simulator account.

The Response could not be decoded as a valid Notification Acknowledgement. Check the Protocol in section A4 to ensure you are sending the correct fields in the correct order with CR-LF separators between the values.

Please let me know What should I do..How can I resolve it.
3 years ago
Hi there,

We have an intermittent issue with this plugin running on nop V3.2. Sometimes, when a customer submits payment, they are charged twice for the transaction and the sale does not register on the website and confirmation emails are not sent to the admin.

This happens for around 1 of every 5 orders and is extremely frustrating for both users and administrators (as you can imagine) any assistance would be very much appreciated.

The version of the SagePay Server plugin we are using is 1.09.

Thanks