Creating a custom payment gateway
Here's a general overview of the process of integrating a custom payment gateway:
1. | Create a payment gateway form with your custom controls to enable customers to enter their payment data such as credit card number, see section Creating custom payment gateway form. |
2. | Create your custom payment gateway class and override required methods for payment processing, see section Creating custom payment gateway class. |
3. | Go to the CMSDesk -> Tools -> E-commerce -> Configuration -> Payment methods. |
4. | Create a new payment method and register your custom payment gateway as described in the Payment methods chapter. |
Creating a custom payment gateway form
1. | Create a new web user control (*.ascx) and place it into your site folder which is located in the root of your web project. |
Since the control is located in the site folder it is included in export package of your site.
2. | Set control class to inherit from abstract class CMS.EcommerceProvider.CMSPaymentGatewayForm |
3. | There are several methods you need to override to reach your required functionality: |
▪ | LoadData() – Initializes form controls with customer payment data. |
▪ | ValidateData() – Validates customer payment data. |
▪ | ProcessData() – Process customer payment data and saves them to the ShoppingCartInfo object. |
4. | There are several properties to get or set required information: |
▪ | ShoppingCartControl – Parent shopping cart control the current shopping cart step belongs to. |
▪ | ShoppingCartInfoObj – Shopping cart object which stores all data during the checkout process. |
Please note: Payment data, such as credit card numbers, credit card codes and others are not saved into the database because of security reasons.
Creating custom payment gateway class
1. | Create a new library (assembly) as a part of your solution and a new class inside this library. |
2. | Add a reference to System.Web assembly into the project with the payment gateway (Right-click the References folder, choose Add reference, select .NET -> System.Web). |
3. | Set your class to inherit from abstract class CMS.EcommerceProvider.CMSPaymentGatewayProvider. |
4. | There are several methods you can override to reach your required functionality: |
▪ | AddCustomData() – Adds payment gateway custom controls to the current shopping cart step. By default CMSPaymentGatewayForm control is added to the payment data container and its data are loaded. |
▪ | RemoveCustomData() – Removes payment gateway custom controls from the current shopping cart step. By default all controls from payment data container are removed. |
▪ | ValidateCustomData() - Validates payment gateway custom data of the current shopping cart step. By default CMSPaymentGatewayForm control data are validated. |
▪ | ProcessCustomData() - Process payment gateway custom data of the current shopping cart step. By default CMSPaymentGatewayForm data are processed. |
▪ | ProcessPayment() - Process payment - you need to override this method to process payment by your payment processor. |
▪ | GetPaymentDataForm() – Loads payment gateway form with custom controls – you need to override this method to get your own payment gateway form. |
5. | There are several properties to get or set required information: |
▪ | ShoppingCartControl – Parent shopping cart control the current shopping cart step belongs to. |
▪ | ShoppingCartInfoObj – Shopping cart object which stores all data during the checkout process .If OrderId is set it is created from existing order, otherwise it is returned from current shopping cart control. |
▪ | OrderId – Order ID. Set this value when you want to process payment for the existing order outside the checkout process. |
▪ | PaymentDataContainer – Payment gateway custom controls container of the current shopping cart step control. |
▪ | PaymentResult – Payment result (see caption Payment Result) |
▪ | IsPaymentCompleted – Indicates whether order payment was already completed. It is determined by order payment result. |
▪ | InfoMessage - Payment result message displayed to user when payment succeeds. |
▪ | ErrorMessage - Payment result message displayed to user when payment fails. |
6. | Compile the library. |
7. | Ensure the library file (*.dll) is included in <your web project folder>/Bin directory. |
Example
The following example shows a custom payment processor implementation. It allows customers to pay for their orders using some external payment gateway similar to PayPal, let’s call it Custom Gateway. Customer is asked for their credit card number in the last step of checkout process. Credit card number is validated for emptiness and processed after the “Finish payment” button is clicked. If it succeeds payment process is performed – required payment data are attached to the payment url and customer is redirected to Custom Gateway. If payment process fails (payment gateway url is not defined) order payment result is updated and appropriate error message is displayed. Notice that order is saved before the customer is asked to pay for it, it happens immediately after the “Order now” button is clicked.
Please note:
o | It is not secure to send credit card information as a part of payment gateway url. Customers usually asked for their credit card number after they are redirected to the payment gateway itself; otherwise another way of sending credit card information should be used instead. |
o | For more details about how payment gateway could inform merchant about the result of the payment which was finished outside their website, see caption PayPal (IPN – Instant Payment Notification). |
Example of custom payment gateway definition.
Custom payment gateway form
It is a simple form with one input field to enter customer credit card number, see image bellow.
CustomGatewayForm.ascx
Please note: If you installed the Kentico CMS project as a web application, you need to rename the CodeFile property on the first line to Codebehind for the code example to be functional.
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomGatewayForm.ascx.cs" Inherits="CMSEcommerce_Example_CustomGatewayForm" %> <asp:Label ID="lblTitle" runat="server" EnableViewState="false" CssClass="BlockTitle" /> <asp:Label ID="lblError" runat="server" EnableViewState="false" CssClass="ErrorLabel" Visible="false" /> <asp:Label ID="lblCardNumber" EnableViewState="false" runat="server" /> <asp:TextBox ID="txtCardNumber" runat="server" /> |
CustomGatewayForm.ascx.cs
[C#]
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
using CMS.EcommerceProvider; using CMS.GlobalHelper;
public partial class CMSEcommerce_Example_CustomGatewayForm : CMSPaymentGatewayForm {
protected void Page_Load(object sender, EventArgs e) { // Initialize label lblTitle.Text = "Your credit card details"; lblCardNumber.Text = "Credit card number:"; }
/// <summary> /// Initializes form controls with customer payment data. /// </summary> public override void LoadData() { // Display customer credit card number txtCardNumber.Text = ValidationHelper.GetString(this.ShoppingCartInfoObj.PaymentGatewayCustomData["CustomGatewayCardNumber"], ""); }
/// <summary> /// Validates customer payment data. /// </summary> /// <returns></returns> public override string ValidateData() { if (txtCardNumber.Text.Trim() == "") { lblError.Visible = true; lblError.Text = "Please enter your credit card number"; return lblError.Text; } return ""; }
/// <summary> /// Process customer payment data. /// </summary> /// <returns></returns> public override string ProcessData() { // Save credit card number this.ShoppingCartInfoObj.PaymentGatewayCustomData["CustomGatewayCardNumber"] = txtCardNumber.Text.Trim(); return ""; } } |
Custom payment gateway class
The following example uses assembly name CMS.CustomProvider and class CMS.CustomProvider.CustomGateway, however, you will need to use your own names.
CustomGateway.cs
[C#]
using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Collections;
using CMS.EcommerceProvider; using CMS.GlobalHelper; using CMS.UIControls; using CMS.ExtendedControls;
namespace CMS.CustomProvider { /// <summary> /// Class representing Custom Gateway processor. /// </summary> public class CustomGateway : CMSPaymentGatewayProvider { /// <summary> /// Returns payment gateway form with custom controls. /// </summary> /// <returns></returns> public override CMSPaymentGatewayForm GetPaymentDataForm() { try { return (CMSPaymentGatewayForm)this.ShoppingCartControl.LoadControl("~/CMSEcommerce/Example/CustomGatewayForm.ascx"); } catch { return null; } }
/// <summary> /// Process payment. /// </summary> public override void ProcessPayment() { // Get payment gateway url string url = this.GetPaymentGatewayUrl();
if (url != "") { // Initialize payment parameters Hashtable parameters = InitializePaymentParameters();
// Add required payment data to the url url = GetFullPaymentGatewayUrl(url, parameters);
// Redirect to payment gateway to finish payment this.ShoppingCartControl.Page.Response.Redirect(url); } else { // Show error message - payment gateway url not found this.ErrorMessage = "Unable to finish payment: Payment gateway url not found.";
// Update payment result this.PaymentResult.PaymentDescription = this.ErrorMessage; this.PaymentResult.PaymentIsCompleted = false;
// Update order payment result in database this.UpdateOrderPaymentResult(); } }
/// <summary> /// Returns table with initialized payment parameters. /// </summary> /// <returns></returns> private Hashtable InitializePaymentParameters() { Hashtable parameters = new Hashtable();
parameters["orderid"] = this.ShoppingCartInfoObj.OrderId; parameters["price"] = this.ShoppingCartInfoObj.TotalPrice; parameters["currency"] = this.ShoppingCartInfoObj.CurrencyInfoObj.CurrencyCode; parameters["cardnumber"] = Convert.ToString(this.ShoppingCartInfoObj.PaymentGatewayCustomData["CustomGatewayCardNumber"]);
return parameters; }
/// <summary> /// Returns payment gateway url with payment data in query string. /// </summary> /// <param name="url">Payment gateway url.</param> /// <param name="parameters">Initialized payment paremeters.</param> /// <returns></returns> private string GetFullPaymentGatewayUrl(string url, Hashtable parameters) { foreach (DictionaryEntry parameter in parameters) { // Add payment data to the url url = UrlHelper.AddParameterToUrl(url, Convert.ToString(parameter.Key), HttpUtility.UrlEncode(Convert.ToString(parameter.Value))); } return url; } } } |