This commit is contained in:
孟帅
2023-05-10 23:54:50 +08:00
parent bbe655a4d8
commit 49a96750bf
314 changed files with 15138 additions and 6244 deletions

View File

@@ -0,0 +1,134 @@
package qqpay
import (
"context"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/qq"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
"hotgo/internal/consts"
"hotgo/internal/model"
"hotgo/internal/model/input/payin"
)
func New(config *model.PayConfig) *qqPay {
return &qqPay{
config: config,
}
}
type qqPay struct {
config *model.PayConfig
}
// Refund 订单退款
func (h *qqPay) Refund(ctx context.Context, in payin.RefundInp) (res *payin.RefundModel, err error) {
err = gerror.New("暂不支持QQ支付申请退款如有疑问请联系管理员")
return
}
// Notify 异步通知
func (h *qqPay) Notify(ctx context.Context, in payin.NotifyInp) (res *payin.NotifyModel, err error) {
notifyReq, err := qq.ParseNotifyToBodyMap(ghttp.RequestFromCtx(ctx).Request)
if err != nil {
return
}
// 验签操作
ok, err := qq.VerifySign(h.config.QQPayApiKey, qq.SignType_MD5, notifyReq)
if err != nil {
return
}
if !ok {
err = gerror.New("QQ支付验签不通过")
return
}
var notify *NotifyRequest
if err = gconv.Scan(notifyReq, &notify); err != nil {
return
}
if notify == nil {
err = gerror.New("解析订单参数失败!")
return
}
if notify.TradeState != "SUCCESS" {
err = gerror.New("非交易支付成功状态,无需处理!")
// 这里如果相对非交易支付成功状态进行处理,可自行调整此处逻辑
// ...
return
}
if notify.OutTradeNo == "" {
err = gerror.New("订单中没有找到商户单号!")
return
}
res = new(payin.NotifyModel)
res.TransactionId = notify.TransactionId
res.OutTradeNo = notify.OutTradeNo
res.PayAt = gtime.New(notify.TimeEnd)
res.ActualAmount = gconv.Float64(notify.CouponFee) / 100 // 用户本次交易中,实际支付的金额 转为元,和系统内保持一至
return
}
// CreateOrder 创建订单
func (h *qqPay) CreateOrder(ctx context.Context, in payin.CreateOrderInp) (res *payin.CreateOrderModel, err error) {
client := GetClient(h.config)
switch in.Pay.TradeType {
case consts.TradeTypeQQWeb, consts.TradeTypeQQWap:
bm := make(gopay.BodyMap)
bm.
Set("mch_id", h.config.QQPayMchId).
Set("body", in.Pay.Subject).
Set("out_trade_no", in.Pay.OutTradeNo).
Set("notify_url", in.Pay.NotifyUrl).
Set("nonce_str", grand.Letters(32)).
Set("spbill_create_ip", in.Pay.CreateIp).
Set("trade_type", "NATIVE"). // MICROPAY、APP、JSAPI、NATIVE
Set("total_fee", int64(in.Pay.PayAmount*100))
qqRsp, err := client.UnifiedOrder(ctx, bm)
if err != nil {
return nil, err
}
if qqRsp.ReturnCode != "SUCCESS" {
err = gerror.New(qqRsp.ReturnMsg)
return nil, err
}
if qqRsp.ResultCode != "SUCCESS" {
err = gerror.New(qqRsp.ErrCodeDes)
return nil, err
}
res = new(payin.CreateOrderModel)
res.TradeType = in.Pay.TradeType
res.PayURL = qqRsp.CodeUrl
res.OutTradeNo = in.Pay.OutTradeNo
default:
err = gerror.Newf("暂未支持的交易方式:%v", in.Pay.TradeType)
}
return
}
func GetClient(config *model.PayConfig) (client *qq.Client) {
client = qq.NewClient(config.QQPayMchId, config.QQPayApiKey)
// 打开Debug开关输出日志默认关闭
if config.Debug {
client.DebugSwitch = gopay.DebugOn
}
return
}

View File

@@ -0,0 +1,23 @@
package qqpay
// NotifyRequest QQ支付异步通知参数
// 文档https://mp.qpay.tenpay.cn/buss/wiki/38/1204
type NotifyRequest struct {
Appid string `xml:"appid,omitempty" json:"appid,omitempty"`
MchId string `xml:"mch_id,omitempty" json:"mch_id,omitempty"`
NonceStr string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"`
Sign string `xml:"sign,omitempty" json:"sign,omitempty"`
DeviceInfo string `xml:"device_info,omitempty" json:"device_info,omitempty"`
TradeType string `xml:"trade_type,omitempty" json:"trade_type,omitempty"`
TradeState string `xml:"trade_state,omitempty" json:"trade_state,omitempty"`
BankType string `xml:"bank_type,omitempty" json:"bank_type,omitempty"`
FeeType string `xml:"fee_type,omitempty" json:"fee_type,omitempty"`
TotalFee string `xml:"total_fee,omitempty" json:"total_fee,omitempty"`
CashFee string `xml:"cash_fee,omitempty" json:"cash_fee,omitempty"`
CouponFee string `xml:"coupon_fee,omitempty" json:"coupon_fee,omitempty"`
TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"`
OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"`
Attach string `xml:"attach,omitempty" json:"attach,omitempty"`
TimeEnd string `xml:"time_end,omitempty" json:"time_end,omitempty"`
Openid string `xml:"openid,omitempty" json:"openid,omitempty"`
}