Search code examples
asp.netrazoropayo

Has anyone used Sage Pay with asp.net Webpages


Has anyone used Sage Pay with asp.net Webpages??

I have downloaded the integration kit from Sage Pay but this is made in webforms and i am having trouble converting it the WebPages format.

Sage Pay are no help so i'm hoping someone out there has done this. Or can point me in the right direction.


Solution

  • I have managed to do this using the class from the SagePay template you can download.

    Put these files in your bin folder:-

    SagePay.IntegrationKit.DotNet.dll
    SagePay.IntegrationKit.DotNet.pdb
    

    Put these files in your App_Code folder:-

    SagePayConfiguration.cs 
    SagePayAPIIntegration.cs 
    SagePayFormIntegration.cs
    

    You also need to add some stuff to your web.config file

    <SagePayConfiguration>
        <!--Mandatory     
        Set to TEST for the Test Server and LIVE for the live environment-->
        <add key="sagepay.api.env" value="TEST" />
    
        <!--Transaction Settings -->
        <add key="sagepay.api.protocolVersion" value="3.00" />
        <add key="sagepay.kit.vendorName" value="your Name" />
        <add key="sagepay.kit.fullUrl" value="your url" />
        <add key="sagepay.kit.currency" value="GBP" />
    
        <!--Optional setting. It's recommended to set the siteFqdn value to the Fully
        Qualified Domain Name of your server.
        This should start http:// or https:// and should be the name by which our servers can call back to yours
        i.e. it MUST be resolvable externally, and have access granted to the Sage Pay servers
        examples would be https://yoursite or http://212.111.32.22/
        NOTE: Do not include any URI path.
        If you leave this value blank the kit will use the current host name-->
        <add key="sagepay.kit.siteFqdn.LIVE" value="http://your web address" />
        <add key="sagepay.kit.siteFqdn.TEST" value="http://your web address" />
    
        <!--Mandatory. Usually PAYMENT. This can be DEFERRED or AUTHENTICATE if your Sage Pay
        account supports those payment types
        NB Ideally all DEFERRED transaction should be released within 6 days (according to card scheme rules).
        DEFERRED transactions can be ABORTed before a RELEASE if necessary-->
        <add key="sagepay.kit.defaultTransactionType" value="PAYMENT" />
    
        <!--0 = If AVS/CV2 enabled then check them.  If rules apply, use rules (default).
        1 = Force AVS/CV2 checks even if not enabled for the account. If rules apply, use rules.
        2 = Force NO AVS/CV2 checks even if enabled on account.
        3 = Force AVS/CV2 checks even if not enabled for the account but DON'T apply any rules.-->
        <add key="sagepay.kit.applyAvsCv2" value="0" />
    
        <!--0 = If 3D-Secure checks are possible and rules allow, perform the checks and apply the authorisation rules. (default)
        1 = Force 3D-Secure checks for this transaction if possible and apply rules for authorisation.
        2 = Do not perform 3D-Secure checks for this transaction and always authorise.
        3 = Force 3D-Secure checks for this transaction if possible but ALWAYS obtain an auth code, irrespective of rule base.-->
        <add key="sagepay.kit.apply3dSecure" value="0" />
    
    
        <!--FORM Protocol Only Settings
    
        Set this value to the Encryption password assigned to you by Sage Pay -->
        <add key="sagepay.kit.form.encryptionPassword.TEST" value="Your password" />
        <add key="sagepay.kit.form.encryptionPassword.LIVE" value="Your password" />
    
    
        <!--The Sage Pay server URLs to which customers will be sent for payment for each environment-->
        <add key="sagepay.api.formPaymentUrl.LIVE" value="https://live.sagepay.com/gateway/service/vspform-register.vsp" />
    
    
        <add key="sagepay.api.formPaymentUrl.TEST" value="https://test.sagepay.com/gateway/service/vspform-register.vsp" />
    
      </SagePayConfiguration>
    

    To make this easier to manage i have but this web.config file in the checkout folder so it is easy to keep updated.

    I also created the following class to encrypt and dencrypt the data:- you can call it what ever you want but it needs to be saved in the App_Code folder.

    using System;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.IO;
    
    public static class EncryptionHelper
    {
        private static byte[] keyAndIvBytes;
    
        static EncryptionHelper()
        {
            // You'll need a more secure way of storing this, I this isn't
            // a real key
            keyAndIvBytes = UTF8Encoding.UTF8.GetBytes("123123123123123b");
        }
    
        public static string ByteArrayToHexString(byte[] ba)
        {
            return BitConverter.ToString(ba).Replace("-", "");
        }
    
        public static byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                             .Where(x => x % 2 == 0)
                             .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                             .ToArray();
        }
    
        public static string DecodeAndDecrypt(string cipherText)
        {
            string DecodeAndDecrypt = AesDecrypt(StringToByteArray(cipherText));
            return (DecodeAndDecrypt);
        }
    
        public static string EncryptAndEncode(string plaintext)
        {
            return ByteArrayToHexString(AesEncrypt(plaintext));
        }
    
        public static string AesDecrypt(Byte[] inputBytes)
        {
            Byte[] outputBytes = inputBytes;
    
            string plaintext = string.Empty;
    
            using (MemoryStream memoryStream = new MemoryStream(outputBytes))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetCryptoAlgorithm().CreateDecryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(cryptoStream))
                    {
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
    
            return plaintext;
        }
    
        public static byte[] AesEncrypt(string inputText)
        {
            byte[] inputBytes = UTF8Encoding.UTF8.GetBytes(inputText);//AbHLlc5uLone0D1q
    
            byte[] result = null;
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetCryptoAlgorithm().CreateEncryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Write))
                {
                    cryptoStream.Write(inputBytes, 0, inputBytes.Length);
                    cryptoStream.FlushFinalBlock();
    
                    result = memoryStream.ToArray();
                }
            }
    
            return result;
        }
    
    
        private static RijndaelManaged GetCryptoAlgorithm()
        {
            RijndaelManaged algorithm = new RijndaelManaged();
            //set the mode, padding and block size
            algorithm.Padding = PaddingMode.PKCS7;
            algorithm.Mode = CipherMode.CBC;
            algorithm.KeySize = 128;
            algorithm.BlockSize = 128;
            return algorithm;
        }
    }
    

    I call the the class like so:-

    string crypt = "blahblahblah";
    string EncryptAndEncode = EncryptionHelper.EncryptAndEncode(crypt);
    string DecodeAndDecrypt = EncryptionHelper.DecodeAndDecrypt(EncryptAndEncode);
    

    When the transaction is complete i get the crypt with this code:-

    IFormPaymentResult PaymentStatusResult = new DataObject();
    
            if (Request.QueryString["crypt"] != null && !string.IsNullOrEmpty(Request.QueryString["crypt"]))
            {
                SagePayFormIntegration sagePayFormIntegration = new SagePayFormIntegration();
                PaymentStatusResult = sagePayFormIntegration.ProcessResult(Request.QueryString["crypt"]);
            } 
    

    you can then call the needed information from the calss like so

    if (PaymentStatusResult.Status == ResponseStatus.NOTAUTHED)
        {reason = "You payment was declined by the bank.  This could be due to insufficient funds, or incorrect card details.";}
    

    You can see all the fields in the Result.aspx of the SagePay template.