Skip to main content

How to integrate SagePay payment form using Asp.Net MVC

Introduction

In Europe Sage Pay is independent payment service provider. It is one of the most trusted payment brands in Europe. Sage Pay makes payments safe and secure. Payment security and fraud prevention are two of their top priorities.

Sagepay provides various integration option for your e-commerce website. Like

1. Form Integration
2. Server Integration
3. Server Iframe integration
4. Direct Integration

In Direct integration, only your server will be save card data and host checkout page, while in all other 3 integration it will be save card data to the SagePay server and checkout pages will be there only. You do not need to create checkout page for that.

Today we are going to understand how Form Integration will work.

Setting in Web.Config

Let’s first list out the data we need to get started.

1. SagePay VendorName
2. Call back URL with IPAddress
3. Encrypted Password

Now let’s have a look at web.config file.
In web.config file go to configuration section add the below code at the first node. We are going to add a new section as a “SagePayConfiguration” later in this file.

<configSections>
    
<section name="SagePayConfiguration" type="SagePayConfiguration" />
</configSections>

now in the configuration section at the last add a below code block

<SagePayConfiguration>
 <!-- Set to TEST for the Test Server and LIVE for the live environment-->
 <add key="sagepay.api.env" value="TEST" />
 <add key="sagepay.api.enableClientValidation" value="true" />
 <add key="sagepay.api.connectionString" value="" />
 
 <add key="sagepay.api.messageLoggerName" value="com.sagepay" />
 <add key="sagepay.api.messageLoggerLevel" value="debug" />

 <add key="sagepay.api.protocolVersion" value="3.00" />
 <add key="sagepay.kit.vendorName" value="*******" />
 <add key="sagepay.kit.fullUrl" value="" />
 <add key="sagepay.kit.currency" value="GBP" />

 <!--If you leave this value blank the kit will use the current host name-->
 <add key="sagepay.kit.siteFqdn.LIVE" value="" />
 <add key="sagepay.kit.siteFqdn.TEST" value="" />

 <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="2" />

 <!--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="2" />

 <!--Optional property. (Server & Form protocols only) For charities registered for Gift Aid, set to 1 to display the Gift Aid check box on the payment pages, or else 0-->
 <add key="sagepay.kit.allowGiftAid" value="1" />

 <!-- Optional setting. if you are a vendor that has a merchant category code of 6012, then you can fill in extra details required for authorisation for Visa transactions -->
 <add key="sagepay.kit.collectRecipientDetails" value="false"/>

 <!-- Set this to true to use colon delimited format for the basket instead of XML -->
 <!-- Note: The 'Trips' details on the 'Extra Information' page will not be displayed if this flag is set to true. -->
 <add key="sagepay.kit.basketxml.disable" value="false" />

 <!--Optional setting. Set to tell the Sage Pay System which merchant account to use. If omitted, the system will use E, then M, then C by default E = Use the e-commerce merchant account (default) M = Use the mail order/telephone order account (if present) C = Use the continuous authority merchant account (if present)-->
 <add key="sagepay.kit.accountType" value="" />

 <!--Optional setting. If you are a Sage Pay Partner and wish to flag transactions with your unique partner id it should be set here-->
 <add key="sagepay.kit.partnerID" value=""/>

 <!--Use this key to send surcharge xml and override the default values set for your account. See the protocol documents for further explanation on using the surcharge xml-->
 <add key="sagepay.kit.surchargeXML" value="&lt;surcharges&gt;&lt;surcharge&gt;&lt;paymentType&gt;VISA&lt;/paymentType&gt;&lt;percentage&gt;2.50&lt;/percentage&gt;&lt;/surcharge&gt;&lt;/surcharges&gt;" />

 <!--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="**********" />
 <add key="sagepay.kit.form.encryptionPassword.LIVE" value="" />

 <!-- 0 = Do not send either customer or vendor e-mails, 1 = Send customer and vendor e-mails if address(es) are provided(DEFAULT). 2 = Send Vendor Email but not Customer Email. If you do not supply this field, 1 is assumed and e-mails are sent if addresses are provided.-->
 <add key="sagepay.kit.form.sendEmail" value="1" />

 <!--Optional setting. Set this to the mail address which will receive order confirmations and failures-->
 <add key="sagepay.kit.form.vendorEmail" value="" />

 <!--Optional setting. Contents of email message. You can specify any custom message to send to your customers in their confirmation e-mail here The field can contain HTML if you wish, and be different for each order. This field is optional-->
 <add key="sagepay.kit.form.emailMessage" value="Thanks for your order" />

 <!--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.serverPaymentUrl.LIVE" value="https://live.sagepay.com/gateway/service/vspserver-register.vsp" />
 <add key="sagepay.api.serverTokenRegisterUrl.LIVE" value="https://live.sagepay.com/gateway/service/token.vsp" />
 <add key="sagepay.api.directPaymentUrl.LIVE" value="https://live.sagepay.com/gateway/service/vspdirect-register.vsp" />
 <add key="sagepay.api.directTokenRegisterUrl.LIVE" value="https://live.sagepay.com/gateway/service/directtoken.vsp" />
 <add key="sagepay.api.direct3dSecureUrl.LIVE" value="https://live.sagepay.com/gateway/service/direct3dcallback.vsp" />
 <add key="sagepay.api.directPayPalCompleteUrl.LIVE" value="https://live.sagepay.com/gateway/service/complete.vsp" />
 <add key="sagepay.api.tokenRemoveUrl.LIVE" value="https://live.sagepay.com/gateway/service/removetoken.vsp" />
 <add key="sagepay.api.abortUrl.LIVE" value="https://live.sagepay.com/gateway/service/abort.vsp" />
 <add key="sagepay.api.authoriseUrl.LIVE" value="https://live.sagepay.com/gateway/service/authorise.vsp" />
 <add key="sagepay.api.cancelUrl.LIVE" value="https://live.sagepay.com/gateway/service/cancel.vsp" />
 <add key="sagepay.api.refundUrl.LIVE" value="https://live.sagepay.com/gateway/service/refund.vsp" />
 <add key="sagepay.api.releaseUrl.LIVE" value="https://live.sagepay.com/gateway/service/release.vsp" />
 <add key="sagepay.api.repeatUrl.LIVE" value="https://live.sagepay.com/gateway/service/repeat.vsp" />
 <add key="sagepay.api.voidUrl.LIVE" value="https://live.sagepay.com/gateway/service/void.vsp" />

 <add key="sagepay.api.formPaymentUrl.TEST" value="https://test.sagepay.com/gateway/service/vspform-register.vsp" />
 <add key="sagepay.api.serverPaymentUrl.TEST" value="https://test.sagepay.com/gateway/service/vspserver-register.vsp" />
 <add key="sagepay.api.serverTokenRegisterUrl.TEST" value="https://test.sagepay.com/gateway/service/token.vsp" />
 <add key="sagepay.api.directPaymentUrl.TEST" value="https://test.sagepay.com/gateway/service/vspdirect-register.vsp" />
 <add key="sagepay.api.directTokenRegisterUrl.TEST" value="https://test.sagepay.com/gateway/service/directtoken.vsp" />
 <add key="sagepay.api.direct3dSecureUrl.TEST" value="https://test.sagepay.com/gateway/service/direct3dcallback.vsp" />
 <add key="sagepay.api.directPayPalCompleteUrl.TEST" value="https://test.sagepay.com/gateway/service/complete.vsp" />
 <add key="sagepay.api.tokenRemoveUrl.TEST" value="https://test.sagepay.com/gateway/service/directtoken.vsp" />
 <add key="sagepay.api.abortUrl.TEST" value="https://test.sagepay.com/gateway/service/abort.vsp" />
 <add key="sagepay.api.authoriseUrl.TEST" value="https://test.sagepay.com/gateway/service/authorise.vsp" />
 <add key="sagepay.api.cancelUrl.TEST" value="https://test.sagepay.com/gateway/service/cancel.vsp" />
 <add key="sagepay.api.refundUrl.TEST" value="https://test.sagepay.com/gateway/service/refund.vsp" />
 <add key="sagepay.api.releaseUrl.TEST" value="https://test.sagepay.com/gateway/service/release.vsp" />
 <add key="sagepay.api.repeatUrl.TEST" value="https://test.sagepay.com/gateway/service/repeat.vsp" />
 <add key="sagepay.api.voidUrl.TEST" value="https://test.sagepay.com/gateway/service/void.vsp" />
 </SagePayConfiguration>

User Detail Form

Now lets have look at the form, it can be as per your requirement, Here for the demo purpose I have create a simple form with 1 fix product for 1 GBP, but you can change it as per your need.

see the below image for the reference how my form is looks and what are the information I am collecting from the user.

Sample Form

In the above form we have asked for FirstName, lastname, billing address, post code, phone number, city, country etc. If you billing address and city address it different then you can ask differently. Now once you click on the submit button it will display same data for the confirmation. Once you click on the submit button again it will redirect you to the Sagepay website for the Checkout with the data you provided in basket.

See the below image for the reference

here on the left side you can see order description and vendor name with how much about you need to pay. While on the right side you need to select “How do you want to pay?” mean using which type of card you want to make payment, it’s visa, visa debit etc.

Once you select the appropriate card to make the payment it will redirect you to the page where it will ask for the card credential, like Name on the card, credit card number, card expire month/year and card CVV number.

See the below image for the reference

Now once you have entered the card detail then click on the “Confirm card detail” button so it will redirect you to review order page where you can review all the detail regarding this order, like order detail, card detail, shipping/billing address etc.

for the reference see the below image

Now once you click on the pay now button it will process your request and make the payment from the card, once it is done successfully then it will redirect request to the address which you have set in “sagepay.kit.siteFqdn.TEST” key in the web.config and “request.SuccessUrl” in the controller, if request is failed then it will redirect to the address which you have set in “sagepay.kit.siteFqdn.TEST” key in the web.config and “request.FailureUrl” in the controller

Once it comes to your call back page again it will have a response in a Crypt variable, then we need to convert it to “IFormPaymentResult” type object so we can read the response, Now how our response looks like see the below image

Sample Response

If you are getting the ResponseStatus.OK that means your transaction is successfully completed.
Summary
In this article we have see how to setup a form integration payment method for SagePay. Here with I have attached a fully working asp.net MVC sample project just download it and in web.config file change below keys with you vendor name.
1. sagepay.api.env – this key may contains TEST or LIVE value, based on your requirement you can set it.
2. sagepay.kit.vendorName – this is the vendor name for you account created on SagePay site.
3. sagepay.kit.siteFqdn.TEST – If in 1. key you set TEST then set callback URL here, just root address of your site else leave it blank
4. sagepay.kit.siteFqdn.LIVE – If in 1. key you set LIVE then set callback URL here, just root address of your site else leave it blank
5. sagepay.kit.form.encryptionPassword.TEST – If in 1. key you set TEST then set encrypted password for your vendor name here, just root address of your site else leave it blank
6. sagepay.kit.form.encryptionPassword.LIVE – If in 1. key you set LIVE then set encrypted password for your vendor name here, just root address of your site else leave it blank

I hope it will be helpful someone who wants to integrate SagePay form.

If you want to download working example then download it from here

Good Luck 🙂

C# interview question answers

Q-1: Which of the following statement is true?
a. try block must be followed by catch and finally block both.
b. try block must be followed by catch or finally block or both.
c. try block cannot include another try block.
d. All of the above.

Correct Answer: (b) try block must be followed by catch or finally block or both.

Q-2: Which of the following datatype can be used with enum?
a. Int
b. String
c. Boolean
4. All of the above

Correct Answer: (a) Int

Q-3: A partial class allows ________
a. Implementation of single class in multiple .cs files.
b. Declaration of multiple classes in a single .cs file.
c. Implementation of multiple interfaces to single class.
d. Multiple class inheritance.

Correct Answer: (a) Implementation of single class in multiple .cs files.

Q-4: C# class can inherit multiple ________
a. Class
b. Interface
c. Abstract class
d. Static class

Correct Answer: (b) Interface

Q-5: Struct is a _____.
a. Reference type
b. Value type
c. Class type
d. String type

Correct Answer: (b) Value type

Q-6: Which of the following is true for ReadOnly variables?
a. Value will be assigned at runtime.
b. Value will be assigned at compile time.
c. Value will be assigned when it accessed first time
d. None of the above

Correct Answer: (a) Value will be assigned at runtime.

Q-7: LINQ stands for ________.
a. Language Integrated Query
b. Local Integration Query
c. Language Included Query
d. Lazy Integrated Query

Correct Answer: (a) Language Integrated Query

Q-8: Which of the following is true for dynamic type in C#?
a. It allows multiple time declaration of a variable.
b. It allows compile time type checking
c. It escapes compile time type checking
d. None of the above.

Correct Answer: (c) It escapes compile time type checking

Q-9: String data type is ______.
a. Mutable
b. Immutable
c. Static
d. Value type

Correct Answer: (b) Immutable

Q-10: Which of the following is right way of declaring an array?
a. Int[] intArray = new int[];
b. Int intArray[] = new int[5];
c. Int[] intArray = new int[5];
d. Int[] intArray = new int[]{1, 2, 3, 4, 5};

Correct Answer: (c) Int[] intArray = new int[5];

Q-11: What is Nullable type?
a. It allows assignment of null to reference type.
b. It allows assignment of null to value type.
c. It allows assignment of null to static class.
d. None of the above.

Correct Answer: (b) It allows assignment of null to value type.

Q-12: Which of the following is a reference type in C#?
a. String
b. Long
c. Boolean
d. None of the above

Correct Answer: (a) String

Q-13: Data type of a variable declared using var will be assigned at _______.
a. Runtime
b. Compile time
c. CLR time
d. Application Initialization time.

Correct Answer: (b) Compile time

Q-14: 10 > 9 ? “10 is greater than 9” : “9 is greater than 10” is an example of _______
a. Ternary operator
b. Conditional operator
c. Greater than operator
d. Inverse operator

Correct Answer: (a) Ternary operator

Q-15: Which of the following statement is true?
a. A finally block may not execute every time
b. A finally block cannot include return or break keyword.
c. A finally block can come before catch block.
d. Multiple finally block is possible.

Correct Answer: (b) A finally block cannot include return or break keyword.

Q-16: What is indexer?
a. It allows an instance of a class to be indexed like an array
b. It allows enumerator with class
c. It creates index for instances of a class.
d. None of the above.

Correct Answer: (a) It allows an instance of a class to be indexed like an array

Q-17: Return type of Predicate <T>() is always a ______.
a. Integer
b. String
c. Boolean
d. Void

Correct Answer: (c) Boolean

Q-18: An array in C# starts with _____ index.
a. One
b. Zero
c. -1
d. None of the above

Correct Answer: (b) Zero

Q-19: Which of the followings are value types in C#?
a. Int32
b. Double
c. Decimal
d. All of the above

Correct Answer: (d) All of the above

Q-20: Func and Action are the types of ______.
a. Utility function
b. Delegate
c. Event
d. Generic class

Correct Answer: (b) Delegate

XmlDocument class

In the previous article we have seen how to write an XML file using XmlWriter class, in this article we will see how to write an XML file using XmlDocument class. Both are writing the XML file only, however when we want to update an existing XML file then XmlDocument class will be easy to use. Because XmlWriter class will use higher memory consumption.

Now look at the below sample code


using System.Xml;

namespace DocumentXml
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument document = new XmlDocument();
            XmlNode rootElement = document.CreateElement("developers");
            document.AppendChild(rootElement);

            XmlNode developerNode = document.CreateElement("developer");
            XmlAttribute noteAttribute = document.CreateAttribute("dept");
            noteAttribute.Value = "DotNet";
            developerNode.Attributes.Append(noteAttribute);
            developerNode.InnerText = "Tarun Dudhatra";
            rootElement.AppendChild(developerNode);

            developerNode = document.CreateElement("developer");
            noteAttribute = document.CreateAttribute("dept");
            noteAttribute.Value = "DotNet";
            developerNode.Attributes.Append(noteAttribute);
            developerNode.InnerText = "Milan Dudhatra";
            rootElement.AppendChild(developerNode);

            document.Save(@"D:\Tarun\developers.xml"); // Change file path here
        }
    }
}

Above code will produce below output


<developers>
  <developer dept="DotNet">Tarun Dudhatra</developer>
  <developer dept="DotNet">Milan Dudhatra</developer>
</developers>

As we can see, first we have created an object of XmlDocument class. It will be used to create new element and new attribute both using the CreateElement() and CreateAttribute() methods. Each time we will do the same process, what I mean here is if we want to create 3 nodes in the root element developers then we will do use document object 3 times to create XmlNode element using the CreateElement(). We append the element to either root element or any other element using .Append() method of the Attributes property. Attributes are appended to the element itself where we want to add in any node. Once all the nodes are created with attributes and appended to the rool element or any other element, the entire XML file is written to the disk using Save() method, which we have write at the last line.

It’s Pretty cool, Isn’t it?

Now download the sample project with code written earlier.