mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-02-03 02:54:41 +08:00
138 lines
3.5 KiB
Go
138 lines
3.5 KiB
Go
// Package qqpay
|
||
// @Link https://github.com/bufanyun/hotgo
|
||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||
// @Author Ms <133814250@qq.com>
|
||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||
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, ¬ify); 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
|
||
}
|