redpack.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package pay
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. "github.com/astaxie/beego"
  7. "github.com/yaotian/gowechat/mch/base"
  8. "github.com/yaotian/gowechat/util"
  9. )
  10. //官方文档: https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
  11. const (
  12. //SceneIDPromotion 商品促销
  13. SceneIDPromotion = "PRODUCT_1"
  14. //SceneIDLuckyDraw 抽奖
  15. SceneIDLuckyDraw = "PRODUCT_2"
  16. //SceneIDPrize 虚拟物品兑奖
  17. SceneIDPrize = "PRODUCT_3"
  18. //SceneIDBenefit 企业内部福利
  19. SceneIDBenefit = "PRODUCT_4"
  20. //SceneIDAgentBonous 渠道分润
  21. SceneIDAgentBonous = "PRODUCT_5"
  22. //SceneIDAgentInsurance 保险回馈
  23. SceneIDAgentInsurance = "PRODUCT_6"
  24. //SceneIDLottery 彩票派奖
  25. SceneIDLottery = "PRODUCT_7"
  26. //SceneIDTax 税务刮奖
  27. SceneIDTax = "PRODUCT_8"
  28. )
  29. //RedPackInput 发红包的配置
  30. type RedPackInput struct {
  31. ToOpenID string //接红包的OpenID
  32. MoneyFen int //分为单位
  33. SendName string //商户名称,String(32) 谁发的红包,一般为发红包的单位
  34. Wishing string //红包祝福语 String(128) “感谢您参加猜灯谜活动,祝您元宵节快乐!”
  35. ActName string //活动名称 String(32) 猜灯谜抢红包活动
  36. Remark string //备注 String(256)
  37. IP string
  38. //非必填,但大于200元,此必填, 有8个选项可供选择
  39. SceneID string
  40. }
  41. func (m *RedPackInput) Check() (isGood bool, err error) {
  42. if input.ToOpenID == "" || input.MoneyFen == 0 || input.SendName == "" || input.Wishing == "" || input.ActName == "" || input.Remark == "" || input.IP == "" {
  43. err = fmt.Errorf("%s", "Input有必填项没有值")
  44. return
  45. }
  46. if input.MoneyFen >= 200*100 && input.SceneID == "" {
  47. err = fmt.Errorf("%s", "大于200元的红包,必须设置SceneID")
  48. return
  49. }
  50. return true, nil
  51. }
  52. //SendRedPack 发红包
  53. func (c *PayTool) SendRedPack(input RedPackInput) (isSuccess bool, err error) {
  54. if isGood, err := input.Check(); !isGood {
  55. return false, err
  56. }
  57. now := time.Now()
  58. dayStr := beego.Date(now, "Ymd")
  59. billno := c.MchID + dayStr + util.RandomStr(10)
  60. var signMap = make(map[string]string)
  61. signMap["nonce_str"] = util.RandomStr(5)
  62. signMap["mch_billno"] = billno //mch_id+yyyymmdd+10位一天内不能重复的数字
  63. signMap["mch_id"] = c.MchID
  64. signMap["wxappid"] = c.AppID
  65. signMap["send_name"] = input.SendName
  66. signMap["re_openid"] = input.ToOpenID
  67. signMap["total_amount"] = util.ToStr(input.MoneyFen)
  68. signMap["total_num"] = "1"
  69. signMap["wishing"] = input.Wishing
  70. signMap["client_ip"] = input.IP
  71. signMap["act_name"] = input.ActName
  72. signMap["remark"] = input.Remark
  73. signMap["sign"] = base.Sign(signMap, c.MchAPIKey, nil)
  74. respMap, err := c.SendRedPack(signMap)
  75. if err != nil {
  76. return false, err
  77. }
  78. result_code, ok := respMap["result_code"]
  79. if !ok {
  80. err = errors.New("no result_code")
  81. return false, err
  82. }
  83. if result_code != "SUCCESS" {
  84. err = errors.New("result code is not success")
  85. return false, err
  86. }
  87. mch_billno, ok := respMap["mch_billno"]
  88. if !ok {
  89. err = errors.New("no mch_billno")
  90. return false, err
  91. }
  92. if billno != mch_billno {
  93. err = errors.New("billno is not correct")
  94. beego.Error(err)
  95. return false, err
  96. }
  97. return true, nil
  98. }