2025-05-27 18:35:01 +08:00
|
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"database/sql"
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
"time"
|
|
|
|
|
"tyc-server/app/main/api/internal/config"
|
|
|
|
|
"tyc-server/app/main/model"
|
|
|
|
|
"tyc-server/common/ctxdata"
|
|
|
|
|
"tyc-server/pkg/core/payment"
|
|
|
|
|
|
2025-06-03 21:39:36 +08:00
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
2025-05-27 18:35:01 +08:00
|
|
|
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// PayService 支付服务
|
|
|
|
|
type PayService struct {
|
|
|
|
|
config config.Config
|
|
|
|
|
orderModel model.OrderModel
|
|
|
|
|
orderRefundModel model.OrderRefundModel
|
|
|
|
|
productModel model.ProductModel
|
|
|
|
|
userAuthModel model.UserAuthModel
|
|
|
|
|
userModel model.UserModel
|
2025-06-03 21:39:36 +08:00
|
|
|
|
asyncService *AsynqService
|
2025-05-27 18:35:01 +08:00
|
|
|
|
alipayService *payment.AliPayService
|
|
|
|
|
wechatService *payment.WechatPayService
|
|
|
|
|
appleService *payment.ApplePayService
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewPayService 创建支付服务
|
2025-06-03 21:39:36 +08:00
|
|
|
|
func NewPayService(c config.Config, orderModel model.OrderModel, orderRefundModel model.OrderRefundModel, productModel model.ProductModel, userAuthModel model.UserAuthModel, userModel model.UserModel, asyncService *AsynqService) *PayService {
|
2025-05-27 18:35:01 +08:00
|
|
|
|
ps := &PayService{
|
|
|
|
|
config: c,
|
|
|
|
|
orderModel: orderModel,
|
|
|
|
|
orderRefundModel: orderRefundModel,
|
|
|
|
|
productModel: productModel,
|
|
|
|
|
userAuthModel: userAuthModel,
|
2025-06-03 20:59:26 +08:00
|
|
|
|
userModel: userModel,
|
2025-06-03 21:39:36 +08:00
|
|
|
|
asyncService: asyncService,
|
2025-05-27 18:35:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据配置选择性初始化支付服务
|
|
|
|
|
if c.Alipay.Enabled {
|
|
|
|
|
// 初始化支付宝服务
|
|
|
|
|
alipayConfig := payment.AlipayConfig{
|
|
|
|
|
AppID: c.Alipay.AppID,
|
|
|
|
|
PrivateKey: c.Alipay.PrivateKey,
|
|
|
|
|
AlipayPublicKey: c.Alipay.AlipayPublicKey,
|
|
|
|
|
IsProduction: c.Alipay.IsProduction,
|
|
|
|
|
NotifyURL: c.Alipay.NotifyUrl,
|
|
|
|
|
ReturnURL: c.Alipay.ReturnURL,
|
|
|
|
|
}
|
|
|
|
|
alipayService, err := payment.NewAliPayService(alipayConfig)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(fmt.Sprintf("初始化支付宝服务失败: %v", err))
|
|
|
|
|
}
|
|
|
|
|
ps.alipayService = alipayService
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.Wxpay.Enabled {
|
|
|
|
|
// 初始化微信支付服务
|
|
|
|
|
wechatConfig := &payment.WechatPayConfig{
|
|
|
|
|
AppID: c.Wxpay.AppID,
|
|
|
|
|
MchID: c.Wxpay.MchID,
|
|
|
|
|
SerialNo: c.Wxpay.MchCertificateSerialNumber,
|
|
|
|
|
MchAPIv3Key: c.Wxpay.MchApiv3Key,
|
|
|
|
|
PrivateKey: c.Wxpay.MchPrivateKeyPath,
|
|
|
|
|
NotifyURL: c.Wxpay.NotifyUrl,
|
|
|
|
|
RefundURL: c.Wxpay.RefundNotifyUrl,
|
|
|
|
|
}
|
|
|
|
|
wechatService, err := payment.NewWechatPayService(wechatConfig)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(fmt.Sprintf("初始化微信支付服务失败: %v", err))
|
|
|
|
|
}
|
|
|
|
|
ps.wechatService = wechatService
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.Applepay.Enabled {
|
|
|
|
|
// 初始化苹果支付服务
|
|
|
|
|
appleConfig := payment.ApplePayConfig{
|
|
|
|
|
BundleID: c.Applepay.BundleID,
|
|
|
|
|
KeyID: c.Applepay.KeyID,
|
|
|
|
|
TeamID: c.Applepay.IssuerID,
|
|
|
|
|
PrivateKey: c.Applepay.LoadPrivateKeyPath,
|
|
|
|
|
IsProduction: !c.Applepay.Sandbox,
|
|
|
|
|
NotifyURL: c.Applepay.ProductionVerifyURL,
|
|
|
|
|
RefundNotifyURL: c.Applepay.SandboxVerifyURL,
|
|
|
|
|
}
|
|
|
|
|
appleService, err := payment.NewApplePayService(appleConfig)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(fmt.Sprintf("初始化苹果支付服务失败: %v", err))
|
|
|
|
|
}
|
|
|
|
|
ps.appleService = appleService
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ps
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CreateOrder 创建支付订单
|
|
|
|
|
func (p *PayService) CreateOrder(ctx context.Context, req *CreateOrderRequest) (*CreateOrderResponse, error) {
|
|
|
|
|
platform, ok := ctx.Value("platform").(string)
|
|
|
|
|
if !ok {
|
|
|
|
|
return nil, fmt.Errorf("获取平台失败")
|
|
|
|
|
}
|
|
|
|
|
userID, err := ctxdata.GetUidFromCtx(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("获取用户信息失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
product, err := p.productModel.FindOneByProductEn(ctx, req.ProductEn)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("获取商品失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
user, err := p.userModel.FindOne(ctx, userID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("获取用户失败: %v", err)
|
|
|
|
|
}
|
2025-06-03 21:50:29 +08:00
|
|
|
|
outTradeNo := req.OrderNo
|
2025-05-27 18:35:01 +08:00
|
|
|
|
var orderID int64
|
|
|
|
|
amount := product.SellPrice
|
|
|
|
|
if user.Inside == 1 {
|
|
|
|
|
amount = 0.01
|
|
|
|
|
}
|
|
|
|
|
// 使用事务创建订单
|
|
|
|
|
var payData interface{}
|
|
|
|
|
err = p.orderModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
|
|
|
// 根据支付方式创建支付订单
|
|
|
|
|
switch req.PayMethod {
|
|
|
|
|
case "alipay":
|
|
|
|
|
orderReq := &payment.AlipayCreateOrderRequest{
|
2025-06-03 21:50:29 +08:00
|
|
|
|
Amount: amount,
|
|
|
|
|
Subject: product.ProductName,
|
|
|
|
|
Platform: payment.PlatformH5,
|
|
|
|
|
OutTradeNo: outTradeNo,
|
2025-05-27 18:35:01 +08:00
|
|
|
|
}
|
|
|
|
|
resp, err := p.alipayService.CreateOrder(ctx, orderReq)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("创建支付宝订单失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
payData = resp.PayParams
|
|
|
|
|
case "wechat":
|
|
|
|
|
orderReq := &payment.Order{
|
|
|
|
|
OutTradeNo: outTradeNo,
|
|
|
|
|
Subject: product.ProductName,
|
|
|
|
|
Amount: amount,
|
|
|
|
|
Platform: payment.PlatformApp,
|
|
|
|
|
NotifyURL: p.config.Wxpay.NotifyUrl,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是小程序支付,需要获取用户的 OpenID
|
|
|
|
|
if platform == "mp-weixin" {
|
|
|
|
|
userAuth, err := p.userAuthModel.FindOneByUserIdAuthType(ctx, userID, model.UserAuthTypeWechatMiniOpenID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("获取用户认证信息失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
orderReq.OpenID = userAuth.AuthKey
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := p.wechatService.CreateOrder(orderReq)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("创建微信支付订单失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
payData = resp.PayParams
|
|
|
|
|
outTradeNo = resp.OrderNo
|
|
|
|
|
// case "apple":
|
|
|
|
|
// orderReq := &payment.AppleCreateOrderRequest{
|
|
|
|
|
// Amount: amount,
|
|
|
|
|
// Subject: product.ProductName,
|
|
|
|
|
// OutTradeNo: outTradeNo,
|
|
|
|
|
// Platform: payment.PlatformApp,
|
|
|
|
|
// NotifyURL: p.config.Applepay.ProductionVerifyURL,
|
|
|
|
|
// }
|
|
|
|
|
// resp, err := p.appleService.CreateOrder(ctx, orderReq)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return fmt.Errorf("创建苹果支付订单失败: %v", err)
|
|
|
|
|
// }
|
|
|
|
|
// payData = resp.PayParams
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("不支持的支付方式: %s", req.PayMethod)
|
|
|
|
|
}
|
|
|
|
|
// 创建订单记录
|
|
|
|
|
order := &model.Order{
|
|
|
|
|
OrderNo: outTradeNo,
|
|
|
|
|
UserId: userID,
|
|
|
|
|
ProductId: product.Id,
|
|
|
|
|
PaymentPlatform: string(req.PayMethod),
|
|
|
|
|
PaymentScene: platform,
|
|
|
|
|
Amount: amount,
|
|
|
|
|
Status: model.OrderStatusPending,
|
|
|
|
|
}
|
|
|
|
|
result, err := p.orderModel.Insert(ctx, session, order)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("创建订单记录失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
orderID, err = result.LastInsertId()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("获取订单ID失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &CreateOrderResponse{
|
|
|
|
|
OrderNo: outTradeNo,
|
|
|
|
|
PayData: payData,
|
|
|
|
|
PayMethod: req.PayMethod,
|
|
|
|
|
OrderID: orderID,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HandlePaymentCallback 处理支付回调
|
|
|
|
|
func (p *PayService) HandlePaymentCallback(ctx context.Context, payType string, req *http.Request) error {
|
|
|
|
|
return p.orderModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
|
|
|
var payOrder *payment.QueryOrderResponse
|
|
|
|
|
var err error
|
|
|
|
|
switch payType {
|
|
|
|
|
case "alipay":
|
|
|
|
|
payOrder, err = p.handleAlipayCallback(ctx, req, session)
|
|
|
|
|
case "wechat":
|
|
|
|
|
payOrder, err = p.handleWechatCallback(ctx, req, session)
|
|
|
|
|
case "apple":
|
|
|
|
|
payOrder, err = p.handleAppleCallback(ctx, req, session)
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("不支持的支付类型: %s", payType)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if payOrder == nil {
|
|
|
|
|
return fmt.Errorf("支付订单信息为空")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询订单
|
|
|
|
|
order, err := p.orderModel.FindOneByOrderNo(ctx, payOrder.OrderNo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("查询订单失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证订单金额
|
|
|
|
|
if payOrder.Amount != order.Amount {
|
|
|
|
|
return fmt.Errorf("订单金额不匹配")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据支付状态更新订单状态
|
|
|
|
|
switch payOrder.Status {
|
|
|
|
|
case payment.StatusSuccess:
|
|
|
|
|
order.Status = model.OrderStatusPaid
|
|
|
|
|
case payment.StatusFailed:
|
|
|
|
|
order.Status = model.OrderStatusFailed
|
|
|
|
|
case payment.StatusClosed:
|
|
|
|
|
order.Status = model.OrderStatusClosed
|
|
|
|
|
case payment.StatusRefunded:
|
|
|
|
|
order.Status = model.OrderStatusRefunding
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("不支持的支付状态: %s", payOrder.Status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新订单状态
|
|
|
|
|
order.PlatformOrderId = sql.NullString{String: payOrder.TransactionID, Valid: true}
|
|
|
|
|
_, err = p.orderModel.Update(ctx, session, order)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("更新订单状态失败: %v", err)
|
|
|
|
|
}
|
2025-06-03 21:39:36 +08:00
|
|
|
|
if asyncErr := p.asyncService.SendQueryTask(order.Id); asyncErr != nil {
|
|
|
|
|
logx.Errorf("异步任务调度失败: %v", asyncErr)
|
|
|
|
|
return asyncErr
|
|
|
|
|
}
|
2025-05-27 18:35:01 +08:00
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// handleAlipayCallback 处理支付宝回调
|
|
|
|
|
func (p *PayService) handleAlipayCallback(ctx context.Context, req *http.Request, session sqlx.Session) (*payment.QueryOrderResponse, error) {
|
|
|
|
|
return p.alipayService.HandlePaymentNotification(req)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// handleWechatCallback 处理微信支付回调
|
|
|
|
|
func (p *PayService) handleWechatCallback(ctx context.Context, req *http.Request, session sqlx.Session) (*payment.QueryOrderResponse, error) {
|
|
|
|
|
notification, err := p.wechatService.HandlePaymentNotification(req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("处理微信支付回调失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将微信支付通知转换为统一的查询订单响应格式
|
|
|
|
|
return &payment.QueryOrderResponse{
|
|
|
|
|
OrderNo: notification.OrderNo,
|
|
|
|
|
TransactionID: notification.TransactionID,
|
|
|
|
|
Status: notification.Status,
|
|
|
|
|
Amount: notification.Amount,
|
|
|
|
|
PayTime: notification.PayTime,
|
|
|
|
|
PayMethod: payment.MethodWechat,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// handleAppleCallback 处理苹果支付回调
|
|
|
|
|
func (p *PayService) handleAppleCallback(ctx context.Context, req *http.Request, session sqlx.Session) (*payment.QueryOrderResponse, error) {
|
|
|
|
|
receipt := req.FormValue("receipt-data")
|
|
|
|
|
if receipt == "" {
|
|
|
|
|
return nil, fmt.Errorf("无效的苹果支付收据")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
verifyResp, err := p.appleService.VerifyReceipt(ctx, receipt)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("验证苹果支付收据失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if verifyResp.Status != payment.StatusSuccess {
|
|
|
|
|
return nil, fmt.Errorf("苹果支付验证失败,状态码: %s", verifyResp.Status)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将苹果支付验证响应转换为统一的查询订单响应格式
|
|
|
|
|
return &payment.QueryOrderResponse{
|
|
|
|
|
OrderNo: verifyResp.OrderNo,
|
|
|
|
|
TransactionID: verifyResp.TransactionID,
|
|
|
|
|
Status: verifyResp.Status,
|
|
|
|
|
Amount: verifyResp.Amount,
|
|
|
|
|
PayTime: time.Now(),
|
|
|
|
|
PayMethod: payment.MethodApple,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Refund 申请退款
|
|
|
|
|
func (p *PayService) Refund(ctx context.Context, req *RefundRequest) (*RefundResponse, error) {
|
|
|
|
|
|
|
|
|
|
// 查询订单信息
|
|
|
|
|
order, err := p.orderModel.FindOne(ctx, req.OrderId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("查询订单失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 验证订单状态
|
|
|
|
|
if order.Status != model.OrderStatusPaid {
|
|
|
|
|
return nil, fmt.Errorf("订单状态为 %s,无法退款", order.Status)
|
|
|
|
|
}
|
|
|
|
|
if req.RefundAmount > order.Amount {
|
|
|
|
|
return nil, fmt.Errorf("退款金额 %.2f 不能大于订单金额 %.2f", req.RefundAmount, order.Amount)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var result refundResult
|
|
|
|
|
result.status = model.OrderRefundStatusPending
|
|
|
|
|
order.Status = model.OrderStatusRefunding
|
|
|
|
|
// 使用事务处理退款流程
|
|
|
|
|
err = p.orderModel.Trans(ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
|
|
|
// 根据支付方式申请退款
|
|
|
|
|
switch order.PaymentPlatform {
|
|
|
|
|
case string(PayMethodAlipay):
|
|
|
|
|
refundReq := &payment.AlipayRefundRequest{
|
|
|
|
|
OrderNo: order.OrderNo,
|
|
|
|
|
RefundAmount: req.RefundAmount,
|
|
|
|
|
}
|
|
|
|
|
resp, err := p.alipayService.Refund(ctx, refundReq)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("支付宝退款申请失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
result = refundResult{
|
|
|
|
|
refundNo: resp.RefundNo,
|
|
|
|
|
status: model.OrderRefundStatusSuccess,
|
|
|
|
|
refundTime: resp.RefundTime,
|
|
|
|
|
refundAmount: resp.RefundAmount,
|
|
|
|
|
platformRefundId: sql.NullString{String: resp.RefundID, Valid: true},
|
|
|
|
|
}
|
2025-06-20 15:11:38 +08:00
|
|
|
|
order.Status = model.OrderStatusRefund
|
2025-05-27 18:35:01 +08:00
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("不支持的支付平台退款: %s", order.PaymentPlatform)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建退款记录
|
|
|
|
|
refund := &model.OrderRefund{
|
|
|
|
|
RefundNo: result.refundNo,
|
|
|
|
|
PlatformRefundId: result.platformRefundId,
|
|
|
|
|
OrderId: order.Id,
|
|
|
|
|
UserId: order.UserId,
|
|
|
|
|
ProductId: order.ProductId,
|
|
|
|
|
RefundAmount: result.refundAmount,
|
|
|
|
|
RefundReason: sql.NullString{String: req.Reason, Valid: true},
|
|
|
|
|
Status: result.status,
|
|
|
|
|
RefundTime: sql.NullTime{Time: result.refundTime, Valid: !result.refundTime.IsZero()},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := p.orderRefundModel.Insert(ctx, session, refund); err != nil {
|
|
|
|
|
return fmt.Errorf("创建退款记录失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新订单状态
|
2025-06-20 15:11:38 +08:00
|
|
|
|
order.Status = model.OrderStatusRefund
|
2025-05-27 18:35:01 +08:00
|
|
|
|
order.RefundTime = sql.NullTime{Time: result.refundTime, Valid: !result.refundTime.IsZero()}
|
|
|
|
|
if _, err := p.orderModel.Update(ctx, session, order); err != nil {
|
|
|
|
|
return fmt.Errorf("更新订单状态失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &RefundResponse{
|
|
|
|
|
RefundNo: result.refundNo,
|
|
|
|
|
Amount: result.refundAmount,
|
|
|
|
|
Status: result.status,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// QueryOrderStatus 查询订单状态
|
|
|
|
|
func (p *PayService) QueryOrderStatus(ctx context.Context, orderNo string) (*OrderStatusResponse, error) {
|
|
|
|
|
// 查询订单信息
|
|
|
|
|
order, err := p.orderModel.FindOneByOrderNo(ctx, orderNo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("查询订单失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据支付方式查询支付状态
|
|
|
|
|
var payStatus payment.PaymentStatus
|
|
|
|
|
switch order.PaymentPlatform {
|
|
|
|
|
case "alipay":
|
|
|
|
|
queryReq := &payment.QueryOrderRequest{
|
|
|
|
|
OrderNo: orderNo,
|
|
|
|
|
}
|
|
|
|
|
resp, err := p.alipayService.QueryOrder(ctx, queryReq)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("查询支付宝订单状态失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
payStatus = resp.Status
|
|
|
|
|
// case "wechat":
|
|
|
|
|
// queryReq := &payment.OrderQuery{
|
|
|
|
|
// OrderNo: orderNo,
|
|
|
|
|
// }
|
|
|
|
|
// resp, err := p.wechatService.QueryOrder(queryReq)
|
|
|
|
|
// if err != nil {
|
|
|
|
|
// return nil, fmt.Errorf("查询微信支付订单状态失败: %v", err)
|
|
|
|
|
// }
|
|
|
|
|
// payStatus = resp.Status
|
|
|
|
|
// case "apple":
|
|
|
|
|
// return nil, fmt.Errorf("苹果支付暂不支持主动查询订单状态")
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("不支持的支付方式: %s", order.PaymentPlatform)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &OrderStatusResponse{
|
|
|
|
|
OrderNo: orderNo,
|
|
|
|
|
PayMethod: PayMethod(order.PaymentPlatform),
|
|
|
|
|
PayStatus: string(payStatus),
|
|
|
|
|
OrderStatus: order.Status,
|
|
|
|
|
Amount: order.Amount,
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PayMethod string
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
PayMethodAlipay PayMethod = "alipay"
|
|
|
|
|
PayMethodWechat PayMethod = "wechat"
|
|
|
|
|
PayMethodApple PayMethod = "apple"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 请求和响应结构体定义
|
|
|
|
|
type CreateOrderRequest struct {
|
|
|
|
|
PayMethod PayMethod `json:"pay_method"` // 支付方式:alipay, wechat, apple
|
|
|
|
|
ProductEn string `json:"product_en"` // 商品英文名
|
2025-06-03 21:50:29 +08:00
|
|
|
|
OrderNo string `json:"order_no"` // 订单号
|
2025-05-27 18:35:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CreateOrderResponse struct {
|
|
|
|
|
OrderNo string `json:"order_no"` // 订单号
|
|
|
|
|
PayData interface{} `json:"pay_data"` // 支付数据
|
|
|
|
|
PayMethod PayMethod `json:"pay_type"` // 支付方式
|
|
|
|
|
OrderID int64 `json:"order_id"` // 订单ID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type RefundRequest struct {
|
|
|
|
|
OrderId int64 `json:"order_id"` // 订单ID
|
|
|
|
|
RefundAmount float64 `json:"refund_amount"` // 退款金额
|
|
|
|
|
Reason string `json:"reason"` // 退款原因
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 定义退款结果结构
|
|
|
|
|
type refundResult struct {
|
|
|
|
|
refundNo string
|
|
|
|
|
status string
|
|
|
|
|
refundTime time.Time
|
|
|
|
|
refundAmount float64
|
|
|
|
|
platformRefundId sql.NullString
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type RefundResponse struct {
|
|
|
|
|
RefundNo string `json:"refund_no"` // 退款单号
|
|
|
|
|
Amount float64 `json:"amount"` // 退款金额
|
|
|
|
|
Status string `json:"status"` // 退款状态
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type OrderStatusResponse struct {
|
|
|
|
|
OrderNo string `json:"order_no"` // 订单号
|
|
|
|
|
PayMethod PayMethod `json:"pay_type"` // 支付方式
|
|
|
|
|
PayStatus string `json:"pay_status"` // 支付状态
|
|
|
|
|
OrderStatus string `json:"order_status"` // 订单状态
|
|
|
|
|
Amount float64 `json:"amount"` // 订单金额
|
|
|
|
|
}
|