wx-sdk 0.0.9

A Wechat SDK written in Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
use super::{get_send, post_send};
use crate::{wechat::WxApiRequestBuilder, SdkResult};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct AddOrder {
    /// 订单来源,0为小程序订单,2为App或H5订单,填2则不发送物流服务通知
    pub add_source: i32,
    /// App或H5的appid,add_source=2时必填,需和开通了物流助手的小程序绑定同一open帐号
    #[serde(default)]
    pub wx_appid: Option<String>,
    /// 订单ID,须保证全局唯一,不超过512字节
    pub order_id: String,
    /// 用户openid,当add_source=2时无需填写(不发送物流服务通知)
    #[serde(default)]
    pub openid: Option<String>,
    /// 快递公司ID,参见getAllDelivery
    pub delivery_id: String,
    /// 快递客户编码或者现付编码
    pub biz_id: String,
    /// 快递备注信息,比如"易碎物品",不超过1024字节
    #[serde(default)]
    pub custom_remark: Option<String>,
    /// 订单标签id,用于平台型小程序区分平台上的入驻方,tagid须与入驻方账号一一对应,非平台型小程序无需填写该字段
    #[serde(default)]
    pub tagid: Option<i64>,
    /// 发件人信息
    pub sender: UserInfo,
    /// 收件人信息
    pub receiver: UserInfo,
    /// 包裹信息,将传递给快递公司
    pub cargo: Cargo,
    /// 商品信息,会展示到物流服务通知和电子面单中
    pub shop: Shop,
    /// 保价信息
    pub insured: Insured,
    /// 服务类型
    pub service: ServiceType,
    /// Unix 时间戳, 单位秒,顺丰必须传。 预期的上门揽件时间,0表示已事先约定取件时间;否则请传预期揽件时间戳,需大于当前时间,收件员会在预期时间附近上门。例如expect_time为“1557989929”,表示希望收件员将在2019年05月16日14:58:49-15:58:49内上门取货。说明:若选择 了预期揽件时间,请不要自己打单,由上门揽件的时候打印。如果是下顺丰散单,则必传此字段,否则不会有收件员上门揽件。
    #[serde(default)]
    pub expect_time: Option<i64>,
    /// 分单策略,【0:线下网点签约,1:总部签约结算】,不传默认线下网点签约。目前支持圆通。
    #[serde(default)]
    pub take_mode: Option<i32>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UserInfo {
    /// 发件人姓名,不超过64字节
    pub name: String,
    /// 发件人座机号码,若不填写则必须填写 mobile,不超过32字节
    #[serde(default)]
    pub tel: Option<String>,
    /// 发件人手机号码,若不填写则必须填写 tel,不超过32字节
    #[serde(default)]
    pub mobile: Option<String>,
    /// 发件人公司名称,不超过64字节
    #[serde(default)]
    pub company: Option<String>,
    /// 发件人邮编,不超过10字节
    #[serde(default)]
    pub post_code: Option<String>,
    /// 发件人国家,不超过64字节
    #[serde(default)]
    pub country: Option<String>,
    /// 发件人省份,比如:"广东省",不超过64字节
    pub province: String,
    /// 发件人市/地区,比如:"广州市",不超过64字节
    pub city: String,
    /// 发件人区/县,比如:"海珠区",不超过64字节
    pub area: String,
    /// 发件人详细地址,比如:"XX路XX号XX大厦XX",不超过512字节
    pub address: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Cargo {
    /// 包裹数量, 需要和detail_list size保持一致
    pub count: i32,
    /// 包裹总重量,单位是千克(kg)
    pub weight: f32,
    /// 包裹长度,单位厘米(cm)
    pub space_x: f32,
    /// 包裹宽度,单位厘米(cm)
    pub space_y: f32,
    /// 包裹高度,单位厘米(cm)
    pub space_z: f32,
    /// 包裹中商品详情列表
    pub detail_list: Vec<Goods>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Goods {
    /// 商品名,不超过128字节
    pub name: String,
    /// 商品数量
    pub count: i32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Shop {
    /// 商家小程序的路径,建议为订单页面
    pub wxa_path: String,
    /// 商品缩略图 url
    pub img_url: String,
    /// 商品名称, 不超过128字节
    pub goods_name: String,
    /// 商品数量
    pub goods_count: i32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Insured {
    /// 是否保价,0 表示不保价,1 表示保价
    pub use_insured: i32,
    /// 保价金额,单位是分,比如: 10000 表示 100 元
    pub insured_value: i32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ServiceType {
    /// 服务类型ID,详见已经支持的快递公司基本信息
    pub service_type: i32,
    /// 服务名称,详见已经支持的快递公司基本信息
    pub service_name: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct AddOrderRes {
    /// 订单ID,下单成功时返回
    pub order_id: String,
    /// 运单ID,下单成功时返回
    pub waybill_id: String,
    /// 运单信息,下单成功时返回
    pub waybill_data: Vec<KeyValue>,
    /// 快递侧错误码,下单失败时返回
    pub delivery_resultcode: i32,
    /// 快递侧错误信息,下单失败时返回
    pub delivery_resultmsg: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct KeyValue {
    /// 运单信息 key
    pub key: String,
    /// 运单信息 value
    pub value: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct QueryOrderList {
    /// 订单列表, 最多不能超过100个
    pub order_list: Vec<QueryOrderItem>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct QueryOrderItem {
    /// 订单ID
    pub order_id: String,
    /// 快递公司ID,参见getAllDelivery
    pub delivery_id: String,
    /// 运单ID
    #[serde(default)]
    pub waybill_id: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct OrderListRes {
    /// 运单列表
    pub order_list: Vec<OrderRes>,
    /// 运单状态, 0正常,1取消
    pub order_status: i32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct OrderRes {
    /// 错误码
    pub errcode: i32,
    /// 错误信息
    pub errmsg: String,
    /// 订单ID
    pub order_id: String,
    /// 快递公司ID,参见getAllDelivery
    pub delivery_id: String,
    /// 运单ID
    pub waybill_id: String,
    /// 运单 html 的 BASE64 结果
    pub print_html: String,
    /// 运单信息
    pub waybill_data: Vec<KeyValue>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct BindAccount {
    /// bind表示绑定,unbind表示解除绑定
    #[serde(rename = "type")]
    pub type_: String,
    /// 快递公司客户编码
    pub biz_id: String,
    /// 快递公司ID
    pub delivery_id: String,
    /// 快递公司客户密码, ems,顺丰,京东非必填
    #[serde(default)]
    pub password: Option<String>,
    /// 备注内容(提交EMS审核需要)
    #[serde(default)]
    pub remark_content: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CancelOrder {
    /// 订单 ID,需保证全局唯一
    pub order_id: String,
    /// 用户openid,当add_source=2时无需填写(不发送物流服务通知)
    #[serde(default)]
    pub openid: Option<String>,
    /// 快递公司ID,参见getAllDelivery
    pub delivery_id: String,
    /// 运单ID
    pub waybill_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DResultCode {
    /// 运力返回的错误码
    pub delivery_resultcode: i32,
    /// 运力返回的错误信息
    pub delivery_resultmsg: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct AccountList {
    /// 账号数量
    pub count: i64,
    /// 账号列表
    pub list: Vec<AccountInfo>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct AccountInfo {
    /// 快递公司客户编码
    pub biz_id: String,
    /// 快递公司ID
    pub delivery_id: String,
    /// 账号绑定时间
    pub create_time: i64,
    /// 账号更新时间
    pub update_time: i64,
    /// 绑定状态
    /// - `0`, 绑定成功
    /// - `1`, 审核中
    /// - `2`, 绑定失败
    /// - `3`, 已解绑
    pub status_code: i32,
    /// 账号别名
    pub alias: String,
    /// 账号绑定失败的错误信息(EMS审核结果)
    pub remark_wrong_msg: String,
    /// 账号绑定时的备注内容(提交EMS审核需要)
    pub remark_content: String,
    /// 电子面单余额
    pub quota_num: f64,
    /// 电子面单余额更新时间
    pub quota_update_time: i64,
    /// 该绑定帐号支持的服务类型
    #[serde(default)]
    pub service_type: Option<Vec<ServiceType>>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DeliveryList {
    /// 快递公司数量
    pub count: i64,
    /// 快递公司信息列表
    pub data: Vec<DeliveryInfo>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DeliveryInfo {
    /// 快递公司 ID
    pub delivery_id: String,
    /// 快递公司名称
    pub delivery_name: String,
    /// 是否支持散单, 1表示支持
    #[serde(default)]
    pub can_use_cash: Option<i32>,
    /// 是否支持查询面单余额, 1表示支持
    #[serde(default)]
    pub can_get_quota: Option<i32>,
    /// 散单对应的bizid,当can_use_cash=1时有效
    #[serde(default)]
    pub cash_biz_id: Option<String>,
    /// 支持的服务类型
    #[serde(default)]
    pub service_type: Option<Vec<ServiceType>>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct QueryOrder {
    /// 订单 ID,需保证全局唯一
    pub order_id: String,
    /// 用户openid,当add_source=2时无需填写(不发送物流服务通知)
    #[serde(default)]
    pub openid: Option<String>,
    /// 快递公司ID,参见getAllDelivery, 必须和waybill_id对应
    pub delivery_id: String,
    /// 运单ID
    #[serde(default)]
    pub waybill_id: Option<String>,
    /// 获取打印面单类型(`1`:一联单,`0`:二联单),默认获取二联单
    #[serde(default)]
    pub print_type: Option<i32>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Order {
    /// 运单 html 的 BASE64 结果
    pub print_html: String,
    /// 运单信息
    pub waybill_data: Vec<KeyValue>,
    /// 快递公司ID
    pub delivery_id: String,
    /// 订单ID
    pub order_id: String,
    /// 运单号
    pub waybill_id: String,
    /// 运单状态, 0正常,1取消
    pub order_status: i32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct QueryPath {
    /// 订单 ID,需保证全局唯一
    pub order_id: String,
    /// 用户openid,当add_source=2时无需填写(不发送物流服务通知)
    #[serde(default)]
    pub openid: Option<String>,
    /// 快递公司ID,参见getAllDelivery
    pub delivery_id: String,
    /// 运单ID
    pub waybill_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PathList {
    /// 用户openid
    pub openid: String,
    /// 快递公司 ID
    pub delivery_id: String,
    /// 运单 ID
    pub waybill_id: String,
    /// 轨迹节点数量
    pub path_item_num: i64,
    /// 轨迹节点列表
    pub path_item_list: Vec<PathItem>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PathItem {
    /// 轨迹节点 Unix 时间戳
    pub action_time: i64,
    /// 轨迹节点类型
    /// - `100001`, 揽件阶段-揽件成功
    /// - `100002`, 揽件阶段-揽件失败
    /// - `100003`, 揽件阶段-分配业务员
    /// - `200001`, 运输阶段-更新运输轨迹
    /// - `300002`, 派送阶段-开始派送
    /// - `300003`, 派送阶段-签收成功
    /// - `300004`, 派送阶段-签收失败
    /// - `400001`, 异常阶段-订单取消
    /// - `400002`, 异常阶段-订单滞留
    pub action_type: i32,
    /// 轨迹节点详情
    pub action_msg: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PrinterList {
    pub count: i64,
    pub openid: Vec<String>,
    pub tagid_list: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct QueryQuota {
    /// 快递公司ID,参见getAllDelivery
    pub delivery_id: String,
    /// 快递公司客户编码
    pub biz_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct QuotaNum {
    /// 电子面单余额
    pub quota_num: i32,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TestUpdateOrder {
    /// 商户id,需填test_biz_id
    pub biz_id: String,
    /// 订单号
    pub order_id: String,
    /// 快递公司id,需填TEST
    pub delivery_id: String,
    /// 运单号
    pub waybill_id: String,
    /// 轨迹变化 Unix 时间戳
    pub action_time: i64,
    /// 轨迹变化类型
    /// - `100001`, 揽件阶段-揽件成功
    /// - `100002`, 揽件阶段-揽件失败
    /// - `100003`, 揽件阶段-分配业务员
    /// - `200001`, 运输阶段-更新运输轨迹
    /// - `300002`, 派送阶段-开始派送
    /// - `300003`, 派送阶段-签收成功
    /// - `300004`, 派送阶段-签收失败
    /// - `400001`, 异常阶段-订单取消
    /// - `400002`, 异常阶段-订单滞留
    pub action_type: i32,
    /// 轨迹变化具体信息说明,使用UTF-8编码
    pub action_msg: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UpdatePrinter {
    /// 打印员 openid
    pub openid: String,
    /// 更新类型
    /// - `"bind"`,绑定
    /// - `"unbind"`,解除绑定
    pub update_type: String,
    /// 用于平台型小程序设置入驻方的打印员面单打印权限,同一打印员最多支持10个tagid,
    /// 使用半角逗号分隔,中间不加空格,如填写123,456,表示该打印员可以拉取到tagid为123和456的下的单,
    /// 非平台型小程序无需填写该字段
    #[serde(default)]
    pub tagid_list: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct QueryContact {
    /// 商户侧下单事件中推送的 Token 字段
    pub token: String,
    /// 运单 ID
    pub waybill_id: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Contact {
    /// 运单 ID
    pub waybill_id: String,
    /// 发件人信息
    pub sender: ContactInfo,
    /// 收件人信息
    pub receiver: ContactInfo,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ContactInfo {
    /// 地址,已经将省市区信息合并
    pub address: String,
    /// 用户姓名
    pub name: String,
    /// 座机号码
    pub tel: String,
    /// 手机号码
    pub mobile: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PreviewTemplate {
    /// 运单 ID
    pub waybill_id: String,
    /// 面单 HTML 模板内容(需经 Base64 编码)
    pub waybill_template: String,
    /// 面单数据。详情参考下单事件返回值中的 WaybillData
    pub waybill_data: String,
    /// 商户下单数据,格式是商户侧下单 API 中的请求体
    pub custom: AddOrder,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Custom {
    pub order_id: String,
    pub openid: String,
    pub delivery_id: String,
    pub biz_id: String,
    #[serde(default)]
    pub custom_remark: String,
    pub sender: UserInfo,
    pub receiver: UserInfo,
    pub shop: Shop,
    pub cargo: Cargo,
    pub insured: Insured,
    pub service: ServiceType,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PreviewTemplateRes {
    /// 运单 ID
    pub waybill_id: String,
    /// 渲染后的面单 HTML 文件(已经过 Base64 编码)
    pub rendered_waybill_template: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UpdateBusiness {
    /// 商户的小程序AppID,即审核商户事件中的 ShopAppID
    pub shop_app_id: String,
    /// 商户账户
    pub biz_id: String,
    /// 审核结果,0 表示审核通过,其他表示审核失败
    pub result_code: i32,
    /// 审核错误原因,仅 result_code 不等于 0 时需要设置
    #[serde(default)]
    pub result_msg: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UpdatePath {
    /// 商户侧下单事件中推送的 Token 字段
    pub token: String,
    /// 运单 ID
    pub waybill_id: String,
    /// 轨迹变化 Unix 时间戳
    pub action_time: i64,
    /// 轨迹变化类型
    /// - `100001`, 揽件阶段-揽件成功
    /// - `100002`, 揽件阶段-揽件失败
    /// - `100003`, 揽件阶段-分配业务员
    /// - `200001`, 运输阶段-更新运输轨迹
    /// - `300002`, 派送阶段-开始派送
    /// - `300003`, 派送阶段-签收成功
    /// - `300004`, 派送阶段-签收失败
    /// - `400001`, 异常阶段-订单取消
    /// - `400002`, 异常阶段-订单滞留
    pub action_type: i32,
    /// 轨迹变化具体信息说明,展示在快递轨迹详情页中。若有手机号码,则直接写11位手机号码。使用UTF-8编码。
    pub action_msg: String,
}

pub struct LogisticsModule<'a, T: WxApiRequestBuilder>(pub(crate) &'a T);

impl<'a, T: WxApiRequestBuilder> LogisticsModule<'a, T> {
    /// 生成运单
    pub async fn add_order(&self, data: &AddOrder) -> SdkResult<AddOrderRes> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/order/add";
        post_send(self.0, url, data).await
    }

    /// 批量获取运单数据
    pub async fn batch_get_order(&self, data: &QueryOrderList) -> SdkResult<OrderListRes> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/order/batchget";
        post_send(self.0, url, data).await
    }

    /// 绑定、解绑物流账号
    pub async fn bind_account(&self, data: &BindAccount) -> SdkResult<()> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/account/bind";
        post_send(self.0, url, data).await
    }

    /// 取消运单
    pub async fn cancel_order(&self, data: &CancelOrder) -> SdkResult<DResultCode> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/order/cancel";
        post_send(self.0, url, data).await
    }

    /// 获取所有绑定的物流账号
    pub async fn get_all_account(&self) -> SdkResult<AccountList> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/account/getall";
        get_send(self.0, url, &()).await
    }

    /// 获取支持的快递公司列表
    pub async fn get_all_delivery(&self) -> SdkResult<DeliveryList> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/delivery/getall";
        get_send(self.0, url, &()).await
    }

    /// 获取运单数据
    pub async fn get_order(&self, data: &QueryOrder) -> SdkResult<Order> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/order/get";
        post_send(self.0, url, data).await
    }

    /// 查询运单轨迹
    pub async fn get_path(&self, data: &QueryPath) -> SdkResult<PathList> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/path/get";
        post_send(self.0, url, data).await
    }

    /// 获取打印员。若需要使用微信打单 PC 软件,才需要调用。
    pub async fn get_printer(&self) -> SdkResult<PrinterList> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/printer/getall";
        get_send(self.0, url, &()).await
    }

    /// 获取电子面单余额。仅在使用加盟类快递公司时,才可以调用。
    pub async fn get_quota(&self, data: &QueryQuota) -> SdkResult<QuotaNum> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/quota/get";
        post_send(self.0, url, data).await
    }

    /// 模拟快递公司更新订单状态, 该接口只能用户测试
    pub async fn test_update_order(&self, data: &TestUpdateOrder) -> SdkResult<()> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/test_update_order";
        post_send(self.0, url, data).await
    }

    /// 配置面单打印员,可以设置多个,若需要使用微信打单 PC 软件,才需要调用。
    pub async fn update_printer(&self, data: &UpdatePrinter) -> SdkResult<()> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/business/printer/update";
        post_send(self.0, url, data).await
    }

    /// 获取面单联系人信息
    pub async fn get_contact(&self, data: &QueryContact) -> SdkResult<Contact> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/delivery/contact/get";
        post_send(self.0, url, data).await
    }

    /// 预览面单模板。用于调试面单模板使用。
    pub async fn preview_template(&self, data: &PreviewTemplate) -> SdkResult<PreviewTemplateRes> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/delivery/template/preview";
        post_send(self.0, url, data).await
    }

    /// 更新商户审核结果
    pub async fn update_business(&self, data: &UpdateBusiness) -> SdkResult<()> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/delivery/service/business/update";
        post_send(self.0, url, data).await
    }

    /// 更新运单轨迹
    pub async fn update_path(&self, data: &UpdatePath) -> SdkResult<()> {
        let url = "https://api.weixin.qq.com/cgi-bin/express/delivery/path/update";
        post_send(self.0, url, data).await
    }
}