This commit is contained in:
2026-07-13 17:13:03 +08:00
parent 28c805fdd8
commit 384ccd24f8
6 changed files with 109 additions and 59 deletions
BIN
View File
Binary file not shown.
+34 -9
View File
@@ -39,9 +39,33 @@ func (c *config) GetPayment(ctx context.Context, req *dto.GetPaymentConfigReq) (
for _, cfg := range configs {
switch cfg.Channel {
case "wechat":
res.Wechat = cfg
if res.Wechat == nil {
res.Wechat = &dto.PaymentTypeConfig{}
}
switch cfg.ChannelType {
case "jsapi":
res.Wechat.Jsapi = cfg
case "h5":
res.Wechat.H5 = cfg
case "app":
res.Wechat.App = cfg
default:
res.Wechat.Jsapi = cfg
}
case "alipay":
res.Alipay = cfg
if res.Alipay == nil {
res.Alipay = &dto.PaymentTypeConfig{}
}
switch cfg.ChannelType {
case "jsapi":
res.Alipay.Jsapi = cfg
case "h5":
res.Alipay.H5 = cfg
case "app":
res.Alipay.App = cfg
default:
res.Alipay.Jsapi = cfg
}
case "offline":
res.Offline = cfg
}
@@ -51,12 +75,13 @@ func (c *config) GetPayment(ctx context.Context, req *dto.GetPaymentConfigReq) (
func (c *config) SavePayment(ctx context.Context, req *dto.SavePaymentConfigReq) (res *struct{}, err error) {
return nil, service.ConfigService.SavePaymentConfig(ctx, &entity.PaymentConfig{
Channel: req.Channel,
AppId: req.AppId,
MchId: req.MchId,
ApiKey: req.ApiKey,
AppSecret: req.AppSecret,
PrivateKey: req.PrivateKey,
PublicKey: req.PublicKey,
Channel: req.Channel,
ChannelType: req.ChannelType,
AppId: req.AppId,
MchId: req.MchId,
ApiKey: req.ApiKey,
AppSecret: req.AppSecret,
PrivateKey: req.PrivateKey,
PublicKey: req.PublicKey,
})
}
+8 -3
View File
@@ -21,6 +21,7 @@ func init() {
if _, err := g.DB().Exec(ctx, `CREATE TABLE IF NOT EXISTS `+public.TableNamePaymentConfig+` (
id INTEGER PRIMARY KEY AUTOINCREMENT,
channel TEXT NOT NULL DEFAULT '',
channel_type TEXT NOT NULL DEFAULT '',
app_id TEXT NOT NULL DEFAULT '',
mch_id TEXT NOT NULL DEFAULT '',
api_key TEXT NOT NULL DEFAULT '',
@@ -34,8 +35,12 @@ func init() {
}
}
func (d *paymentConfigDao) GetByChannel(ctx context.Context, channel string) (res *entity.PaymentConfig, err error) {
r, err := g.DB().Model(public.TableNamePaymentConfig).Ctx(ctx).Where("channel", channel).Limit(1).One()
func (d *paymentConfigDao) GetByChannel(ctx context.Context, channel string, typeOpt ...string) (res *entity.PaymentConfig, err error) {
m := g.DB().Model(public.TableNamePaymentConfig).Ctx(ctx).Where("channel", channel)
if len(typeOpt) > 0 && typeOpt[0] != "" {
m = m.Where("channel_type", typeOpt[0])
}
r, err := m.Limit(1).One()
if err != nil {
return nil, err
}
@@ -48,7 +53,7 @@ func (d *paymentConfigDao) GetByChannel(ctx context.Context, channel string) (re
}
func (d *paymentConfigDao) Save(ctx context.Context, data *entity.PaymentConfig) error {
existing, err := d.GetByChannel(ctx, data.Channel)
existing, err := d.GetByChannel(ctx, data.Channel, data.ChannelType)
if err != nil {
return err
}
+18 -11
View File
@@ -42,19 +42,26 @@ type GetPaymentConfigReq struct {
g.Meta `path:"/payment" method:"get" tags:"支付配置" summary:"获取支付配置"`
}
type PaymentTypeConfig struct {
Jsapi *entity.PaymentConfig `json:"jsapi,omitempty"`
H5 *entity.PaymentConfig `json:"h5,omitempty"`
App *entity.PaymentConfig `json:"app,omitempty"`
}
type GetPaymentConfigRes struct {
Wechat *entity.PaymentConfig `json:"wechat"`
Alipay *entity.PaymentConfig `json:"alipay"`
Offline *entity.PaymentConfig `json:"offline"`
Wechat *PaymentTypeConfig `json:"wechat,omitempty"`
Alipay *PaymentTypeConfig `json:"alipay,omitempty"`
Offline *entity.PaymentConfig `json:"offline,omitempty"`
}
type SavePaymentConfigReq struct {
g.Meta `path:"/payment" method:"post" tags:"支付配置" summary:"保存支付配置"`
Channel string `json:"channel" v:"required" dc:"支付渠道: wechat/alipay/offline"`
AppId string `json:"appId"`
MchId string `json:"mchId"`
ApiKey string `json:"apiKey"`
AppSecret string `json:"appSecret"`
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
g.Meta `path:"/payment" method:"post" tags:"支付配置" summary:"保存支付配置"`
Channel string `json:"channel" v:"required" dc:"支付渠道: wechat/alipay/offline"`
ChannelType string `json:"channelType" dc:"支付类型: jsapi/h5/app/native/manual"`
AppId string `json:"appId"`
MchId string `json:"mchId"`
ApiKey string `json:"apiKey"`
AppSecret string `json:"appSecret"`
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
}
+11 -10
View File
@@ -5,14 +5,15 @@ import (
)
type PaymentConfig struct {
Id int64 `orm:"id" json:"id"`
Channel string `orm:"channel" json:"channel"`
AppId string `orm:"app_id" json:"appId"`
MchId string `orm:"mch_id" json:"mchId"`
ApiKey string `orm:"api_key" json:"apiKey"`
AppSecret string `orm:"app_secret" json:"appSecret"`
PrivateKey string `orm:"private_key" json:"privateKey"`
PublicKey string `orm:"public_key" json:"publicKey"`
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"`
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"`
Id int64 `orm:"id" json:"id"`
Channel string `orm:"channel" json:"channel"`
ChannelType string `orm:"channel_type" json:"channelType"`
AppId string `orm:"app_id" json:"appId"`
MchId string `orm:"mch_id" json:"mchId"`
ApiKey string `orm:"api_key" json:"apiKey"`
AppSecret string `orm:"app_secret" json:"appSecret"`
PrivateKey string `orm:"private_key" json:"privateKey"`
PublicKey string `orm:"public_key" json:"publicKey"`
CreatedAt *gtime.Time `orm:"created_at" json:"createdAt"`
UpdatedAt *gtime.Time `orm:"updated_at" json:"updatedAt"`
}
+38 -26
View File
@@ -41,25 +41,38 @@ type AlipayConfig struct {
PublicKey string `json:"public_key"`
}
func (s *paymentService) GetPaymentConfig() PaymentConfig {
func (s *paymentService) GetPaymentConfig(channel, channelType string) (WechatConfig, AlipayConfig, error) {
ctx := context.Background()
pc := PaymentConfig{}
if wc, _ := dao.PaymentConfigDao.GetByChannel(ctx, "wechat"); wc != nil {
pc.Wechat = WechatConfig{
switch channel {
case "wechat":
wc, err := dao.PaymentConfigDao.GetByChannel(ctx, "wechat", channelType)
if err != nil {
return WechatConfig{}, AlipayConfig{}, err
}
if wc == nil || wc.AppId == "" || wc.MchId == "" || wc.ApiKey == "" {
return WechatConfig{}, AlipayConfig{}, errors.New("微信支付(" + channelType + ")未配置")
}
return WechatConfig{
AppId: wc.AppId,
MchId: wc.MchId,
ApiKey: wc.ApiKey,
AppSecret: wc.AppSecret,
}, AlipayConfig{}, nil
case "alipay":
ac, err := dao.PaymentConfigDao.GetByChannel(ctx, "alipay", channelType)
if err != nil {
return WechatConfig{}, AlipayConfig{}, err
}
}
if ac, _ := dao.PaymentConfigDao.GetByChannel(ctx, "alipay"); ac != nil {
pc.Alipay = AlipayConfig{
if ac == nil || ac.AppId == "" || ac.PrivateKey == "" {
return WechatConfig{}, AlipayConfig{}, errors.New("支付宝支付(" + channelType + ")未配置")
}
return WechatConfig{}, AlipayConfig{
AppId: ac.AppId,
PrivateKey: ac.PrivateKey,
PublicKey: ac.PublicKey,
}
}, nil
}
return pc
return WechatConfig{}, AlipayConfig{}, errors.New("不支持的支付渠道")
}
// Prepay 创建支付订单并调起渠道
@@ -98,16 +111,8 @@ func (s *paymentService) Prepay(ctx context.Context, userId int64, amount int64,
// 外部渠道需要检查支付配置
if channel != "offline" {
pc := s.GetPaymentConfig()
switch channel {
case "wechat":
if pc.Wechat.AppId == "" || pc.Wechat.MchId == "" || pc.Wechat.ApiKey == "" {
return nil, "", "", "", errors.New("微信支付未配置,请先联系管理员配置支付参数")
}
case "alipay":
if pc.Alipay.AppId == "" || pc.Alipay.PrivateKey == "" {
return nil, "", "", "", errors.New("支付宝支付未配置,请先联系管理员配置支付参数")
}
if _, _, err := s.GetPaymentConfig(channel, chanType); err != nil {
return nil, "", "", "", err
}
}
@@ -141,9 +146,11 @@ func (s *paymentService) Prepay(ctx context.Context, userId int64, amount int64,
switch channel {
case "wechat":
codeUrl, prepayJson, err = s.callWechat(ctx, order, s.GetPaymentConfig().Wechat)
wechatCfg, _, _ := s.GetPaymentConfig("wechat", chanType)
codeUrl, prepayJson, err = s.callWechat(ctx, order, wechatCfg)
case "alipay":
codeUrl, redirectUrl, err = s.callAlipay(ctx, order, s.GetPaymentConfig().Alipay)
_, alipayCfg, _ := s.GetPaymentConfig("alipay", chanType)
codeUrl, redirectUrl, err = s.callAlipay(ctx, order, alipayCfg)
case "offline":
// 线下支付无需调起外部渠道,直接返回
}
@@ -223,19 +230,24 @@ func (s *paymentService) ConfirmOffline(ctx context.Context, orderNo string) err
// HandleNotify 处理渠道回调
func (s *paymentService) HandleNotify(ctx context.Context, channel string, body []byte) error {
pc := s.GetPaymentConfig()
var orderNo, tradeNo string
switch channel {
case "wechat":
var err error
orderNo, tradeNo, err = s.verifyWechatNotify(body, pc.Wechat)
wechatCfg, _, err := s.GetPaymentConfig("wechat", "native")
if err != nil {
return err
}
orderNo, tradeNo, err = s.verifyWechatNotify(body, wechatCfg)
if err != nil {
return err
}
case "alipay":
var err error
orderNo, tradeNo, err = s.verifyAlipayNotify(body, pc.Alipay)
_, alipayCfg, err := s.GetPaymentConfig("alipay", "native")
if err != nil {
return err
}
orderNo, tradeNo, err = s.verifyAlipayNotify(body, alipayCfg)
if err != nil {
return err
}