hotgo/server/internal/library/payment/qqpay/handle.go

138 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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, &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
}