World is now on Opti ID! Learn more

janaka.fernando
May 5, 2015
  2021
(0 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

Please login to comment.
Latest blogs
Make Global Assets Site- and Language-Aware at Indexing Time

I had a support case the other day with a question around search on global assets on a multisite. This is the result of that investigation. This co...

dada | Jun 26, 2025

The remote server returned an error: (400) Bad Request – when configuring Azure Storage for an older Optimizely CMS site

How to fix a strange issue that occurred when I moved editor-uploaded files for some old Optimizely CMS 11 solutions to Azure Storage.

Tomas Hensrud Gulla | Jun 26, 2025 |

Enable Opal AI for your Optimizely products

Learn how to enable Opal AI, and meet your infinite workforce.

Tomas Hensrud Gulla | Jun 25, 2025 |

Deploying to Optimizely Frontend Hosting: A Practical Guide

Optimizely Frontend Hosting is a cloud-based solution for deploying headless frontend applications - currently supporting only Next.js projects. It...

Szymon Uryga | Jun 25, 2025

World on Opti ID

We're excited to announce that world.optimizely.com is now integrated with Opti ID! What does this mean for you? New Users:  You can now log in wit...

Patrick Lam | Jun 22, 2025

Avoid Scandinavian Letters in File Names in Optimizely CMS

Discover how Scandinavian letters in file names can break media in Optimizely CMS—and learn a simple code fix to automatically sanitize uploads for...

Henning Sjørbotten | Jun 19, 2025 |