message.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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. // EventSubscribePopup 用户操作订阅通知弹窗事件推送,用户在图文等场景内订阅通知的操作
  40. EventSubscribePopup EventType = "subscribe_msg_popup_event"
  41. // EventSubscribeMsgChange 用户管理订阅通知,用户在服务通知管理页面做通知管理时的操作
  42. EventSubscribeMsgChange EventType = "subscribe_msg_change_event"
  43. // EventSubscribeMsgSent 发送订阅通知,调用 bizsend 接口发送通知
  44. EventSubscribeMsgSent EventType = "subscribe_msg_sent_event"
  45. // ConfirmReceiveMethodAuto 自动确认收货
  46. ConfirmReceiveMethodAuto ConfirmReceiveMethod = 1
  47. // ConfirmReceiveMethodManual 手动确认收货
  48. ConfirmReceiveMethodManual ConfirmReceiveMethod = 2
  49. )
  50. const (
  51. // InfoTypeAcceptSubscribeMessage 接受订阅通知
  52. InfoTypeAcceptSubscribeMessage InfoType = "accept"
  53. // InfoTypeRejectSubscribeMessage 拒绝订阅通知
  54. InfoTypeRejectSubscribeMessage InfoType = "reject"
  55. )
  56. // PushReceiver 接收消息推送
  57. // 暂仅支付 Aes 加密方式
  58. type PushReceiver struct {
  59. *context.Context
  60. }
  61. // NewPushReceiver 实例化
  62. func NewPushReceiver(ctx *context.Context) *PushReceiver {
  63. return &PushReceiver{
  64. Context: ctx,
  65. }
  66. }
  67. // GetMsg 获取接收到的消息 (如果是加密的返回解密数据)
  68. func (receiver *PushReceiver) GetMsg(r *http.Request) (string, []byte, error) {
  69. // 判断请求格式
  70. var dataType string
  71. contentType := r.Header.Get("Content-Type")
  72. if strings.HasPrefix(contentType, "text/xml") {
  73. // xml 格式
  74. dataType = DataTypeXML
  75. } else {
  76. // json 格式
  77. dataType = DataTypeJSON
  78. }
  79. // 读取参数,验证签名
  80. signature := r.FormValue("signature")
  81. timestamp := r.FormValue("timestamp")
  82. nonce := r.FormValue("nonce")
  83. encryptType := r.FormValue("encrypt_type")
  84. // 验证签名
  85. tmpArr := []string{
  86. receiver.Token,
  87. timestamp,
  88. nonce,
  89. }
  90. sort.Strings(tmpArr)
  91. tmpSignature := util.Signature(tmpArr...)
  92. if tmpSignature != signature {
  93. return dataType, nil, errors.New("signature error")
  94. }
  95. if encryptType == "aes" {
  96. // 解密
  97. var reqData DataReceived
  98. if dataType == DataTypeXML {
  99. if err := xml.NewDecoder(r.Body).Decode(&reqData); err != nil {
  100. return dataType, nil, err
  101. }
  102. } else {
  103. if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
  104. return dataType, nil, err
  105. }
  106. }
  107. _, rawMsgBytes, err := util.DecryptMsg(receiver.AppID, reqData.Encrypt, receiver.EncodingAESKey)
  108. return dataType, rawMsgBytes, err
  109. }
  110. // 不加密
  111. byteData, err := io.ReadAll(r.Body)
  112. return dataType, byteData, err
  113. }
  114. // GetMsgData 获取接收到的消息 (解密数据)
  115. func (receiver *PushReceiver) GetMsgData(r *http.Request) (MsgType, EventType, PushData, error) {
  116. dataType, decryptMsg, err := receiver.GetMsg(r)
  117. if err != nil {
  118. return "", "", nil, err
  119. }
  120. var (
  121. msgType MsgType
  122. eventType EventType
  123. )
  124. if dataType == DataTypeXML {
  125. var commonToken CommonPushData
  126. if err := xml.Unmarshal(decryptMsg, &commonToken); err != nil {
  127. return "", "", nil, err
  128. }
  129. msgType, eventType = commonToken.MsgType, commonToken.Event
  130. } else {
  131. var commonToken CommonPushData
  132. if err := json.Unmarshal(decryptMsg, &commonToken); err != nil {
  133. return "", "", nil, err
  134. }
  135. msgType, eventType = commonToken.MsgType, commonToken.Event
  136. }
  137. if msgType == MsgTypeEvent {
  138. pushData, err := receiver.getEvent(dataType, eventType, decryptMsg)
  139. // 暂不支持其他事件类型
  140. return msgType, eventType, pushData, err
  141. }
  142. // 暂不支持其他消息类型
  143. return msgType, eventType, decryptMsg, nil
  144. }
  145. // getEvent 获取事件推送的数据
  146. func (receiver *PushReceiver) getEvent(dataType string, eventType EventType, decryptMsg []byte) (PushData, error) {
  147. switch eventType {
  148. case EventTypeTradeManageRemindAccessAPI:
  149. // 提醒接入发货信息管理服务 API
  150. var pushData PushDataRemindAccessAPI
  151. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  152. return &pushData, err
  153. case EventTypeTradeManageRemindShipping:
  154. // 提醒需要上传发货信息
  155. var pushData PushDataRemindShipping
  156. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  157. return &pushData, err
  158. case EventTypeTradeManageOrderSettlement:
  159. // 订单将要结算或已经结算
  160. var pushData PushDataOrderSettlement
  161. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  162. return &pushData, err
  163. case EventTypeWxaMediaCheck:
  164. // 媒体内容安全异步审查结果通知
  165. var pushData MediaCheckAsyncData
  166. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  167. return &pushData, err
  168. case EventTypeAddExpressPath:
  169. // 运单轨迹更新
  170. var pushData PushDataAddExpressPath
  171. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  172. return &pushData, err
  173. case EventTypeSecvodUpload:
  174. // 短剧媒资上传完成
  175. var pushData PushDataSecVodUpload
  176. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  177. return &pushData, err
  178. case EventTypeSecvodAudit:
  179. // 短剧媒资审核状态
  180. var pushData PushDataSecVodAudit
  181. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  182. return &pushData, err
  183. case EventTypeXpayGoodsDeliverNotify:
  184. // 道具发货推送事件
  185. var pushData PushDataXpayGoodsDeliverNotify
  186. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  187. return &pushData, err
  188. case EventTypeXpayCoinPayNotify:
  189. // 代币支付推送事件
  190. var pushData PushDataXpayCoinPayNotify
  191. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  192. return &pushData, err
  193. case EventSubscribePopup:
  194. // 用户操作订阅通知弹窗事件推送
  195. return receiver.unmarshalSubscribePopup(dataType, decryptMsg)
  196. case EventSubscribeMsgChange:
  197. // 用户管理订阅通知事件推送
  198. return receiver.unmarshalSubscribeMsgChange(dataType, decryptMsg)
  199. case EventSubscribeMsgSent:
  200. // 用户发送订阅通知事件推送
  201. return receiver.unmarshalSubscribeMsgSent(dataType, decryptMsg)
  202. }
  203. // 暂不支持其他事件类型,直接返回解密后的数据,由调用方处理
  204. return decryptMsg, nil
  205. }
  206. // unmarshal 解析推送的数据
  207. func (receiver *PushReceiver) unmarshal(dataType string, decryptMsg []byte, pushData interface{}) error {
  208. if dataType == DataTypeXML {
  209. return xml.Unmarshal(decryptMsg, pushData)
  210. }
  211. return json.Unmarshal(decryptMsg, pushData)
  212. }
  213. // unmarshalSubscribePopup
  214. func (receiver *PushReceiver) unmarshalSubscribePopup(dataType string, decryptMsg []byte) (PushData, error) {
  215. var pushData PushDataSubscribePopup
  216. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  217. if err == nil {
  218. listData := gjson.Get(string(decryptMsg), "List")
  219. if listData.IsObject() {
  220. listItem := SubscribeMsgPopupEventList{}
  221. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil {
  222. return &pushData, parseErr
  223. }
  224. pushData.SetSubscribeMsgPopupEvents([]SubscribeMsgPopupEventList{listItem})
  225. } else if listData.IsArray() {
  226. listItems := make([]SubscribeMsgPopupEventList, 0)
  227. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil {
  228. return &pushData, parseErr
  229. }
  230. pushData.SetSubscribeMsgPopupEvents(listItems)
  231. }
  232. }
  233. return &pushData, err
  234. }
  235. // unmarshalSubscribeMsgChange 解析用户管理订阅通知事件推送
  236. func (receiver *PushReceiver) unmarshalSubscribeMsgChange(dataType string, decryptMsg []byte) (PushData, error) {
  237. var pushData PushDataSubscribeMsgChange
  238. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  239. if err == nil {
  240. listData := gjson.Get(string(decryptMsg), "List")
  241. if listData.IsObject() {
  242. listItem := SubscribeMsgChangeList{}
  243. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil {
  244. return &pushData, parseErr
  245. }
  246. pushData.SetSubscribeMsgChangeEvents([]SubscribeMsgChangeList{listItem})
  247. } else if listData.IsArray() {
  248. listItems := make([]SubscribeMsgChangeList, 0)
  249. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil {
  250. return &pushData, parseErr
  251. }
  252. pushData.SetSubscribeMsgChangeEvents(listItems)
  253. }
  254. }
  255. return &pushData, err
  256. }
  257. // unmarshalSubscribeMsgSent 解析用户发送订阅通知事件推送
  258. func (receiver *PushReceiver) unmarshalSubscribeMsgSent(dataType string, decryptMsg []byte) (PushData, error) {
  259. var pushData PushDataSubscribeMsgSent
  260. err := receiver.unmarshal(dataType, decryptMsg, &pushData)
  261. if err == nil {
  262. listData := gjson.Get(string(decryptMsg), "List")
  263. if listData.IsObject() {
  264. listItem := SubscribeMsgSentList{}
  265. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItem); parseErr != nil {
  266. return &pushData, parseErr
  267. }
  268. pushData.SetSubscribeMsgSentEvents([]SubscribeMsgSentList{listItem})
  269. } else if listData.IsArray() {
  270. listItems := make([]SubscribeMsgSentList, 0)
  271. if parseErr := json.Unmarshal([]byte(listData.Raw), &listItems); parseErr != nil {
  272. return &pushData, parseErr
  273. }
  274. pushData.SetSubscribeMsgSentEvents(listItems)
  275. }
  276. }
  277. return &pushData, err
  278. }
  279. // DataReceived 接收到的数据
  280. type DataReceived struct {
  281. Encrypt string `json:"Encrypt" xml:"Encrypt"` // 加密的消息体
  282. }
  283. // PushData 推送的数据 (已转对应的结构体)
  284. type PushData interface{}
  285. // CommonPushData 推送数据通用部分
  286. type CommonPushData struct {
  287. XMLName xml.Name `json:"-" xml:"xml"`
  288. MsgType MsgType `json:"MsgType" xml:"MsgType"` // 消息类型,为固定值 "event"
  289. Event EventType `json:"Event" xml:"Event"` // 事件类型
  290. ToUserName string `json:"ToUserName" xml:"ToUserName"` // 小程序的原始 ID
  291. FromUserName string `json:"FromUserName" xml:"FromUserName"` // 发送方账号(一个 OpenID,此时发送方是系统账号)
  292. CreateTime int64 `json:"CreateTime" xml:"CreateTime"` // 消息创建时间(整型),时间戳
  293. }
  294. // MediaCheckAsyncData 媒体内容安全异步审查结果通知
  295. type MediaCheckAsyncData struct {
  296. CommonPushData
  297. Appid string `json:"appid" xml:"appid"`
  298. TraceID string `json:"trace_id" xml:"trace_id"`
  299. Version int `json:"version" xml:"version"`
  300. Detail []*MediaCheckDetail `json:"detail" xml:"detail"`
  301. Errcode int `json:"errcode" xml:"errcode"`
  302. Errmsg string `json:"errmsg" xml:"errmsg"`
  303. Result MediaCheckAsyncResult `json:"result" xml:"result"`
  304. }
  305. // MediaCheckDetail 检测结果详情
  306. type MediaCheckDetail struct {
  307. Strategy string `json:"strategy" xml:"strategy"`
  308. Errcode int `json:"errcode" xml:"errcode"`
  309. Suggest security.CheckSuggest `json:"suggest" xml:"suggest"`
  310. Label int `json:"label" xml:"label"`
  311. Prob int `json:"prob" xml:"prob"`
  312. }
  313. // MediaCheckAsyncResult 检测结果
  314. type MediaCheckAsyncResult struct {
  315. Suggest security.CheckSuggest `json:"suggest" xml:"suggest"`
  316. Label security.CheckLabel `json:"label" xml:"label"`
  317. }
  318. // PushDataOrderSettlement 订单将要结算或已经结算通知
  319. type PushDataOrderSettlement struct {
  320. CommonPushData
  321. TransactionID string `json:"transaction_id" xml:"transaction_id"` // 支付订单号
  322. MerchantID string `json:"merchant_id" xml:"merchant_id"` // 商户号
  323. SubMerchantID string `json:"sub_merchant_id" xml:"sub_merchant_id"` // 子商户号
  324. MerchantTradeNo string `json:"merchant_trade_no" xml:"merchant_trade_no"` // 商户订单号
  325. PayTime int64 `json:"pay_time" xml:"pay_time"` // 支付成功时间,秒级时间戳
  326. ShippedTime int64 `json:"shipped_time" xml:"shipped_time"` // 发货时间,秒级时间戳
  327. EstimatedSettlementTime int64 `json:"estimated_settlement_time" xml:"estimated_settlement_time"` // 预计结算时间,秒级时间戳。发货时推送才有该字段
  328. ConfirmReceiveMethod ConfirmReceiveMethod `json:"confirm_receive_method" xml:"confirm_receive_method"` // 确认收货方式:1. 自动确认收货;2. 手动确认收货。结算时推送才有该字段
  329. ConfirmReceiveTime int64 `json:"confirm_receive_time" xml:"confirm_receive_time"` // 确认收货时间,秒级时间戳。结算时推送才有该字段
  330. SettlementTime int64 `json:"settlement_time" xml:"settlement_time"` // 订单结算时间,秒级时间戳。结算时推送才有该字段
  331. }
  332. // PushDataRemindShipping 提醒需要上传发货信息
  333. type PushDataRemindShipping struct {
  334. CommonPushData
  335. TransactionID string `json:"transaction_id" xml:"transaction_id"` // 微信支付订单号
  336. MerchantID string `json:"merchant_id" xml:"merchant_id"` // 商户号
  337. SubMerchantID string `json:"sub_merchant_id" xml:"sub_merchant_id"` // 子商户号
  338. MerchantTradeNo string `json:"merchant_trade_no" xml:"merchant_trade_no"` // 商户订单号
  339. PayTime int64 `json:"pay_time" xml:"pay_time"` // 支付成功时间,秒级时间戳
  340. Msg string `json:"msg" xml:"msg"` // 消息文本内容
  341. }
  342. // PushDataRemindAccessAPI 提醒接入发货信息管理服务 API 信息
  343. type PushDataRemindAccessAPI struct {
  344. CommonPushData
  345. Msg string `json:"msg" xml:"msg"` // 消息文本内容
  346. }
  347. // PushDataAddExpressPath 运单轨迹更新信息
  348. type PushDataAddExpressPath struct {
  349. CommonPushData
  350. DeliveryID string `json:"DeliveryID" xml:"DeliveryID"` // 快递公司 ID
  351. WayBillID string `json:"WaybillId" xml:"WaybillId"` // 运单 ID
  352. OrderID string `json:"OrderId" xml:"OrderId"` // 订单 ID
  353. Version int `json:"Version" xml:"Version"` // 轨迹版本号(整型)
  354. Count int `json:"Count" xml:"Count"` // 轨迹节点数(整型)
  355. Actions []*PushDataAddExpressPathAction `json:"Actions" xml:"Actions"` // 轨迹节点列表
  356. }
  357. // PushDataAddExpressPathAction 轨迹节点
  358. type PushDataAddExpressPathAction struct {
  359. ActionTime int64 `json:"ActionTime" xml:"ActionTime"` // 轨迹节点 Unix 时间戳
  360. ActionType int `json:"ActionType" xml:"ActionType"` // 轨迹节点类型
  361. ActionMsg string `json:"ActionMsg" xml:"ActionMsg"` // 轨迹节点详情
  362. }
  363. // PushDataSecVodUpload 短剧媒资上传完成
  364. type PushDataSecVodUpload struct {
  365. CommonPushData
  366. UploadEvent SecVodUploadEvent `json:"upload_event" xml:"upload_event"` // 上传完成事件
  367. }
  368. // SecVodUploadEvent 短剧媒资上传完成事件
  369. type SecVodUploadEvent struct {
  370. MediaID int64 `json:"media_id" xml:"media_id"` // 媒资 id
  371. SourceContext string `json:"source_context" xml:"source_context"` // 透传上传接口中开发者设置的值。
  372. ErrCode int `json:"errcode" xml:"errcode"` // 错误码,上传失败时该值非
  373. ErrMsg string `json:"errmsg" xml:"errmsg"` // 错误提示
  374. }
  375. // PushDataSecVodAudit 短剧媒资审核状态
  376. type PushDataSecVodAudit struct {
  377. CommonPushData
  378. AuditEvent SecVodAuditEvent `json:"audit_event" xml:"audit_event"` // 审核状态事件
  379. }
  380. // SecVodAuditEvent 短剧媒资审核状态事件
  381. type SecVodAuditEvent struct {
  382. DramaID int64 `json:"drama_id" xml:"drama_id"` // 剧目 id
  383. SourceContext string `json:"source_context" xml:"source_context"` // 透传上传接口中开发者设置的值
  384. AuditDetail DramaAuditDetail `json:"audit_detail" xml:"audit_detail"` // 剧目审核结果,单独每一集的审核结果可以根据 drama_id 查询剧集详情得到
  385. }
  386. // DramaAuditDetail 剧目审核结果
  387. type DramaAuditDetail struct {
  388. Status int `json:"status" xml:"status"` // 审核状态,0 为无效值;1 为审核中;2 为最终失败;3 为审核通过;4 为驳回重填
  389. CreateTime int64 `json:"create_time" xml:"create_time"` // 提审时间戳
  390. AuditTime int64 `json:"audit_time" xml:"audit_time"` // 审核时间戳
  391. }
  392. // PushDataXpayGoodsDeliverNotify 道具发货推送
  393. type PushDataXpayGoodsDeliverNotify struct {
  394. CommonPushData
  395. OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid
  396. OutTradeNo string `json:"OutTradeNo" xml:"OutTradeNo"` // 业务订单号
  397. Env int `json:"Env" xml:"Env"` // ,环境配置 0:现网环境(也叫正式环境)1:沙箱环境
  398. WeChatPayInfo WeChatPayInfo `json:"WeChatPayInfo" xml:"WeChatPayInfo"` // 微信支付信息 非微信支付渠道可能没有
  399. GoodsInfo GoodsInfo `json:"GoodsInfo" xml:"GoodsInfo"` // 道具参数信息
  400. }
  401. // WeChatPayInfo 微信支付信息
  402. type WeChatPayInfo struct {
  403. MchOrderNo string `json:"MchOrderNo" xml:"MchOrderNo"` // 微信支付商户单号
  404. TransactionID string `json:"TransactionId" xml:"TransactionId"` // 交易单号(微信支付订单号)
  405. PaidTime int64 `json:"PaidTime" xml:"PaidTime"` // 用户支付时间,Linux 秒级时间戳
  406. }
  407. // GoodsInfo 道具参数信息
  408. type GoodsInfo struct {
  409. ProductID string `json:"ProductId" xml:"ProductId"` // 道具 ID
  410. Quantity int `json:"Quantity" xml:"Quantity"` // 数量
  411. OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格(单位:分)
  412. ActualPrice int64 `json:"ActualPrice" xml:"ActualPrice"` // 物品实际支付价格(单位:分)
  413. Attach string `json:"Attach" xml:"Attach"` // 透传信息
  414. }
  415. // PushDataXpayCoinPayNotify 代币支付推送
  416. type PushDataXpayCoinPayNotify struct {
  417. CommonPushData
  418. OpenID string `json:"OpenId" xml:"OpenId"` // 用户 openid
  419. OutTradeNo string `json:"OutTradeNo" xml:"OutTradeNo"` // 业务订单号
  420. Env int `json:"Env" xml:"Env"` // ,环境配置 0:现网环境(也叫正式环境)1:沙箱环境
  421. WeChatPayInfo WeChatPayInfo `json:"WeChatPayInfo" xml:"WeChatPayInfo"` // 微信支付信息 非微信支付渠道可能没有
  422. CoinInfo CoinInfo `json:"CoinInfo" xml:"CoinInfo"` // 代币参数信息
  423. }
  424. // CoinInfo 代币参数信息
  425. type CoinInfo struct {
  426. Quantity int `json:"Quantity" xml:"Quantity"` // 数量
  427. OrigPrice int64 `json:"OrigPrice" xml:"OrigPrice"` // 物品原始价格(单位:分)
  428. ActualPrice int64 `json:"ActualPrice" xml:"ActualPrice"` // 物品实际支付价格(单位:分)
  429. Attach string `json:"Attach" xml:"Attach"` // 透传信息
  430. }
  431. // PushDataSubscribePopup 用户操作订阅通知弹窗事件推送
  432. type PushDataSubscribePopup struct {
  433. CommonPushData
  434. subscribeMsgPopupEventList []SubscribeMsgPopupEventList `json:"-"`
  435. SubscribeMsgPopupEvent SubscribeMsgPopupEvent `xml:"SubscribeMsgPopupEvent"`
  436. }
  437. // SubscribeMsgPopupEvent 用户操作订阅通知弹窗消息回调
  438. type SubscribeMsgPopupEvent struct {
  439. List []SubscribeMsgPopupEventList `xml:"List"`
  440. }
  441. // SubscribeMsgPopupEventList 订阅消息事件列表
  442. type SubscribeMsgPopupEventList struct {
  443. TemplateID string `xml:"TemplateId" json:"TemplateId"`
  444. SubscribeStatusString string `xml:"SubscribeStatusString" json:"SubscribeStatusString"`
  445. PopupScene string `xml:"PopupScene" json:"PopupScene"`
  446. }
  447. // SetSubscribeMsgPopupEvents 设置订阅消息事件
  448. func (s *PushDataSubscribePopup) SetSubscribeMsgPopupEvents(list []SubscribeMsgPopupEventList) {
  449. s.subscribeMsgPopupEventList = list
  450. }
  451. // GetSubscribeMsgPopupEvents 获取订阅消息事件数据
  452. func (s *PushDataSubscribePopup) GetSubscribeMsgPopupEvents() []SubscribeMsgPopupEventList {
  453. if s.subscribeMsgPopupEventList != nil {
  454. return s.subscribeMsgPopupEventList
  455. }
  456. if s.SubscribeMsgPopupEvent.List == nil || len(s.SubscribeMsgPopupEvent.List) < 1 {
  457. return nil
  458. }
  459. return s.SubscribeMsgPopupEvent.List
  460. }
  461. // PushDataSubscribeMsgChange 用户管理订阅通知事件推送
  462. type PushDataSubscribeMsgChange struct {
  463. CommonPushData
  464. SubscribeMsgChangeEvent SubscribeMsgChangeEvent `xml:"SubscribeMsgChangeEvent"`
  465. subscribeMsgChangeList []SubscribeMsgChangeList `json:"-"`
  466. }
  467. // SubscribeMsgChangeEvent 用户管理订阅通知回调
  468. type SubscribeMsgChangeEvent struct {
  469. List []SubscribeMsgChangeList `xml:"List" json:"List"`
  470. }
  471. // SubscribeMsgChangeList 订阅消息事件列表
  472. type SubscribeMsgChangeList struct {
  473. TemplateID string `xml:"TemplateId" json:"TemplateId"`
  474. SubscribeStatusString string `xml:"SubscribeStatusString" json:"SubscribeStatusString"`
  475. }
  476. // SetSubscribeMsgChangeEvents 设置订阅消息事件
  477. func (s *PushDataSubscribeMsgChange) SetSubscribeMsgChangeEvents(list []SubscribeMsgChangeList) {
  478. s.subscribeMsgChangeList = list
  479. }
  480. // GetSubscribeMsgChangeEvents 获取订阅消息事件数据
  481. func (s *PushDataSubscribeMsgChange) GetSubscribeMsgChangeEvents() []SubscribeMsgChangeList {
  482. if s.subscribeMsgChangeList != nil {
  483. return s.subscribeMsgChangeList
  484. }
  485. if s.SubscribeMsgChangeEvent.List == nil || len(s.SubscribeMsgChangeEvent.List) < 1 {
  486. return nil
  487. }
  488. return s.SubscribeMsgChangeEvent.List
  489. }
  490. // PushDataSubscribeMsgSent 用户发送订阅通知事件推送
  491. type PushDataSubscribeMsgSent struct {
  492. CommonPushData
  493. SubscribeMsgSentEvent SubscribeMsgSentEvent `xml:"SubscribeMsgSentEvent"`
  494. subscribeMsgSentEventList []SubscribeMsgSentList `json:"-"`
  495. }
  496. // SubscribeMsgSentEvent 用户发送订阅通知回调
  497. type SubscribeMsgSentEvent struct {
  498. List []SubscribeMsgSentList `xml:"List" json:"List"`
  499. }
  500. // SubscribeMsgSentList 订阅消息事件列表
  501. type SubscribeMsgSentList struct {
  502. TemplateID string `xml:"TemplateId" json:"TemplateId"`
  503. MsgID string `xml:"MsgID" json:"MsgID"`
  504. ErrorCode string `xml:"ErrorCode" json:"ErrorCode"`
  505. ErrorStatus string `xml:"ErrorStatus" json:"ErrorStatus"`
  506. }
  507. // SetSubscribeMsgSentEvents 设置订阅消息事件
  508. func (s *PushDataSubscribeMsgSent) SetSubscribeMsgSentEvents(list []SubscribeMsgSentList) {
  509. s.subscribeMsgSentEventList = list
  510. }
  511. // GetSubscribeMsgSentEvents 获取订阅消息事件数据
  512. func (s *PushDataSubscribeMsgSent) GetSubscribeMsgSentEvents() []SubscribeMsgSentList {
  513. if s.subscribeMsgSentEventList != nil {
  514. return s.subscribeMsgSentEventList
  515. }
  516. if s.SubscribeMsgSentEvent.List == nil || len(s.SubscribeMsgSentEvent.List) < 1 {
  517. return nil
  518. }
  519. return s.SubscribeMsgSentEvent.List
  520. }