Developing Custom Payment Gateway
4/19/2012 Miro Remias, Solution Architect
PayPal,
Authorize.NET,
Customer Credit,
? Custom Payment Gateway,
Market Place:
E-way,
PayPal Payflow Pro,
Built-in Payment Gateways
1
SQL Database
Checkout steps
Kentico
Save order
Buyer(s)
Update result
Payment
provider
HTTP(S) POST
Redirect
Redirect (optional)
A)
B)
Payment Notification
Payment gateway class, payment gateway form (1)
Payment result (2)
Payment Notification (3)
Security (4)
Real world example - DEMO
Agenda
2
Update result 2
PN page
Thank you page
3
Confirmation (optional)
Authorize.NET
PayPal
(1) Payment Gateway Class
API CMS.EcommerceProvider.CMSPaymentGatewayProvider
ShoppingCartControl (ShoppingCart)
ShoppingCartInfoObj (ShoppingCartInfo)
OrderId (int)
PaymentResult (PaymentResultInfo)
IsPaymentCompleted (bool)
PaymentResult.PaymentIsCompleted
AddCustomData() - CMSPaymentGatewayForm control is added to the payment data container and its
data are loaded.
RemoveCustomData() - All controls from payment data container are removed.
ValidateCustomData() - CMSPaymentGatewayForm control data are validated.
ProcessCustomData() - CMSPaymentGatewayForm data are processed.
ShoppingCartInfoObj.PaymentGatewayCustomData (Hashtable)
ProcessPayment() - Override this method to process payment by your payment processor.
GetPaymentDataForm() - Override this method to get your own payment gateway form.
(static)GetPaymentGatewayProvider(int paymentOptionId) Loads payment gateway.
UpdateOrderPaymentResult() - Updates order payment result in database.
OrderId
PaymentResult
(1) Payment Gateway Form
API CMS.EcommerceProvider.CMSPaymentGatewayForm
ShoppingCartControl (ShoppingCart)
ShoppingCartInfoObj (ShoppingCartInfo)
PaymentGatewayCustomData (Hashtable)
LoadData() - Initializes form controls with customer payment data
CMSPaymentGatewayProvider.AddCustomData() - ShoppingCartPaymentGateway
ValidateData() - Validates form data and returns error message if some error occurs
CMSPaymentGatewayProvider.ValidateCustomData() - ShoppingCartPaymentGateway
ProcessData() - Process form data and returns error message if some error occurs
CMSPaymentGatewayProvider.ProcessCustomData() - ShoppingCartPaymentGateway
UI
(1) I Dont Need Payment Gateway Form
PaymentOptionInfo poi = PaymentOptionInfoProvider.GetPaymentOptionInfo(this.ShoppingCartInfoObj.ShoppingCartPaymentOptionID);
if (poi != null && poi.PaymentOptionClassName.ToLower().Equals("worldpayprovider"))
{
this.ButtonNextClickAction();
}
else
{
LoadData();
}
API
ShoppingCartPaymentGateway
API
CMS.Ecommerce.OrderInfo
OrderPaymentResult
CMS.Ecommerce.PaymentResultInfo
PaymentDate
PaymentMethodID
PaymentMethodName
PaymentIsCompleted
PaymentStatusName
PaymentStatusCode
PaymentTransactionID
LoadPaymentResultXml(string xml)
CMS.Ecommerce.OrderInfo
OrderIsPaid
Note: You dont need to specify both value and item text if they are
identical ((1) item text, (2) item value)
(2) Working With Payment Result
Database
COM_Order [Table]
OrderPaymentResult [Column]
COM_Order [Table]
OrderIsPaid [Column](new from version 6.0)
// Create/address new/existing PaymentResultItemInfo
PaymentResultItemInfo itemObj =
EnsurePaymentResultItemInfo("verified", HEADER_VERIFIED);
// PaymentResultItemInfo itemObj =
GetPaymentResultItemInfo("verified");
if(itemObj != null)
{
// item.Name
// item.Header
item.Value = "";
item.Text = "";
}
// Save new item
SetPaymentResultItemInfo(item);
<result>
<item name="date" header="{$PaymentGateway.Result.Date$}"
value="4/12/2012 8:30:19 PM" />
<item name="method"
header="{$PaymentGateway.Result.PaymentMethod$}" text="Word Pay"
value="5" />
<item name="completed"
header="{$PaymentGateway.Result.IsCompleted$}" value="1"
text="{$PaymentGateway.Result.PaymentCompleted$}" />
<item name="transactionid"
header="{$PaymentGateway.Result.TransactionID$}" value="6dc9af1c.."
/>
<item name="description"
header="{$PaymentGateway.Result.Description$}" />
<item name="verified"
header="{$PaymentGateway.WorldPayResult.Verification$}" value="1"
text="{$PaymentGateway.WorldPayResult.Verification.Verified$}" />
</result>
API
CMS.EcommerceProvider.CMSPaymentGatewayProvider
OrderId
PaymentResult
UpdateOrderPaymentResult()
(3) Payment Notification
Physical page (.aspx) vs. virtual page (served by Kentico),
PN page is not displaying anything - it should only process the received data,
Common location: ~\CMSModules\Ecommerce\CMSPages\
PN page needs to be accessible by public user,
Compare order data (COM_Order) and secret (e.g. from settings) with payment
gateway response/result data,
Confirm payment with payment gateway (optional),
Log any exceptions, error or suspicious behavior into Event log,
Update order payment result,
Confirmation e-mails are automatically sent,
int orderID = 5; // from response
int paymentOptionID = 6; // from order (based on orderID)
// Load payment provider
CMSPaymentGatewayProvider provider =
(WorldPayProvider)CMSPaymentGatewayProvider.GetPaymentGatewayProvider(paymentOptionID);
provider.OrderId = orderId;
// Compare data
// provider.PaymentResult =
provider.UpdateOrderPaymentResult();
(4) Security
Consider using SSL (HTTPS) on shopping cart page when collecting
sensitive information,
Use POST instead of GET (redirect) if possible,
Redirect/post with SSL (HTTPS),
Do not send sensitive information as part of the URL (querystring),
Verify data/integrity/result/etc. against some secret information,
Dont save sensitive information in Kentico,
Customer credit card etc.,
Use payment gateway security features,
Be paranoid!,
Real World Example
Understand how payment gateway works,
o Documentation,
Develop payment gateway class, form, PN page etc.
o Take advantage of documentation examples,
o Provide your code from App_Code folder,
No need to rebuild your DLL file when upgrading or applying hotfix,
Use custom setting keys,
o CMS Site Manager -> Development -> Custom Settings (new from version 6.0),
Register payment option (gateway) in Kentico,
o Assign it to some shipping option,
Test and review the security,
[DEMO]
Questions
?
Sources
E-commerce Guide
http://devnet.kentico.com/docs/ecommerceguide/index.html
Contact
Miro Remias
e-mail: miro@kentico.com
consulting: http://www.kentico.com/Support/Consulting/Overview