message.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. package message
  2. import (
  3. "encoding/json"
  4. "encoding/xml"
  5. "errors"
  6. "io"
  7. "net/http"
  8. "sort"
  9. "strings"
  10. "github.com/tidwall/gjson"
  11. "github.com/silenceper/wechat/v2/miniprogram/context"
  12. "github.com/silenceper/wechat/v2/miniprogram/security"
  13. "github.com/silenceper/wechat/v2/util"
  14. )
  15. // ConfirmReceiveMethod 确认收货方式
  16. type ConfirmReceiveMethod int8
  17. const (
  18. // EventTypeTradeManageRemindAccessAPI 提醒接入发货信息管理服务 API
  19. // 小程序完成账期授权时/小程序产生第一笔交易时/已产生交易但从未发货的小程序,每天一次
  20. EventTypeTradeManageRemindAccessAPI EventType = "trade_manage_remind_access_api"
  21. // EventTypeTradeManageRemindShipping 提醒需要上传发货信息
  22. // 曾经发过货的小程序,订单超过 48 小时未发货时
  23. EventTypeTradeManageRemindShipping EventType = "trade_manage_remind_shipping"
  24. // EventTypeTradeManageOrderSettlement 订单将要结算或已经结算
  25. // 订单完成发货时/订单结算时
  26. EventTypeTradeManageOrderSettlement EventType = "trade_manage_order_settlement"
  27. // EventTypeAddExpressPath 运单轨迹更新事件
  28. EventTypeAddExpressPath EventType = "add_express_path"
  29. // EventTypeSecvodUpload 短剧媒资上传完成事件
  30. EventTypeSecvodUpload EventType = "secvod_upload_event"
  31. // EventTypeSecvodAudit 短剧媒资审核状态事件
  32. EventTypeSecvodAudit EventType = "secvod_audit_event"
  33. // EventTypeWxaMediaCheck 媒体内容安全异步审查结果通知
  34. EventTypeWxaMediaCheck EventType = "wxa_media_check"
  35. // EventTypeXpayGoodsDeliverNotify 道具发货推送事件
  36. EventTypeXpayGoodsDeliverNotify EventType = "xpay_goods_deliver_notify"
  37. // EventTypeXpayCoinPayNotify 代币支付推送事件
  38. EventTypeXpayCoinPayNotify EventType = "xpay_coin_pay_notify"
  39. // EventTypeXpayRefundNotify 退款推送事件
  40. EventTypeXpayRefundNotify EventType = "xpay_refund_notify"
  41. // EventTypeXpaySubscribeIosRefundQueryNotify iOS Apple 支付退款问询事件
  42. EventTypeXpaySubscribeIosRefundQueryNotify EventType = "xpay_subscribe_ios_refund_query_notify"
  43. // EventTypeXpayComplaintNotify 用户投诉推送事件
  44. EventTypeXpayComplaintNotify EventType = "xpay_complaint_notify"
  45. // EventSubscribePopup 用户操作订阅通知弹窗事件推送,用户在图文等场景内订阅通知的操作
  46. EventSubscribePopup EventType = "subscribe_msg_popup_event"
  47. // EventSubscribeMsgChange 用户管理订阅通知,用户在服务通知管理页面做通知管理时的操作
  48. EventSubscribeMsgChange EventType = "subscribe_msg_change_event"
  49. // EventSubscribeMsgSent 发送订阅通知,调用 bizsend 接口发送通知
  50. EventSubscribeMsgSent EventType = "subscribe_msg_sent_event"
  51. // ConfirmReceiveMethodAuto 自动确认收货
  52. ConfirmReceiveMethodAuto ConfirmReceiveMethod = 1
  53. // ConfirmReceiveMethodManual 手动确认收货
  54. ConfirmReceiveMethodManual ConfirmReceiveMethod = 2
  55. )
  56. const (
  57. // InfoTypeAcceptSubscribeMessage 接受订阅通知
  58. InfoTypeAcceptSubscribeMessage InfoType = "accept"
  59. // InfoTypeRejectSubscribeMessage 拒绝订阅通知
  60. InfoTypeRejectSubscribeMessage InfoType = "reject"
  61. )
  62. // PushReceiver 接收消息推送
  63. // 暂仅支付 Aes 加密方式
  64. type PushReceiver struct {
  65. *context.Context
  66. }
  67. // NewPushReceiver 实例化
  68. func NewPushReceiver(ctx *context.Context) *PushReceiver {
  69. return &PushReceiver{
  70. Context: ctx,
  71. }
  72. }
  73. // GetMsg 获取接收到的消息 (如果是加密的返回解密数据)
  74. func (receiver *PushReceiver) GetMsg(r *http.Request) (string, []byte, error) {
  75. // 判断请求格式
  76. var dataType string
  77. contentType := r.Header.Get("Content-Type")
  78. if strings.HasPrefix(contentType, "text/xml") {
  79. // xml 格式
  80. dataType = DataTypeXML
  81. } else {
  82. // json 格式
  83. dataType = DataTypeJSON
  84. }
  85. // 读取参数,验证签名
  86. signature := r.FormValue("signature")
  87. timestamp := r.FormValue("timestamp")
  88. nonce := r.FormValue("nonce")
  89. encryptType := r.FormValue("encrypt_type")
  90. // 验证签名
  91. tmpArr := []string{
  92. receiver.Token,
  93. timestamp,
  94. nonce,
  95. }
  96. sort.Strings(tmpArr)
  97. tmpSignature := util.Signature(tmpArr...)
  98. if tmpSignature != signature {
  99. return dataType, nil, errors.New("signature error")
  100. }
  101. if encryptType == "aes" {
  102. // 解密
  103. var reqData DataReceived
  104. if dataType == DataTypeXML {
  105. if err := xml.NewDecoder(r.Body).Decode(&reqData); err != nil {
  106. return dataType, nil, err
  107. }
  108. } else {
  109. if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
  110. return dataType, nil, err
  111. }
  112. }
  113. _, rawMsgBytes, err := util.DecryptMsg(receiver.AppID, reqData.Encrypt, receiver.EncodingAESKey)
  114. return dataType, rawMsgBytes, err
  115. }
  116. // 不加密
  117. byteData, err := io.ReadAll(r.Body)
  118. return dataType, byteData, err
  119. }
  120. // GetMsgData 获取接收到的消息 (解密数据)
  121. func (receiver *PushReceiver) GetMsgData(r *http.Request) (MsgType, EventType, PushData, error) {
  122. dataType, decryptMsg, err := receiver.GetMsg(r)
  123. if err != nil {
  124. return "", "", nil, err
  125. }
  126. var (
  127. msgType MsgType
  128. eventType EventType
  129. )
  130. if dataType == DataTypeXML {
  131. var commonToken CommonPushData
  132. if err := xml.Unmarshal(decryptMsg, &commonToken); err != nil {
  133. return "", "", nil, err
  134. }
  135. msgType, eventType = commonToken.MsgType, commonToken.Event
  136. } else {
  137. var commonToken CommonPushData
  138. if err := json.Unmarshal(decryptMsg, &commonToken); err != nil {
  139. return "", "", nil, err
  140. }
  141. msgType, eventType = commonToken.MsgType, commonToken.Event
  142. }
  143. if msgType == MsgTypeEvent {
  144. pushData, err := receiver.getEvent(dataType, eventType, decryptMsg)
  145. // 暂不支持其他事件类型
  146. return msgType, eventType, pushData, err
  147. }
  148. // 暂不支持其他消息类型
  149. return msgType, eventType, decryptMsg, nil
  150. }
  151. // getEvent 获取事件推送的数据
  152. func (receiver *PushReceiver) getEvent(dataType string, eventType EventType, decryptMsg []byte) (PushData, error) {
  153. switch eventType {
  154. case EventTypeTradeManageRemindAccessAPI:
  155. // 提醒接入发货信息管理服务 API
  156. var pushData PushDataRemindAccessAPI
  157. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  158. return &pushData, err
  159. case EventTypeTradeManageRemindShipping:
  160. // 提醒需要上传发货信息
  161. var pushData PushDataRemindShipping
  162. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  163. return &pushData, err
  164. case EventTypeTradeManageOrderSettlement:
  165. // 订单将要结算或已经结算
  166. var pushData PushDataOrderSettlement
  167. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  168. return &pushData, err
  169. case EventTypeWxaMediaCheck:
  170. // 媒体内容安全异步审查结果通知
  171. var pushData MediaCheckAsyncData
  172. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  173. return &pushData, err
  174. case EventTypeAddExpressPath:
  175. // 运单轨迹更新
  176. var pushData PushDataAddExpressPath
  177. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  178. return &pushData, err
  179. case EventTypeSecvodUpload:
  180. // 短剧媒资上传完成
  181. var pushData PushDataSecVodUpload
  182. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  183. return &pushData, err
  184. case EventTypeSecvodAudit:
  185. // 短剧媒资审核状态
  186. var pushData PushDataSecVodAudit
  187. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  188. return &pushData, err
  189. case EventTypeXpayGoodsDeliverNotify:
  190. // 道具发货推送事件
  191. var pushData PushDataXpayGoodsDeliverNotify
  192. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  193. return &pushData, err
  194. case EventTypeXpayCoinPayNotify:
  195. // 代币支付推送事件
  196. var pushData PushDataXpayCoinPayNotify
  197. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  198. return &pushData, err
  199. case EventTypeXpayRefundNotify:
  200. // 退款推送事件
  201. return receiver.unmarshalPushData(dataType, decryptMsg, &PushDataXpayRefundNotify{})
  202. case EventTypeXpaySubscribeIosRefundQueryNotify: // iOS Apple 支付退款问询事件
  203. return receiver.unmarshalPushData(dataType, decryptMsg, &PushDataXpaySubscribeIosRefundQueryNotify{})
  204. case EventTypeXpayComplaintNotify:
  205. // 用户投诉推送事件
  206. return receiver.unmarshalPushData(dataType, decryptMsg, &PushDataXpayComplaintNotify{})
  207. case EventSubscribePopup:
  208. // 用户操作订阅通知弹窗事件推送
  209. return receiver.unmarshalSubscribePopup(dataType, decryptMsg)
  210. case EventSubscribeMsgChange:
  211. // 用户管理订阅通知事件推送
  212. return receiver.unmarshalSubscribeMsgChange(dataType, decryptMsg)
  213. case EventSubscribeMsgSent:
  214. // 用户发送订阅通知事件推送
  215. return receiver.unmarshalSubscribeMsgSent(dataType, decryptMsg)
  216. }
  217. // 暂不支持其他事件类型,直接返回解密后的数据,由调用方处理
  218. return decryptMsg, nil
  219. }
  220. // unmarshal 解析推送的数据
  221. func (receiver *PushReceiver) unmarshal(dataType string, decryptMsg []byte, pushData interface{}) error {
  222. if dataType == DataTypeXML {
  223. return xml.Unmarshal(decryptMsg, pushData)
  224. }
  225. return json.Unmarshal(decryptMsg, pushData)
  226. }
  227. // unmarshalPushData unmarshal push data helper
  228. func (receiver *PushReceiver) unmarshalPushData(dataType string, decryptMsg []byte, pushData interface{}) (PushData, error) {
  229. err := receiver.unmarshal(dataType, decryptMsg, pushData)
  230. return pushData, err
  231. }
  232. // unmarshalSubscribePopup
  233. func (receiver *PushReceiver) unmarshalSubscribePopup(dataType string, decryptMsg []byte) (PushData, error) {
  234. var pushData PushDataSubscribePopup
  235. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  236. if err == nil {
  237. listData := gjson.Get(string(decryptMsg), "List")
  238. if listData.IsObject() {
  239. listItem := SubscribeMsgPopupEventList{}
  240. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil {
  241. return &pushData, parseErr
  242. }
  243. pushData.SetSubscribeMsgPopupEvents([]SubscribeMsgPopupEventList{listItem})
  244. } else if listData.IsArray() {
  245. listItems := make([]SubscribeMsgPopupEventList, 0)
  246. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil {
  247. return &pushData, parseErr
  248. }
  249. pushData.SetSubscribeMsgPopupEvents(listItems)
  250. }
  251. }
  252. return &pushData, err
  253. }
  254. // unmarshalSubscribeMsgChange 解析用户管理订阅通知事件推送
  255. func (receiver *PushReceiver) unmarshalSubscribeMsgChange(dataType string, decryptMsg []byte) (PushData, error) {
  256. var pushData PushDataSubscribeMsgChange
  257. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  258. if err == nil {
  259. listData := gjson.Get(string(decryptMsg), "List")
  260. if listData.IsObject() {
  261. listItem := SubscribeMsgChangeList{}
  262. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil {
  263. return &pushData, parseErr
  264. }
  265. pushData.SetSubscribeMsgChangeEvents([]SubscribeMsgChangeList{listItem})
  266. } else if listData.IsArray() {
  267. listItems := make([]SubscribeMsgChangeList, 0)
  268. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil {
  269. return &pushData, parseErr
  270. }
  271. pushData.SetSubscribeMsgChangeEvents(listItems)
  272. }
  273. }
  274. return &pushData, err
  275. }
  276. // unmarshalSubscribeMsgSent 解析用户发送订阅通知事件推送
  277. func (receiver *PushReceiver) unmarshalSubscribeMsgSent(dataType string, decryptMsg []byte) (PushData, error) {
  278. var pushData PushDataSubscribeMsgSent
  279. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  280. if err == nil {
  281. listData := gjson.Get(string(decryptMsg), "List")
  282. if listData.IsObject() {
  283. listItem := SubscribeMsgSentList{}
  284. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil {
  285. return &pushData, parseErr
  286. }
  287. pushData.SetSubscribeMsgSentEvents([]SubscribeMsgSentList{listItem})
  288. } else if listData.IsArray() {
  289. listItems := make([]SubscribeMsgSentList, 0)
  290. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil {
  291. return &pushData, parseErr
  292. }
  293. pushData.SetSubscribeMsgSentEvents(listItems)
  294. }
  295. }
  296. return &pushData, err
  297. }
  298. // DataReceived 接收到的数据
  299. type DataReceived struct {
  300. Encrypt string `json:"Encrypt" xml:"Encrypt"` // 加密的消息体
  301. }
  302. // PushData 推送的数据 (已转对应的结构体)
  303. type PushData interface{}
  304. // CommonPushData 推送数据通用部分
  305. type CommonPushData struct {
  306. XMLName xml.Name `json:"-" xml:"xml"`
  307. MsgType MsgType `json:"MsgType" xml:"MsgType"` // 消息类型,为固定值 "event"
  308. Event EventType `json:"Event" xml:"Event"` // 事件类型
  309. ToUserName string `json:"ToUserName" xml:"ToUserName"` // 小程序的原始 ID
  310. FromUserName string `json:"FromUserName" xml:"FromUserName"` // 发送方账号(一个 OpenID,此时发送方是系统账号)
  311. CreateTime int64 `json:"CreateTime" xml:"CreateTime"` // 消息创建时间(整型),时间戳
  312. }
  313. // MediaCheckAsyncData 媒体内容安全异步审查结果通知
  314. type MediaCheckAsyncData struct {
  315. CommonPushData
  316. Appid string `json:"appid" xml:"appid"`
  317. TraceID string `json:"trace_id" xml:"trace_id"`
  318. Version int `json:"version" xml:"version"`
  319. Detail []*MediaCheckDetail `json:"detail" xml:"detail"`
  320. Errcode int `json:"errcode" xml:"errcode"`
  321. Errmsg string `json:"errmsg" xml:"errmsg"`
  322. Result MediaCheckAsyncResult `json:"result" xml:"result"`
  323. }
  324. // MediaCheckDetail 检测结果详情
  325. type MediaCheckDetail struct {
  326. Strategy string `json:"strategy" xml:"strategy"`
  327. Errcode int `json:"errcode" xml:"errcode"`
  328. Suggest security.CheckSuggest `json:"suggest" xml:"suggest"`
  329. Label int `json:"label" xml:"label"`
  330. Prob int `json:"prob" xml:"prob"`
  331. }
  332. // MediaCheckAsyncResult 检测结果
  333. type MediaCheckAsyncResult struct {
  334. Suggest security.CheckSuggest `json:"suggest" xml:"suggest"`
  335. Label security.CheckLabel `json:"label" xml:"label"`
  336. }
  337. // PushDataOrderSettlement 订单将要结算或已经结算通知
  338. type PushDataOrderSettlement struct {
  339. CommonPushData
  340. TransactionID string `json:"transaction_id" xml:"transaction_id"` // 支付订单号
  341. MerchantID string `json:"merchant_id" xml:"merchant_id"` // 商户号
  342. SubMerchantID string `json:"sub_merchant_id" xml:"sub_merchant_id"` // 子商户号
  343. MerchantTradeNo string `json:"merchant_trade_no" xml:"merchant_trade_no"` // 商户订单号
  344. PayTime int64 `json:"pay_time" xml:"pay_time"` // 支付成功时间,秒级时间戳
  345. ShippedTime int64 `json:"shipped_time" xml:"shipped_time"` // 发货时间,秒级时间戳
  346. EstimatedSettlementTime int64 `json:"estimated_settlement_time" xml:"estimated_settlement_time"` // 预计结算时间,秒级时间戳。发货时推送才有该字段
  347. ConfirmReceiveMethod ConfirmReceiveMethod `json:"confirm_receive_method" xml:"confirm_receive_method"` // 确认收货方式:1. 自动确认收货;2. 手动确认收货。结算时推送才有该字段
  348. ConfirmReceiveTime int64 `json:"confirm_receive_time" xml:"confirm_receive_time"` // 确认收货时间,秒级时间戳。结算时推送才有该字段
  349. SettlementTime int64 `json:"settlement_time" xml:"settlement_time"` // 订单结算时间,秒级时间戳。结算时推送才有该字段
  350. }
  351. // PushDataRemindShipping 提醒需要上传发货信息
  352. type PushDataRemindShipping struct {
  353. CommonPushData
  354. TransactionID string `json:"transaction_id" xml:"transaction_id"` // 微信支付订单号
  355. MerchantID string `json:"merchant_id" xml:"merchant_id"` // 商户号
  356. SubMerchantID string `json:"sub_merchant_id" xml:"sub_merchant_id"` // 子商户号
  357. MerchantTradeNo string `json:"merchant_trade_no" xml:"merchant_trade_no"` // 商户订单号
  358. PayTime int64 `json:"pay_time" xml:"pay_time"` // 支付成功时间,秒级时间戳
  359. Msg string `json:"msg" xml:"msg"` // 消息文本内容
  360. }
  361. // PushDataRemindAccessAPI 提醒接入发货信息管理服务 API 信息
  362. type PushDataRemindAccessAPI struct {
  363. CommonPushData
  364. Msg string `json:"msg" xml:"msg"` // 消息文本内容
  365. }
  366. // PushDataAddExpressPath 运单轨迹更新信息
  367. type PushDataAddExpressPath struct {
  368. CommonPushData
  369. DeliveryID string `json:"DeliveryID" xml:"DeliveryID"` // 快递公司 ID
  370. WayBillID string `json:"WaybillId" xml:"WaybillId"` // 运单 ID
  371. OrderID string `json:"OrderId" xml:"OrderId"` // 订单 ID
  372. Version int `json:"Version" xml:"Version"` // 轨迹版本号(整型)
  373. Count int `json:"Count" xml:"Count"` // 轨迹节点数(整型)
  374. Actions []*PushDataAddExpressPathAction `json:"Actions" xml:"Actions"` // 轨迹节点列表
  375. }
  376. // PushDataAddExpressPathAction 轨迹节点
  377. type PushDataAddExpressPathAction struct {
  378. ActionTime int64 `json:"ActionTime" xml:"ActionTime"` // 轨迹节点 Unix 时间戳
  379. ActionType int `json:"ActionType" xml:"ActionType"` // 轨迹节点类型
  380. ActionMsg string `json:"ActionMsg" xml:"ActionMsg"` // 轨迹节点详情
  381. }
  382. // PushDataSecVodUpload 短剧媒资上传完成
  383. type PushDataSecVodUpload struct {
  384. CommonPushData
  385. UploadEvent SecVodUploadEvent `json:"upload_event" xml:"upload_event"` // 上传完成事件
  386. }
  387. // SecVodUploadEvent 短剧媒资上传完成事件
  388. type SecVodUploadEvent struct {
  389. MediaID int64 `json:"media_id" xml:"media_id"` // 媒资 id
  390. SourceContext string `json:"source_context" xml:"source_context"` // 透传上传接口中开发者设置的值。
  391. ErrCode int `json:"errcode" xml:"errcode"` // 错误码,上传失败时该值非
  392. ErrMsg string `json:"errmsg" xml:"errmsg"` // 错误提示
  393. }
  394. // PushDataSecVodAudit 短剧媒资审核状态
  395. type PushDataSecVodAudit struct {
  396. CommonPushData
  397. AuditEvent SecVodAuditEvent `json:"audit_event" xml:"audit_event"` // 审核状态事件
  398. }
  399. // SecVodAuditEvent 短剧媒资审核状态事件
  400. type SecVodAuditEvent struct {
  401. DramaID int64 `json:"drama_id" xml:"drama_id"` // 剧目 id
  402. SourceContext string `json:"source_context" xml:"source_context"` // 透传上传接口中开发者设置的值
  403. AuditDetail DramaAuditDetail `json:"audit_detail" xml:"audit_detail"` // 剧目审核结果,单独每一集的审核结果可以根据 drama_id 查询剧集详情得到
  404. }
  405. // DramaAuditDetail 剧目审核结果
  406. type DramaAuditDetail struct {
  407. Status int `json:"status" xml:"status"` // 审核状态,0 为无效值;1 为审核中;2 为最终失败;3 为审核通过;4 为驳回重填
  408. CreateTime int64 `json:"create_time" xml:"create_time"` // 提审时间戳
  409. AuditTime int64 `json:"audit_time" xml:"audit_time"` // 审核时间戳
  410. }
  411. // PushDataXpayGoodsDeliverNotify 道具发货推送
  412. type PushDataXpayGoodsDeliverNotify struct {
  413. CommonPushData
  414. OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid
  415. OutTradeNo string `json:"OutTradeNo" xml:"OutTradeNo"` // 业务订单号
  416. Env int `json:"Env" xml:"Env"` // ,环境配置 0:现网环境(也叫正式环境)1:沙箱环境
  417. WeChatPayInfo WeChatPayInfo `json:"WeChatPayInfo" xml:"WeChatPayInfo"` // 微信支付信息 非微信支付渠道可能没有
  418. GoodsInfo GoodsInfo `json:"GoodsInfo" xml:"GoodsInfo"` // 道具参数信息
  419. TeamInfo XpayTeamInfo `json:"TeamInfo" xml:"TeamInfo"` // 拼团信息
  420. }
  421. // WeChatPayInfo 微信支付信息
  422. type WeChatPayInfo struct {
  423. MchOrderNo string `json:"MchOrderNo" xml:"MchOrderNo"` // 微信支付商户单号
  424. TransactionID string `json:"TransactionId" xml:"TransactionId"` // 交易单号(微信支付订单号)
  425. PaidTime int64 `json:"PaidTime" xml:"PaidTime"` // 用户支付时间,Linux 秒级时间戳
  426. }
  427. // GoodsInfo 道具参数信息
  428. type GoodsInfo struct {
  429. ProductID string `json:"ProductId" xml:"ProductId"` // 道具 ID
  430. Quantity int `json:"Quantity" xml:"Quantity"` // 数量
  431. OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格(单位:分)
  432. ActualPrice int64 `json:"ActualPrice" xml:"ActualPrice"` // 物品实际支付价格(单位:分)
  433. Attach string `json:"Attach" xml:"Attach"` // 透传信息
  434. }
  435. // PushDataXpayCoinPayNotify 代币支付推送
  436. type PushDataXpayCoinPayNotify struct {
  437. CommonPushData
  438. OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid
  439. OutTradeNo string `json:"OutTradeNo" xml:"OutTradeNo"` // 业务订单号
  440. Env int `json:"Env" xml:"Env"` // ,环境配置 0:现网环境(也叫正式环境)1:沙箱环境
  441. WeChatPayInfo WeChatPayInfo `json:"WeChatPayInfo" xml:"WeChatPayInfo"` // 微信支付信息 非微信支付渠道可能没有
  442. CoinInfo CoinInfo `json:"CoinInfo" xml:"CoinInfo"` // 代币参数信息
  443. }
  444. // CoinInfo 代币参数信息
  445. type CoinInfo struct {
  446. Quantity int `json:"Quantity" xml:"Quantity"` // 数量
  447. OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格(单位:分)
  448. ActualPrice int64 `json:"ActualPrice" xml:"ActualPrice"` // 物品实际支付价格(单位:分)
  449. Attach string `json:"Attach" xml:"Attach"` // 透传信息
  450. }
  451. // PushDataSubscribePopup 用户操作订阅通知弹窗事件推送
  452. type PushDataSubscribePopup struct {
  453. CommonPushData
  454. subscribeMsgPopupEventList []SubscribeMsgPopupEventList `json:"-"`
  455. SubscribeMsgPopupEvent SubscribeMsgPopupEvent `xml:"SubscribeMsgPopupEvent"`
  456. }
  457. // SubscribeMsgPopupEvent 用户操作订阅通知弹窗消息回调
  458. type SubscribeMsgPopupEvent struct {
  459. List []SubscribeMsgPopupEventList `xml:"List"`
  460. }
  461. // SubscribeMsgPopupEventList 订阅消息事件列表
  462. type SubscribeMsgPopupEventList struct {
  463. TemplateID string `xml:"TemplateId" json:"TemplateId"`
  464. SubscribeStatusString string `xml:"SubscribeStatusString" json:"SubscribeStatusString"`
  465. PopupScene string `xml:"PopupScene" json:"PopupScene"`
  466. }
  467. // SetSubscribeMsgPopupEvents 设置订阅消息事件
  468. func (s *PushDataSubscribePopup) SetSubscribeMsgPopupEvents(list []SubscribeMsgPopupEventList) {
  469. s.subscribeMsgPopupEventList = list
  470. }
  471. // GetSubscribeMsgPopupEvents 获取订阅消息事件数据
  472. func (s *PushDataSubscribePopup) GetSubscribeMsgPopupEvents() []SubscribeMsgPopupEventList {
  473. if s.subscribeMsgPopupEventList != nil {
  474. return s.subscribeMsgPopupEventList
  475. }
  476. if s.SubscribeMsgPopupEvent.List == nil || len(s.SubscribeMsgPopupEvent.List) < 1 {
  477. return nil
  478. }
  479. return s.SubscribeMsgPopupEvent.List
  480. }
  481. // PushDataSubscribeMsgChange 用户管理订阅通知事件推送
  482. type PushDataSubscribeMsgChange struct {
  483. CommonPushData
  484. SubscribeMsgChangeEvent SubscribeMsgChangeEvent `xml:"SubscribeMsgChangeEvent"`
  485. subscribeMsgChangeList []SubscribeMsgChangeList `json:"-"`
  486. }
  487. // SubscribeMsgChangeEvent 用户管理订阅通知回调
  488. type SubscribeMsgChangeEvent struct {
  489. List []SubscribeMsgChangeList `xml:"List" json:"List"`
  490. }
  491. // SubscribeMsgChangeList 订阅消息事件列表
  492. type SubscribeMsgChangeList struct {
  493. TemplateID string `xml:"TemplateId" json:"TemplateId"`
  494. SubscribeStatusString string `xml:"SubscribeStatusString" json:"SubscribeStatusString"`
  495. }
  496. // SetSubscribeMsgChangeEvents 设置订阅消息事件
  497. func (s *PushDataSubscribeMsgChange) SetSubscribeMsgChangeEvents(list []SubscribeMsgChangeList) {
  498. s.subscribeMsgChangeList = list
  499. }
  500. // GetSubscribeMsgChangeEvents 获取订阅消息事件数据
  501. func (s *PushDataSubscribeMsgChange) GetSubscribeMsgChangeEvents() []SubscribeMsgChangeList {
  502. if s.subscribeMsgChangeList != nil {
  503. return s.subscribeMsgChangeList
  504. }
  505. if s.SubscribeMsgChangeEvent.List == nil || len(s.SubscribeMsgChangeEvent.List) < 1 {
  506. return nil
  507. }
  508. return s.SubscribeMsgChangeEvent.List
  509. }
  510. // PushDataSubscribeMsgSent 用户发送订阅通知事件推送
  511. type PushDataSubscribeMsgSent struct {
  512. CommonPushData
  513. SubscribeMsgSentEvent SubscribeMsgSentEvent `xml:"SubscribeMsgSentEvent"`
  514. subscribeMsgSentEventList []SubscribeMsgSentList `json:"-"`
  515. }
  516. // SubscribeMsgSentEvent 用户发送订阅通知回调
  517. type SubscribeMsgSentEvent struct {
  518. List []SubscribeMsgSentList `xml:"List" json:"List"`
  519. }
  520. // SubscribeMsgSentList 订阅消息事件列表
  521. type SubscribeMsgSentList struct {
  522. TemplateID string `xml:"TemplateId" json:"TemplateId"`
  523. MsgID string `xml:"MsgID" json:"MsgID"`
  524. ErrorCode string `xml:"ErrorCode" json:"ErrorCode"`
  525. ErrorStatus string `xml:"ErrorStatus" json:"ErrorStatus"`
  526. }
  527. // SetSubscribeMsgSentEvents 设置订阅消息事件
  528. func (s *PushDataSubscribeMsgSent) SetSubscribeMsgSentEvents(list []SubscribeMsgSentList) {
  529. s.subscribeMsgSentEventList = list
  530. }
  531. // GetSubscribeMsgSentEvents 获取订阅消息事件数据
  532. func (s *PushDataSubscribeMsgSent) GetSubscribeMsgSentEvents() []SubscribeMsgSentList {
  533. if s.subscribeMsgSentEventList != nil {
  534. return s.subscribeMsgSentEventList
  535. }
  536. if s.SubscribeMsgSentEvent.List == nil || len(s.SubscribeMsgSentEvent.List) < 1 {
  537. return nil
  538. }
  539. return s.SubscribeMsgSentEvent.List
  540. }
  541. // XpayTeamInfo team purchase info
  542. type XpayTeamInfo struct {
  543. ActivityID string `json:"ActivityId" xml:"ActivityId"` // 活动 id
  544. TeamID string `json:"TeamId" xml:"TeamId"` // 团 id
  545. TeamType int `json:"TeamType" xml:"TeamType"` // 团类型 1-支付全部,拼成退款
  546. TeamAction int `json:"TeamAction" xml:"TeamAction"` // 0-创团 1-参团
  547. }
  548. // PushDataXpayRefundNotify 退款推送
  549. type PushDataXpayRefundNotify struct {
  550. CommonPushData
  551. OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid
  552. WxRefundID string `json:"WxRefundId" xml:"WxRefundId"` // 微信退款单号
  553. MchRefundID string `json:"MchRefundId" xml:"MchRefundId"` // 商户退款单号
  554. WxOrderID string `json:"WxOrderId" xml:"WxOrderId"` // 退款单对应支付单的微信单号
  555. MchOrderID string `json:"MchOrderId" xml:"MchOrderId"` // 退款单对应支付单的商户单号
  556. RefundFee int `json:"RefundFee" xml:"RefundFee"` // 退款金额,单位分
  557. RetCode int `json:"RetCode" xml:"RetCode"` // 退款结果,0 为成功
  558. RetMsg string `json:"RetMsg" xml:"RetMsg"` // 退款结果详情
  559. RefundStartTimestamp int64 `json:"RefundStartTimestamp" xml:"RefundStartTimestamp"` // 开始退款时间,秒级时间戳
  560. RefundSuccTimestamp int64 `json:"RefundSuccTimestamp" xml:"RefundSuccTimestamp"` // 结束退款时间,秒级时间戳
  561. WxpayRefundTransactionID string `json:"WxpayRefundTransactionId" xml:"WxpayRefundTransactionId"` // 退款单的微信支付单号
  562. RetryTimes int `json:"RetryTimes" xml:"RetryTimes"` // 重试次数,从 0 开始
  563. TeamInfo XpayTeamInfo `json:"TeamInfo" xml:"TeamInfo"` // 拼团信息
  564. }
  565. // PushDataXpaySubscribeIosRefundQueryNotify iOS Apple 支付退款问询事件
  566. // 文档:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/virtual-payment/ios.html
  567. type PushDataXpaySubscribeIosRefundQueryNotify struct {
  568. CommonPushData
  569. RefundTime string `json:"refund_time" xml:"refund_time"` // 问询时间,Unix 时间戳
  570. OrderTime string `json:"order_time" xml:"order_time"` // 该笔退款的订单时间,Unix 时间戳
  571. ChannelBill string `json:"channel_bill" xml:"channel_bill"` // Apple 支付票据号
  572. BundleID string `json:"bundleid" xml:"bundleid"` // 应用的 Apple bundleid
  573. ProductID string `json:"product_id" xml:"product_id"` // 道具 id
  574. PCount string `json:"p_count" xml:"p_count"` // 道具/代币数量
  575. RefundRequestReason string `json:"refund_request_reason" xml:"refund_request_reason"` // 用户请求退款的原因
  576. ProvideStatus string `json:"provide_status" xml:"provide_status"` // 发货状态,0:未发货 1:已发货 2:发货中
  577. PayOrderID string `json:"pay_order_id" xml:"pay_order_id"` // 退款对应支付订单号
  578. }
  579. // IosRefundQueryResponse iOS Apple 支付退款问询应答
  580. type IosRefundQueryResponse struct {
  581. ResultCode int32 `json:"result_code" xml:"result_code"` // 结果码,0-放过,建议退款;1-拦截,拒绝退款
  582. ResultInfo string `json:"result_info" xml:"result_info"` // 结果描述
  583. Evidence string `json:"evidence" xml:"evidence"` // 决策凭据,必填,用于退款审计
  584. }
  585. // PushDataXpayComplaintNotify 用户投诉推送
  586. type PushDataXpayComplaintNotify struct {
  587. CommonPushData
  588. OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid
  589. WxOrderID string `json:"WxOrderId" xml:"WxOrderId"` // 微信单号
  590. MchOrderID string `json:"MchOrderId" xml:"MchOrderId"` // 商户单号
  591. TransactionID string `json:"TransactionId" xml:"TransactionId"` // 微信支付交易单号
  592. ComplaintID string `json:"ComplaintId" xml:"ComplaintId"` // 投诉单号
  593. ComplaintDetail string `json:"ComplaintDetail" xml:"ComplaintDetail"` // 投诉详情
  594. ComplaintTime int64 `json:"ComplaintTime" xml:"ComplaintTime"` // 投诉时间,秒级时间戳
  595. RetryTimes int `json:"RetryTimes" xml:"RetryTimes"` // 重试次数,从 0 开始
  596. RequestID string `json:"RequestId" xml:"RequestId"` // 请求编号
  597. }