wxpay_service.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package wxpay
  2. import (
  3. "context"
  4. "crypto/rsa"
  5. "github.com/gogf/gf/frame/g"
  6. "github.com/gogf/gf/net/ghttp"
  7. "github.com/wechatpay-apiv3/wechatpay-go/core"
  8. "github.com/wechatpay-apiv3/wechatpay-go/core/option"
  9. "github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
  10. wxpayUtils "github.com/wechatpay-apiv3/wechatpay-go/utils"
  11. "log"
  12. "youngmini_server/app/utils"
  13. )
  14. var service = new(wxPayService)
  15. type wxPayService struct {
  16. }
  17. // 前端点击支付,post请求到此,请求体包括:产品id ,订单金额(单位是分),订单包含的积分等
  18. func (s *wxPayService) WxPayRequest(r *ghttp.Request, req WxPayRequestData) (WxPayResponseData, error) {
  19. //通过session获取openId
  20. openId, err := utils.SessionTalentInfo.GetOpenIdFromSession(r)
  21. //配置文件中获取其他
  22. if err != nil {
  23. log.Fatalf("get WxOpenId error:%s", err)
  24. }
  25. appID := g.Config().GetString("miniapp.appid")
  26. mchID := g.Config().GetString("miniapp.mchid")
  27. mchCertificateSerialNumber := g.Config().GetString("miniapp.mchCertificateSerialNumber")
  28. mchAPIv3Key := g.Config().GetString("miniapp.mchAPIv3Key")
  29. // 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
  30. mchPrivateKey, err := wxpayUtils.LoadPrivateKeyWithPath("./apiclient_key.pem")
  31. if err != nil {
  32. log.Fatalf("load merchant private key error:%s", err)
  33. }
  34. ctx := context.Background()
  35. // 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
  36. opts := []core.ClientOption{
  37. option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
  38. }
  39. client, err := core.NewClient(ctx, opts...)
  40. if err != nil {
  41. log.Fatalf("new wechat pay client err:%s", err)
  42. }
  43. svc := jsapi.JsapiApiService{Client: client}
  44. // 得到prepay_id,以及调起支付所需的参数和签名
  45. //我自己定义的订单id。微信会把这个也响应回来
  46. var tradeId = utils.GetUuid.GetRandomString(32)
  47. resp, result, err := svc.PrepayWithRequestPayment(ctx,
  48. jsapi.PrepayRequest{
  49. Appid: core.String(appID),
  50. Mchid: core.String(mchID),
  51. Description: core.String(req.Description),
  52. OutTradeNo: core.String(tradeId),
  53. NotifyUrl: core.String("https://younggee.com/wxPayCallBack"), //微信支付回调地址 需要通过nginx重定向给后端接口
  54. Amount: &jsapi.Amount{
  55. Total: core.Int64(req.Amount),
  56. },
  57. Payer: &jsapi.Payer{
  58. Openid: core.String(openId),
  59. },
  60. },
  61. )
  62. if err == nil {
  63. log.Println(resp)
  64. log.Println(result)
  65. var packageStr = "prepay_id=" + *resp.PrepayId
  66. var parts []string
  67. parts = append(parts, appID)
  68. parts = append(parts, *resp.TimeStamp)
  69. parts = append(parts, tradeId)
  70. parts = append(parts, packageStr)
  71. sign, err := getSign(parts, mchPrivateKey)
  72. if err == nil {
  73. var res = WxPayResponseData{
  74. Package: packageStr,
  75. TimeStamp: *resp.TimeStamp,
  76. NonceStr: tradeId,
  77. PaySign: sign,
  78. }
  79. return res, nil
  80. } else {
  81. log.Println(err)
  82. }
  83. } else {
  84. log.Println(err)
  85. }
  86. return WxPayResponseData{}, err
  87. }
  88. func getSign(parts []string, privateKey *rsa.PrivateKey) (string, error) {
  89. var str string
  90. for i := range parts {
  91. str += parts[i] + "\n"
  92. }
  93. sign, err := wxpayUtils.SignSHA256WithRSA(str, privateKey)
  94. if err != nil {
  95. log.Println(err)
  96. return "", err
  97. } else {
  98. log.Println(sign)
  99. return sign, nil
  100. }
  101. }