Payment providers
This article describes how payment providers are implemented in Litium. This only applies if you intend to change a payment provider to implement additional functionality, or intend to develop a new payment provider.
The payment providers provide the functionality to collect payments from the customer's account. There are two basic models of collecting payments from a customer. In Litium this is called payment modes.
- One phased: The money is directly collected from the customer's account. This is the "charge" payment mode.
- Two phased: In the first phase the money is reserved on the customer's account. In the second phase the money is collected. This is the "reserve" payment mode.
Payment method
This is the method of payment such as credit card, bank direct debit, invoice, etc. Different payment providers support different payment methods. You can find a complete list of supported payment methods here.
Communication
The communication between Litium and the payment provider will depend on the specific technology used by the respective payment provider. As of 2012, the payment providers are using the following technologies, but note that this is subject to change.
- PayEx: Web Services
- Nets: HTTP Post & Web Services (limited support in Web Services)
- Klarna: XmlRpc
- Dibs: HTTP Post
- PayPal: NVP (PayPal specific)
- DirectPay: Not relevant, as this is internal
- Handelsbanken Ecster: Web services
Blocking vs. non-blocking calls
As a developer, it is important that you understand when the payment provider is going to return control back to you when a method is called, or if at all it is going to return in the method you called. In this respect, the communication between Litium and the payment provider is either blocking or non-blocking, based on the situation and provider.
- A non-blocking method call is asynchronous by nature. Litium will transfer the control to the payment provider, and redirect the user to the payment provider site.
- A blocking method call is synchronous by nature. Litium will wait for a reply from the payment provider, and will halt the execution until the result is returned. The control will remain inside Litium.
Notes:
- For PayEx, the control is redirected to a remote PayEx address to continue checkout flow in the Execute Payment implementation of the checkout flow template page. This is a non-blocking call, since it is a redirection. All other calls are web services calls, which are synchrounous, therefore blocking.
- For Nets, the control is redirected to Nets, using an HTTP Post, in Execute Payment implementation of the checkout flow template page. This is a non-blocking call, since it is an HTTP Post. All other calls are web services calls, which are synchrounous, therefore blocking.
- For Paypal, the control is redirected to PayPal, using an HTTP Post, in Execute Payment implementation of the checkout flow template page. This is a non-blocking call, since it is an HTTP Post. All other calls are synchrounous, therefore blocking.
- All calls to Klarna are blocking, because each call is a synchronous XML RPC request.
- All calls to Dibs are non-blocking, because each call is an HTTP Post.
Implementation
The payment providers are implemented using the plugin architecture, with a common interface for all payment providers. So, each payment provider implements the IPaymentProvider interface. Additionally, the payment provider is an extension of the PaymentInfo entity object. For this reason, each payment provider must inherit from the PaymentProviderBase base class.
All payment provider functionality is abstracted into the IPaymentProvider interface. Therefore, all payment providers are managed in the same way in Litium. This simplifies how you would use payment providers in your checkout flow, because you do not need to consider the specific payment provider when using it, you only need to use the IPaymentProvider interface.
Invoking IPaymentInterface methods
The individual payment providers should not be instantiated from your code. Instead, always use the instance attached to the PaymentInfo entity object of the Order entity object. The following example shows how the CompletePayment() method of a payment provider is invoked.
/// <summary>
/// Called when delivery is confirmed.
/// </summary>
/// <param name="carrier">The carrier.</param>
/// <param name="state">The state.</param>
/// <param name="token">The token.</param>
protected virtual void OnDeliveryConfirmation(DeliveryCarrier carrier,
State<DeliveryCarrier> state, SecurityToken token)
{
//NOTE: we take the order and call the CompletePayment method using
// IPaymentProvider interface.
Order order = ModuleECommerce.Instance.Orders.GetOrder(carrier.OrderID, token);
if (order != null)
{
PaymentInfo paymentInfo = order.PaymentInfo[0];
if (paymentInfo.PaymentProvider.CanCompleteCurrentTransaction)
{
paymentInfo.PaymentProvider.CompletePayment(null, token);
}
}
}