wxpay_service.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. // 给结构体绑定一个方法,相当于类方法,
  18. func (s *wxPayService) WxPayRequest(r *ghttp.Request, req WxPayRequestData) (WxPayResponseData, error) {
  19. openId, err := utils.SessionTalentInfo.GetOpenIdFromSession(r)
  20. if err != nil {
  21. log.Fatalf("get WxOpenId error:%s", err)
  22. }
  23. appID := g.Config().GetString("miniapp.appid")
  24. mchID := g.Config().GetString("miniapp.mchid")
  25. mchCertificateSerialNumber := g.Config().GetString("miniapp.mchCertificateSerialNumber")
  26. mchAPIv3Key := g.Config().GetString("miniapp.mchAPIv3Key")
  27. // 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
  28. mchPrivateKey, err := wxpayUtils.LoadPrivateKeyWithPath("./apiclient_key.pem")
  29. if err != nil {
  30. log.Fatalf("load merchant private key error:%s", err)
  31. }
  32. ctx := context.Background()
  33. // 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
  34. opts := []core.ClientOption{
  35. option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
  36. }
  37. client, err := core.NewClient(ctx, opts...)
  38. if err != nil {
  39. log.Fatalf("new wechat pay client err:%s", err)
  40. }
  41. svc := jsapi.JsapiApiService{Client: client}
  42. // 得到prepay_id,以及调起支付所需的参数和签名
  43. var tradeId = utils.GetUuid.GetRandomString(32)
  44. resp, result, err := svc.PrepayWithRequestPayment(ctx,
  45. jsapi.PrepayRequest{
  46. Appid: core.String(appID),
  47. Mchid: core.String(mchID),
  48. Description: core.String(req.Description),
  49. OutTradeNo: core.String(tradeId),
  50. NotifyUrl: core.String("https://www.weixin.qq.com/wxpay/pay.php"),
  51. Amount: &jsapi.Amount{
  52. Total: core.Int64(req.Amount),
  53. },
  54. Payer: &jsapi.Payer{
  55. Openid: core.String(openId),
  56. },
  57. },
  58. )
  59. if err == nil {
  60. log.Println(resp)
  61. log.Println(result)
  62. var packageStr = "prepay_id=" + *resp.PrepayId
  63. var parts []string
  64. parts = append(parts, appID)
  65. parts = append(parts, *resp.TimeStamp)
  66. parts = append(parts, tradeId)
  67. parts = append(parts, packageStr)
  68. sign, err := getSign(parts, mchPrivateKey)
  69. if err == nil {
  70. var res = WxPayResponseData{
  71. Package: packageStr,
  72. TimeStamp: *resp.TimeStamp,
  73. NonceStr: tradeId,
  74. PaySign: sign,
  75. }
  76. return res, nil
  77. } else {
  78. log.Println(err)
  79. }
  80. } else {
  81. log.Println(err)
  82. }
  83. return WxPayResponseData{}, err
  84. }
  85. func getSign(parts []string, privateKey *rsa.PrivateKey) (string, error) {
  86. var str string
  87. for i := range parts {
  88. str += parts[i] + "\n"
  89. }
  90. sign, err := wxpayUtils.SignSHA256WithRSA(str, privateKey)
  91. if err != nil {
  92. log.Println(err)
  93. return "", err
  94. } else {
  95. log.Println(sign)
  96. return sign, nil
  97. }
  98. }