修改交易服务函数命名;调整 docker compose 脚本;
This commit is contained in:
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/shopspring/decimal"
|
||||
wecahtpaycore "github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
@@ -21,16 +19,14 @@ import (
|
||||
"platform/web/tasks"
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
wecahtpaycore "github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var ComplementEvents = []trade2.CompleteEvent{
|
||||
ResourceOnTradeComplete{},
|
||||
UserOnTradeComplete{},
|
||||
}
|
||||
|
||||
var Trade = &tradeService{}
|
||||
|
||||
type tradeService struct {
|
||||
@@ -258,67 +254,92 @@ func (s *tradeService) CreateTrade(uid int32, now time.Time, data *CreateTradeDa
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *tradeService) OnTradeCompleted(data *OnTradeCompletedData) error {
|
||||
// 更新交易状态
|
||||
var trade = new(m.Trade)
|
||||
var err = g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
|
||||
return q.Q.Transaction(func(q *q.Query) (err error) {
|
||||
trade, err = completeTrade(q, data)
|
||||
return
|
||||
})
|
||||
func (s *tradeService) CompleteTrade(data *CheckTradeData) error {
|
||||
return g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
|
||||
|
||||
// 检查订单状态
|
||||
result, err := s.ConfirmTradeCompleted(data)
|
||||
if err != nil {
|
||||
return core.NewServErr("确认交易状态失败", err)
|
||||
}
|
||||
|
||||
// 更新交易状态
|
||||
trade, err := completeTrade(&OnTradeCompletedData{data.TradeNo, *result})
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易失败", err)
|
||||
}
|
||||
|
||||
// 处理交易完成事件
|
||||
err = afterTradeComplete(trade)
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易完成事件失败", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易失败", err)
|
||||
}
|
||||
|
||||
// 处理交易完成事件
|
||||
err = completeTradeAfter(trade)
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易完成事件失败", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func completeTrade(q *q.Query, data *OnTradeCompletedData) (*m.Trade, error) {
|
||||
var tradeNo = data.TradeNo
|
||||
var transId = data.TransId
|
||||
var payment = data.Payment
|
||||
var acquirer = data.Acquirer
|
||||
var paidAt = data.Time
|
||||
func (s *tradeService) OnTradeCompleted(data *OnTradeCompletedData) error {
|
||||
return g.Redsync.WithLock(tradeLockKey(data.TradeNo), func() error {
|
||||
|
||||
// 获取交易信息
|
||||
trade, err := q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
Take()
|
||||
if err != nil {
|
||||
return nil, core.NewBizErr("获取交易信息失败", err)
|
||||
}
|
||||
// 更新交易状态
|
||||
trade, err := completeTrade(data)
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易失败", err)
|
||||
}
|
||||
|
||||
// 检查交易状态
|
||||
switch trade2.Status(trade.Status) {
|
||||
case trade2.StatusCanceled:
|
||||
return nil, core.NewBizErr("交易已取消")
|
||||
case trade2.StatusSuccess:
|
||||
return nil, core.NewBizErr("交易已完成")
|
||||
case trade2.StatusPending:
|
||||
}
|
||||
// 处理交易完成事件
|
||||
err = afterTradeComplete(trade)
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易完成事件失败", err)
|
||||
}
|
||||
|
||||
// 更新交易信息
|
||||
trade.Status = int32(trade2.StatusSuccess)
|
||||
trade.OuterNo = &transId
|
||||
trade.Payment = payment
|
||||
trade.Acquirer = u.P(int32(acquirer))
|
||||
trade.CompletedAt = u.P(orm.LocalDateTime(paidAt))
|
||||
_, err = q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
Updates(trade)
|
||||
if err != nil {
|
||||
return nil, core.NewServErr("更新交易信息失败", err)
|
||||
}
|
||||
|
||||
return trade, nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
func completeTradeAfter(trade *m.Trade) error {
|
||||
func completeTrade(data *OnTradeCompletedData) (*m.Trade, error) {
|
||||
var trade = new(m.Trade)
|
||||
var err = q.Q.Transaction(func(tx *q.Query) error {
|
||||
var tradeNo = data.TradeNo
|
||||
var transId = data.TransId
|
||||
var payment = data.Payment
|
||||
var acquirer = data.Acquirer
|
||||
var paidAt = data.Time
|
||||
|
||||
// 获取交易信息
|
||||
trade, err := q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
Take()
|
||||
if err != nil {
|
||||
return core.NewBizErr("获取交易信息失败", err)
|
||||
}
|
||||
|
||||
// 检查交易状态
|
||||
switch trade2.Status(trade.Status) {
|
||||
case trade2.StatusCanceled:
|
||||
return core.NewBizErr("交易已取消")
|
||||
case trade2.StatusSuccess:
|
||||
return core.NewBizErr("交易已完成")
|
||||
case trade2.StatusPending:
|
||||
}
|
||||
|
||||
// 更新交易信息
|
||||
trade.Status = int32(trade2.StatusSuccess)
|
||||
trade.OuterNo = &transId
|
||||
trade.Payment = payment
|
||||
trade.Acquirer = u.P(int32(acquirer))
|
||||
trade.CompletedAt = u.P(orm.LocalDateTime(paidAt))
|
||||
_, err = q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
Updates(trade)
|
||||
if err != nil {
|
||||
return core.NewServErr("更新交易信息失败", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return trade, err
|
||||
}
|
||||
func afterTradeComplete(trade *m.Trade) error {
|
||||
|
||||
// 恢复购买信息
|
||||
productData, err := g.Redis.Get(context.Background(), tradeProductKey(trade.InnerNo)).Result()
|
||||
@@ -327,6 +348,11 @@ func completeTradeAfter(trade *m.Trade) error {
|
||||
}
|
||||
|
||||
// 执行资源创建
|
||||
var ComplementEvents = []trade2.CompleteEvent{
|
||||
ResourceOnTradeComplete{},
|
||||
UserOnTradeComplete{},
|
||||
}
|
||||
|
||||
for _, event := range ComplementEvents {
|
||||
info, ok := event.Check(trade2.Type(trade.Type))
|
||||
if !ok {
|
||||
@@ -348,7 +374,7 @@ func completeTradeAfter(trade *m.Trade) error {
|
||||
}
|
||||
|
||||
func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now time.Time) error {
|
||||
err := g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
|
||||
return g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
|
||||
switch method {
|
||||
|
||||
case trade2.MethodAlipay:
|
||||
@@ -356,11 +382,11 @@ func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now tim
|
||||
OutTradeNo: tradeNo,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return core.NewServErr("上游取消交易失败", err)
|
||||
}
|
||||
if resp.Code != alipay.CodeSuccess {
|
||||
slog.Warn("支付宝交易取消失败", "code", resp.Code, "sub_code", resp.SubCode, "msg", resp.Msg)
|
||||
return errors.New("交易取消失败")
|
||||
slog.Error("支付宝交易取消失败", "code", resp.Code, "sub_code", resp.SubCode, "msg", resp.Msg)
|
||||
return errors.New("上游取消交易失败")
|
||||
}
|
||||
|
||||
case trade2.MethodWeChat:
|
||||
@@ -369,12 +395,16 @@ func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now tim
|
||||
OutTradeNo: &tradeNo,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return core.NewServErr("上游取消交易失败", err)
|
||||
}
|
||||
if resp.Response.StatusCode != http.StatusNoContent {
|
||||
body, _ := io.ReadAll(resp.Response.Body)
|
||||
slog.Warn("微信交易取消失败", "code", resp.Response.StatusCode, "body", string(body))
|
||||
return errors.New("交易取消失败")
|
||||
body, err := io.ReadAll(resp.Response.Body)
|
||||
if err != nil {
|
||||
slog.Error("读取微信交易取消响应失败", "error", err)
|
||||
return core.NewServErr("上游取消交易失败", err)
|
||||
}
|
||||
slog.Error("微信交易取消失败", "code", resp.Response.StatusCode, "body", string(body))
|
||||
return errors.New("上游取消交易失败")
|
||||
}
|
||||
|
||||
case trade2.MethodSft, trade2.MethodSftAlipay, trade2.MethodSftWeChat:
|
||||
@@ -390,61 +420,56 @@ func (s *tradeService) CancelTrade(tradeNo string, method trade2.Method, now tim
|
||||
return ErrTransactionNotSupported
|
||||
}
|
||||
|
||||
err := q.Q.Transaction(func(q *q.Query) error {
|
||||
return cancelTrade(q, tradeNo, now)
|
||||
})
|
||||
err := cancelTrade(tradeNo, now)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易取消失败", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s *tradeService) OnTradeCanceled(q *q.Query, tradeNo string, now time.Time) error {
|
||||
func (s *tradeService) OnTradeCanceled(tradeNo string, now time.Time) error {
|
||||
err := g.Redsync.WithLock(tradeLockKey(tradeNo), func() error {
|
||||
return cancelTrade(q, tradeNo, now)
|
||||
return cancelTrade(tradeNo, now)
|
||||
})
|
||||
if err != nil {
|
||||
return core.NewServErr("处理交易取消失败", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func cancelTrade(q *q.Query, tradeNo string, now time.Time) error {
|
||||
// 获取交易信息
|
||||
var status trade2.Status
|
||||
err := q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
Select(q.Trade.Status).
|
||||
Scan(&status)
|
||||
if err != nil {
|
||||
return core.NewBizErr("获取交易信息失败", err)
|
||||
}
|
||||
func cancelTrade(tradeNo string, now time.Time) error {
|
||||
return q.Q.Transaction(func(q *q.Query) error {
|
||||
// 获取交易信息
|
||||
var status trade2.Status
|
||||
err := q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
Select(q.Trade.Status).
|
||||
Scan(&status)
|
||||
if err != nil {
|
||||
return core.NewBizErr("获取交易信息失败", err)
|
||||
}
|
||||
|
||||
// 检查交易状态
|
||||
switch status {
|
||||
case trade2.StatusCanceled:
|
||||
return core.NewBizErr("交易已取消")
|
||||
case trade2.StatusSuccess:
|
||||
return core.NewBizErr("交易已完成")
|
||||
case trade2.StatusPending:
|
||||
}
|
||||
// 检查交易状态
|
||||
switch status {
|
||||
case trade2.StatusCanceled:
|
||||
return core.NewBizErr("交易已取消")
|
||||
case trade2.StatusSuccess:
|
||||
return core.NewBizErr("交易已完成")
|
||||
case trade2.StatusPending:
|
||||
}
|
||||
|
||||
// 更新交易状态
|
||||
_, err = q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
UpdateSimple(
|
||||
q.Trade.Status.Value(int32(trade2.StatusCanceled)),
|
||||
q.Trade.CanceledAt.Value(orm.LocalDateTime(now)),
|
||||
)
|
||||
if err != nil {
|
||||
return core.NewServErr("更新交易状态失败", err)
|
||||
}
|
||||
return nil
|
||||
// 更新交易状态
|
||||
_, err = q.Trade.
|
||||
Where(q.Trade.InnerNo.Eq(tradeNo)).
|
||||
UpdateSimple(
|
||||
q.Trade.Status.Value(int32(trade2.StatusCanceled)),
|
||||
q.Trade.CanceledAt.Value(orm.LocalDateTime(now)),
|
||||
)
|
||||
if err != nil {
|
||||
return core.NewServErr("更新交易状态失败", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *tradeService) RefundTrade(tradeNo string, method trade2.Method) error {
|
||||
|
||||
Reference in New Issue
Block a user