让代理充值复用现有网页支付能力
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m7s

微信按当前 v2/v3 配置分别生成 MWEB/H5 链接,支付宝复用 C 端 WAP 链接,并让可用支付方式基于生效配置判断。

Constraint: 支付链接统一通过 qr_content 返回,由前端渲染二维码;按要求不运行测试

Rejected: 微信 Native 与支付宝当面付 | 会引入非当前商户配置所需的额外产品开通

Confidence: high

Scope-risk: moderate

Directive: 微信 H5/MWEB 二维码仅承诺系统相机或外部浏览器扫码链路

Tested: 相关 Go 包编译通过;gofmt 与 git diff --check 通过

Not-tested: 按用户要求未运行自动化测试及真实支付联调
This commit is contained in:
2026-07-30 11:41:50 +08:00
parent 0f4f0d1176
commit 8fc667daee
24 changed files with 692 additions and 352 deletions

View File

@@ -11,7 +11,7 @@ import (
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
// RecoverOnlinePaymentService 批量收敛长期待预下单或待支付的代理在线充值。
// RecoverOnlinePaymentService 批量收敛长期缺少支付链接或待支付的代理在线充值。
type RecoverOnlinePaymentService struct {
db *gorm.DB
wechat OnlinePaymentPort
@@ -75,18 +75,23 @@ func (s *RecoverOnlinePaymentService) recoverOne(ctx context.Context, payment *m
}
if payment.QRContent == "" {
if !adapter.Available(config) {
return errors.New(errors.CodeNoPaymentConfig, "代理充值预下单配置不可用")
return errors.New(errors.CodeNoPaymentConfig, "代理充值支付配置不可用")
}
// 支付宝 WAP 链接由本地签名生成,可以安全重建;微信 H5 下单结果未知时只允许查单。
if payment.PaymentMethod != constants.RechargeMethodAlipay {
return s.queryPayment(ctx, adapter, payment, recharge, config)
}
expireAt := now.Add(30 * time.Minute)
if payment.ExpireAt != nil && payment.ExpireAt.After(now) {
expireAt = *payment.ExpireAt
}
result, err := adapter.PreCreate(ctx, OnlinePaymentRequest{
PaymentNo: payment.PaymentNo, Description: "代理主钱包充值", Amount: payment.Amount,
result, err := adapter.CreatePaymentURL(ctx, OnlinePaymentRequest{
PaymentID: payment.ID, PaymentNo: payment.PaymentNo, CorrelationID: payment.PaymentNo,
Description: "代理主钱包充值", Amount: payment.Amount,
ExpireAt: expireAt, Config: config,
})
if err != nil {
// 恢复阶段不能仅凭预下单错误推断未收款,保留本地状态等待下次查单。
// 恢复阶段不能仅凭链接生成错误推断未收款,保留本地状态等待下次查单。
return nil
}
if result.QRContent == "" {
@@ -96,11 +101,17 @@ func (s *RecoverOnlinePaymentService) recoverOne(ctx context.Context, payment *m
Where("id = ? AND status = ? AND qr_content = ''", payment.ID, model.PaymentRecordStatusPending).
Update("qr_content", result.QRContent)
if update.Error != nil {
return errors.Wrap(errors.CodeDatabaseError, update.Error, "恢复代理充值扫码付款内容失败")
return errors.Wrap(errors.CodeDatabaseError, update.Error, "恢复代理充值支付链接失败")
}
return nil
}
queryResult, err := adapter.Query(ctx, payment.PaymentNo, config)
return s.queryPayment(ctx, adapter, payment, recharge, config)
}
func (s *RecoverOnlinePaymentService) queryPayment(ctx context.Context, adapter OnlinePaymentPort, payment *model.Payment, recharge *model.AgentRechargeRecord, config *model.WechatConfig) error {
queryResult, err := adapter.Query(ctx, OnlinePaymentRequest{
PaymentID: payment.ID, PaymentNo: payment.PaymentNo, CorrelationID: payment.PaymentNo, Config: config,
})
if err != nil {
return nil
}