Skip to content

订单回调

回调属于高级接入方式,Python、Go 示例默认使用订单轮询,不需要配置回调。只有自行实现回调接收服务时,才需要在创建订单时传入 callback_url

回调地址

回调地址必须是公网可访问的 HTTP/HTTPS 地址,不能指向:

  • localhost127.0.0.1
  • 私有 IP 网段
  • 仅内网可解析的域名

回调签名

回调使用与你的接收端约定的 API Key / Secret,签名规则与普通请求相同:

text
POST\n<callback path>\n<timestamp>\n<raw body md5>

必须使用收到的原始请求体字节验证签名,不能先解析 JSON 后重新序列化。

python
import hashlib
import hmac
import time

def verify_callback(path, timestamp, signature, raw_body, api_secret):
    if abs(int(time.time()) - int(timestamp)) > 60:
        return False
    body_md5 = hashlib.md5(raw_body).hexdigest()
    sign_string = f"POST\n{path}\n{timestamp}\n{body_md5}"
    expected = hmac.new(
        api_secret.encode("utf-8"),
        sign_string.encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
go
func verifyCallback(path, timestamp, signature string, rawBody, secret []byte) bool {
    unixTime, err := strconv.ParseInt(timestamp, 10, 64)
    if err != nil || math.Abs(float64(time.Now().Unix()-unixTime)) > 60 {
        return false
    }
    bodyMD5 := md5.Sum(rawBody)
    signString := strings.Join([]string{
        "POST", path, timestamp, hex.EncodeToString(bodyMD5[:]),
    }, "\n")
    mac := hmac.New(sha256.New, secret)
    mac.Write([]byte(signString))
    expected := hex.EncodeToString(mac.Sum(nil))
    return hmac.Equal([]byte(expected), []byte(signature))
}

请求体

json
{
  "event": "order.updated",
  "order_id": 101,
  "order_no": "DJ20260301120000ABCD",
  "status": "completed",
  "fulfillment": {
    "type": "auto",
    "status": "delivered",
    "payload": "ABCD-EFGH-1234-5678",
    "delivery_data": null,
    "delivered_at": "2026-03-01T12:01:00Z"
  },
  "timestamp": 1772366460
}
字段必填说明
event事件名称
order_idCheapEmail 订单 ID
order_noCheapEmail 订单号
status最新订单状态
fulfillment交付完成时出现
timestamp事件时间戳

成功响应

json
{
  "ok": true,
  "message": "received"
}

处理要求

  1. 使用 CheapEmail 返回的 order_idorder_no 查找本地订单。
  2. 验证签名和时间戳后再处理数据。
  3. 回调处理必须幂等,重复请求不能重复发货。
  4. delivered / completed 应触发本地交付。
  5. 回调失败时使用 GET /orders/:id 轮询兜底。
  6. 上游失败不要直接自动退款,应进入异常订单处理流程。

CheapEmail Open API Documentation