intracity.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. package express
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/silenceper/wechat/v2/util"
  6. )
  7. // 同城配送 API URL
  8. // https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/intracity_service.html
  9. const (
  10. // 开通门店权限
  11. intracityApplyURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/apply?access_token=%s"
  12. // 创建门店
  13. intracityCreateStoreURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/createstore?access_token=%s"
  14. // 查询门店
  15. intracityQueryStoreURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/querystore?access_token=%s"
  16. // 更新门店
  17. intracityUpdateStoreURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/updatestore?access_token=%s"
  18. // 门店运费充值
  19. intracityStoreChargeURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/storecharge?access_token=%s"
  20. // 门店运费退款
  21. intracityStoreRefundURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/storerefund?access_token=%s"
  22. // 门店运费流水查询
  23. intracityQueryFlowURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/queryflow?access_token=%s"
  24. // 门店余额查询
  25. intracityBalanceQueryURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/balancequery?access_token=%s"
  26. // 预下配送单(查询运费)
  27. intracityPreAddOrderURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/preaddorder?access_token=%s"
  28. // 创建配送单
  29. intracityAddOrderURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/addorder?access_token=%s"
  30. // 查询配送单
  31. intracityQueryOrderURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/queryorder?access_token=%s"
  32. // 取消配送单
  33. intracityCancelOrderURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/cancelorder?access_token=%s"
  34. // 模拟配送回调(仅用于测试)
  35. intracityMockNotifyURL = "https://api.weixin.qq.com/cgi-bin/express/intracity/mocknotify?access_token=%s"
  36. )
  37. // PayMode 充值/扣费主体
  38. type PayMode string
  39. const (
  40. // PayModeStore 门店
  41. PayModeStore PayMode = "PAY_MODE_STORE"
  42. // PayModeApp 小程序
  43. PayModeApp PayMode = "PAY_MODE_APP"
  44. // PayModeComponent 服务商
  45. PayModeComponent PayMode = "PAY_MODE_COMPONENT"
  46. )
  47. // OrderPattern 运力偏好
  48. type OrderPattern uint32
  49. const (
  50. // OrderPatternPriceFirst 价格优先
  51. OrderPatternPriceFirst OrderPattern = 1
  52. // OrderPatternTransFirst 运力优先
  53. OrderPatternTransFirst OrderPattern = 2
  54. )
  55. // FlowType 流水类型
  56. type FlowType uint32
  57. const (
  58. // FlowTypeCharge 充值流水
  59. FlowTypeCharge FlowType = 1
  60. // FlowTypeConsume 消费流水
  61. FlowTypeConsume FlowType = 2
  62. // FlowTypeRefund 退款流水
  63. FlowTypeRefund FlowType = 3
  64. )
  65. // IntracityDeliveryStatus 配送单状态
  66. type IntracityDeliveryStatus int32
  67. const (
  68. // IntracityDeliveryStatusReady 配送单待接单
  69. IntracityDeliveryStatusReady IntracityDeliveryStatus = 100
  70. // IntracityDeliveryStatusPickedUp 配送单待取货
  71. IntracityDeliveryStatusPickedUp IntracityDeliveryStatus = 101
  72. // IntracityDeliveryStatusOngoing 配送单配送中
  73. IntracityDeliveryStatusOngoing IntracityDeliveryStatus = 102
  74. // IntracityDeliveryStatusFinished 配送单已送达
  75. IntracityDeliveryStatusFinished IntracityDeliveryStatus = 200
  76. // IntracityDeliveryStatusCancelled 配送单已取消
  77. IntracityDeliveryStatusCancelled IntracityDeliveryStatus = 300
  78. // IntracityDeliveryStatusAbnormal 配送单异常
  79. IntracityDeliveryStatusAbnormal IntracityDeliveryStatus = 400
  80. )
  81. // IntracityAddressInfo 门店地址信息
  82. type IntracityAddressInfo struct {
  83. Province string `json:"province"` // 省/自治区/直辖市
  84. City string `json:"city"` // 地级市
  85. Area string `json:"area"` // 县/县级市/区
  86. Street string `json:"street"` // 街道
  87. House string `json:"house"` // 具体门牌号或详细地址
  88. Lat float64 `json:"lat"` // 门店所在地纬度
  89. Lng float64 `json:"lng"` // 门店所在地经度
  90. Phone string `json:"phone"` // 门店联系电话
  91. Name string `json:"name,omitempty"` // 联系人姓名(收货地址时使用)
  92. }
  93. // IntracityStoreInfo 门店信息
  94. type IntracityStoreInfo struct {
  95. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  96. OutStoreID string `json:"out_store_id"` // 自定义门店编号
  97. CityID string `json:"city_id"` // 门店所在城市ID
  98. StoreName string `json:"store_name"` // 门店名称
  99. OrderPattern OrderPattern `json:"order_pattern"` // 运力偏好
  100. ServiceTransPrefer string `json:"service_trans_prefer"` // 优先使用的运力ID
  101. AddressInfo IntracityAddressInfo `json:"address_info"` // 门店地址信息
  102. }
  103. // ============ 门店管理接口 ============
  104. // IntracityApply 开通门店权限
  105. // https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/intracity_service.html
  106. func (express *Express) IntracityApply(ctx context.Context) error {
  107. accessToken, err := express.GetAccessToken()
  108. if err != nil {
  109. return err
  110. }
  111. uri := fmt.Sprintf(intracityApplyURL, accessToken)
  112. response, err := util.PostJSONContext(ctx, uri, map[string]interface{}{})
  113. if err != nil {
  114. return err
  115. }
  116. return util.DecodeWithCommonError(response, "IntracityApply")
  117. }
  118. // CreateStoreRequest 创建门店请求参数
  119. type CreateStoreRequest struct {
  120. OutStoreID string `json:"out_store_id"` // 自定义门店编号
  121. StoreName string `json:"store_name"` // 门店名称
  122. OrderPattern OrderPattern `json:"order_pattern,omitempty"` // 运力偏好:1-价格优先,2-运力优先
  123. ServiceTransPrefer string `json:"service_trans_prefer,omitempty"` // 优先使用的运力ID,order_pattern=2时必填
  124. AddressInfo IntracityAddressInfo `json:"address_info"` // 门店地址信息
  125. }
  126. // CreateStoreResponse 创建门店返回参数
  127. type CreateStoreResponse struct {
  128. util.CommonError
  129. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  130. AppID string `json:"appid"` // 小程序appid
  131. OutStoreID string `json:"out_store_id"` // 自定义门店ID
  132. }
  133. // IntracityCreateStore 创建门店
  134. func (express *Express) IntracityCreateStore(ctx context.Context, req *CreateStoreRequest) (res CreateStoreResponse, err error) {
  135. accessToken, err := express.GetAccessToken()
  136. if err != nil {
  137. return
  138. }
  139. uri := fmt.Sprintf(intracityCreateStoreURL, accessToken)
  140. response, err := util.PostJSONContext(ctx, uri, req)
  141. if err != nil {
  142. return
  143. }
  144. err = util.DecodeWithError(response, &res, "IntracityCreateStore")
  145. return
  146. }
  147. // QueryStoreRequest 查询门店请求参数
  148. type QueryStoreRequest struct {
  149. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号
  150. OutStoreID string `json:"out_store_id,omitempty"` // 自定义门店编号
  151. }
  152. // QueryStoreResponse 查询门店返回参数
  153. type QueryStoreResponse struct {
  154. util.CommonError
  155. Total uint32 `json:"total"` // 符合条件的门店总数
  156. AppID string `json:"appid"` // 小程序appid
  157. StoreList []IntracityStoreInfo `json:"store_list"` // 门店信息列表
  158. }
  159. // IntracityQueryStore 查询门店
  160. func (express *Express) IntracityQueryStore(ctx context.Context, req *QueryStoreRequest) (res QueryStoreResponse, err error) {
  161. accessToken, err := express.GetAccessToken()
  162. if err != nil {
  163. return
  164. }
  165. uri := fmt.Sprintf(intracityQueryStoreURL, accessToken)
  166. response, err := util.PostJSONContext(ctx, uri, req)
  167. if err != nil {
  168. return
  169. }
  170. err = util.DecodeWithError(response, &res, "IntracityQueryStore")
  171. return
  172. }
  173. // UpdateStoreKeyInfo 更新门店的key信息
  174. type UpdateStoreKeyInfo struct {
  175. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号
  176. OutStoreID string `json:"out_store_id,omitempty"` // 自定义门店编号,二选一
  177. }
  178. // UpdateStoreContent 更新门店的内容
  179. type UpdateStoreContent struct {
  180. StoreName string `json:"store_name,omitempty"` // 门店名称
  181. OrderPattern OrderPattern `json:"order_pattern,omitempty"` // 运力偏好
  182. ServiceTransPrefer string `json:"service_trans_prefer,omitempty"` // 优先使用的运力ID
  183. AddressInfo *IntracityAddressInfo `json:"address_info,omitempty"` // 门店地址信息
  184. }
  185. // UpdateStoreRequest 更新门店请求参数
  186. type UpdateStoreRequest struct {
  187. Keys UpdateStoreKeyInfo `json:"keys"` // 门店编号
  188. Content UpdateStoreContent `json:"content"` // 更新内容
  189. }
  190. // IntracityUpdateStore 更新门店
  191. func (express *Express) IntracityUpdateStore(ctx context.Context, req *UpdateStoreRequest) error {
  192. accessToken, err := express.GetAccessToken()
  193. if err != nil {
  194. return err
  195. }
  196. uri := fmt.Sprintf(intracityUpdateStoreURL, accessToken)
  197. response, err := util.PostJSONContext(ctx, uri, req)
  198. if err != nil {
  199. return err
  200. }
  201. return util.DecodeWithCommonError(response, "IntracityUpdateStore")
  202. }
  203. // ============ 充值退款接口 ============
  204. // StoreChargeRequest 门店运费充值请求参数
  205. type StoreChargeRequest struct {
  206. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号,pay_mode=PAY_MODE_STORE时必传
  207. ServiceTransID string `json:"service_trans_id"` // 运力ID
  208. Amount uint32 `json:"amount"` // 充值金额,单位:分,50元起充
  209. PayMode PayMode `json:"pay_mode,omitempty"` // 充值主体
  210. }
  211. // StoreChargeResponse 门店运费充值返回参数
  212. type StoreChargeResponse struct {
  213. util.CommonError
  214. PayURL string `json:"payurl"` // 充值页面地址
  215. AppID string `json:"appid"` // 小程序appid
  216. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  217. }
  218. // IntracityStoreCharge 门店运费充值
  219. func (express *Express) IntracityStoreCharge(ctx context.Context, req *StoreChargeRequest) (res StoreChargeResponse, err error) {
  220. accessToken, err := express.GetAccessToken()
  221. if err != nil {
  222. return
  223. }
  224. uri := fmt.Sprintf(intracityStoreChargeURL, accessToken)
  225. response, err := util.PostJSONContext(ctx, uri, req)
  226. if err != nil {
  227. return
  228. }
  229. err = util.DecodeWithError(response, &res, "IntracityStoreCharge")
  230. return
  231. }
  232. // StoreRefundRequest 门店运费退款请求参数
  233. type StoreRefundRequest struct {
  234. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号
  235. PayMode PayMode `json:"pay_mode,omitempty"` // 充值/扣费主体
  236. ServiceTransID string `json:"service_trans_id"` // 运力ID
  237. }
  238. // StoreRefundResponse 门店运费退款返回参数
  239. type StoreRefundResponse struct {
  240. util.CommonError
  241. AppID string `json:"appid"` // 小程序appid
  242. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  243. RefundAmount uint32 `json:"refund_amount"` // 退款金额,单位:分
  244. }
  245. // IntracityStoreRefund 门店运费退款
  246. func (express *Express) IntracityStoreRefund(ctx context.Context, req *StoreRefundRequest) (res StoreRefundResponse, err error) {
  247. accessToken, err := express.GetAccessToken()
  248. if err != nil {
  249. return
  250. }
  251. uri := fmt.Sprintf(intracityStoreRefundURL, accessToken)
  252. response, err := util.PostJSONContext(ctx, uri, req)
  253. if err != nil {
  254. return
  255. }
  256. err = util.DecodeWithError(response, &res, "IntracityStoreRefund")
  257. return
  258. }
  259. // QueryFlowRequest 门店运费流水查询请求参数
  260. type QueryFlowRequest struct {
  261. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  262. FlowType FlowType `json:"flow_type"` // 流水类型:1-充值,2-消费,3-退款
  263. ServiceTransID string `json:"service_trans_id,omitempty"` // 运力ID
  264. BeginTime uint32 `json:"begin_time,omitempty"` // 开始时间戳
  265. EndTime uint32 `json:"end_time,omitempty"` // 结束时间戳
  266. PayMode PayMode `json:"pay_mode"` // 扣费主体
  267. }
  268. // FlowRecordInfo 流水记录信息
  269. type FlowRecordInfo struct {
  270. FlowType FlowType `json:"flow_type"` // 流水类型
  271. AppID string `json:"appid"` // appid
  272. WxStoreID string `json:"wx_store_id"` // 微信门店ID
  273. PayOrderID uint64 `json:"pay_order_id,omitempty"` // 充值订单号
  274. WxOrderID string `json:"wx_order_id,omitempty"` // 订单ID(消费流水)
  275. ServiceTransID string `json:"service_trans_id"` // 运力ID
  276. OpenID string `json:"openid,omitempty"` // 用户openid(消费流水)
  277. DeliveryStatus int32 `json:"delivery_status,omitempty"` // 运单状态(消费流水)
  278. PayAmount int32 `json:"pay_amount"` // 支付金额,单位:分
  279. PayTime uint32 `json:"pay_time,omitempty"` // 支付时间
  280. PayStatus string `json:"pay_status,omitempty"` // 支付状态
  281. RefundStatus string `json:"refund_status,omitempty"` // 退款状态
  282. RefundAmount int32 `json:"refund_amount,omitempty"` // 退款金额
  283. RefundTime uint32 `json:"refund_time,omitempty"` // 退款时间
  284. DeductAmount int32 `json:"deduct_amount,omitempty"` // 扣除违约金
  285. CreateTime uint32 `json:"create_time"` // 创建时间
  286. ConsumeDeadline uint32 `json:"consume_deadline,omitempty"` // 有效截止日期
  287. BillID string `json:"bill_id,omitempty"` // 运单ID
  288. DeliveryFinishedTime uint32 `json:"delivery_finished_time,omitempty"` // 运单完成配送的时间
  289. }
  290. // QueryFlowResponse 门店运费流水查询返回参数
  291. type QueryFlowResponse struct {
  292. util.CommonError
  293. Total uint32 `json:"total"` // 总数
  294. FlowList []FlowRecordInfo `json:"flow_list"` // 流水数组
  295. TotalPayAmt int `json:"total_pay_amt"` // 总支付金额
  296. TotalRefundAmt int `json:"total_refund_amt"` // 总退款金额
  297. TotalDeductAmt int `json:"total_deduct_amt"` // 总违约金(消费流水返回)
  298. }
  299. // IntracityQueryFlow 门店运费流水查询
  300. func (express *Express) IntracityQueryFlow(ctx context.Context, req *QueryFlowRequest) (res QueryFlowResponse, err error) {
  301. accessToken, err := express.GetAccessToken()
  302. if err != nil {
  303. return
  304. }
  305. uri := fmt.Sprintf(intracityQueryFlowURL, accessToken)
  306. response, err := util.PostJSONContext(ctx, uri, req)
  307. if err != nil {
  308. return
  309. }
  310. err = util.DecodeWithError(response, &res, "IntracityQueryFlow")
  311. return
  312. }
  313. // BalanceQueryRequest 门店余额查询请求参数
  314. type BalanceQueryRequest struct {
  315. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号
  316. ServiceTransID string `json:"service_trans_id,omitempty"` // 运力ID
  317. PayMode PayMode `json:"pay_mode,omitempty"` // 充值/扣费主体
  318. }
  319. // BalanceInfo 余额信息
  320. type BalanceInfo struct {
  321. ServiceTransID string `json:"service_trans_id"` // 运力ID
  322. Balance int32 `json:"balance"` // 余额,单位:分
  323. }
  324. // BalanceQueryResponse 门店余额查询返回参数
  325. type BalanceQueryResponse struct {
  326. util.CommonError
  327. AppID string `json:"appid"` // 小程序appid
  328. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  329. BalanceList []BalanceInfo `json:"balance_list"` // 余额列表
  330. }
  331. // IntracityBalanceQuery 门店余额查询
  332. func (express *Express) IntracityBalanceQuery(ctx context.Context, req *BalanceQueryRequest) (res BalanceQueryResponse, err error) {
  333. accessToken, err := express.GetAccessToken()
  334. if err != nil {
  335. return
  336. }
  337. uri := fmt.Sprintf(intracityBalanceQueryURL, accessToken)
  338. response, err := util.PostJSONContext(ctx, uri, req)
  339. if err != nil {
  340. return
  341. }
  342. err = util.DecodeWithError(response, &res, "IntracityBalanceQuery")
  343. return
  344. }
  345. // ============ 配送订单接口 ============
  346. // CargoInfo 货物信息
  347. type CargoInfo struct {
  348. Name string `json:"name"` // 货物名称
  349. Num uint32 `json:"num,omitempty"` // 货物数量
  350. Price uint32 `json:"price,omitempty"` // 货物价格,单位:分
  351. Weight uint32 `json:"weight,omitempty"` // 货物重量,单位:克
  352. }
  353. // PreAddOrderRequest 预下配送单请求参数
  354. type PreAddOrderRequest struct {
  355. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号,二选一
  356. OutStoreID string `json:"out_store_id,omitempty"` // 自定义门店编号,二选一
  357. UserOpenID string `json:"user_openid"` // 用户openid
  358. UserPhone string `json:"user_phone,omitempty"` // 用户联系电话
  359. UserName string `json:"user_name,omitempty"` // 用户姓名
  360. UserLat float64 `json:"user_lat"` // 用户地址纬度
  361. UserLng float64 `json:"user_lng"` // 用户地址经度
  362. UserAddress string `json:"user_address"` // 用户详细地址
  363. ServiceTransID string `json:"service_trans_id,omitempty"` // 运力ID,不传则查询所有运力
  364. PayMode PayMode `json:"pay_mode,omitempty"` // 充值/扣费主体
  365. CargoInfo *CargoInfo `json:"cargo_info,omitempty"` // 货物信息
  366. }
  367. // TransInfo 运力信息
  368. type TransInfo struct {
  369. ServiceTransID string `json:"service_trans_id"` // 运力ID
  370. ServiceName string `json:"service_name"` // 运力名称
  371. Price uint32 `json:"price"` // 配送费用,单位:分
  372. Distance uint32 `json:"distance"` // 配送距离,单位:米
  373. Errcode int `json:"errcode"` // 错误码,0表示成功
  374. Errmsg string `json:"errmsg"` // 错误信息
  375. }
  376. // PreAddOrderResponse 预下配送单返回参数
  377. type PreAddOrderResponse struct {
  378. util.CommonError
  379. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  380. AppID string `json:"appid"` // 小程序appid
  381. TransList []TransInfo `json:"trans_list"` // 运力列表
  382. }
  383. // IntracityPreAddOrder 预下配送单(查询运费)
  384. func (express *Express) IntracityPreAddOrder(ctx context.Context, req *PreAddOrderRequest) (res PreAddOrderResponse, err error) {
  385. accessToken, err := express.GetAccessToken()
  386. if err != nil {
  387. return
  388. }
  389. uri := fmt.Sprintf(intracityPreAddOrderURL, accessToken)
  390. response, err := util.PostJSONContext(ctx, uri, req)
  391. if err != nil {
  392. return
  393. }
  394. err = util.DecodeWithError(response, &res, "IntracityPreAddOrder")
  395. return
  396. }
  397. // AddOrderRequest 创建配送单请求参数
  398. type AddOrderRequest struct {
  399. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号,二选一
  400. OutStoreID string `json:"out_store_id,omitempty"` // 自定义门店编号,二选一
  401. OutOrderID string `json:"out_order_id"` // 自定义订单号,需唯一
  402. ServiceTransID string `json:"service_trans_id,omitempty"` // 运力ID
  403. UserOpenID string `json:"user_openid"` // 用户openid
  404. UserPhone string `json:"user_phone"` // 用户联系电话
  405. UserName string `json:"user_name"` // 用户姓名
  406. UserLat float64 `json:"user_lat"` // 用户地址纬度
  407. UserLng float64 `json:"user_lng"` // 用户地址经度
  408. UserAddress string `json:"user_address"` // 用户详细地址
  409. PayMode PayMode `json:"pay_mode,omitempty"` // 充值/扣费主体
  410. CargoInfo *CargoInfo `json:"cargo_info,omitempty"` // 货物信息
  411. OrderDetailPath string `json:"order_detail_path,omitempty"` // 订单详情页路径
  412. CallbackURL string `json:"callback_url,omitempty"` // 配送状态回调URL
  413. UseInsurance uint32 `json:"use_insurance,omitempty"` // 是否使用保价:0-不使用,1-使用
  414. InsuranceValue uint32 `json:"insurance_value,omitempty"` // 保价金额,单位:分
  415. ExpectTime uint32 `json:"expect_time,omitempty"` // 期望送达时间戳
  416. Remark string `json:"remark,omitempty"` // 备注
  417. }
  418. // AddOrderResponse 创建配送单返回参数
  419. type AddOrderResponse struct {
  420. util.CommonError
  421. WxOrderID string `json:"wx_order_id"` // 微信订单号
  422. AppID string `json:"appid"` // 小程序appid
  423. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  424. OutOrderID string `json:"out_order_id"` // 自定义订单号
  425. ServiceTransID string `json:"service_trans_id"` // 运力ID
  426. BillID string `json:"bill_id"` // 运力订单号
  427. Price uint32 `json:"price"` // 配送费用,单位:分
  428. Distance uint32 `json:"distance"` // 配送距离,单位:米
  429. }
  430. // IntracityAddOrder 创建配送单
  431. func (express *Express) IntracityAddOrder(ctx context.Context, req *AddOrderRequest) (res AddOrderResponse, err error) {
  432. accessToken, err := express.GetAccessToken()
  433. if err != nil {
  434. return
  435. }
  436. uri := fmt.Sprintf(intracityAddOrderURL, accessToken)
  437. response, err := util.PostJSONContext(ctx, uri, req)
  438. if err != nil {
  439. return
  440. }
  441. err = util.DecodeWithError(response, &res, "IntracityAddOrder")
  442. return
  443. }
  444. // QueryOrderRequest 查询配送单请求参数
  445. type QueryOrderRequest struct {
  446. WxOrderID string `json:"wx_order_id,omitempty"` // 微信订单号,二选一
  447. OutOrderID string `json:"out_order_id,omitempty"` // 自定义订单号,二选一
  448. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号
  449. OutStoreID string `json:"out_store_id,omitempty"` // 自定义门店编号
  450. }
  451. // RiderInfo 骑手信息
  452. type RiderInfo struct {
  453. Name string `json:"name"` // 骑手姓名
  454. Phone string `json:"phone"` // 骑手电话
  455. RiderCode string `json:"rider_code"` // 骑手编号
  456. RiderImgURL string `json:"rider_img_url"` // 骑手头像URL
  457. }
  458. // QueryOrderResponse 查询配送单返回参数
  459. type QueryOrderResponse struct {
  460. util.CommonError
  461. WxOrderID string `json:"wx_order_id"` // 微信订单号
  462. AppID string `json:"appid"` // 小程序appid
  463. WxStoreID string `json:"wx_store_id"` // 微信门店编号
  464. OutOrderID string `json:"out_order_id"` // 自定义订单号
  465. ServiceTransID string `json:"service_trans_id"` // 运力ID
  466. BillID string `json:"bill_id"` // 运力订单号
  467. DeliveryStatus IntracityDeliveryStatus `json:"delivery_status"` // 配送状态
  468. Price uint32 `json:"price"` // 配送费用,单位:分
  469. Distance uint32 `json:"distance"` // 配送距离,单位:米
  470. CreateTime uint32 `json:"create_time"` // 订单创建时间
  471. RiderInfo *RiderInfo `json:"rider_info"` // 骑手信息
  472. FinishTime uint32 `json:"finish_time"` // 订单完成时间
  473. }
  474. // IntracityQueryOrder 查询配送单
  475. func (express *Express) IntracityQueryOrder(ctx context.Context, req *QueryOrderRequest) (res QueryOrderResponse, err error) {
  476. accessToken, err := express.GetAccessToken()
  477. if err != nil {
  478. return
  479. }
  480. uri := fmt.Sprintf(intracityQueryOrderURL, accessToken)
  481. response, err := util.PostJSONContext(ctx, uri, req)
  482. if err != nil {
  483. return
  484. }
  485. err = util.DecodeWithError(response, &res, "IntracityQueryOrder")
  486. return
  487. }
  488. // CancelOrderRequest 取消配送单请求参数
  489. type CancelOrderRequest struct {
  490. WxOrderID string `json:"wx_order_id,omitempty"` // 微信订单号,二选一
  491. OutOrderID string `json:"out_order_id,omitempty"` // 自定义订单号,二选一
  492. WxStoreID string `json:"wx_store_id,omitempty"` // 微信门店编号
  493. OutStoreID string `json:"out_store_id,omitempty"` // 自定义门店编号
  494. CancelReason string `json:"cancel_reason,omitempty"` // 取消原因
  495. }
  496. // CancelOrderResponse 取消配送单返回参数
  497. type CancelOrderResponse struct {
  498. util.CommonError
  499. WxOrderID string `json:"wx_order_id"` // 微信订单号
  500. RefundAmount int32 `json:"refund_amount"` // 退款金额,单位:分
  501. DeductAmount int32 `json:"deduct_amount"` // 扣除违约金,单位:分
  502. }
  503. // IntracityCancelOrder 取消配送单
  504. func (express *Express) IntracityCancelOrder(ctx context.Context, req *CancelOrderRequest) (res CancelOrderResponse, err error) {
  505. accessToken, err := express.GetAccessToken()
  506. if err != nil {
  507. return
  508. }
  509. uri := fmt.Sprintf(intracityCancelOrderURL, accessToken)
  510. response, err := util.PostJSONContext(ctx, uri, req)
  511. if err != nil {
  512. return
  513. }
  514. err = util.DecodeWithError(response, &res, "IntracityCancelOrder")
  515. return
  516. }
  517. // MockNotifyRequest 模拟配送回调请求参数(仅用于测试)
  518. type MockNotifyRequest struct {
  519. WxOrderID string `json:"wx_order_id"` // 微信订单号
  520. DeliveryStatus IntracityDeliveryStatus `json:"delivery_status"` // 配送状态
  521. }
  522. // IntracityMockNotify 模拟配送回调(仅用于测试)
  523. func (express *Express) IntracityMockNotify(ctx context.Context, req *MockNotifyRequest) error {
  524. accessToken, err := express.GetAccessToken()
  525. if err != nil {
  526. return err
  527. }
  528. uri := fmt.Sprintf(intracityMockNotifyURL, accessToken)
  529. response, err := util.PostJSONContext(ctx, uri, req)
  530. if err != nil {
  531. return err
  532. }
  533. return util.DecodeWithCommonError(response, "IntracityMockNotify")
  534. }