How We Built a Custom AXS Payment Gateway for Dynamics 365 Commerce

If you've ever tried to connect a regional payment provider to Dynamics 365 Commerce, you've probably hit the same wall we did: Microsoft's payment connector framework only covers a fixed list of providers, and if yours isn't on that list, none of the built-in plumbing helps you. The storefront can't just be pointed at a new gateway and left to figure it out.

That's exactly the wall a client of ours hit with AXS, one of Singapore's most widely used payment methods. Their customers used AXS everywhere else. Their Dynamics 365 Commerce storefront couldn't take it, and every checkout that defaulted to card was a checkout at risk of being abandoned.

Here's how we built the integration, the four mistakes that quietly sink projects like this one, and the questions worth asking before you build yours.

The real requirement wasn't "accept AXS"

On paper, the ask was simple: let customers pay with AXS, and have the order show up in Dynamics 365 Finance and Operations exactly like every other order.

That second half is where the actual work lives. An order has to reach F&O with the correct amount, a payment record, the customer's details, and the line items — and it has to be reconcilable afterward. A payment that succeeds without producing an order is worse than a payment that fails outright, because now the customer has been charged and nobody knows it.

To make it more interesting, this wasn't one storefront. It was three storefronts, in two languages, each needing customers routed back to their own site after payment. Whatever we built had to hold up across all six combinations, not just the happy path.

Why we didn't just bolt AXS onto the storefront

The tempting shortcut is to do it all in the storefront: add a payment button, call the gateway from the browser, redirect the customer, done. It's tempting because it's fast. It also fails on two counts.

Security. AXS authenticates callers with a client ID and secret, and every request is encrypted as a JWE token. Anything sitting in front-end code is readable by anyone who opens developer tools — so putting gateway credentials in the storefront hands them to the public.

Trust. If the browser tells the server how much to charge, then anyone who can edit that request can pay a dollar for a thousand-dollar order.

Think of it as the difference between a shop with a cash register behind the counter versus one where the till sits on the sidewalk. So we built a small middleware service on Azure Functions that sits between the storefront and AXS. The credentials live there and nowhere else. The storefront never talks to AXS directly and never learns anything sensitive.

Not sure if a requirement like this needs custom development at all? Our guide on customization versus configuration in Dynamics 365 is a good place to start.

How the payment actually flows

Here's the shape of it: the storefront and AXS never talk to each other directly. Everything routes through the middleware, which is the only place that holds the AXS secret and the only place that ever computes a real amount.

![Diagram showing the AXS payment flow: the storefront and AXS never communicate directly — every request routes through a middleware service on Azure Functions, which holds the AXS credentials, computes the real cart total, verifies the payment outcome with AXS, and only then creates the order in Dynamics 365 F&O.](./Infographic - AXS Payment.png)

Once the middleware was in place, the checkout flow broke down into five steps:

  1. The customer chooses AXS at checkout. The storefront asks the middleware for a payment link, sending only the cart ID, storefront, and language — never an amount.
  2. Middleware builds the payment request. It reads the real cart total from Commerce server-side, encrypts it into a JWE token with the AXS client secret, and returns a hosted checkout URL.
  3. The customer pays on AXS's hosted page. Card details never touch our storefront or our systems, which keeps the integration well clear of card-data compliance scope.
  4. AXS returns the customer to the order confirmation page, carrying a reference that identifies the payment.
  5. The confirmation page verifies the payment with AXS through the middleware — and only then creates the order in F&O and clears the cart.

Step five is the one that matters most, and it's also the one most integrations get wrong.

Four problems most integrations like this get wrong

1. The redirect is not proof of payment

It's natural to treat a customer landing back on your site as proof the payment went through. It isn't. Customers arrive before the gateway has finished settling. They close the tab after paying and never come back. Someone can type the confirmation URL directly into a browser. In every case, the redirect tells you where the browser went — not what happened to the money.

The only authoritative answer comes from AXS itself, through its webhook or a direct transaction query. Our confirmation page asks and waits for a definite answer before creating an order. That one decision eliminates both expensive failure modes: an order created for a payment that never cleared, and a payment taken with no order behind it.

2. "We can't tell" is not the same as "not paid"

When the middleware can't reach AXS — a timeout, a maintenance window — the honest answer is unknown, not failed. Code that treats "can't tell" as "declined" will eventually throw away a real payment and tell a customer their order didn't go through while their card was charged.

That's why the integration handles three outcomes, not two:

![Flowchart showing the confirmation page asking AXS whether a payment was made, branching into three outcomes: Paid, which creates the order in F&O; Declined, which returns the customer to try again; and Unconfirmed, where no order is created and the payment reference is kept for finance to reconcile.](./Infographic - Outcomes.png)

Outcome What it means What happens
Paid AXS confirms the payment cleared Order is created in F&O
Declined Card was rejected, no money moved Customer is returned to try again
Unconfirmed AXS couldn't be reached; status unknown No order created, no failure claimed — reference is preserved for finance to reconcile

That third row is the one most teams skip. It's also the one that protects the business.

3. Three storefronts, two languages, one payment account

AXS accepts exactly one return URL per payment. With three storefronts each running in English and Chinese, that's six possible destinations — and sending a paying customer to the wrong one isn't a small bug.

Configuring the return URL per site in the CMS works fine until someone mistypes a field. Instead, the storefront tells the middleware only who it is — which entity, which storefront, which language — and the middleware resolves the destination from its own settings. Nobody can misroute a payment through a content edit, and nobody holding just the API key can nominate an arbitrary destination either.

4. The platform has opinions of its own

Two Dynamics 365 Commerce behaviors shaped this build, and they're worth knowing before you scope anything similar:

  • Keyed-in prices are restricted. Overriding a line price may be refused outright depending on product setup and channel type — online store channels are far more locked down than point-of-sale.
  • Cart quantity limits are real, and low. Ten per line by default, and hitting it surfaces as an opaque status rather than a clear error message.

Neither is a defect. Both cost a sprint if you discover them during UAT instead of during design.

Building a payment or system integration for Dynamics 365? See our Integration Services.

What the business ended up with

Customers pay the way they already prefer. Orders land in F&O with the right amount and a payment record, ready for reconciliation. Gateway credentials sit in exactly one place, and that place can be rotated without touching the storefront. Adding a fourth storefront or a third language is now a configuration change, not a rebuild.

And the failure cases are boring — which, for anything involving payments, is the highest compliment there is. A declined card just returns the customer to try again. An unreachable gateway holds the order instead of losing it.

Thinking about a similar integration? Start with these five questions

If your payment provider has no Dynamics 365 connector, the build itself is entirely doable. The risk isn't the code — it's the handful of states nobody thinks about until the first one costs real money. Before you write a line of code, get answers to:

  1. Where does the authoritative "was this paid?" answer come from, and what happens when you can't reach it?
  2. Who computes the amount — and can a browser influence it?
  3. What happens to a customer who pays and never returns to the site?
  4. How many storefronts and languages will this need to serve two years from now?
  5. Which platform rules — price overrides, quantity limits, channel type — does the requirement quietly depend on?

Get it right the first time

We build custom payment and system integrations for Dynamics 365 Commerce, including providers with no certified connector. If you already have an integration scoped — or want a second opinion before committing — take a look at our Dynamics 365 integration services, or book a free consultation and we'll walk through these five questions against your setup.

DynamicDay Technologies is a Microsoft-certified Dynamics 365 partner with 10+ years of experience and 35+ projects delivered across eCommerce, retail, manufacturing, startups, and professional services.

author-profile

Kishan Suthar

Functional Consultant

Kishan is a skilled Technical Consultant at Dynamic Day Technologies, specializing in MS Dynamics. With extensive expertise in streamlining business processes and providing tailored Microsoft solutions, Kishan is committed to helping organizations optimize their operations through innovative and effective ERP systems.

Let’s talk something great together

INDIA

A 1116 Sidhhi Vinayak Business Tower Nr. Adani School Makarba, Ahmedabad, Gujarat 380051


Follow us

Collaborate with us