-
Notifications
You must be signed in to change notification settings - Fork 2
Creating Custom Payment Gateways
Custom Payment Gateways ultimately boil down to a custom ViewComponent with JavaScript hooks into the ecommerce libraries, and an API to handle the payment events and order updates. Creating a custom payment gateway should take roughly 3-10 hours, depending on complexity of the payment gateway. Let's break down the processes and then go into detail.
When a user selects a payment method, the Generic Ecommerce attempts to load the view-component with name Generic.Ecom.ThePaymentOptionCodeName
(of course, ThePaymentOptionCodeName should be the value found in Kentico's Admin -> Store Configuration -> Payment Methods -> Code name field).
This View Component's HTML is injected onto the page, and any <script>
tag that has the data-initialize
is evaluated.
The first step is to create a payment
method and append it to the checkout
property (initialized by the default ecommerceEvents.js). This will either be triggered after the Order is created, or if the order is created, once you submit payment (in the next step).
Ultimately this method should finalize or preserve your payment, then dispatch the payment-result
event via the document.body.dispatchEvent(checkout.paymentResultEevnt(paymentResultJson))
, which will trigger finalizing and redirecting if the paymentResultJson.paymentSuccessful
value is true, or render the paymentResultJson.message
if the paymentSuccessful is false.
Once a person has entered their payment information, it is important that Kentico creates the Order Object before payment initializes. When an order is created, the checkout
(initialized by the default ecommerceEvents.js) property will contain the orderGUID property.
If this value is not present, then the order needs to be created. So on your payment gateway's 'pay' button, execute the following:
checkout.sendCreateOrder = async function (ev) {
ev.preventDefault();
if (!checkout.orderGUID) {
// Initializes the Order Creation logic, this will attempt to trigger checkout.payment once done
document.body.dispatchEvent(checkout.createOrderEvent);
} else {
// Order is already created, proceed to attempt to pay
await checkout.payment(null);
}
}
Your payment gateway will need to update the Kentico Order with a Payment Successful or payment failure.
In order to do this, you will need to create a JsonResult action on a controller, and in it get the order based on the OrderGUID (checkout.orderGUID
), and then create a new PaymentResultInfo
and call order.UpdateOrderStatus(thePaymentResultInfo);
Lastly it should return a JsonResult with PaymentSuccessful
(true/false) and optionally a Message
(especially if false).
Here's an example:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task < IActionResult > Pay([FromBody] MyPaymentModel model) {
// verify Payment
var order = (await OrderInfoProvider.Get().WhereEquals(nameof(OrderInfo.OrderGUID), model.OrderGUID).TopN(1).GetEnumerableTypedResultAsync()).FirstOrDefault();
var paymentResult = somePaymentService.VerifyPayment(model.PaymentAuthCode);
if (paymentResult.Successful) {
// Creates a payment result object that will be viewable in Xperience
PaymentResultInfo result = new PaymentResultInfo {
PaymentDate = DateTime.Now,
PaymentDescription = "Transaction with Transaction ID: " + paymentResult.RequestId,
PaymentIsCompleted = paymentResult.Successful,
PaymentIsFailed = !paymentResult.Successful,
PaymentTransactionID = paymentResult.RequestId,
PaymentStatusValue = $ "Response Code: {paymentResult.StatusCode}, Description: {paymentResult.Content}",
PaymentMethodName = "MyCustomPayment"
};
// Saves the payment result to the database
order.UpdateOrderStatus(result);
return new JsonResult(new {
PaymentSuccessful = paymentIntent.Status == "succeeded"
});
} else {
PaymentResultInfo result = new PaymentResultInfo {
PaymentDate = DateTime.Now,
PaymentDescription = "Transaction failed",
PaymentIsCompleted = paymentResult.Successful,
PaymentIsFailed = !paymentResult.Successful,
PaymentTransactionID = "",
PaymentStatusValue = $ "Response Code: {paymentResult.StatusCode}, Description: {paymentResult.Content}",
PaymentMethodName = "MyCustomPayment"
};
// Saves the payment result to the database
order.UpdateOrderStatus(result);
return new JsonResult(new {
Message = $ "Failed Transaction. {paymentResult.Code}: {paymentResult.Message}. Please contact us and refrence {order.OrderID}."
});
}
return new JsonResult(new {
Message = "Transaction Failed."
});
}
It may be easier, however, to simply look at one of the existing custom payment gateways that is available. See the StripeJS repository for an advanced implementation.
If you do create your own payment gateway, please notify us once the package is created so we can add a link to it in this repository.
- Installation / Setup
- Design Principle
- Basic Usage
- Operations and Interfaces
- Customization Points
- Creating Custom Payment Gateways