Sitecore Ordercloud

Pre-built Checkout Integrations in .NET

Suggest an edit
Oliver Heywood

Published by Oliver Heywood

June 20th, 2022

Introduction

Checkout integrations are one of the most challenging and most critical pieces of an e-commerce project. This guide is about open source .NET projects we've published to accelerate your checkout and put your integrations on solid footing. These projects include pre-built integrations with shippers, tax calculators, and payment processors as well as a complete integration scaffolding that ties these pieces together with the webhook routes OrderCloud expects.

Checkout basics in OrderCloud

Complexity in checkout comes from a variety of sources. Some parts have fairly standard user experience expectations (such as paying with a credit card) but are made complex by security requirements. Other parts are much less standardized (such as shipping rules and rates) and the complexity comes from custom business logic. The challenge for an e-commerce platform like OrderCloud is to provide the right balance between flexibility and guide-rails.

In OrderCloud, implementing checkout starts with the Integration Event API resource. If you have not read the Order Checkout Integration Event guide, it contains technical details on these events. The short description is that checkout events in the OrderCloud platform (such as estimate shipping, calculate order prices, or submit order) trigger webhook requests from the platform to configured REST api endpoints which contain customer-specific logic. This webhook delegation ensures a secure environment for handling sensitive data like 3rd party credentials and sensitive processes like tax calculation. The structure of the request bodies, response bodies and the recommended flow of events provide guide-rails for a successful checkout, while the ability to inject custom logic provides flexibility.

Historically, we've seen 3 categories of independent software vendors used in most checkout flows. In order of user interaction these are

  1. A shipping logistics provider that can give shipping cost estimates for different services based on the items being shipped to each unique destination. These estimates form a basis for what the purchaser will pay for various shipping services, though they may be marked up, marked down, or altered by any other logic. After checkout, a similar integration can be used in a warehouse app to purchase and print shipping labels, but the cost of actually purchasing shipping here is unrelated to the buyer's displayed shipping cost (except by the commercial needs of the business). EasyPost is an example of this type of vendor.
  2. A tax calculation provider. This is mainly relevant in the United States where the complexity of federal and state tax requires a dedicated software system for compliance. Since most vendors have API rate limiting, it is important to only calculate tax estimates after the user has entered checkout and not every time they modify their cart. Furthermore, tax must be calculated after shipping costs have been added to the order, since tax is applied to some shipping costs. Therefore, the tax cost must be displayed to the buyer after they select a shipping method and before they enter payment details. This is technically only an estimate until the order is submitted and the tax cost is finalized in the provider's system. Avalara is an example of this type of vendor.
  3. A payment processing provider. The most basic necessity is to accept credit and debit cards, after that a wide range of payment types exist that may add value: Paypal, digital wallets, bank transfers, etc. To avoid costly PCI compliance, sensitive card data (full card numbers and cvvs) can never be stored in, manipulated by, or even visible to the merchant's technology system. Users must enter card details into an Iframe provided by the processor, who will forward the merchant a card token or ID representing the full card data. Similarly, a shopper's saved credit cards need to be vaulted in the payment processor system. Stripe is an example of this type of vendor.

We focused on these 3 categories of integrations when we built the scaffolding starting project.

The scaffolding starter project

Open source on github we've published a complete API project built with .NET 6. It contains more than boilerplate, it also has all the server-side functionality you need for basic checkout, including integrations. Out of the box, the project uses EasyPost for shipping, Avalara for tax, and Stripe for payment processing. These default providers are leaders in their fields and partners with OrderCloud. Don't worry about lock-in though, we've explicitly made swapping providers very easy.

Our recommended approach to devops is to host this API using an Azure Web App and to deploy using Github Actions. This approach is easy because when you clone the source code, it will include this yml config which specifies a github action to build the API and deploy it to Azure. If you don't want to use these providers, you could deploy elsewhere by modifing the Github Action, and/or use a different deploy tool. If you are using these two, follow the steps below.

  • Create a new Web App Service in Azure.
  • Set environment variables on the app service by following this guide. You will need to get API keys from OrderCloud, EasyPost, Avalara, and Stripe. If you skip this step and deploy right away, your site will show an error "ASP.NET Core app failed to start".
  • Edit the .github/workflows/dotnet.yml file by setting the variables AZURE_APP_NAME and AZURE_SLOT_NAME based on what you created in Azure.
  • Download a Publish Profile for your web app from Azure and save it as a Github repository secret with name AZURE_WEBAPP_PUBLISH_PROFILE. Follow these steps. This will authenticate deployments.
  • Run the github action by pushing to the dev branch. Once it succeeds, visit your base URL, you should see a UI with route documentation for the API.
  • Finally, use the OrderCloud portal to create an Integration Event object with the CustomImplementationUrl set to your API and the HashKey set to your project's WebhookHashKey environment variable.
  • If you request the calculate order endpoint as a test, you should see a tax calculation coming from Avalara.

Here is a quick tour of some of the highlights of the scaffolding project code.

  • CheckoutController.cs defines the API routes that respond to OrderCloud integration events.
  • CheckoutCommand.cs contains the bulk of the logic for these responses.
  • Startup.cs injects the EasyPost, Avalara, and Stripe services.
  • AppSettings.cs shows the environment variables that are expected.
  • Xp.cs defines all the extended properties in this project.

Connect a custom checkout experience to pre-built integrations

Checkout Integration Stack

Switching providers by swapping out nuget packages

Looking through the code in CheckoutCommand.cs, you may notice that the logic does not depend directly on specific software vendors. Instead, behavior is abstracted out by interfaces like IShippingRateCalculator, ITaxCalculator, and IPaymentProcessor. Meanwhile, classes like EasyPostService implement those interfaces. This is an intentional strategy to make switching providers extremely easy.

Looking at Startup.cs, you may also notice that the classes EasyPostService, AvalaraService, and StripeService are not defined in this project, they are being imported from separate nuget packages. This is another important piece of our integration strategy - to publish pre-built integrations as code libraries. Combined with the interface definitions, this means that switching providers is as easy as swapping out a nuget package and changing dependency injection in Startup.cs.

In fact, to kickstart this effort with examples, we have published nuget package integrations with 3 providers in each of the 3 categories. Source code and readmes for these integrations can be found here.

VendorPackage NameNuget
StripeOrderCloud.Integrations.Payment.Stripe
BlueSnapOrderCloud.Integrations.Payment.BlueSnap
CardConnectOrderCloud.Integrations.Payment.CardConnect
EasyPostOrderCloud.Integrations.Shipping.EasyPost
FedexOrderCloud.Integrations.Shipping.Fedex
UPSOrderCloud.Integrations.Shipping.UPS
AvalaraOrderCloud.Integrations.Tax.Avalara
VertexOrderCloud.Integrations.Tax.Vertex
TaxJarOrderCloud.Integrations.Tax.TaxJar

Creating a custom integration

This strategy also lends itself to easily creating your own, totally custom implementations for the interfaces like ITaxCalculator and not having to modify the logic in the scaffolding project at all. You don't have to make these integrations public, but if you would like to add your integration to list above, we would love to have it. Take a look at this contributing integrations guide and feel free to start a conversation in a github issue.