janaka.fernando
May 5, 2015
visibility 4878
star star star star star
(1 votes)

Implementing Pay by Credit payments

The Scenario

One common scenario for B2B Commerce is allowing organizations to pay using credit for purchases which they will have to settle by invoice at a later date.  Normally an organization would have to go through an approval and receive a credit limit from the retailer.

In this example I will show how we implemented a basic payment gateway for setting up Pay by Credit payment methods.

 

Credit fields for Organization

To start with we will add two new fields to the Organization entity through Business Foundation.   Both fields will be a Currency data type. 

First add CreditLimit which will be used to set the limit for the Organization.  By default this will not be null and be 0 as not every organization should have a credit limit.  

Image PaybyCredit-Org1.PNG

Next add another Currency field called CreditBalance, this again will have 0 as the default value and allow Nulls.  It will also allow negative values.  Make the changes and Save.  Now from the organization screen click on the Forms tab and edit the Edit Form.

Image PaybyCredit-Org3.PNG

Select the Credit Balance field and click on the Remove button. 

Image PaybyCredit-Org4.PNG

Now that these two fields are available you can open an existing organization or create a new one.  Set the Credit Limit value to some value like 5000 and save.  Note that we don't want to set the Credit Balance as we will be updating this through the payment provider.  This is why we removed it from edit view.

Add a Payment Gateway

Now we are ready to add some code to the solution.  We will utilize the exisitng OtherPayment payment type for our example.  If we had some additional payment properties we wanted to set we could create our own derived payment type, for example CreditPayment.  The payment gateway code is best if its in a seperate code library as it needs to be referenced by both the front end and Commerce Manager sites.  We will create a new gateway called CreditLimitPaymentGateway which implements IPaymentGateway.  

The main method you need to implement is ProcessPayment.  This takes the incoming payment and allows you to pass back a message from the payment gateway.  Because the credit limit is on the organization we retrieve this through the current contact.  The full source below shows a number of validations against whether the credit payment is valid.  If valid we update the credit on the account to the organization.  

public class CreditLimitPaymentGateway : IPaymentGateway
    {
        public const string CreditLimitKey = "CreditLimit";
        public const string CreditBalanceKey = "CreditBalance";
        
        public bool ProcessPayment(Payment payment, ref string message)
        {
            bool hasPaid = false;

            if (payment is OtherPayment)
            {
                // Get the customer's organisation
                Organization organization =  CustomerContext.Current.CurrentContact.ContactOrganization;
                if (organization != null && !string.IsNullOrWhiteSpace(organization.Name))
                {
                    decimal limit = Convert.ToDecimal(organization[CreditLimitKey]);
                    decimal balance = Convert.ToDecimal(organization[CreditBalanceKey]);
                    decimal totalWithPurchase = balance + payment.Amount;

                    if (limit > 0)
                    {
                        if (totalWithPurchase <= limit)
                        {
                            // Take payment
                            if (UpdateCreditToAccount(organization, totalWithPurchase))
                            {
                                hasPaid = true;
                            }
                            else
                            {
                                message = "Unable to add credit to your account.";
                            }
                        }
                        else
                        {
                            message = "You have insufficient credit for this purchase.";
                        }
                    }
                    else
                    {
                        message = "You do not have a credit limit.";
                    }
                    
                }
                else
                {
                    message = "You can only pay by credit on business accounts.";
                }
            }
            else
            {
                message = "Only Credit Payments can be accepted.";
            }

            return hasPaid;
        }

        private bool UpdateCreditToAccount(Organization organization, decimal totalWithPurchase)
        {
            try
            {
                organization[CreditBalanceKey] = totalWithPurchase;
                organization.SaveChanges();
                return true;
            }
            catch (Exception ex)
            {
                //Log exception
                return false;
            }
            
        }

        public IDictionary<string, string> Settings
        {
            get;
            set;
        }
    }

Configure the Payment Method

Once this project has been compiled and referenced in both the web and commerce manager project you can start utilising the new Payment gateway.   Go into the Administration in Commerce Manager and open up the Order System -> Payments section.  Here normally you will choose the language that the payment type is applicable to (usually defaulted to 'English' or your default language) and then click on New.  In the next screen you will configure your new Pay by Credit payment method to use the new CreditLimitPaymentGateway and appropriate OtherPayment class.  See example below

Image Blog-PaymentMethod.JPG

Wiring it up

I'm not going to go into detail here too much as how the payment option is displayed on the front end of your checkout page is up to you.  If you use the EPiServer Starter Kit or Github OXXAS Starter Kit then these work by retrieving all payment methods for the market and displaying them automatically.  You will need to update a bit of code to ensure that an OtherPayment is sent with the appropriate amount, and some handling if the workflow throws and error on the payment method, for example if the credit limit has been reached.

Now the rest is up to you to decide how you could extend this further.

Happy coding!

May 05, 2015

Comments

error Please login to comment.
Latest blogs
Composition Over Inheritance: Why Your Content Contract Is Not a Base Class

Inside the structural conformance pattern in SaaS CMS — from server-side inheritance to pipeline governance. A contract in Optimizely SaaS CMS is...

Vipin Banka | Sep 19, 2026

Optimizely Opti ID Integration: Why the API Key Was Missing from the DXP Management Portal

While working on an Optimizely CMS 12 Opti ID integration recently, we ran into an issue that initially appeared to be related to SSO authenticatio...

Madhu | Sep 18, 2026 |

Extending a Contract: What You Can Override

Contracts share fields across content types — but not every field setting can be overridden. Push the same contract onto several components, and CM...

Chirag Khanna | Sep 18, 2026 |

Building a Blazor Server UI Inside the Optimizely CMS 13 Admin Shell

What I learned shipping a Blazor Server UI inside Optimizely CMS 13 — Razor components in a NuGet package, the Blazor hub next to MapContent(),...

Stanisław Szołkowski | Sep 17, 2026 |

Giving Optimizely 13 Content Types Meaningful Icons and Thumbnails

When working with an Optimizely CMS solution that has evolved over time, it is common to end up with many content types. As the number grows, the...

Pär Wissmark | Sep 16, 2026 |

force-dynamic vs connection() for Optimizely Graph

If you have built an Optimizely CMS SDK site, you already know getContentByPath on a catch-all. This post is about the part that file never says ou...

Chirag Khanna | Sep 16, 2026 |