Skip to Content

One Addon, Many Gateways: A Reusable POS Payment Layer for Odoo (WeChat Pay + Alipay in China)

August 22, 2026 by
One Addon, Many Gateways: A Reusable POS Payment Layer for Odoo (WeChat Pay + Alipay in China)
Majorbird

One Addon, Many Gateways: A Reusable POS Payment Layer for Odoo (WeChat Pay + Alipay in China)

一套支付层,多个通道:微信支付与支付宝接入Odoo收银台

Un solo addon, muchas pasarelas: una capa de pagos POS reutilizable para Odoo (WeChat Pay + Alipay en China)

Un addon, toutes les passerelles : une couche de paiement POS réutilisable pour Odoo (WeChat Pay + Alipay en Chine)

إضافة واحدة، بوابات متعددة: طبقة دفع لنقاط البيع قابلة لإعادة الاستخدام في Odoo (WeChat Pay وAlipay في الصين)

Một addon, nhiều cổng thanh toán: lớp tích hợp thanh toán POS tái sử dụng cho Odoo với WeChat Pay + Alipay tại Trung Quốc

One Payment Layer, Many Gateways: WeChat Pay and Alipay at the Odoo POS

If you run retail in China, the payment question is not really a question. Customers pay with WeChat Pay and Alipay, at the counter, by app. The interesting part is what sits behind that tap, and whether the way you connect it to Odoo will still be standing after your third store, your second payment provider, and your next Odoo upgrade.

Most first attempts do not survive that far. Here is why, and what a version that lasts actually looks like.

The one-off that does not scale

A common first cut is a low-code workflow that signs the request and calls the gateway. It demos fine. It also tends to rot for reasons that have nothing to do with payments and everything to do with engineering discipline. The merchant signing secret ends up sitting inline in the workflow. The runtime updates itself with nothing pinned, so a change you did not make can break production. The awkward moment where a customer is still keying a PIN gets handled with a tangle of branch steps and no durable record of what happened. Retries and reconciliation are hard to express reliably. And every new customer means rebuilding the whole flow by hand, with nothing unit tested and no state you can carry forward.

None of that is a payments problem. It is a "we built a product out of a prototype" problem, and it is the exact trap Majorbird set out to remove.

One contract, many gateways

The design principle is simple: the Odoo POS should speak one neutral language, no matter which provider is on the other end. So the point-of-sale side talks to a single HTTP contract with a small, fixed vocabulary: pay (order reference, amount, the scanned code, the target gateway), query or poll, refund, cancel, plus a raw proxy as an escape hatch for the unusual case.

Payment status is normalized into one set of states that every gateway maps onto: created, paying, paid or failed or cancelled, then refunding, refunded or partially refunded. The messy provider-specific detail, the signing algorithm, the field names, how amounts are formatted, which endpoint to hit, is isolated inside a per-gateway module and kept behind a registry.

That is what makes "one addon, many gateways" real rather than a slogan. The Odoo payment method only stores an endpoint and which gateway to use. Adding a new provider is one new module plus one line in the registry. The POS addon itself does not change. No module rework, no forked copies, no per-client special build.

Why China POS payments are their own problem

It is worth being honest that this is genuinely harder than wiring up a Western card gateway, and for reasons that surprise people.

The flow is inverted. Instead of the customer scanning a merchant QR code, the cashier scans the code shown in the customer's app. This is the customer-presented barcode, or micropay, flow.

The answer is often not immediate. A charge may clear instantly, or it may sit while the customer keys a PIN, reported as a "user paying" style status. There is no synchronous yes or no. You have to poll until it resolves. Just as important, ambiguous replies such as "system busy" or "user still paying" must never be treated as failure, because retrying a charge that actually succeeded is how you double-charge a customer. A payment left stuck in "paying" past a timeout has to be automatically reversed so money is never stranded.

Reconciliation needs your own ledger. The gateways answer one transaction at a time; there is no "list today's sales" to lean on, so the system keeps its own durable record and reconciles against it. And behind the single contract the two providers are different worlds: WeChat Pay v2 uses XML with MD5 signing and a client TLS certificate for refunds, while Alipay uses JSON with RSA2. The whole point of the neutral contract is that the cashier, and the Odoo POS, never have to know any of that.

From hack to service

Turning that into something you can run for many merchants is mostly ordinary software discipline applied properly. The gateway runs as one versioned service with immutable image tags, so what you tested is what ships. Configuration is over code: credentials and gateways come from the environment, nothing sensitive is hardcoded, and secrets are pulled from a vault at startup rather than baked into the artifact. The signing logic is unit tested. There is a durable ledger, a background reconciliation safety net for the stuck-payment case, an operations dashboard, and self-verifying backups. Onboarding a new customer becomes a checklist, not a rebuild.

What it means at the counter

For a retailer the result is quiet, which is the goal. You take WeChat Pay and Alipay directly at the Odoo point of sale, with real-time confirmation and refunds, and the payments reconcile into Odoo automatically instead of someone matching payment-app totals to sales by hand at the end of the day. Adding a new provider does not mean a custom rebuild. Multi-store and multi-customer rollout is faster, maintenance is lower, and the payment log is auditable end to end.

Today the POS addon targets Odoo 18 Enterprise POS, while the gateway service itself is independent of the Odoo version. A port to Odoo 19 is planned.

Our take

China payment rails are not the hard part; almost anyone can make a single charge go through once. The hard part is doing it the same way for every store, every provider, and every upgrade, without a rebuild each time and without a double-charge waiting to happen. That is the difference between an integration that works in a demo and one that works in production, and it is the same diagnose-before-build discipline Majorbird brings to the rest of an Odoo implementation.

If you are weighing how to take WeChat Pay and Alipay at your Odoo POS, or you are already nursing a one-off integration that is starting to cost you, that is a good conversation to have before it breaks at the worst possible moment. Talk it through with the Majorbird team at odoo@majorbird.com or www.majorbird.com.

in News
Ninety Percent Configuration, One Front Door Hand-Coded