package handlers import ( "fmt" "github.com/shopspring/decimal" "github.com/valyala/fasthttp/fasthttpadaptor" "log/slog" "net/http" trade2 "platform/web/domains/trade" g "platform/web/globals" q "platform/web/queries" s "platform/web/services" "time" "github.com/gofiber/fiber/v2" "github.com/smartwalle/alipay/v3" "github.com/wechatpay-apiv3/wechatpay-go/services/payments" ) // region TradeCheckSSE func TradeCheckSSE(c *fiber.Ctx) error { // 设置响应头 c.Set("Content-Type", "text/event-stream") c.Set("Cache-Control", "no-cache") c.Set("Connection", "keep-alive") return nil } // endregion // region AlipayCallback func AlipayCallback(c *fiber.Ctx) (err error) { // 解析请求 httpRequest := new(http.Request) if err := fasthttpadaptor.ConvertRequest(c.Context(), httpRequest, false); err != nil { return err } if err := httpRequest.ParseForm(); err != nil { return err } notification, err := g.Alipay.DecodeNotification(httpRequest.Form) if err != nil { return err } slog.Debug("支付宝支付回调", "notification", fmt.Sprintf("%+v", notification)) // 查询交易信息 trade, err := q.Q.Trade.Where(q.Trade.InnerNo.Eq(notification.OutTradeNo)).Take() if err != nil { return c.SendString("success") } switch alipay.TradeStatus(notification.NotifyType) { // 等待支付 case alipay.TradeStatusWaitBuyerPay: // 不需要处理 // 支付关闭 case alipay.TradeStatusClosed: switch trade2.Type(trade.Type) { // 购买产品 case trade2.TypePurchase: err = s.Resource.CancelResource(notification.OutTradeNo, time.Now(), true) if err != nil { return err } // 余额充值 case trade2.TypeRecharge: } // 支付成功 case alipay.TradeStatusSuccess: // 收集交易状态 payment, err := decimal.NewFromString(notification.TotalAmount) if err != nil { return err } paidAt, err := time.Parse("2006-01-02 15:04:05", notification.GmtPayment) if err != nil { return err } verified := &s.TradeSuccessResult{ TransId: notification.TradeNo, Payment: payment, Time: paidAt, } switch trade2.Type(trade.Type) { // 余额充值 case trade2.TypeRecharge: err := s.User.RechargeConfirm(notification.OutTradeNo, verified) if err != nil { return err } // 购买产品 case trade2.TypePurchase: err = s.Resource.CompleteResource(notification.OutTradeNo, time.Now(), verified) if err != nil { return err } } // 交易结束 case alipay.TradeStatusFinished: // 结束交易状态 } return c.SendString("success") } func isRefund(notification *alipay.Notification) bool { return notification.OutBizNo != "" || notification.RefundFee != "" || notification.GmtRefund != "" } // endregion // region WechatPayCallback func WechatPayCallback(c *fiber.Ctx) error { // 解析请求参数 req := new(http.Request) if err := fasthttpadaptor.ConvertRequest(c.Context(), req, false); err != nil { return err } content := new(payments.Transaction) _, err := g.WechatPay.Notify.ParseNotifyRequest(c.Context(), req, content) if err != nil { return err } slog.Debug("微信支付回调", "content", fmt.Sprintf("%+v", content)) // 查询交易信息 trade, err := q.Q.Trade.Where(q.Trade.InnerNo.Eq(*content.OutTradeNo)).Take() if err != nil { // 跳过测试通知 return nil } switch *content.TradeState { // 支付成功 case "SUCCESS": // 收集交易状态 payment := decimal.NewFromInt(*content.Amount.PayerTotal).Div(decimal.NewFromInt(100)) paidAt, err := time.Parse(time.RFC3339, *content.SuccessTime) if err != nil { return err } verified := &s.TradeSuccessResult{ TransId: *content.TransactionId, Payment: payment, Time: paidAt, } switch { // 余额充值 case trade.Type == int32(trade2.TypeRecharge): err := s.User.RechargeConfirm(*content.OutTradeNo, verified) if err != nil { return err } // 购买产品 case trade.Type == int32(trade2.TypePurchase): err = s.Resource.CompleteResource(*content.OutTradeNo, time.Now(), verified) if err != nil { return err } } } return nil } // endregion