Creating a custom payment gateway
Creating a custom payment gateway
To integrate your custom payment gateway:
Create a payment gateway form with your custom controls to allow customers to enter their payment data. For example credit card numbers, credit cart codes, etc.
Create a custom payment gateway class and override methods required for processing the payment.
If you create the custom payment gateway class in your project’s App_Code folder (or Old_App_Code on web applications), you need to register the class using:
[assembly: RegisterCustomClass("CustomGateway", typeof(CustomGateway))]
(Optional) Create an IPN handler for your payment gateway.
Open the Store configuration application.
Switch to the Payment methods tab.
Create a new payment method and register your custom payment gateway.
Creating a custom payment gateway form
Create a new web user control (*.ascx) and place it into your website folder, which is located in the root of your web project.
Because the control is located in the website folder, it is included in the export package of your site. See Export folder structure for more details.
Set the control class to inherit from the abstract CMS.Ecommerce.Web.UI.CMSPaymentGatewayForm class.
Override the following methods to reach the required functionality.
LoadData() - initializes form controls with customer payment data.
ValidateData() - validates customer payment data.
ProcessData() - processes customer payment data and saves it to the ShoppingCartInfo object.Besides, there are several properties to get or set information related to the purchase:
PaymentProvider - gets/sets the payment provider which initialized this control.
PaymentGatewayCustomData - gets the payment gateway custom data storage.
Payment data, such as credit card numbers, credit card codes, etc., is not saved into the database due to security reasons.
Creating a custom payment gateway class
Create the CustomGateway.cs class under the App_Code directory (Old_App_Code for web applications).
Set the class to inherit from the CMS.Ecommerce.Web.UI.CMSPaymentGatewayProvider abstract class.
(Optional) Override the following methods to reach the required functionality.
ValidateCustomData() - validates payment gateway custom data of the current shopping cart step. By default, validates the CMSPaymentGatewayForm control data.
ProcessCustomData() - processes payment gateway custom data of the current shopping cart step. By default, processes the CMSPaymentGatewayForm data.
ProcessPayment() - processes the payment. You need to override this method to have the payment processed by your payment processor.
Besides, there are several properties to get or set information related to the purchase:ShoppingCartInfoObj - specifies the shopping cart object that stores all data during the checkout process. If the OrderId property is specified, it is created from the existing order. Otherwise, it is returned from the current shopping cart control.
OrderId - specifies a unique identifier (ID) of the currently processed order.
PaymentResult - specifies the result of the currently processed payment.
PaymentDataForm - gets the payment gateway form with custom controls.
IsPaymentCompleted - indicates if payment is completed. It is determined by the order payment result.
InfoMessage - specifies the payment result message displayed to the user when payment succeeds.
ErrorMessage - specifies the payment result message displayed to the user when payment fails.
Compile the project (if you installed your Kentico project as a web application).
Handling IPN for custom payment gateways
If you wish to use Instant Payment Notification (IPN) with your payment gateway, you need to create a custom HTTP handler that performs the required communication between your Kentico application and the payment service. Do not handle IPN requests using standard pages (web forms), otherwise you will encounter security errors due to invalid CSRF tokens.
See also: Payment Gateways and CSRF protection
Examples
The examples demonstrate an implementation of a custom payment processor. The processor allows customers to pay for their orders using an external payment gateway similar to PayPal.
How payment works
- In the appropriate step (usually the last step) of the checkout process, the system asks the customer for their credit card number.
- After the customer confirms payment (by clicking Finish payment in the sample checkout process), the system validates the credit card number for an empty value and processes it.
- If successful, the payment process is performed – the required payment data is attached to the payment URL, and the customer is redirected to the payment gateway.
- If the payment process fails (the payment gateway URL is not defined), the payment result is updated and an appropriate error message is displayed.
The system saves the order before asking the customer to pay. Specifically, this happens immediately after placing the order, i.e. after clicking Order now in the sample checkout process.
It is not secure to send credit card information as a part of the payment gateway URL. Therefore, customers are usually asked for their credit card details after being redirected to the payment gateway.
If this is not the case, we recommend that you use some other way of sending your customers’ credit card information.
Custom payment gateway form
Here you can see a simple form with one input field where the customers enter their credit card numbers.
CustomGatewayForm.ascx
If you installed your Kentico project as a web application, for the code example to work, you need to rename the CodeFile property on the first line to Codebehind.
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomGatewayForm.ascx.cs" Inherits="EcommerceSite_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
using System;
using CMS.Ecommerce.Web.UI;
using CMS.Helpers;
public partial class EcommerceSite_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(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
PaymentGatewayCustomData["CustomGatewayCardNumber"] = txtCardNumber.Text.Trim();
return "";
}
}
Custom payment gateway class
The following example creates and registers the gateway class in the project’s App_Code folder (or Old_App_Code on web applications).
CustomGateway.cs
using System;
using System.Collections;
using CMS;
using CMS.Base;
using CMS.Ecommerce.Web.UI;
using CMS.Helpers;
[assembly: RegisterCustomClass("CustomGateway", typeof(CustomGateway))]
public class CustomGateway : CMSPaymentGatewayProvider
{
/// <summary>
/// Returns path to payment gateway form with custom controls.
/// </summary>
public override string GetPaymentDataFormPath()
{
return "~/EcommerceSite/CustomGatewayForm.ascx";
}
/// <summary>
/// Process payment.
/// </summary>
public override void ProcessPayment()
{
// Get payment gateway url
string url = 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
URLHelper.Redirect(url);
}
else
{
// Show error message - payment gateway url not found
ErrorMessage = "Unable to finish payment: Payment gateway url not found.";
// Update payment result
PaymentResult.PaymentDescription = ErrorMessage;
PaymentResult.PaymentIsCompleted = false;
// Update order payment result in database
UpdateOrderPaymentResult();
}
}
/// <summary>
/// Returns table with initialized payment parameters.
/// </summary>
/// <returns></returns>
private Hashtable InitializePaymentParameters()
{
Hashtable parameters = new Hashtable();
parameters["orderid"] = ShoppingCartInfoObj.OrderId;
parameters["price"] = ShoppingCartInfoObj.TotalPrice;
parameters["currency"] = ShoppingCartInfoObj.Currency.CurrencyCode;
parameters["cardnumber"] = ValidationHelper.GetString(PaymentDataForm.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), URLHelper.UrlEncodeQueryString(parameter.Value.ToString()));
}
return url;
}
}
For further details on how to create your custom payment gateway, see the Developing Custom Payment Gateway webinar.