diff --git a/api/proto/vas/proto/pay.go b/api/proto/vas/proto/pay.go index 5435d4a0..5eef2fee 100644 --- a/api/proto/vas/proto/pay.go +++ b/api/proto/vas/proto/pay.go @@ -31,6 +31,7 @@ const ( PayTypeAlipayH5 = "alipay_h5" // 支付宝 h5 PayTypeWxpayNative = "wxpay_native" // 微信 native PayTypeWxpayJsapi = "wxpay_jsapi" // 微信 jsapi + PayTypeWxpayH5 = "wxpay_h5" // 微信支付 h5 ) const ( @@ -66,7 +67,8 @@ type CreateOrderData struct { AlipayParamStr string `json:"alipay_param_str"` // 支付宝 app支付参数 AlipayH5ParamStr string `json:"alipay_h5_param_str"` // 支付宝 h5支付参数 WxpayNativeParamStr string `json:"wxpay_native_param_str"` // 微信支付 native支付参数 - WxpayJsapiParamObj wxpaycli.JsapiPayResp `json:"wxpay_jsapi_param_obj"` // 微信支付 native + WxpayJsapiParamObj wxpaycli.JsapiPayResp `json:"wxpay_jsapi_param_obj"` // 微信支付 jsapi支付参数 + WxpayH5ParamStr string `json:"wxpay_h5_param_str"` // 微信支付 h5支付参数 } // 预解锁联系方式 @@ -150,6 +152,7 @@ type H5DirectUnlockWechatData struct { AlipayH5ParamStr string `json:"alipay_h5_param_str"` // 支付宝 h5支付参数 WxpayNativeParamStr string `json:"wxpay_native_param_str"` // 微信支付 native支付参数 WxpayJsapiParamObj wxpaycli.JsapiPayResp `json:"wxpay_jsapi_param_obj"` // 微信支付 native + WxpayH5ParamStr string `json:"wxpay_h5_param_str"` // 微信支付 h5支付参数 } // 支付宝回调参数 diff --git a/app/mix/service/logic/vas.go b/app/mix/service/logic/vas.go index 377bd49e..fd959788 100644 --- a/app/mix/service/logic/vas.go +++ b/app/mix/service/logic/vas.go @@ -98,6 +98,7 @@ func (v *Vas) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data alipayH5ParamStr string wxpayNativeParamStr string wxpayJsapiParamObj wxpaycli.JsapiPayResp + wxpayH5ParamStr string ) defer func() { @@ -241,6 +242,24 @@ func (v *Vas) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data return } req.Oid3 = wxpayCli.AppId + case vasproto.PayTypeWxpayH5: + wxpayCli := wxpaycli.GetDefaultWxpayClient() + h5PayParam := &wxpaycli.H5PayParam{ + Description: product.Subject, + OutTradeNo: orderId, + TotalAmount: product.RealPrice, + TimeOutSeconds: 900, + Cip: ctx.ClientIP(), + } + if len(h5PayParam.Cip) <= 0 { + h5PayParam.Cip = "112.124.18.6" + } + wxpayH5ParamStr, err = wxpayCli.H5Pay(ctx, h5PayParam) + if err != nil { + logger.Error("wxpay H5Pay fail, req: %v, h5PayParam: %v, err: %v", util.ToJson(req), util.ToJson(h5PayParam), err) + return + } + req.Oid3 = wxpayCli.AppId } // 添加订单 @@ -284,6 +303,7 @@ func (v *Vas) CreateOrder(ctx *gin.Context, req *vasproto.CreateOrderReq) (data AlipayH5ParamStr: alipayH5ParamStr, WxpayNativeParamStr: wxpayNativeParamStr, WxpayJsapiParamObj: wxpayJsapiParamObj, + WxpayH5ParamStr: wxpayH5ParamStr, } return } @@ -1554,6 +1574,7 @@ func (v *Vas) H5DirectUnlockWechat(ctx *gin.Context, req *vasproto.H5DirectUnloc AlipayH5ParamStr: cData.AlipayH5ParamStr, WxpayNativeParamStr: cData.WxpayNativeParamStr, WxpayJsapiParamObj: cData.WxpayJsapiParamObj, + WxpayH5ParamStr: cData.WxpayH5ParamStr, } return } diff --git a/bizcommon/util/util.go b/bizcommon/util/util.go index 410368fb..545be135 100644 --- a/bizcommon/util/util.go +++ b/bizcommon/util/util.go @@ -106,3 +106,10 @@ func BytesToString(b []byte) (s string) { _sptr.Len = _bptr.Len return s } + +func UnescapeJsonStr(s string) string { + s = strings.ReplaceAll(s, "\\u003c", "<") + s = strings.ReplaceAll(s, "\\u003e", ">") + s = strings.ReplaceAll(s, "\\u0026", "&") + return s +} diff --git a/library/payclients/wxpaycli/client.go b/library/payclients/wxpaycli/client.go index 1e6e7d89..ebe1eed1 100644 --- a/library/payclients/wxpaycli/client.go +++ b/library/payclients/wxpaycli/client.go @@ -242,3 +242,47 @@ func rsaSign(prvkey []byte, hash crypto.Hash, data []byte) ([]byte, error) { } return rsa.SignPKCS1v15(cryptorand.Reader, privateKey.(*rsa.PrivateKey), hash, hashed) } + +// 微信支付 h5支付 +type H5PayParam struct { + Description string + OutTradeNo string // 商家订单id,我们自己的订单id + TotalAmount int64 // 金额,单位:分 + TimeOutSeconds int // 订单有效时间,单位:秒 + Cip string // 客户端ip +} + +func (c *WxpayClient) H5Pay(ctx context.Context, param *H5PayParam) (wxpayH5ParamStr string, err error) { + if param.TimeOutSeconds <= 0 { + param.TimeOutSeconds = DefaultOrderTimeoutSeconds + } + bm := gopay.BodyMap{ + "appid": c.AppId, + "description": param.Description, + "out_trade_no": param.OutTradeNo, + "time_expire": time.Now().Add(time.Second * time.Duration(param.TimeOutSeconds)).Format(time.RFC3339), + "notify_url": c.NotifyUrl, + "amount": gopay.BodyMap{ + "total": param.TotalAmount, + "currency": "CNY", + }, + "scene_info": gopay.BodyMap{ + "payer_client_ip": param.Cip, + "h5_info": gopay.BodyMap{ + "type": "Wap", + }, + }, + } + resp, err := c.clientV3.V3TransactionH5(ctx, bm) + if err != nil { + return + } + if resp.Code != wxpayv3.Success { + logger.Info("wxpayv3 NativePay fail, code: %v, error: %v, response: %v", resp.Code, resp.Error, util.ToJson(resp.Response)) + return + } + + wxpayH5ParamStr = resp.Response.H5Url + logger.Info("wxpayv3 H5 success, code: %v, error: %v, response: %v", resp.Code, resp.Error, util.ToJson(resp.Response)) + return +} diff --git a/library/payclients/wxpaycli/client_test.go b/library/payclients/wxpaycli/client_test.go index 06af3218..28cba7e5 100644 --- a/library/payclients/wxpaycli/client_test.go +++ b/library/payclients/wxpaycli/client_test.go @@ -1,7 +1,9 @@ package wxpaycli import ( + "bytes" "context" + "encoding/json" "fmt" "os" "service/app/mix/conf" @@ -74,3 +76,40 @@ func TestWxpayClient_JsapiPay(t *testing.T) { } t.Log(util.ToJson(r)) } + +type Track struct { + XmlRequest string `json:"xmlRequest"` +} + +func (t *Track) JSON() ([]byte, error) { + buffer := &bytes.Buffer{} + encoder := json.NewEncoder(buffer) + // encoder.SetEscapeHTML(false) + err := encoder.Encode(t) + return buffer.Bytes(), err +} + +func AT() { + message := Track{} + message.XmlRequest = "XML" + fmt.Println("Before Marshal", message) + messageJSON, _ := message.JSON() + fmt.Println("After marshal", string(messageJSON)) +} + +func TestWxpayClient_H5Pay(t *testing.T) { + cli := GetDefaultWxpayClient() + + resp, err := cli.H5Pay(context.Background(), &H5PayParam{ + Description: "hello", + OutTradeNo: idgenerator.GenOrderId(), + TotalAmount: 1, + TimeOutSeconds: 3600 * 24, + Cip: "223.104.41.0", + }) + if err != nil { + t.Log(err.Error()) + return + } + t.Log(resp) +}