weChatV2Server.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package server
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/go-pay/gopay"
  6. "github.com/go-pay/gopay/wechat"
  7. "github.com/shopspring/decimal"
  8. "github.com/spf13/viper"
  9. "go_zh/pkg/utils"
  10. "strconv"
  11. "sync"
  12. "time"
  13. )
  14. type WeChatV2Server struct {
  15. MchId string
  16. PrivateKey string
  17. CertFile string //公钥证书地址
  18. PrivateKeyFile string //私钥证书地址
  19. AppId string //appid
  20. AppSecret string
  21. AppletId string
  22. AppletKey string
  23. PublicKeyInfo string
  24. PrivateKeyFileInfo string
  25. }
  26. var (
  27. weChatV2ServerInstance *WeChatV2Server
  28. weChatV2ServerOnce sync.Once
  29. )
  30. // GetWeChatV2ServerInstance 获取单例实例
  31. func GetWeChatV2ServerInstance() *WeChatV2Server {
  32. weChatV2ServerOnce.Do(func() {
  33. weChatV2ServerInstance = &WeChatV2Server{
  34. MchId: viper.GetString("weChat.mchId"),
  35. PrivateKey: viper.GetString("weChat.privateKey"),
  36. CertFile: viper.GetString("weChat.certFile"),
  37. PrivateKeyFile: viper.GetString("weChat.keyFile"),
  38. AppId: viper.GetString("weChat.appId"),
  39. AppSecret: viper.GetString("weChat.appSecret"),
  40. AppletId: viper.GetString("weChat.appletId"),
  41. AppletKey: viper.GetString("weChat.appletKey"),
  42. }
  43. weChatPublicKeyStr := utils.LoadPublicKeyWithPath(weChatV2ServerInstance.CertFile)
  44. weChatV2ServerInstance.PublicKeyInfo = weChatPublicKeyStr
  45. weChatPrivateKeyStr := utils.LoadPrivateKeyWithPath(weChatV2ServerInstance.PrivateKeyFile)
  46. weChatV2ServerInstance.PrivateKeyFileInfo = weChatPrivateKeyStr
  47. })
  48. return weChatV2ServerInstance
  49. }
  50. type JsApiV2Data struct {
  51. AppId string `json:"appId"` //员工ID
  52. NonceStr string `json:"nonceStr"` //当前登录token
  53. Package string `json:"package"` //当前登录token
  54. SignType string `json:"signType"` //当前登录token
  55. TimeStamp string `json:"timeStamp"` //当前登录token
  56. PaySign string `json:"paySign"` //当前登录token
  57. }
  58. // WeChatV2JsPay 获取
  59. func (weChatV2 *WeChatV2Server) WeChatV2JsPay(orderSn string, payMoney decimal.Decimal, notifyUrl string, boby string, openId string, clientIP string) JsApiV2Data {
  60. // 初始化微信客户端
  61. // appId:应用ID
  62. // mchId:商户ID
  63. // apiKey:API秘钥值
  64. // isProd:是否是正式环境
  65. client := wechat.NewClient(weChatV2.AppId, weChatV2.MchId, weChatV2.PrivateKey, true)
  66. bm := make(gopay.BodyMap)
  67. bm.Set("nonce_str", utils.Md5Sign(orderSn)).
  68. Set("spbill_create_ip", clientIP).
  69. Set("appid", weChatV2.AppId).
  70. Set("mch_id", weChatV2.MchId).
  71. Set("body", boby).
  72. Set("out_trade_no", orderSn).
  73. Set("notify_url", notifyUrl).
  74. Set("trade_type", "JSAPI").
  75. Set("total_fee", payMoney.Mul(decimal.NewFromInt(100)).IntPart()).
  76. Set("openid", openId)
  77. wxRsp, err := client.UnifiedOrder(context.Background(), bm)
  78. if err != nil {
  79. fmt.Println("err:", err)
  80. }
  81. // ====微信小程序 paySign====
  82. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  83. packages := "prepay_id=" + wxRsp.PrepayId // 此处的 wxRsp.PrepayId ,统一下单成功后得到
  84. // 获取微信小程序支付的 paySign
  85. // appId:AppID
  86. // nonceStr:随机字符串
  87. // packages:统一下单成功后拼接得到的值
  88. // signType:签名方式,务必与统一下单时用的签名方式一致
  89. // timeStamp:时间
  90. // apiKey:API秘钥值
  91. paySign := wechat.GetMiniPaySign(weChatV2.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, weChatV2.PrivateKey)
  92. data := JsApiV2Data{
  93. AppId: weChatV2.AppId,
  94. NonceStr: utils.Md5Sign(timeStamp),
  95. Package: "prepay_id=" + wxRsp.PrepayId,
  96. SignType: "MD5",
  97. TimeStamp: timeStamp,
  98. PaySign: paySign,
  99. }
  100. return data
  101. }