Transitioning from Sitecore Experience Commerce to OrderCloud: Tax and Payments

Reading Time: 7 minutes

In this article, we will review and compare tax and payments between Sitecore Experience Commerce and OrderCloud to facilitate developers looking to transition from XC to OrderCloud as well as identify a path for migration of existing XC solutions to OrderCloud.

We will look at a high-level comparison of architecture, functionality, and data models, with greater focus on transitioning from Sitecore Experience Commerce, meaning identifying a close path to parity in OrderCloud, using the Habitat catalog and SXA Storefront.

Conceptual Architecture and Features

Tax

The Commerce Engine’s tax plugin is considered sample code that is sufficient enough to support basic tax requirements, however tax calculations will typically be customised to support the tax provider integrations that cater to tax laws for the countries and/or regions the storefront will be servicing.

The following list contains highlights of the tax plugin:

  • Tax is calculated as a cart adjustment when a fulfillment component is applied to the cart.
  • Tax is calculated as a cart line adjustment where a fullfillment component exists on the cart line.
  • XC waits for a cart to contain a fulfillment component before calculating taxes, as the delivery address is intended to identify applicable tax laws, but not catered for without customisation.
  • Sellable item pricing does not include tax.
  • Applying the tag taxexempt will omit sellable items from tax calculations.
  • Tax is calculated as a flat rate, i.e. tax is not dynamically calculated based on country/region tax laws.

The GlobalTaxPolicy provides the configuration properties of the sample tax plugin.

{
  "$type": "Sitecore.Commerce.Plugin.Tax.GlobalTaxPolicy, Sitecore.Commerce.Plugin.Tax",
  "DefaultCartTaxRate": 0.1,
  "DefaultItemTaxRate": 0.1
  "TaxExemptTagsEnabled":true,
  "TaxExemptTag":"taxexempt",
  "TaxCalculationEnabled": true, // Not hooked up
  "PriceIncudesTax": false, // Not hooked up
  "CalculateTaxBasedOn": "ShippingAddress", // Not hooked up
  "ShippingTaxClass": "CartItems", // Not hooked up
  "RoundAtSubTotal": false // Not hooked up
}

When it comes to tax in the OrderCloud platform, it is unopinionated on the methods of which to achieve tax calculations due to the numerous unique tax regulations around the world. Instead, OrderCloud allows the implementer to address tax calculations via the order calculate integration event, whether it be through integrations third party tax providers or complete custom implementation.

Figure 1 shows an overview of the order calculate integration event implementation in regards to calculating taxes. OrderCloud’s /calculate endpoint forwards the request along with the order worksheet to the middleware’s /ordercalculate endpoint. The middleware will then construct and return the OrderCalculateResponse model, containing the calculated TaxTotal, which OrderCloud then copy to the order’s TaxCost property. To track line item level taxes, calculated taxes can be stored in the OrderCalculateResponse‘s xp.

The TaxCost is used in OrderCloud’s calculations of the order Total, i.e. Total = Subtotal + TaxCost + ShippingCost - PromotionDiscount.

Figure 1: The order calculate integration event overview.

The calling system in figure 1 may be the client-side storefront or the middleware, depending on the implementation details.

Payments

Gift Cards vs Spending Accounts

XC provides a gift card payment type, which is integrated into the SXA storefront checkout to demonstrate end-to-end functionality of gift card payments. It is treated as a sample implementation as the functionality in the Commerce Engine is typically replaced with an integration to a gift card payment provider.

Reviewing OrderCloud’s supported payment types, spending accounts most closely resemble XC’s gift card implementation as it has the ability to track the available funds. One minor difference is that spending accounts are created under the context of a buyer and is therefore tied to the buyer users within that buyer, whereas gift cards in XC are globally accessible.

To differentiate spending accounts representing gift cards from other spending account types, xp can be leveraged to specify the type.

Figure 2: Gift card architecture comparison.

Global Payment Configuration

In an XC SXA implementation, payments are configured at a global level under sitecore/Commerce/Commerce Control Panel/Shared Settings, as depicted in figure 3. The configuration is split across Payment Option Types and Payment Options and linked via the PaymentOption Type property on the payment option item, however there really isn’t any discernable difference between the two within the SXA/Commerce Engine implementation.

Figure 3: Payment option to payment option type in the Sitecore Content Editor.

Instead of a BYO payment types approach, OrderCloud has defined three payment types, being purchase order, credit card, and spending account, with each type serving a different approach to handling order payments. For example, the credit card payment type would integrate with a payment service provider for perform transactions, while the spending account manages a balance maintained purely with OrderCloud, including adjusting the balance upon successful order submission.

Figure 4: Payment architecture overview.

As XC contains multiple Payment Option Types that could map to a single OrderCloud payment type, xp can be leveraged to represent multiple sub-types. The following table shows how XC’s Payment Option Types could map to Payment Types in OrderCloud.

Payment Option Type (XC)Payment Type (OrderCloud)xp (OrderCloud)
Card PaymentCredit Cardxp.Type: “Basic Card”
Federated PaymentCredit Cardxp.Type: “Braintree”
Gift Card PaymentSpending Accountxp.Type: “Gift Card”
Loyalty Card PaymentSpending Accountxp.Type: “Loyalty Card”

More information on payment types can be found in OrderCloud: Flexible Fulfillment > Apply Payments.

Storefront Payment Configuration

Payment options are also configured against an SXA storefront with a subset of those configured in the Shared Settings.

Figure 5: Storefront payment configuration.

While OrderCloud doesn’t have the context of storefronts, storefront-specific payment options will likely be a consideration for middleware’s logic for identifying applicable payments options.

Payment Components vs Payments

When it comes to the implementation, this is where the Commerce Engine plugins take the payment configurations and provide the functionality for the payment types. The sample Braintree plugin and the GiftCards plugin will add a FederatedPaymentComponent or a GiftCardComponent to the cart respectively, which will then be used to dictate how those payments are interacted with throughout the platform, during and post order creation.

OrderCloud uses the payments entity in a more concrete way, using the Type property to facilitate the payment behaviour. For example, selecting the spending account type will require the also specifying a spending account that is assigned to the buyer user via buyer or buyer user group assignment.

Figure 6: An order paid for using both a credit card and a gift card payment types.

Sales Activities vs Transactions

XC orders use sales activities to track the transaction activities of each order payment component while OrderCloud uses transactions for the same purpose.

Figure 7: Sales activities vs transaction architecture.

Functionality

The Storefront Checkout Billing Step

Turning our attention to the storefront functionality of the billing checkout steps from Carts to Unsubmitted Orders: Storefront User Journey, we will look at adding the email address and payment details to the cart/unsubmitted order, focusing on varying APIs of the two platforms.

Figure 8: The checkout billing aspects of the storefront user journey.

Viewing the interaction diagram in figure 9, the SXA storefront utilises the BillingDataJsonResult to provide the necessary data to render and facilitate payment option logic in the storefront. Once the user has submitted the payment details, all payment data is then sent to the Commerce Engine together to be added to the cart.

A few notes on the payment functionality:

  • Payments are only supported at the cart-level.
  • The email address is collected per order as the user may wish not to use the email address associated to their account (for registered users). This email is typically used for communications to the customer, such as email confirmation, invoicing, shipments, etc.
  • XC has logic to prevent a gift card sellable item to be purchased with a gift card payment.
Figure 9: The billing checkout step of the SXA storefront.

To replicate similar behaviour in an OrderCloud storefront implementation, figure 10 provides an approach to the billing checkout step.

  1. The /paymentoptions middleware endpoint retrieves the applicable payment options for the order, dependent on the storefront and business requirements.
  2. The email address is PATCHed to the order xp for specific order context.
  3. All payments can be added to the order via ../payments endpoint; the data sent may differ based on payment type.
Figure 10: An example approach for the delivery checkout step in an OrderCloud storefront.

Data Mapping

With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.

In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.

OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.

Spending Accounts

The following mapping shows how XC’s default implementation of gift cards can be translated into OrderCloud using spending accounts.

OC PropertyData TypeRequiredXC Entity/ComponentXC PropertyData TypeNotes
buyerIDstringYesN/AN/AN/A
IDstringNoGiftCardGiftCardCodestringUse format “GiftCard-<GiftCardCode>”
NamestringYesGiftCardNamestring
BalancedecimalYesGiftCardBalance.Amountdecimal
AllowAsPaymentMethodbooleanNoN/AN/AN/ASet to true.
RedemptionCodestringNoGiftCardGiftCardCodestring
StartDateDateTimeOffsetNoGiftCardActivationDateDateTimeOffset
EndDateDateTimeOffsetNoN/AN/AN/A
xpobjectNoN/AN/AN/A
xp.TypestringNoN/AN/AN/ASet to "GiftCard".
xp.InitialAmountdecimalNoGiftCardOriginalAmount.Amountdecimal
xp.CurrencystringNoGiftCardOriginalAmount.CurrencyCodestringRecommended for handling multi-currency validation.

References

Continue the Series

  1. Transitioning from Sitecore Experience Commerce to OrderCloud: Customers to Buyer Users
  2. Transitioning from Sitecore Experience Commerce to OrderCloud: Customers and Buyers – API Access
  3. Transitioning from Sitecore Experience Commerce to OrderCloud: Catalogs and Categories
  4. Transitioning from Sitecore Experience Commerce to OrderCloud: Sellable Items To Products
  5. Transitioning from Sitecore Experience Commerce to OrderCloud: Inventory and Pricing
  6. Transitioning from Sitecore Experience Commerce to OrderCloud: Carts to Unsubmitted Orders and Carts
  7. Transitioning from Sitecore Experience Commerce to OrderCloud: Fulfillments to Shipping
  8. Transitioning from Sitecore Experience Commerce to OrderCloud: Tax and Payments
  9. Transitioning from Sitecore Experience Commerce to OrderCloud: Orders
  10. Transitioning from Sitecore Experience Commerce to OrderCloud: Order Workflow and Minions
  11. Transitioning from Sitecore Experience Commerce to OrderCloud: Promotions

Transitioning from Sitecore Experience Commerce to OrderCloud: Fulfillments to Shipping

Reading Time: 6 minutes

In this article, we will review and compare Sitecore Experience Commerce fulfillments and OrderCloud shipping to facilitate developers looking to transition from XC to OrderCloud as well as identify a path for migration of existing XC solutions to OrderCloud.

We will look at a high-level comparison of architecture, functionality, and data models, with greater focus on transitioning from Sitecore Experience Commerce, meaning identifying a close path to parity in OrderCloud, using the Habitat catalog and SXA Storefront.

Conceptual Architecture and Features

Fulfillment Configuration

Global Fulfillment Configuration

In an XC SXA implementation, fulfillments are configured at a global level under sitecore/Commerce/Commerce Control Panel/Shared Settings, as depicted in figure 1. The configuration is split across Fulfillment Option Types and Fulfillment Options and linked via the Fulfillment Option Type property on the fulfillment option item.

Figure 1: Fulfillment option to fulfillment option type in the Sitecore Content Editor.

This tiered architecture can be a little confusing, so each tier can be thought of as follows:

  • Fulfillment Option Type: The high-level approach in which the order will be fulfilled, e.g. Deliver to Address, Digital Delivery, Pick Up From Store, etc.
  • Fulfillment Option: The collection of methods for the type of fulfillment, e.g. Ship items. This could also be as considered a shipping vendor, such as DHL or FedEx.
  • Fulfillment Method: The specific method of delivery, which will be assigned to the order and may be accompanied by a fee.

The fulfillment fees associated to each fulfillment method are then configured in the Commerce Engine environment configuration under GlobalPhysicalFulfillmentPolicy.FulfillmentFees, which also supports multi-currency fees per fulfillment method.

"$type": "Sitecore.Commerce.Plugin.Fulfillment.GlobalPhysicalFulfillmentPolicy, Sitecore.Commerce.Plugin.Fulfillment",
"FulfillmentFees": {
  "$type": "System.Collections.Generic.List`1[[Sitecore.Commerce.Plugin.Fulfillment.FulfillmentFee, Sitecore.Commerce.Plugin.Fulfillment]], mscorlib",
  "$values": [
    {
      "$type": "Sitecore.Commerce.Plugin.Fulfillment.FulfillmentFee, Sitecore.Commerce.Plugin.Fulfillment",
      "Fee": {
        "$type": "Sitecore.Commerce.Core.Money, Sitecore.Commerce.Core",
        "CurrencyCode": "USD",
        "Amount": 15.0
      },
      "Name": "Ground",
      "Policies": {
        "$type": "System.Collections.Generic.List`1[[Sitecore.Commerce.Core.Policy, Sitecore.Commerce.Core]], mscorlib",
        "$values": []
      }
    },
    ...
}

Bringing this together into a friendly-ish diagram view, figure 2 shows the representation of fulfillment architecture across the Sitecore and Commerce Engine platforms.

Figure 2: Fulfillment architecture overview.

In OrderCloud, there are no fulfillment object equivalents to house and support fulfillment configurations. Instead, OrderCloud relies on the middleware application to provide its business logic, integrations, calculations, etc. to address the unique shipping business requirements for the OrderCloud storefront solution, which we cover in greater detail in Ship Estimates.

For now, figure 2 may be used as a reference point when evaluating how fulfillment/shipping data could be designed if business requirements identify that the custom middleware solution should persist shipping configuration data to a custom database.

Storefront Fulfillment Configuration

One last configuration requirement for an SXA storefront is to select the fulfillment options that will be applicable for that particular storefront.

Figure 3: Storefront fulfillment configuration.

Once again, OrderCloud lets the middleware manage the storefront specific shipping logic and calculations, which is covered in Ship Estimates, so this may just be a consideration for your custom middleware implementation.

Functionality

Ship Estimates

While OrderCloud depends on the middleware application to drive shipping data and behaviour, it does not leave the implementer high and dry. The order checkout integration event sees the /estimateshipping endpoint trigger the /ShippingRates endpoint of the middleware, handing it the order worksheet for context. The middleware can then execute its custom logic, which may include integrations to shipping providers, external systems, etc., to determine ship estimates.

The calling system in figure 4 may be the client-side storefront or the middleware, depending on the implementation details.

Figure 4: The order checkout integration event interaction overview.

The resulting ShipEstimateResponse model from the middleware’s /ShippingRates endpoint will be expected to consist of a breakdown of shipping estimates, representing a subset of line items and the shipping methods and costs that are available for the order.

In comparison to the SXA storefront, the ShipEstimateResponse model is basically the equivalent to the DeliveryDataJsonResult application model, which contains the ShippingOptions at the order and line levels.

Figure 5: The high-level view of ship estimates in a ShipEstimateResponse model.

For the integration event to trigger, the order checkout integration event will need to be configured with the middleware’s publicly accessible domain assigned to the CustomImplementationUrl of the integration event, and integration event’s ID assigned to the OrderCheckoutIntegrationEventID of the API Client.

The API Client used for the integration event will likely be the same client used for the Anonymous and Registered Users.

Figure 6: OrderCheckout integration event assignment to API client example.

The Storefront Checkout Delivery Step

Turning our attention to the storefront functionality of the delivery checkout steps from Carts to Unsubmitted Orders: Storefront User Journey, we will look at adding fulfillment details to the cart/unsubmitted order, focusing on varying APIs of the two platforms.

Figure 7: The fulfillment focused view of the storefront user journey.

Viewing the interaction diagram in figure 8, the SXA storefront utilises the DeliveryDataJsonResult to provide the necessary data to render and drive fulfillment functionality. Once the user has submitted the fulfillment details, all fulfillment data is then sent to the Commerce Engine together to be added to the cart.

A few notes on the fulfillment functionality:

  • Fulfillments can be set against the cart as a whole or for each and every cart line.
  • As sellable items can be classified as either a physical or digital item, XC contains logic to tie these to varying fulfillment types, which will collect different data relevant to its classification. For example, physical items require a physical fullfillment, consisting of a physical delivery address and the fulfillment method id, while digital items require digital fulfillments, consisting of recipient email address, gifting message and the fulfillment method id.
Figure 8: The delivery checkout step of the SXA storefront.

To replicate similar behaviour in an OrderCloud storefront implementation, figure 9 provides an approach to the delivery checkout step, which intentionally deviates from the SXA storefront functionality to demonstrate a more granular approach to building up the order using the OrderCloud API.

  1. The /shippingoptions middleware endpoint retrieves the available shipping options for the order, such as delivery or click and collect, with order-level or line-level shipping options, which will then drive storefront functionality for the various data collection methods for the respective shipping option selected.
  2. Fleshing out the approach for physical delivery shipping options, shipping addresses can be input manually or by referencing an existing address assigned to the user.
  3. The ../estimateshipping integration event can leverage the ShippingOption set on the order xp as well as the shipping details, such as shipping addresses, can be used for calculating shipping estimates by our middleware and third party integrations.
  4. The ../shipmethods sets the shipping methods for the order or line items.
Figure 9: An example approach for the delivery checkout step in an OrderCloud storefront.

References

Continue the Series

  1. Transitioning from Sitecore Experience Commerce to OrderCloud: Customers to Buyer Users
  2. Transitioning from Sitecore Experience Commerce to OrderCloud: Customers and Buyers – API Access
  3. Transitioning from Sitecore Experience Commerce to OrderCloud: Catalogs and Categories
  4. Transitioning from Sitecore Experience Commerce to OrderCloud: Sellable Items To Products
  5. Transitioning from Sitecore Experience Commerce to OrderCloud: Inventory and Pricing
  6. Transitioning from Sitecore Experience Commerce to OrderCloud: Carts to Unsubmitted Orders and Carts
  7. Transitioning from Sitecore Experience Commerce to OrderCloud: Fulfillments to Shipping
  8. Transitioning from Sitecore Experience Commerce to OrderCloud: Tax and Payments
  9. Transitioning from Sitecore Experience Commerce to OrderCloud: Orders
  10. Transitioning from Sitecore Experience Commerce to OrderCloud: Order Workflow and Minions
  11. Transitioning from Sitecore Experience Commerce to OrderCloud: Promotions