POST /tms-partner/api/v1/orderUsage 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.jsonExample 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
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.