web
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
|
||||
wechatutils "github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
)
|
||||
@@ -25,6 +26,7 @@ type WeChatPayService struct {
|
||||
config *config.WeChatPayConfig
|
||||
client *core.Client
|
||||
jsapiSvc *jsapi.JsapiApiService
|
||||
nativeSvc *native.NativeApiService
|
||||
refundSvc *refunddomestic.RefundsApiService
|
||||
privateKey *rsa.PrivateKey
|
||||
orderRepo *repository.OrderRepository
|
||||
@@ -74,6 +76,9 @@ func NewWeChatPayService(cfg *config.WeChatPayConfig, orderRepo *repository.Orde
|
||||
// 创建JSAPI服务
|
||||
jsapiSvc := &jsapi.JsapiApiService{Client: client}
|
||||
|
||||
// 创建Native扫码支付服务
|
||||
nativeSvc := &native.NativeApiService{Client: client}
|
||||
|
||||
// 创建退款服务
|
||||
refundSvc := &refunddomestic.RefundsApiService{Client: client}
|
||||
|
||||
@@ -86,6 +91,7 @@ func NewWeChatPayService(cfg *config.WeChatPayConfig, orderRepo *repository.Orde
|
||||
config: cfg,
|
||||
client: client,
|
||||
jsapiSvc: jsapiSvc,
|
||||
nativeSvc: nativeSvc,
|
||||
refundSvc: refundSvc,
|
||||
privateKey: privateKey,
|
||||
orderRepo: orderRepo,
|
||||
@@ -174,6 +180,99 @@ func (s *WeChatPayService) CreateOrder(ctx context.Context, order *model.Order,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateNativeOrder 创建Native扫码支付订单(用于PC端)
|
||||
func (s *WeChatPayService) CreateNativeOrder(ctx context.Context, order *model.Order) (*WeChatPayResponse, error) {
|
||||
// 生成唯一的微信支付订单号
|
||||
wechatOutTradeNo := utils.GenerateWechatOutTradeNo()
|
||||
|
||||
logger.Info("开始创建Native扫码支付订单",
|
||||
"orderNo", order.OrderNo,
|
||||
"wechatOutTradeNo", wechatOutTradeNo,
|
||||
"totalAmount", order.TotalAmount,
|
||||
"hasClient", s.client != nil)
|
||||
|
||||
// 更新订单的微信支付订单号
|
||||
err := s.orderRepo.UpdateByOrderNo(order.OrderNo, map[string]interface{}{
|
||||
"wechat_out_trade_no": wechatOutTradeNo,
|
||||
"updated_at": time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("更新订单微信支付订单号失败", "error", err, "orderNo", order.OrderNo)
|
||||
return nil, fmt.Errorf("更新订单失败: %v", err)
|
||||
}
|
||||
|
||||
// 如果没有客户端(开发环境),使用模拟数据
|
||||
if s.client == nil {
|
||||
logger.Warn("开发环境下使用模拟Native支付数据")
|
||||
return s.createMockNativePayment(order)
|
||||
}
|
||||
|
||||
// 构建Native预支付请求
|
||||
req := native.PrepayRequest{
|
||||
Appid: core.String(s.config.AppID),
|
||||
Mchid: core.String(s.config.MchID),
|
||||
Description: core.String(fmt.Sprintf("订单号: %s", order.OrderNo)),
|
||||
OutTradeNo: core.String(wechatOutTradeNo),
|
||||
NotifyUrl: core.String(s.config.NotifyURL),
|
||||
Amount: &native.Amount{
|
||||
Total: core.Int64(int64(order.TotalAmount)),
|
||||
Currency: core.String("CNY"),
|
||||
},
|
||||
}
|
||||
|
||||
// 调用Native预支付API
|
||||
resp, result, err := s.nativeSvc.Prepay(ctx, req)
|
||||
if err != nil {
|
||||
log.Printf("call Native Prepay err:%s", err)
|
||||
logger.Error("创建Native支付订单失败", "error", err, "orderNo", order.OrderNo)
|
||||
return nil, fmt.Errorf("创建Native支付订单失败: %v", err)
|
||||
}
|
||||
|
||||
if result.Response.StatusCode != 200 {
|
||||
log.Printf("Native Prepay status=%d", result.Response.StatusCode)
|
||||
return nil, fmt.Errorf("Native预支付请求失败,状态码: %d", result.Response.StatusCode)
|
||||
}
|
||||
|
||||
log.Printf("Native Prepay success, code_url=%s", *resp.CodeUrl)
|
||||
logger.Info("微信Native支付API响应",
|
||||
"codeUrl", *resp.CodeUrl,
|
||||
"orderNo", order.OrderNo)
|
||||
|
||||
return &WeChatPayResponse{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
Data: map[string]interface{}{
|
||||
"qrcode_url": *resp.CodeUrl,
|
||||
"order_no": order.OrderNo,
|
||||
"amount": order.TotalAmount,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// createMockNativePayment 创建模拟Native支付数据(开发环境使用)
|
||||
func (s *WeChatPayService) createMockNativePayment(order *model.Order) (*WeChatPayResponse, error) {
|
||||
// 生成模拟的二维码URL
|
||||
mockQRCodeURL := fmt.Sprintf("weixin://wxpay/bizpayurl?pr=mock_%s", utils.GenerateRandomString(10))
|
||||
|
||||
logger.Info("生成模拟Native支付参数",
|
||||
"environment", s.config.Environment,
|
||||
"qrcodeUrl", mockQRCodeURL,
|
||||
"orderNo", order.OrderNo,
|
||||
"totalAmount", order.TotalAmount)
|
||||
|
||||
return &WeChatPayResponse{
|
||||
Code: 0,
|
||||
Message: "模拟支付创建成功",
|
||||
Data: map[string]interface{}{
|
||||
"qrcode_url": mockQRCodeURL,
|
||||
"order_no": order.OrderNo,
|
||||
"amount": order.TotalAmount,
|
||||
"sandbox": true,
|
||||
"tips": "这是模拟环境的Native支付,请使用测试接口模拟支付成功",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// createMockPayment 创建模拟支付数据(沙盒环境使用)
|
||||
func (s *WeChatPayService) createMockPayment(order *model.Order, openID string) (*WeChatPayResponse, error) {
|
||||
mockPrepayID := fmt.Sprintf("wx%d%s", time.Now().Unix(), generateNonceStr()[:8])
|
||||
|
||||
Reference in New Issue
Block a user