POST/order
Environmentv1 · en
Sandbox
https://dev-gw.metfone.com.kh/tms-partner/api/v1
Production
https://gw-express.metfone.com.kh/tms-partner/api/v1
API version
v1
API language
en
On this page
POST /tms-partner/api/v1/order

Usage and important notes

Send top-level moneyCollection on this request. Pricing and creation are independent. If it is absent or null, the recorded response cod becomes 0 even if the quote included COD. Negative COD produces INVALID_PRICE. Do not send the obsolete request field cod: it is not read. Compare the returned cod against your intended collection amount.

Provide sender and recipient names, international-format phones, and addresses. The source describes seller as the fallback when shipper is empty, buyer when consignee is empty, and returnContact defaulting to shipper. Each parcel needs weight/weightUnit, dimensions, type, and at least one item with a name and positive weight. measurementUnit defaults to the literal CENTIMET. Only payerType=CONSIGNEE or SELLER is accepted; other values produce PAYER_INVALID.

vas containing GTN/NTN/VTT may override the submitted receiveType. deliveryPostcode is required unless vas contains GTN or VTT; with GTN it is forced to null. Source names and sender/receiver service labels are retained rather than reinterpreted.

txId supports partner-side reconciliation/deduplication; the source does not establish server-enforced idempotency, a deduplication window, or safe repeat-create behavior. Retain the initial response and reconcile an ambiguous timeout before submitting another create. Do not assume a repeated txId prevents a duplicate shipment.

Response: save id for label creation, status lookup, and cancellation. Creation uses textual status=CONFIRMED and statusName; status lookup/webhooks use numeric codes. totalFees includes VAT after discounts and totalTax is VAT. estDeliveryTime.date is DD/MM/YYYY. partnerInfo uses snake_case keys inside an otherwise camelCase order response. Addresses are reduced to components and formattedAddress; no address-level id/code/geometry or component typeName/typeLabel is echoed.

Authentication headers

Header Requirement Value / meaning
X-Api-Token Required ${API_TOKEN}: environment-specific token issued by TMS
X-Client-Source Required ${PARTNER_CODE}: partner code paired with the token
Content-Type With a JSON body application/json
Accept Required by source application/json
Accept-Language Optional vn, en, my, km, lo

Request fields

Provide sender/recipient or documented seller/buyer fallback. Requiredness describes source business requirements, not guaranteed validation responses.

Field Type Required Description
receiveType string See description AT_HOME or AT_STORE; GTN/NTN/VTT in vas can cause recalculation and override. Values: AT_HOME, AT_STORE.
shipper object See description ContactInfo. Sender and recipient need name, phone and address, subject to seller/buyer fallback.
shipper.name string See description Contact name. Examples use synthetic people.
shipper.phone string See description International format, e.g. Cambodia +855; replace the environment placeholder.
shipper.type string See description Examples: PARTNER_WAREHOUSE, PERSON, HOME, OFFICE; complete enum not supplied.
shipper.postOffice string See description Post-office code for drop-off at a branch.
shipper.address object See description Address supplied by the partner.
shipper.address.components array When parent is present Use current administrative API IDs and codes.
shipper.address.components[].id string See description Use the identifier returned by the API, not the illustrative value.
shipper.address.components[].code string See description Use the identifier returned by the API, not the illustrative value.
shipper.address.components[].name string See description Location name or street address.
shipper.address.components[].type string See description NATIONAL, PROVINCE, DISTRICT, VILLAGE or OTHER according to level.
shipper.address.components[].level number See description 0 country; 1 province; 2 district; 3 village; 999 street/detail.
consignee object See description ContactInfo. Sender and recipient need name, phone and address, subject to seller/buyer fallback.
consignee.name string See description Contact name. Examples use synthetic people.
consignee.phone string See description International format, e.g. Cambodia +855; replace the environment placeholder.
consignee.type string See description Examples: PARTNER_WAREHOUSE, PERSON, HOME, OFFICE; complete enum not supplied.
consignee.postOffice string See description Post-office code for drop-off at a branch.
consignee.address object See description Address supplied by the partner.
consignee.address.components array When parent is present Use current administrative API IDs and codes.
consignee.address.components[].id string See description Use the identifier returned by the API, not the illustrative value.
consignee.address.components[].code string See description Use the identifier returned by the API, not the illustrative value.
consignee.address.components[].name string See description Location name or street address.
consignee.address.components[].type string See description NATIONAL, PROVINCE, DISTRICT, VILLAGE or OTHER according to level.
consignee.address.components[].level number See description 0 country; 1 province; 2 district; 3 village; 999 street/detail.
seller object See description Optional seller, used if shipper is empty.
seller.name string See description Contact name. Examples use synthetic people.
seller.phone string See description International format, e.g. Cambodia +855; replace the environment placeholder.
seller.type string See description Examples: PARTNER_WAREHOUSE, PERSON, HOME, OFFICE; complete enum not supplied.
seller.postOffice string See description Post-office code for drop-off at a branch.
seller.address object See description Address supplied by the partner.
seller.address.components array When parent is present Use current administrative API IDs and codes.
seller.address.components[].id string See description Use the identifier returned by the API, not the illustrative value.
seller.address.components[].code string See description Use the identifier returned by the API, not the illustrative value.
seller.address.components[].name string See description Location name or street address.
seller.address.components[].type string See description NATIONAL, PROVINCE, DISTRICT, VILLAGE or OTHER according to level.
seller.address.components[].level number See description 0 country; 1 province; 2 district; 3 village; 999 street/detail.
buyer object See description Optional buyer, used if consignee is empty.
buyer.name string See description Contact name. Examples use synthetic people.
buyer.phone string See description International format, e.g. Cambodia +855; replace the environment placeholder.
buyer.type string See description Examples: PARTNER_WAREHOUSE, PERSON, HOME, OFFICE; complete enum not supplied.
buyer.postOffice string See description Post-office code for drop-off at a branch.
buyer.address object See description Address supplied by the partner.
buyer.address.components array When parent is present Use current administrative API IDs and codes.
buyer.address.components[].id string See description Use the identifier returned by the API, not the illustrative value.
buyer.address.components[].code string See description Use the identifier returned by the API, not the illustrative value.
buyer.address.components[].name string See description Location name or street address.
buyer.address.components[].type string See description NATIONAL, PROVINCE, DISTRICT, VILLAGE or OTHER according to level.
buyer.address.components[].level number See description 0 country; 1 province; 2 district; 3 village; 999 street/detail.
returnContact object See description Return contact; defaults to shipper.
returnContact.name string See description Contact name. Examples use synthetic people.
returnContact.phone string See description International format, e.g. Cambodia +855; replace the environment placeholder.
returnContact.type string See description Examples: PARTNER_WAREHOUSE, PERSON, HOME, OFFICE; complete enum not supplied.
returnContact.postOffice string See description Post-office code for drop-off at a branch.
returnContact.address object See description Address supplied by the partner.
returnContact.address.components array When parent is present Use current administrative API IDs and codes.
returnContact.address.components[].id string See description Use the identifier returned by the API, not the illustrative value.
returnContact.address.components[].code string See description Use the identifier returned by the API, not the illustrative value.
returnContact.address.components[].name string See description Location name or street address.
returnContact.address.components[].type string See description NATIONAL, PROVINCE, DISTRICT, VILLAGE or OTHER according to level.
returnContact.address.components[].level number See description 0 country; 1 province; 2 district; 3 village; 999 street/detail.
parcel object Yes Parcel dimensions and goods.
parcel.weight number Yes Parcel weight.
parcel.weightUnit string Yes Weight unit documented as GRAM.
parcel.length number Yes Length, cm.
parcel.width number Yes Width, cm.
parcel.height number Yes Height, cm.
parcel.measurementUnit string See description Defaults to CENTIMET (source spelling). Default: CENTIMET.
parcel.type string Yes Parcel type. Values: GOODS, DOCUMENT.
parcel.items array Yes At least one item.
parcel.items[].name string When parent is present Item name.
parcel.items[].type string See description Item type shown in the example.
parcel.items[].value number See description Declared item value.
parcel.items[].weight number When parent is present Item weight; must be greater than zero.
parcel.items[].quantity number See description Item quantity.
payerType string Yes Only CONSIGNEE and SELLER accepted; otherwise PAYER_INVALID. Values: CONSIGNEE, SELLER.
service string Yes Main service code from get-service.
vas array See description Extra service codes selected from available services.
moneyCollection number See description COD must be resent here. Omitted/null becomes cod=0. Negative values produce INVALID_PRICE.
detailedFees object See description Use the results returned by get-all.
detailedFees.serviceFee array See description Recommended pricing details.
detailedFees.serviceFee[].service string See description Service code from pricing.
detailedFees.serviceFee[].name string See description Service name shown in the example.
detailedFees.serviceFee[].fee number See description Use main/extra beforeVatPrice, not VAT-inclusive price.
detailedFees.serviceFee[].surchargeType string See description Only valid values are retained, but the source does not list those values. Ask TMS.
detailedFees.serviceFee[].type string See description Source example says VAS, conflicting with the prose surchargeType field. Not a confirmed substitute.
voucher string See description Voucher code.
reference string See description Partner internal reference.
pickupAppointment object See description Optional appointment. Confirm day/time encoding before use.
pickupAppointment.dayOfWeek array See description Days of week; item encoding not specified by the source.
pickupAppointment.hours array See description Time slots; item encoding not specified by the source.
pickupAppointment.note string See description Appointment note.
deliveryAppointment object See description Optional appointment. Confirm day/time encoding before use.
deliveryAppointment.dayOfWeek array See description Days of week; item encoding not specified by the source.
deliveryAppointment.hours array See description Time slots; item encoding not specified by the source.
deliveryAppointment.note string See description Appointment note.
note string See description Order note.
invoice string See description Invoice requested from sender or receiver. Values: NONE, BY_SENDER, BY_RECEIVER. Default: NONE.
orderScope string See description Order scope. Values: DOMESTIC, INTERNATIONAL. Default: DOMESTIC.
deliveryPostcode string See description Required unless vas contains GTN or VTT. GTN forces this field to null.
txId string See description Partner transaction ID for reconciliation/client-side deduplication. Server idempotency is NOT established.

Example JSON body

Save as request.json. Replace every ${…} string and example ID with actual environment values before sending. cURL with --data @request.json does not interpolate variables inside JSON files. Identities are synthetic.

{
  "receiveType": "AT_HOME",
  "shipper": {
    "name": "Example Warehouse",
    "phone": "${SHIPPER_PHONE}",
    "type": "PARTNER_WAREHOUSE",
    "address": {
      "components": [
        {
          "name": "Example warehouse, Street A",
          "type": "OTHER",
          "level": 999
        },
        {
          "id": "5025963",
          "code": "120211",
          "name": "Voat Phnum",
          "type": "VILLAGE",
          "level": 3
        },
        {
          "id": "4059553",
          "code": "1202",
          "name": "Doun Penh",
          "type": "DISTRICT",
          "level": 2
        },
        {
          "id": "4025120",
          "code": "PNP",
          "name": "Phnom Penh",
          "type": "PROVINCE",
          "level": 1
        },
        {
          "type": "NATIONAL",
          "name": "Cambodia",
          "code": "KH",
          "level": 0
        }
      ]
    }
  },
  "consignee": {
    "name": "Example Recipient",
    "phone": "${CONSIGNEE_PHONE}",
    "address": {
      "components": [
        {
          "name": "Example recipient, Street B",
          "type": "OTHER",
          "level": 999
        },
        {
          "id": "5025109",
          "code": "010201",
          "name": "បន្ទាយនាង",
          "type": "VILLAGE",
          "level": 3
        },
        {
          "id": "4059452",
          "code": "0102",
          "name": "មង្គលបូរី",
          "type": "DISTRICT",
          "level": 2
        },
        {
          "id": "4025109",
          "code": "BAN",
          "name": "Banteay Meanchey",
          "type": "PROVINCE",
          "level": 1
        },
        {
          "type": "NATIONAL",
          "name": "Cambodia",
          "code": "KH",
          "level": 0
        }
      ]
    }
  },
  "parcel": {
    "weight": 100,
    "weightUnit": "GRAM",
    "length": 10,
    "width": 10,
    "height": 10,
    "measurementUnit": "CENTIMET",
    "type": "GOODS",
    "items": [
      {
        "name": "Example product",
        "type": "GOODS",
        "value": 50,
        "weight": 10,
        "quantity": 8
      }
    ]
  },
  "payerType": "CONSIGNEE",
  "service": "CCN",
  "vas": [
    "NTN",
    "VTT"
  ],
  "moneyCollection": 50,
  "invoice": "NONE",
  "reference": "EXAMPLE-REFERENCE-001",
  "txId": "00000000-0000-4000-8000-000000000001",
  "note": ""
}

cURL example

BASE_URL must include /tms-partner/api/v1. Load the token and partner code from your private environment; never paste secrets into documentation or AI prompts.

curl --request POST "${BASE_URL}/order" \
  --header "X-Api-Token: ${API_TOKEN}" \
  --header "X-Client-Source: ${PARTNER_CODE}" \
  --header "Accept-Language: en" \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --data @request.json

Example response

{
  "id": "EXAMPLE-ORDER-001",
  "status": "CONFIRMED",
  "statusName": "Awaiting acceptance",
  "service": "CCN",
  "serviceName": "Express",
  "orderScope": "DOMESTIC",
  "shipper": {
    "name": "Example Warehouse",
    "address": {
      "components": [
        {
          "name": "Example warehouse, Street A",
          "type": "OTHER",
          "level": 999
        },
        {
          "id": "5025963",
          "code": "120211",
          "name": "Voat Phnum",
          "type": "VILLAGE",
          "level": 3
        },
        {
          "id": "4059553",
          "code": "1202",
          "name": "Doun Penh",
          "type": "DISTRICT",
          "level": 2
        },
        {
          "id": "4025120",
          "code": "PNP",
          "name": "Phnom Penh",
          "type": "PROVINCE",
          "level": 1
        },
        {
          "type": "NATIONAL",
          "name": "Cambodia",
          "code": "KH",
          "level": 0
        }
      ],
      "formattedAddress": "Example warehouse, Phnom Penh, Cambodia"
    }
  },
  "consignee": {
    "name": "Example Recipient",
    "phone": "${CONSIGNEE_PHONE}",
    "address": {
      "components": [
        {
          "name": "Example recipient, Street B",
          "type": "OTHER",
          "level": 999
        },
        {
          "id": "5025109",
          "code": "010201",
          "name": "បន្ទាយនាង",
          "type": "VILLAGE",
          "level": 3
        },
        {
          "id": "4059452",
          "code": "0102",
          "name": "មង្គលបូរី",
          "type": "DISTRICT",
          "level": 2
        },
        {
          "id": "4025109",
          "code": "BAN",
          "name": "Banteay Meanchey",
          "type": "PROVINCE",
          "level": 1
        },
        {
          "type": "NATIONAL",
          "name": "Cambodia",
          "code": "KH",
          "level": 0
        }
      ],
      "formattedAddress": "Example recipient, Banteay Meanchey, Cambodia"
    }
  },
  "parcel": {
    "weight": 100,
    "weightUnit": "GRAM",
    "length": 10,
    "width": 10,
    "height": 10,
    "measurementUnit": "CENTIMET",
    "type": "GOODS",
    "items": [
      {
        "name": "Example product",
        "type": "GOODS",
        "value": 50,
        "weight": 10,
        "quantity": 8
      }
    ]
  },
  "cod": 50,
  "totalFees": 1.75,
  "totalTax": 0.16,
  "originalPrice": 1.59,
  "detailedFees": {
    "currency": "USD",
    "serviceFee": [
      {
        "service": "CCN",
        "fee": 1.44,
        "feeAfterVat": 1.59,
        "vatPrice": 0.14
      }
    ]
  },
  "payerType": "CONSIGNEE",
  "vas": [
    "NTN",
    "VTT"
  ],
  "estDeliveryTime": {
    "days": 1.5,
    "date": "15/10/2026"
  },
  "createdAt": "2026-10-14T09:00:00+00:00",
  "txId": "00000000-0000-4000-8000-000000000001",
  "invoice": "NONE",
  "receiveType": "AT_HOME",
  "partnerInfo": {
    "id": 900001,
    "partner_code": "EXAMPLE-PARTNER",
    "partner_name": "Example Partner",
    "type": "PARTNER"
  }
}

Response fields

Field Type Required Description
id string See description Use the identifier returned by the API, not the illustrative value.
status string See description Creation example uses CONFIRMED, unlike numeric lookup/webhook status.
statusName string See description Creation status label: awaiting acceptance.
service string See description Use the identifier returned by the API, not the illustrative value.
serviceName string See description Main service name.
orderScope string See description Order scope.
shipper object See description Sender snapshot.
shipper.name string See description Sender name.
shipper.phone string See description Sender phone when returned.
shipper.address object See description Simplified response address; components do not echo typeName/typeLabel.
shipper.address.components array See description Use current administrative API IDs and codes.
shipper.address.components[].id string See description Use the identifier returned by the API, not the illustrative value.
shipper.address.components[].code string See description Use the identifier returned by the API, not the illustrative value.
shipper.address.components[].name string See description Location name or street address.
shipper.address.components[].type string See description NATIONAL, PROVINCE, DISTRICT, VILLAGE or OTHER according to level.
shipper.address.components[].level number See description 0 country; 1 province; 2 district; 3 village; 999 street/detail.
shipper.address.formattedAddress string See description Formatted address; no address-level id, code or geometry.
consignee object See description Recipient snapshot.
consignee.name string See description Recipient name.
consignee.phone string See description Recipient phone.
consignee.address object See description Simplified response address; components do not echo typeName/typeLabel.
consignee.address.components array See description Use current administrative API IDs and codes.
consignee.address.components[].id string See description Use the identifier returned by the API, not the illustrative value.
consignee.address.components[].code string See description Use the identifier returned by the API, not the illustrative value.
consignee.address.components[].name string See description Location name or street address.
consignee.address.components[].type string See description NATIONAL, PROVINCE, DISTRICT, VILLAGE or OTHER according to level.
consignee.address.components[].level number See description 0 country; 1 province; 2 district; 3 village; 999 street/detail.
consignee.address.formattedAddress string See description Formatted address; no address-level id, code or geometry.
parcel object See description Returned parcel may be partial; request requiredness is not a response guarantee.
parcel.weight number See description Parcel weight.
parcel.weightUnit string See description Weight unit documented as GRAM.
parcel.length number See description Length, cm.
parcel.width number See description Width, cm.
parcel.height number See description Height, cm.
parcel.measurementUnit string See description Defaults to CENTIMET (source spelling). Default: CENTIMET.
parcel.type string See description Parcel type. Values: GOODS, DOCUMENT.
parcel.items array See description Returned goods items.
parcel.items[].name string See description Item name.
parcel.items[].type string See description Item type shown in the example.
parcel.items[].value number See description Declared item value.
parcel.items[].weight number See description Item weight; must be greater than zero.
parcel.items[].quantity number See description Item quantity.
cod number See description Persisted COD; compare with request.moneyCollection.
totalFees number See description Total fees after discounts including VAT.
totalTax number See description Total VAT.
originalPrice number See description Original price shown in the source example; calculation not specified.
detailedFees object See description Recorded detailed fees.
detailedFees.currency string See description Example uses USD; do not assume every pricing response uses this currency.
detailedFees.serviceFee array See description Recorded fees.
detailedFees.serviceFee[].service string See description Use the identifier returned by the API, not the illustrative value.
detailedFees.serviceFee[].fee number See description Pre-VAT fee.
detailedFees.serviceFee[].feeAfterVat number See description Fee after VAT.
detailedFees.serviceFee[].vatPrice number See description VAT amount.
payerType string See description Payer.
vas array See description Extra services.
estDeliveryTime object See description Delivery estimate.
estDeliveryTime.days number See description Estimated day count.
estDeliveryTime.date string See description Estimated delivery date, DD/MM/YYYY.
createdAt string See description Creation timestamp.
txId string See description Transaction identifier derived from supplied txId or generated by the system; no server deduplication guarantee.
invoice string See description Invoice mode.
receiveType string See description Resolved receive type.
partnerInfo object See description Optional discount identity; X-Client-Source normally suffices. Uses snake_case.
partnerInfo.id number See description Internal partner ID.
partnerInfo.partner_code string See description Partner code.
partnerInfo.partner_name string See description Partner name.
partnerInfo.email string See description Partner email.
partnerInfo.type string See description Partner type, e.g. PARTNER.

Address levels

Level type Order requirement
0 NATIONAL Optional; code KH, name Cambodia
1 PROVINCE Required; id/code from provinces
2 DISTRICT Required; id/code from level 2
3 VILLAGE Required; id/code from level 3
999 OTHER Optional; house number, street, building

COD persistence diagram

Diagram
Diagram; View source
View source
flowchart TD
  A["product.moneyCollection in pricing"] --> B["Select COD service branch only"]
  B --> C["Create a separate order request"]
  C --> D{"Top-level moneyCollection supplied?"}
  D -->|Yes| E["Persist and compare response.cod"]
  D -->|Missing or null| F["Order records cod = 0"]

Error handling

See HTTP codes and source limitations. HTTP success does not prove COD, fees, or cancellation are correct; inspect the documented business fields. Do not assume create-order retries are safe.

AI resources

Give your AI assistant the current company’s documentation, Markdown pages, and OpenAPI contract.

Source
Help me integrate with Metfone Express (v1).
Read https://mfexpress-partner-docs.zhst.app/mfexpress/en/llms.txt first, then https://mfexpress-partner-docs.zhst.app/mfexpress/en/llms-full.txt and https://mfexpress-partner-docs.zhst.app/mfexpress/en/openapi.json.
Use only the documented endpoints, authentication, schemas and examples. Ask me about my application stack and the operation I need before writing code. Identify any documented limitations or inconsistencies. Keep credentials in environment variables, never in client-side code. Use the sandbox for examples; do not execute requests or change production data without my explicit approval.
Documentation locale: en. API language value: en.
Current page: https://mfexpress-partner-docs.zhst.app/mfexpress/en/create-order.