创建订单
order_code 是当前商家账户范围内的自然幂等键。第一次创建返回
201;相同规范化请求重放返回 200;同编号不同内容返回 409。业务字段
只接受 JSON body;当前版本不接受 query 参数,URL 包含 query 参数时返回 400。
顾客字段省略表示不更新,nullable 字段显式 null 才表示清空。
POST
/ordersHeader parameters
Idempotency-Keystring调用方生成的重试标识。订单的主要幂等键是 `order_code`,本请求头提供附加的重试关联信息。
同一请求重试时必须保持该值不变。
min length 16 · max length 128
Request body
requiredapplication/jsonorder_codeOrderCoderequired由调用方指定的订单编号,同一商家内唯一,是创建订单的幂等键。
⚠️ 它同时是顾客自助验证身份时的因子之一(凭「手机号 + 订单号」绑定微信、在公众号里找订单、找回密码),
因此必须不可预测:请使用随机字符串(建议至少 8 位随机字母数字,可带固定前缀便于对账),
⛔ 不要用自增序号、日期加流水号或 CRM 主键这类能推算出来的编号。
Darkroom 自己生成的订单号是 6 位随机大写字母数字(约 10 亿种组合),在限流下被猜中的概率接近零;
自定义连号会让这层保护失效。详见接入指南「幂等与错误处理」中的「订单号怎么取」。
min length 3 · max length 40 · matches ^[A-Za-z0-9][A-Za-z0-9._:-]{2,39}$
scheduled_datestring<date>requiredscheduled_start_timestringrequired门店本地时间,必须包含秒。
matches ^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$
store_codestringrequiredmin length 1 · max length 64
servicesServiceInput[]requiredmin items 1 · max items 50
Show propertiesHide properties
Array of
ServiceInputservice_codestringrequiredmin length 1 · max length 64
unit_price_amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
quantityintegerrequiredmin 1 · max 999
customerCustomerInputrequired用国家区号与手机号定位顾客。已有顾客只更新请求中实际出现的字段;
省略字段保持原值,nullable 字段显式 null 才清空,空字符串校验失败。
Show propertiesHide properties
namestring | nullmin length 1 · max length 100
country_calling_codestringrequiredmatches ^\+[1-9][0-9]{0,3}$
mobilestringrequired不带国家区号、不带任何分隔符的手机号,6–11 位数字。
区号写在 country_calling_code 里。空号码会被拒绝(400 invalid_request)。
matches ^[0-9]{6,11}$
emailstring<email> | nullmin length 1 · max length 255
genderstring | nullAllowed:
femalemaleunspecifiednullchildChildInput | anyShow propertiesHide properties
Any of:
ChildInput
namestring | nullmin length 1 · max length 100
genderstring | nullAllowed:
femalemaleunspecifiednullbirthdaystring<date> | nullany
anyprepaymentPrepaymentShow propertiesHide properties
amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
methodstring | null可用值由当前商家配置决定。
min length 1 · max length 64
remarkstring | nullmin length 1 · max length 1000
coupon_codestring | nullmin length 1 · max length 255
customer_remarkstring | nullmin length 1 · max length 5000
team_remarkstring | nullmin length 1 · max length 5000
source_created_atstring<date-time> | null外部系统最初建立订单的时间。
Responses
200相同规范化请求的安全重放。
dataOrderrequiredShow propertiesHide properties
order_codeOrderCoderequired由调用方指定的订单编号,同一商家内唯一,是创建订单的幂等键。
⚠️ 它同时是顾客自助验证身份时的因子之一(凭「手机号 + 订单号」绑定微信、在公众号里找订单、找回密码),
因此必须不可预测:请使用随机字符串(建议至少 8 位随机字母数字,可带固定前缀便于对账),
⛔ 不要用自增序号、日期加流水号或 CRM 主键这类能推算出来的编号。
Darkroom 自己生成的订单号是 6 位随机大写字母数字(约 10 亿种组合),在限流下被猜中的概率接近零;
自定义连号会让这层保护失效。详见接入指南「幂等与错误处理」中的「订单号怎么取」。
min length 3 · max length 40 · matches ^[A-Za-z0-9][A-Za-z0-9._:-]{2,39}$
statusstringrequiredscheduled_datestring<date>requiredscheduled_start_timestringrequiredmatches ^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$
store_codestringrequiredservicesServiceSummary[]requiredShow propertiesHide properties
Array of
ServiceSummaryservice_codestringrequiredmin length 1 · max length 64
unit_price_amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
quantityintegerrequiredmin 1 · max 999
namestringrequiredtotal_price_amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
coupon_codestring | nullrequiredprepaymentPrepaymentrequiredShow propertiesHide properties
amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
methodstring | null可用值由当前商家配置决定。
min length 1 · max length 64
remarkstring | nullmin length 1 · max length 1000
customerCustomerSummaryrequiredShow propertiesHide properties
customer_idstringrequirednamestring | nullrequiredcountry_calling_codestringrequiredmobilestringrequiredemailstring<email> | nullrequiredgenderstring | nullrequiredAllowed:
femalemaleunspecifiednullchildChildInput | anyShow propertiesHide properties
Any of:
ChildInput
namestring | nullmin length 1 · max length 100
genderstring | nullAllowed:
femalemaleunspecifiednullbirthdaystring<date> | nullany
anycustomer_remarkstring | nullrequiredteam_remarkstring | nullrequiredcreated_atstring<date-time>requiredidempotent_replaybooleanrequiredrequest_idstringrequired201第一次成功创建订单。
dataOrderrequiredShow propertiesHide properties
order_codeOrderCoderequired由调用方指定的订单编号,同一商家内唯一,是创建订单的幂等键。
⚠️ 它同时是顾客自助验证身份时的因子之一(凭「手机号 + 订单号」绑定微信、在公众号里找订单、找回密码),
因此必须不可预测:请使用随机字符串(建议至少 8 位随机字母数字,可带固定前缀便于对账),
⛔ 不要用自增序号、日期加流水号或 CRM 主键这类能推算出来的编号。
Darkroom 自己生成的订单号是 6 位随机大写字母数字(约 10 亿种组合),在限流下被猜中的概率接近零;
自定义连号会让这层保护失效。详见接入指南「幂等与错误处理」中的「订单号怎么取」。
min length 3 · max length 40 · matches ^[A-Za-z0-9][A-Za-z0-9._:-]{2,39}$
statusstringrequiredscheduled_datestring<date>requiredscheduled_start_timestringrequiredmatches ^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$
store_codestringrequiredservicesServiceSummary[]requiredShow propertiesHide properties
Array of
ServiceSummaryservice_codestringrequiredmin length 1 · max length 64
unit_price_amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
quantityintegerrequiredmin 1 · max 999
namestringrequiredtotal_price_amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
coupon_codestring | nullrequiredprepaymentPrepaymentrequiredShow propertiesHide properties
amountMoneyAmountrequiredmatches ^(0|[1-9][0-9]{0,7})\.[0-9]{2}$
methodstring | null可用值由当前商家配置决定。
min length 1 · max length 64
remarkstring | nullmin length 1 · max length 1000
customerCustomerSummaryrequiredShow propertiesHide properties
customer_idstringrequirednamestring | nullrequiredcountry_calling_codestringrequiredmobilestringrequiredemailstring<email> | nullrequiredgenderstring | nullrequiredAllowed:
femalemaleunspecifiednullchildChildInput | anyShow propertiesHide properties
Any of:
ChildInput
namestring | nullmin length 1 · max length 100
genderstring | nullAllowed:
femalemaleunspecifiednullbirthdaystring<date> | nullany
anycustomer_remarkstring | nullrequiredteam_remarkstring | nullrequiredcreated_atstring<date-time>requiredidempotent_replaybooleanrequiredrequest_idstringrequired400JSON 或请求格式无效。
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsErrorDetail[]Show propertiesHide properties
Array of
ErrorDetailfieldstringrequiredreasonstringrequiredrequest_idstringrequired401`invalid_token`(token 格式非法、已过期或已被撤销)或 `missing_token`
(缺少 `Authorization: Bearer`)。收到 401 后,可以获取新令牌并重试一次;
如果仍返回 401,请停止自动重试并检查凭据状态。
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsErrorDetail[]Show propertiesHide properties
Array of
ErrorDetailfieldstringrequiredreasonstringrequiredrequest_idstringrequired403`insufficient_scope`(token 的 scope 不含本端点所需权限)或
`credential_disabled`(凭据已被停用)。
`orders:write` 不包含 `orders:read`;查询订单必须显式授予 `orders:read`。
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsErrorDetail[]Show propertiesHide properties
Array of
ErrorDetailfieldstringrequiredreasonstringrequiredrequest_idstringrequired409`order_code_conflict` 表示同一 `order_code` 已对应内容不同的订单。
请停止自动重试并检查来源系统的订单编号分配规则。
内容相同的重放请求会返回 200 和 `idempotent_replay: true`。
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsErrorDetail[]Show propertiesHide properties
Array of
ErrorDetailfieldstringrequiredreasonstringrequiredrequest_idstringrequired422门店、服务、顾客、优惠码或订金业务数据不可接受。
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsErrorDetail[]Show propertiesHide properties
Array of
ErrorDetailfieldstringrequiredreasonstringrequiredrequest_idstringrequired429API 同时采用分钟配额和秒级突发限制,两者使用不同的等待时间:
- `rate_limit_exceeded`:已达到分钟配额,默认值为 20 req/min/key。
`Retry-After` 表示距下一分钟窗口的秒数。
- `burst_limit_exceeded`:已达到 2 req/s/key 的短时请求限制。
`Retry-After` 通常为 1 秒。
秒级突发限制不会提高分钟配额。即使请求速率不超过 2 req/s,
每分钟请求总量仍不得超过对应凭据的分钟配额。
`/oauth/token` 另有独立配额(10 req/min/client_id)。
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsErrorDetail[]Show propertiesHide properties
Array of
ErrorDetailfieldstringrequiredreasonstringrequiredrequest_idstringrequired503`api_temporarily_unavailable` 表示 API 功能、凭据服务或订单依赖暂时不可用。
可以使用设有次数上限的指数退避策略重试,避免短时间内发送大量重复请求。
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequireddetailsErrorDetail[]Show propertiesHide properties
Array of
ErrorDetailfieldstringrequiredreasonstringrequiredrequest_idstringrequiredRequest
curl -X POST "https://api.darkroom.net/v2/orders" \
-H "Content-Type: application/json" \
-d '{
"order_code": "crm-20260727-K7Q2XM",
"scheduled_date": "<date>",
"scheduled_start_time": "string",
"store_code": "string",
"services": [
{
"service_code": "string",
"unit_price_amount": "699.00",
"quantity": 1
}
],
"customer": {
"name": "string",
"country_calling_code": "string",
"mobile": "string",
"email": "<email>",
"gender": "female",
"child": {
"name": "string",
"gender": "female",
"birthday": "<date>"
}
},
"prepayment": {
"amount": "699.00",
"method": "string",
"remark": "string"
},
"coupon_code": "string",
"customer_remark": "string",
"team_remark": "string",
"source_created_at": "2024-01-01T00:00:00Z"
}'const response = await fetch("https://api.darkroom.net/v2/orders", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"order_code": "crm-20260727-K7Q2XM",
"scheduled_date": "<date>",
"scheduled_start_time": "string",
"store_code": "string",
"services": [
{
"service_code": "string",
"unit_price_amount": "699.00",
"quantity": 1
}
],
"customer": {
"name": "string",
"country_calling_code": "string",
"mobile": "string",
"email": "<email>",
"gender": "female",
"child": {
"name": "string",
"gender": "female",
"birthday": "<date>"
}
},
"prepayment": {
"amount": "699.00",
"method": "string",
"remark": "string"
},
"coupon_code": "string",
"customer_remark": "string",
"team_remark": "string",
"source_created_at": "2024-01-01T00:00:00Z"
})
});import requests
response = requests.post(
"https://api.darkroom.net/v2/orders",
headers={
"Content-Type": "application/json"
},
json={
"order_code": "crm-20260727-K7Q2XM",
"scheduled_date": "<date>",
"scheduled_start_time": "string",
"store_code": "string",
"services": [
{
"service_code": "string",
"unit_price_amount": "699.00",
"quantity": 1
}
],
"customer": {
"name": "string",
"country_calling_code": "string",
"mobile": "string",
"email": "<email>",
"gender": "female",
"child": {
"name": "string",
"gender": "female",
"birthday": "<date>"
}
},
"prepayment": {
"amount": "699.00",
"method": "string",
"remark": "string"
},
"coupon_code": "string",
"customer_remark": "string",
"team_remark": "string",
"source_created_at": "2024-01-01T00:00:00Z"
},
)Response
{
"data": {
"order_code": "crm-20260727-K7Q2XM",
"status": "string",
"scheduled_date": "<date>",
"scheduled_start_time": "string",
"store_code": "string",
"services": [
{
"service_code": "string",
"unit_price_amount": "699.00",
"quantity": 0,
"name": "string"
}
],
"total_price_amount": "699.00",
"coupon_code": "string",
"prepayment": {
"amount": "699.00",
"method": "string",
"remark": "string"
},
"customer": {
"customer_id": "string",
"name": "string",
"country_calling_code": "string",
"mobile": "string",
"email": "<email>",
"gender": "female",
"child": {
"name": "string",
"gender": "female",
"birthday": "<date>"
}
},
"customer_remark": "string",
"team_remark": "string",
"created_at": "2024-01-01T00:00:00Z"
},
"idempotent_replay": true,
"request_id": "string"
}{
"data": {
"order_code": "crm-20260727-K7Q2XM",
"status": "string",
"scheduled_date": "<date>",
"scheduled_start_time": "string",
"store_code": "string",
"services": [
{
"service_code": "string",
"unit_price_amount": "699.00",
"quantity": 0,
"name": "string"
}
],
"total_price_amount": "699.00",
"coupon_code": "string",
"prepayment": {
"amount": "699.00",
"method": "string",
"remark": "string"
},
"customer": {
"customer_id": "string",
"name": "string",
"country_calling_code": "string",
"mobile": "string",
"email": "<email>",
"gender": "female",
"child": {
"name": "string",
"gender": "female",
"birthday": "<date>"
}
},
"customer_remark": "string",
"team_remark": "string",
"created_at": "2024-01-01T00:00:00Z"
},
"idempotent_replay": true,
"request_id": "string"
}{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"reason": "string"
}
]
},
"request_id": "string"
}{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"reason": "string"
}
]
},
"request_id": "string"
}{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"reason": "string"
}
]
},
"request_id": "string"
}{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"reason": "string"
}
]
},
"request_id": "string"
}{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"reason": "string"
}
]
},
"request_id": "string"
}{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"reason": "string"
}
]
},
"request_id": "string"
}{
"error": {
"code": "string",
"message": "string",
"details": [
{
"field": "string",
"reason": "string"
}
]
},
"request_id": "string"
}