附近小店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

express_business.go 14 KiB

3 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. package weapp
  2. const (
  3. apiBindAccount = "/cgi-bin/express/business/account/bind"
  4. apiGetAllAccount = "/cgi-bin/express/business/account/getall"
  5. apiGetExpressPath = "/cgi-bin/express/business/path/get"
  6. apiAddExpressOrder = "/cgi-bin/express/business/order/add"
  7. apiCancelExpressOrder = "/cgi-bin/express/business/order/cancel"
  8. apiGetAllDelivery = "/cgi-bin/express/business/delivery/getall"
  9. apiGetExpressOrder = "/cgi-bin/express/business/order/get"
  10. apiGetPrinter = "/cgi-bin/express/business/printer/getall"
  11. apiGetQuota = "/cgi-bin/express/business/quota/get"
  12. apiUpdatePrinter = "/cgi-bin/express/business/printer/update"
  13. apiTestUpdateOrder = "/cgi-bin/express/business/test_update_order"
  14. )
  15. // ExpressAccount 物流账号
  16. type ExpressAccount struct {
  17. Type BindType `json:"type"` // bind表示绑定,unbind表示解除绑定
  18. BizID string `json:"biz_id"` // 快递公司客户编码
  19. DeliveryID string `json:"delivery_id"` // 快递公司 ID
  20. Password string `json:"password"` // 快递公司客户密码
  21. RemarkContent string `json:"remark_content"` // 备注内容(提交EMS审核需要)
  22. }
  23. // BindType 绑定动作类型
  24. type BindType = string
  25. // 所有绑定动作类型
  26. const (
  27. Bind = "bind" // 绑定
  28. Unbind = "unbind" // 解除绑定
  29. )
  30. // Bind 绑定、解绑物流账号
  31. // token 接口调用凭证
  32. func (ea *ExpressAccount) Bind(token string) (*CommonError, error) {
  33. api := baseURL + apiBindAccount
  34. return ea.bind(api, token)
  35. }
  36. func (ea *ExpressAccount) bind(api, token string) (*CommonError, error) {
  37. url, err := tokenAPI(api, token)
  38. if err != nil {
  39. return nil, err
  40. }
  41. res := new(CommonError)
  42. if err := postJSON(url, ea, res); err != nil {
  43. return nil, err
  44. }
  45. return res, nil
  46. }
  47. // AccountList 所有绑定的物流账号
  48. type AccountList struct {
  49. CommonError
  50. Count uint `json:"count"` // 账号数量
  51. List []struct {
  52. BizID string `json:"biz_id"` // 快递公司客户编码
  53. DeliveryID string `json:"delivery_id"` // 快递公司 ID
  54. CreateTime uint `json:"create_time"` // 账号绑定时间
  55. UpdateTime uint `json:"update_time"` // 账号更新时间
  56. StatusCode BindStatus `json:"status_code"` // 绑定状态
  57. Alias string `json:"alias"` // 账号别名
  58. RemarkWrongMsg string `json:"remark_wrong_msg"` // 账号绑定失败的错误信息(EMS审核结果)
  59. RemarkContent string `json:"remark_content"` // 账号绑定时的备注内容(提交EMS审核需要))
  60. QuotaNum uint `json:"quota_num"` // 电子面单余额
  61. QuotaUpdateTime uint `json:"quota_update_time"` // 电子面单余额更新时间
  62. } `json:"list"` // 账号列表
  63. }
  64. // BindStatus 账号绑定状态
  65. type BindStatus = int8
  66. // 所有账号绑定状态
  67. const (
  68. BindSuccess = 0 // 成功
  69. BindFailed = -1 // 系统失败
  70. )
  71. // GetAllAccount 获取所有绑定的物流账号
  72. // token 接口调用凭证
  73. func GetAllAccount(token string) (*AccountList, error) {
  74. api := baseURL + apiGetAllAccount
  75. return getAllAccount(api, token)
  76. }
  77. func getAllAccount(api, token string) (*AccountList, error) {
  78. url, err := tokenAPI(api, token)
  79. if err != nil {
  80. return nil, err
  81. }
  82. res := new(AccountList)
  83. if err := postJSON(url, requestParams{}, res); err != nil {
  84. return nil, err
  85. }
  86. return res, nil
  87. }
  88. // ExpressPathGetter 查询运单轨迹所需参数
  89. type ExpressPathGetter ExpressOrderGetter
  90. // GetExpressPathResponse 运单轨迹
  91. type GetExpressPathResponse struct {
  92. CommonError
  93. OpenID string `json:"openid"` // 用户openid
  94. DeliveryID string `json:"delivery_id"` // 快递公司 ID
  95. WaybillID string `json:"waybill_id"` // 运单 ID
  96. PathItemNum uint `json:"path_item_num"` // 轨迹节点数量
  97. PathItemList []ExpressPathNode `json:"path_item_list"` // 轨迹节点列表
  98. }
  99. // ExpressPathNode 运单轨迹节点
  100. type ExpressPathNode struct {
  101. ActionTime uint `json:"action_time"` // 轨迹节点 Unix 时间戳
  102. ActionType uint `json:"action_type"` // 轨迹节点类型
  103. ActionMsg string `json:"action_msg"` // 轨迹节点详情
  104. }
  105. // Get 查询运单轨迹
  106. // token 接口调用凭证
  107. func (ep *ExpressPathGetter) Get(token string) (*GetExpressPathResponse, error) {
  108. api := baseURL + apiGetExpressPath
  109. return ep.get(api, token)
  110. }
  111. func (ep *ExpressPathGetter) get(api, token string) (*GetExpressPathResponse, error) {
  112. url, err := tokenAPI(api, token)
  113. if err != nil {
  114. return nil, err
  115. }
  116. res := new(GetExpressPathResponse)
  117. if err := postJSON(url, ep, res); err != nil {
  118. return nil, err
  119. }
  120. return res, nil
  121. }
  122. // ExpressOrderSource 订单来源
  123. type ExpressOrderSource = uint8
  124. // 所有订单来源
  125. const (
  126. FromWeapp ExpressOrderSource = 0 // 小程序订单
  127. FromAppOrH5 = 2 // APP或H5订单
  128. )
  129. // ExpressOrderCreator 订单创建器
  130. type ExpressOrderCreator struct {
  131. ExpressOrder
  132. AddSource ExpressOrderSource `json:"add_source"` // 订单来源,0为小程序订单,2为App或H5订单,填2则不发送物流服务通知
  133. WXAppID string `json:"wx_appid,omitempty"` // App或H5的appid,add_source=2时必填,需和开通了物流助手的小程序绑定同一open帐号
  134. ExpectTime uint `json:"expect_time,omitempty"` // 顺丰必须填写此字段。预期的上门揽件时间,0表示已事先约定取件时间;否则请传预期揽件时间戳,需大于当前时间,收件员会在预期时间附近上门。例如expect_time为“1557989929”,表示希望收件员将在2019年05月16日14:58:49-15:58:49内上门取货。
  135. TagID uint `json:"tagid,omitempty"` //订单标签id,用于平台型小程序区分平台上的入驻方,tagid须与入驻方账号一一对应,非平台型小程序无需填写该字段
  136. }
  137. // InsureStatus 保价状态
  138. type InsureStatus = uint8
  139. // 所有保价状态
  140. const (
  141. Uninsured = 0 // 不保价
  142. Insured = 1 // 保价
  143. )
  144. // CreateExpressOrderResponse 创建订单返回数据
  145. type CreateExpressOrderResponse struct {
  146. CommonError
  147. OrderID string `json:"order_id"` // 订单ID,下单成功时返回
  148. WaybillID string `json:"waybill_id"` // 运单ID,下单成功时返回
  149. WaybillData []struct {
  150. Key string `json:"key"` // 运单信息 key
  151. Value string `json:"value"` // 运单信息 value
  152. } `json:"waybill_data"` // 运单信息,下单成功时返回
  153. DeliveryResultcode int `json:"delivery_resultcode"` // 快递侧错误码,下单失败时返回
  154. DeliveryResultmsg string `json:"delivery_resultmsg"` // 快递侧错误信息,下单失败时返回
  155. }
  156. // Create 生成运单
  157. // token 接口调用凭证
  158. func (creator *ExpressOrderCreator) Create(token string) (*CreateExpressOrderResponse, error) {
  159. api := baseURL + apiAddExpressOrder
  160. return creator.create(api, token)
  161. }
  162. func (creator *ExpressOrderCreator) create(api, token string) (*CreateExpressOrderResponse, error) {
  163. url, err := tokenAPI(api, token)
  164. if err != nil {
  165. return nil, err
  166. }
  167. res := new(CreateExpressOrderResponse)
  168. if err := postJSON(url, creator, res); err != nil {
  169. return nil, err
  170. }
  171. return res, nil
  172. }
  173. // CancelOrderResponse 取消订单返回数据
  174. type CancelOrderResponse struct {
  175. CommonError
  176. Count uint `json:"count"` //快递公司数量
  177. Data []struct {
  178. DeliveryID string `json:"delivery_id"` // 快递公司 ID
  179. DeliveryName string `json:"delivery_name"` // 快递公司名称
  180. } `json:"data"` //快递公司信息列表
  181. }
  182. // DeliveryList 支持的快递公司列表
  183. type DeliveryList struct {
  184. CommonError
  185. Count uint `json:"count"` // 快递公司数量
  186. Data []struct {
  187. ID string `json:"delivery_id"` // 快递公司 ID
  188. Name string `json:"delivery_name"` // 快递公司名称
  189. } `json:"data"` // 快递公司信息列表
  190. }
  191. // GetAllDelivery 获取支持的快递公司列表
  192. // token 接口调用凭证
  193. func GetAllDelivery(token string) (*DeliveryList, error) {
  194. api := baseURL + apiGetAllDelivery
  195. return getAllDelivery(api, token)
  196. }
  197. func getAllDelivery(api, token string) (*DeliveryList, error) {
  198. queries := requestQueries{
  199. "access_token": token,
  200. }
  201. url, err := encodeURL(api, queries)
  202. if err != nil {
  203. return nil, err
  204. }
  205. res := new(DeliveryList)
  206. if err := getJSON(url, res); err != nil {
  207. return nil, err
  208. }
  209. return res, nil
  210. }
  211. // ExpressOrderGetter 订单获取器
  212. type ExpressOrderGetter struct {
  213. OrderID string `json:"order_id"` // 订单 ID,需保证全局唯一
  214. OpenID string `json:"openid,omitempty"` // 用户openid,当add_source=2时无需填写(不发送物流服务通知)
  215. DeliveryID string `json:"delivery_id"` // 快递公司ID,参见getAllDelivery
  216. WaybillID string `json:"waybill_id"` // 运单ID
  217. }
  218. // GetExpressOrderResponse 获取运单返回数据
  219. type GetExpressOrderResponse struct {
  220. CommonError
  221. PrintHTML string `json:"print_html"` // 运单 html 的 BASE64 结果
  222. WaybillData []struct {
  223. Key string `json:"key"` // 运单信息 key
  224. Value string `json:"value"` // 运单信息 value
  225. } `json:"waybill_data"` // 运单信息
  226. }
  227. // Get 获取运单数据
  228. // token 接口调用凭证
  229. func (getter *ExpressOrderGetter) Get(token string) (*GetExpressOrderResponse, error) {
  230. api := baseURL + apiGetExpressOrder
  231. return getter.get(api, token)
  232. }
  233. func (getter *ExpressOrderGetter) get(api, token string) (*GetExpressOrderResponse, error) {
  234. url, err := tokenAPI(api, token)
  235. if err != nil {
  236. return nil, err
  237. }
  238. res := new(GetExpressOrderResponse)
  239. if err := postJSON(url, getter, res); err != nil {
  240. return nil, err
  241. }
  242. return res, nil
  243. }
  244. // ExpressOrderCanceler 订单取消器
  245. type ExpressOrderCanceler ExpressOrderGetter
  246. // Cancel 取消运单
  247. // token 接 口调用凭证
  248. func (canceler *ExpressOrderCanceler) Cancel(token string) (*CommonError, error) {
  249. api := baseURL + apiCancelExpressOrder
  250. return canceler.cancel(api, token)
  251. }
  252. func (canceler *ExpressOrderCanceler) cancel(api, token string) (*CommonError, error) {
  253. url, err := tokenAPI(api, token)
  254. if err != nil {
  255. return nil, err
  256. }
  257. res := new(CommonError)
  258. if err := postJSON(url, canceler, res); err != nil {
  259. return nil, err
  260. }
  261. return res, nil
  262. }
  263. // GetPrinterResponse 获取打印员返回数据
  264. type GetPrinterResponse struct {
  265. CommonError
  266. Count uint `json:"count"` // 已经绑定的打印员数量
  267. OpenID []string `json:"openid"` // 打印员 openid 列表
  268. TagIDList []string `json:"tagid_list"`
  269. }
  270. // GetPrinter 获取打印员。若需要使用微信打单 PC 软件,才需要调用。
  271. // token 接口调用凭证
  272. func GetPrinter(token string) (*GetPrinterResponse, error) {
  273. api := baseURL + apiGetPrinter
  274. return getPrinter(api, token)
  275. }
  276. func getPrinter(api, token string) (*GetPrinterResponse, error) {
  277. url, err := tokenAPI(api, token)
  278. if err != nil {
  279. return nil, err
  280. }
  281. res := new(GetPrinterResponse)
  282. if err := getJSON(url, res); err != nil {
  283. return nil, err
  284. }
  285. return res, nil
  286. }
  287. // QuotaGetter 电子面单余额获取器
  288. type QuotaGetter struct {
  289. DeliveryID string `json:"delivery_id"` // 快递公司ID,参见getAllDelivery
  290. BizID string `json:"biz_id"` // 快递公司客户编码
  291. }
  292. // QuotaGetResponse 电子面单余额
  293. type QuotaGetResponse struct {
  294. CommonError
  295. Number uint // 电子面单余额
  296. }
  297. // Get 获取电子面单余额。仅在使用加盟类快递公司时,才可以调用。
  298. func (getter *QuotaGetter) Get(token string) (*QuotaGetResponse, error) {
  299. api := baseURL + apiGetQuota
  300. return getter.get(api, token)
  301. }
  302. func (getter *QuotaGetter) get(api, token string) (*QuotaGetResponse, error) {
  303. url, err := tokenAPI(api, token)
  304. if err != nil {
  305. return nil, err
  306. }
  307. res := new(QuotaGetResponse)
  308. if err := postJSON(url, getter, res); err != nil {
  309. return nil, err
  310. }
  311. return res, nil
  312. }
  313. // UpdateExpressOrderTester 模拟的快递公司更新订单
  314. type UpdateExpressOrderTester struct {
  315. BizID string `json:"biz_id"` // 商户id,需填test_biz_id
  316. OrderID string `json:"order_id"` // 订单ID,下单成功时返回
  317. WaybillID string `json:"waybill_id"` // 运单 ID
  318. DeliveryID string `json:"delivery_id"` // 快递公司 ID
  319. ActionTime uint `json:"action_time"` // 轨迹变化 Unix 时间戳
  320. ActionType uint `json:"action_type"` // 轨迹变化类型
  321. ActionMsg string `json:"action_msg"` // 轨迹变化具体信息说明,展示在快递轨迹详情页中。若有手机号码,则直接写11位手机号码。使用UTF-8编码。
  322. }
  323. // Test 模拟快递公司更新订单状态, 该接口只能用户测试
  324. func (tester *UpdateExpressOrderTester) Test(token string) (*CommonError, error) {
  325. api := baseURL + apiTestUpdateOrder
  326. return tester.test(api, token)
  327. }
  328. func (tester *UpdateExpressOrderTester) test(api, token string) (*CommonError, error) {
  329. url, err := tokenAPI(api, token)
  330. if err != nil {
  331. return nil, err
  332. }
  333. res := new(CommonError)
  334. if err := postJSON(url, tester, res); err != nil {
  335. return nil, err
  336. }
  337. return res, nil
  338. }
  339. // PrinterUpdater 打印员更新器
  340. type PrinterUpdater struct {
  341. OpenID string `json:"openid"` // 打印员 openid
  342. Type BindType `json:"update_type"` // 更新类型
  343. TagIDList string `json:"tagid_list"` // 用于平台型小程序设置入驻方的打印员面单打印权限,同一打印员最多支持10个tagid,使用逗号分隔,如填写123,456,表示该打印员可以拉取到tagid为123和456的下的单,非平台型小程序无需填写该字段
  344. }
  345. // Update 更新打印员。若需要使用微信打单 PC 软件,才需要调用。
  346. func (updater *PrinterUpdater) Update(token string) (*CommonError, error) {
  347. api := baseURL + apiUpdatePrinter
  348. return updater.update(api, token)
  349. }
  350. func (updater *PrinterUpdater) update(api, token string) (*CommonError, error) {
  351. url, err := tokenAPI(api, token)
  352. if err != nil {
  353. return nil, err
  354. }
  355. res := new(CommonError)
  356. if err := postJSON(url, updater, res); err != nil {
  357. return nil, err
  358. }
  359. return res, nil
  360. }