If you sell on more than one channel — and almost every brand of any meaningful size does — you already know this picture. The Magento store emits an order in one JSON shape. The Shopify store emits an order in a second shape. The BigCommerce store emits an order in a third. The fulfillment system, the warehouse, the customer-service portal, the support agent’s LLM, and the loyalty platform downstream of all that do not care which storefront the order originated on. They just want to read the order. One shape. One URL. One auth. One trace.
What every team does instead is write three translators. One per storefront. None of them shared. None of them versioned together. All of them quietly drifting out of sync every time Shopify ships an Orders API minor version or Magento changes how items carries a configurable product. The cost is not the translator. The cost is the drift — the slow accumulation of three slightly different views of what an “order” is across the enterprise.
This is a textbook case for a Naftiko capability.
What Naftiko is
Naftiko is an open framework for declaring an API integration once, in a single YAML file, and running it as a versioned, observable capability. The YAML names what the capability consumes — the upstream APIs in whatever real shape they ship today — and what it exposes — clean, governed surfaces on top of those upstreams. REST endpoints for humans and dashboards. MCP tools for AI agents. From the same spec, with the same auth, the same transform, the same observability.
The point is the decoupling. The storefronts keep shipping whatever order shape they ship. The downstream systems keep reading whatever order shape they want to read. The capability owns the seam in between. When Shopify renames a field next quarter, you change one transform. You do not chase fifteen consumers.
Why TMF622 v5 for ecommerce orders
TM Forum’s TMF622 Product Ordering Management API v5.0 is the vendor-neutral REST + JSON vocabulary for “an order.” It was born in telecom, but the object it describes is general — productOrderItem for the lines, relatedParty for the buyer and seller, requestedStartDate for the placement timestamp, state for the lifecycle, itemPrice and orderTotalPrice for the money, payment and billingAccount for the financial side, note for the operator comments. Every one of those concepts exists in a Magento salesOrder, a Shopify Order, and a BigCommerce v2/orders response. They just live under different field names, in different envelopes, with different conventions for how a discount or a tax line shows up.
TMF622 is the place where those three views become one view. If your warehouse already speaks TMF622, your billing system already speaks TMF622, your support portal already speaks TMF622, and your AI assistant already speaks TMF622, then there is exactly one thing left to do — wrap the three storefronts in a capability that hands back TMF622 on every read.
What the capability looks like
The shape is repetitive on purpose. Three consume namespaces — one for Magento, one for Shopify, one for BigCommerce — each authenticating the way that platform expects, each pointing at the platform’s native order-by-ID endpoint. One exposes block for MCP. One exposes block for REST. Three transforms, one per upstream, each pinned to a JSONata file in the repo. The transforms are the place where storefront semantics get reconciled into TMF622 v5.
naftiko: "1.0.0-alpha2"
info:
title: Manage Storefront Orders — TMF622
description: >
Wraps Magento, Shopify, and BigCommerce order APIs and exposes every
order as a TMF622 v5 ProductOrder via REST and MCP. One capability,
three storefronts, one contract.
binds:
- namespace: env
keys:
MAGENTO_TOKEN: MAGENTO_TOKEN
SHOPIFY_TOKEN: SHOPIFY_TOKEN
BIGCOMMERCE_TOKEN: BIGCOMMERCE_TOKEN
capability:
consumes:
- namespace: magento
type: http
baseUri: "https://store.example.com"
description: "Magento 2 REST order resource."
authentication:
type: bearer
token: "{{MAGENTO_TOKEN}}"
resources:
- name: order
path: "/rest/V1/orders/{{order_id}}"
operations:
- name: get-magento-order
method: GET
inputParameters:
- name: order_id
in: path
required: true
- namespace: shopify
type: http
baseUri: "https://shop.example.myshopify.com"
description: "Shopify Admin REST order resource."
authentication:
type: header
name: X-Shopify-Access-Token
value: "{{SHOPIFY_TOKEN}}"
resources:
- name: order
path: "/admin/api/2025-01/orders/{{order_id}}.json"
operations:
- name: get-shopify-order
method: GET
inputParameters:
- name: order_id
in: path
required: true
- namespace: bigcommerce
type: http
baseUri: "https://api.bigcommerce.com"
description: "BigCommerce v2 order resource."
authentication:
type: header
name: X-Auth-Token
value: "{{BIGCOMMERCE_TOKEN}}"
resources:
- name: order
path: "/stores/{{store_hash}}/v2/orders/{{order_id}}"
operations:
- name: get-bigcommerce-order
method: GET
inputParameters:
- name: store_hash
in: path
required: true
- name: order_id
in: path
required: true
exposes:
- type: mcp
address: "0.0.0.0"
port: 3063
namespace: manage-storefront-orders
description: >
TMF622 v5 ProductOrder reader for Magento, Shopify, and
BigCommerce. One tool per storefront, identical output shape.
tools:
- name: get-magento-order-tmf622
description: "Fetch a Magento order by ID and return as a TMF622 v5 ProductOrder."
hints:
readOnly: true
inputParameters:
- name: order_id
type: string
required: true
call: magento.get-magento-order
transform:
engine: jsonata
template: "transforms/magento-to-tmf622.jsonata"
- name: get-shopify-order-tmf622
description: "Fetch a Shopify order by ID and return as a TMF622 v5 ProductOrder."
hints:
readOnly: true
inputParameters:
- name: order_id
type: string
required: true
call: shopify.get-shopify-order
transform:
engine: jsonata
template: "transforms/shopify-to-tmf622.jsonata"
- name: get-bigcommerce-order-tmf622
description: "Fetch a BigCommerce order by store hash and order ID and return as a TMF622 v5 ProductOrder."
hints:
readOnly: true
inputParameters:
- name: store_hash
type: string
required: true
- name: order_id
type: string
required: true
call: bigcommerce.get-bigcommerce-order
transform:
engine: jsonata
template: "transforms/bigcommerce-to-tmf622.jsonata"
- type: rest
address: "0.0.0.0"
port: 8093
namespace: manage-storefront-orders-rest
resources:
- name: magento-order
path: "/productOrder/magento/{order_id}"
operations:
- name: get-magento-order-tmf622
method: GET
inputParameters:
- name: order_id
in: path
required: true
call: magento.get-magento-order
transform:
engine: jsonata
template: "transforms/magento-to-tmf622.jsonata"
- name: shopify-order
path: "/productOrder/shopify/{order_id}"
operations:
- name: get-shopify-order-tmf622
method: GET
inputParameters:
- name: order_id
in: path
required: true
call: shopify.get-shopify-order
transform:
engine: jsonata
template: "transforms/shopify-to-tmf622.jsonata"
- name: bigcommerce-order
path: "/productOrder/bigcommerce/{store_hash}/{order_id}"
operations:
- name: get-bigcommerce-order-tmf622
method: GET
inputParameters:
- name: store_hash
in: path
required: true
- name: order_id
in: path
required: true
call: bigcommerce.get-bigcommerce-order
transform:
engine: jsonata
template: "transforms/bigcommerce-to-tmf622.jsonata"
Each consumes block names the storefront’s real native order endpoint. Each transform is a single JSONata file checked into the same repo as the capability. The mapping is explicit, versioned, and reviewable — line_items[*] becomes productOrderItem[*], the storefront’s financial_status plus fulfillment_status becomes a single TMF622 state, the storefront’s customer becomes relatedParty with role customer, the storefront’s totals become orderTotalPrice with itemPrice on each line. Three storefronts. One contract. The day Shopify ships a new API version, you bump the consume path, you adjust the JSONata where the shape moved, and every downstream caller — including the agent — keeps working without knowing anything happened.
Traceable, observable, integrated into AI
The same three properties that made the cXML and Hybris/Commerce Cloud capabilities worth standing up apply here, and in a multi-storefront brand they hit even harder.
Traceable. Every order read — Magento, Shopify, BigCommerce — flows through one engine. The trace tells you which storefront the order came from, which transform version produced the TMF622 output, which auth credential was used, how long the upstream took. When customer service asks “is order 9001 the same in our system as it is in Shopify?” the answer is a query against one trace store, not a five-team escalation.
Observable. One capability, three upstreams, three error-rate signals. If Shopify rate-limits you at noon, you see it in one dashboard. If BigCommerce returns an unexpected currency code on a tax line, the validation failure shows up in the capability’s metrics — not buried in a fulfillment retry queue. The capability becomes the early-warning system for storefront drift.
Integrated into AI. The same MCP tools that hand TMF622 ProductOrders to your warehouse are the tools a customer-service agent’s LLM uses when a shopper says “where is my order from the Magento site?” The agent does not know — and does not need to know — that one storefront calls it entity_id and another calls it id. It calls get-magento-order-tmf622 and reads productOrderItem[*].state. The minute you add a fourth storefront — Salesforce Commerce Cloud, Shopware, Centra, whatever shows up next — you add a fourth consume block and a fourth transform. The agent and the warehouse keep working. They never see the new platform’s wire format. They see TMF622.
The bigger move
The storefronts are doing their job. The Magento order shape, the Shopify order shape, and the BigCommerce order shape are each well-considered designs for the workload that platform was built for. The problem is never the platform. The problem is the seam — the place where three platform-specific views have to become one enterprise-wide view of “an order.” Today that seam lives in fifteen translators across five teams, and it costs you the moment any of the three storefronts ships a change.
A Naftiko capability moves that seam into one file, behind one engine, with one observable surface, and a built-in MCP endpoint your AI stack can use the day you deploy it. That is what it looks like to wrap three storefronts behind one TMF622 v5 contract without rewriting any of them. And it is the cleanest place to land before the fourth storefront, the fifth marketplace, and the agent your CFO asked about last week show up at the door.