feat: 业务逻辑补全 — 佣金待审记录、C端订单重构、支付抽象、富友支付、卡设备状态联动
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
F-1: 佣金链断裂时创建 status=99 零额待审记录,新增修正接口 POST /commission-records/:id/resolve F-4: C端订单查询从 Handler 迁移至 Service 层,移除 SkipPermissionCtx J-1: 富友支付 JSAPI/MiniApp 预下单实现,回调补全签名验证 J-2: 平台钱包代购支持(buyerType 为空时使用资产所属代理钱包) J-3: 套餐激活后自动更新卡/设备 status=3,最后套餐过期后更新 status=4 支付抽象: 引入 PaymentProvider 接口 + 微信/富友适配器,CreateOrder 支持多支付渠道 修复: 设备/IoT卡响应 DTO 移除 omitempty,空值字段返回 null 而非省略
This commit is contained in:
@@ -70,3 +70,23 @@ func (h *ShopCommissionHandler) ListCommissionRecords(c *fiber.Ctx) error {
|
||||
|
||||
return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size)
|
||||
}
|
||||
|
||||
// ResolveCommissionRecord 修正待审佣金记录
|
||||
// POST /api/admin/commission-records/:id/resolve
|
||||
func (h *ShopCommissionHandler) ResolveCommissionRecord(c *fiber.Ctx) error {
|
||||
recordID, err := strconv.ParseUint(c.Params("id"), 10, 64)
|
||||
if err != nil || recordID == 0 {
|
||||
return errors.New(errors.CodeInvalidParam, "无效的佣金记录ID")
|
||||
}
|
||||
|
||||
var req dto.CommissionRecordResolveRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
|
||||
if err := h.service.ResolveCommissionRecord(c.UserContext(), uint(recordID), &req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return response.Success(c, nil)
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ func (h *ClientAssetHandler) GetAssetInfo(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
// 调用服务层获取设备实时 Gateway 数据(per D-11)
|
||||
// Gateway 失败时 DeviceRealtime 为 null,不阻断主流程(per D-06)
|
||||
// Gateway 失败时 DeviceRealtime 仅含 gateway_msg,不阻断主流程(per D-06)
|
||||
if resp.AssetType == "device" {
|
||||
realtimeResp, realtimeErr := h.assetService.GetRealtimeStatus(
|
||||
c.UserContext(), "device", resp.AssetID,
|
||||
@@ -669,5 +669,6 @@ func mapDeviceGatewayInfoToClientInfo(g *dto.DeviceGatewayInfo) *dto.DeviceRealt
|
||||
info.DeviceType = g.DeviceType
|
||||
info.Imei = g.IMEI
|
||||
info.Imsi = g.IMSI
|
||||
info.GatewayMsg = g.GatewayMsg
|
||||
return info
|
||||
}
|
||||
|
||||
@@ -1,58 +1,33 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/middleware"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
asset "github.com/break/junhong_cmp_fiber/internal/service/asset"
|
||||
clientorder "github.com/break/junhong_cmp_fiber/internal/service/client_order"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/response"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ClientOrderHandler C 端订单处理器
|
||||
// 提供 D1~D3 下单、列表、详情接口。
|
||||
type ClientOrderHandler struct {
|
||||
clientOrderService *clientorder.Service
|
||||
assetService *asset.Service
|
||||
orderStore *postgres.OrderStore
|
||||
personalDeviceStore *postgres.PersonalCustomerDeviceStore
|
||||
iotCardStore *postgres.IotCardStore
|
||||
deviceStore *postgres.DeviceStore
|
||||
logger *zap.Logger
|
||||
db *gorm.DB
|
||||
clientOrderService *clientorder.Service
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewClientOrderHandler 创建 C 端订单处理器。
|
||||
func NewClientOrderHandler(
|
||||
clientOrderService *clientorder.Service,
|
||||
assetService *asset.Service,
|
||||
orderStore *postgres.OrderStore,
|
||||
personalDeviceStore *postgres.PersonalCustomerDeviceStore,
|
||||
iotCardStore *postgres.IotCardStore,
|
||||
deviceStore *postgres.DeviceStore,
|
||||
logger *zap.Logger,
|
||||
db *gorm.DB,
|
||||
) *ClientOrderHandler {
|
||||
return &ClientOrderHandler{
|
||||
clientOrderService: clientOrderService,
|
||||
assetService: assetService,
|
||||
orderStore: orderStore,
|
||||
personalDeviceStore: personalDeviceStore,
|
||||
iotCardStore: iotCardStore,
|
||||
deviceStore: deviceStore,
|
||||
logger: logger,
|
||||
db: db,
|
||||
clientOrderService: clientOrderService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,73 +70,16 @@ func (h *ClientOrderHandler) ListOrders(c *fiber.Ctx) error {
|
||||
req.PageSize = constants.MaxPageSize
|
||||
}
|
||||
|
||||
resolved, err := h.resolveAssetFromIdentifier(c, req.Identifier)
|
||||
customerID, ok := middleware.GetCustomerID(c)
|
||||
if !ok || customerID == 0 {
|
||||
return errors.New(errors.CodeUnauthorized)
|
||||
}
|
||||
|
||||
list, total, err := h.clientOrderService.ListOrders(c.UserContext(), customerID, &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := h.db.WithContext(resolved.SkipPermissionCtx).
|
||||
Model(&model.Order{}).
|
||||
Where("generation = ?", resolved.Generation)
|
||||
|
||||
if resolved.Asset.AssetType == constants.ResourceTypeDevice {
|
||||
query = query.Where("order_type = ? AND device_id = ?", model.OrderTypeDevice, resolved.Asset.AssetID)
|
||||
} else {
|
||||
query = query.Where("order_type = ? AND iot_card_id = ?", model.OrderTypeSingleCard, resolved.Asset.AssetID)
|
||||
}
|
||||
|
||||
if req.PaymentStatus != nil {
|
||||
query = query.Where("payment_status = ?", *req.PaymentStatus)
|
||||
}
|
||||
|
||||
var total int64
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "查询订单总数失败")
|
||||
}
|
||||
|
||||
var orders []*model.Order
|
||||
offset := (req.Page - 1) * req.PageSize
|
||||
if err := query.Order("created_at DESC").Offset(offset).Limit(req.PageSize).Find(&orders).Error; err != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "查询订单列表失败")
|
||||
}
|
||||
|
||||
orderIDs := make([]uint, 0, len(orders))
|
||||
for _, order := range orders {
|
||||
if order == nil {
|
||||
continue
|
||||
}
|
||||
orderIDs = append(orderIDs, order.ID)
|
||||
}
|
||||
|
||||
itemMap, err := h.loadOrderItemMap(resolved.SkipPermissionCtx, orderIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
list := make([]dto.ClientOrderListItem, 0, len(orders))
|
||||
for _, order := range orders {
|
||||
if order == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
packageNames := make([]string, 0, len(itemMap[order.ID]))
|
||||
for _, item := range itemMap[order.ID] {
|
||||
if item == nil || item.PackageName == "" {
|
||||
continue
|
||||
}
|
||||
packageNames = append(packageNames, item.PackageName)
|
||||
}
|
||||
|
||||
list = append(list, dto.ClientOrderListItem{
|
||||
OrderID: order.ID,
|
||||
OrderNo: order.OrderNo,
|
||||
TotalAmount: order.TotalAmount,
|
||||
PaymentStatus: order.PaymentStatus,
|
||||
CreatedAt: formatClientOrderTime(order.CreatedAt),
|
||||
PackageNames: packageNames,
|
||||
})
|
||||
}
|
||||
|
||||
return response.SuccessWithPagination(c, list, total, req.Page, req.PageSize)
|
||||
}
|
||||
|
||||
@@ -178,208 +96,10 @@ func (h *ClientOrderHandler) GetOrderDetail(c *fiber.Ctx) error {
|
||||
return errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
|
||||
order, items, err := h.orderStore.GetByIDWithItems(c.UserContext(), uint(orderID))
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNotFound, "订单不存在")
|
||||
}
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "查询订单详情失败")
|
||||
}
|
||||
|
||||
virtualNo, err := h.getOrderVirtualNo(c.UserContext(), order)
|
||||
resp, err := h.clientOrderService.GetOrderDetail(c.UserContext(), customerID, uint(orderID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
owned, ownErr := h.isCustomerOwnAsset(c.UserContext(), customerID, virtualNo)
|
||||
if ownErr != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, ownErr, "查询资产归属失败")
|
||||
}
|
||||
if !owned {
|
||||
return errors.New(errors.CodeForbidden, "无权限操作该资产或资源不存在")
|
||||
}
|
||||
|
||||
packages := make([]dto.ClientOrderPackageItem, 0, len(items))
|
||||
for _, item := range items {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
packages = append(packages, dto.ClientOrderPackageItem{
|
||||
PackageID: item.PackageID,
|
||||
PackageName: item.PackageName,
|
||||
Price: item.UnitPrice,
|
||||
Quantity: item.Quantity,
|
||||
})
|
||||
}
|
||||
|
||||
resp := &dto.ClientOrderDetailResponse{
|
||||
OrderID: order.ID,
|
||||
OrderNo: order.OrderNo,
|
||||
TotalAmount: order.TotalAmount,
|
||||
PaymentStatus: order.PaymentStatus,
|
||||
PaymentMethod: order.PaymentMethod,
|
||||
CreatedAt: formatClientOrderTime(order.CreatedAt),
|
||||
PaidAt: formatClientOrderTimePtr(order.PaidAt),
|
||||
CompletedAt: nil,
|
||||
Packages: packages,
|
||||
}
|
||||
|
||||
return response.Success(c, resp)
|
||||
}
|
||||
|
||||
func (h *ClientOrderHandler) resolveAssetFromIdentifier(c *fiber.Ctx, identifier string) (*resolvedAssetContext, error) {
|
||||
customerID, ok := middleware.GetCustomerID(c)
|
||||
if !ok || customerID == 0 {
|
||||
return nil, errors.New(errors.CodeUnauthorized)
|
||||
}
|
||||
|
||||
identifier = strings.TrimSpace(identifier)
|
||||
if identifier == "" {
|
||||
identifier = strings.TrimSpace(c.Query("identifier"))
|
||||
}
|
||||
if identifier == "" {
|
||||
return nil, errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
|
||||
skipPermissionCtx := context.WithValue(c.UserContext(), constants.ContextKeySubordinateShopIDs, []uint{})
|
||||
assetInfo, err := h.assetService.Resolve(skipPermissionCtx, identifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
owned, ownErr := h.isCustomerOwnAsset(skipPermissionCtx, customerID, assetInfo.VirtualNo)
|
||||
if ownErr != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, ownErr, "查询资产归属失败")
|
||||
}
|
||||
if !owned {
|
||||
return nil, errors.New(errors.CodeForbidden, "无权限操作该资产或资源不存在")
|
||||
}
|
||||
|
||||
generation, genErr := h.getAssetGeneration(skipPermissionCtx, assetInfo.AssetType, assetInfo.AssetID)
|
||||
if genErr != nil {
|
||||
return nil, genErr
|
||||
}
|
||||
|
||||
return &resolvedAssetContext{
|
||||
CustomerID: customerID,
|
||||
Identifier: identifier,
|
||||
Asset: assetInfo,
|
||||
Generation: generation,
|
||||
SkipPermissionCtx: skipPermissionCtx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *ClientOrderHandler) isCustomerOwnAsset(ctx context.Context, customerID uint, virtualNo string) (bool, error) {
|
||||
records, err := h.personalDeviceStore.GetByCustomerID(ctx, customerID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
if record == nil {
|
||||
continue
|
||||
}
|
||||
if record.Status == constants.StatusEnabled && record.VirtualNo == virtualNo {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (h *ClientOrderHandler) getAssetGeneration(ctx context.Context, assetType string, assetID uint) (int, error) {
|
||||
switch assetType {
|
||||
case "card":
|
||||
card, err := h.iotCardStore.GetByID(ctx, assetID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return 0, errors.New(errors.CodeAssetNotFound)
|
||||
}
|
||||
return 0, errors.Wrap(errors.CodeDatabaseError, err, "查询卡信息失败")
|
||||
}
|
||||
return card.Generation, nil
|
||||
case constants.ResourceTypeDevice:
|
||||
device, err := h.deviceStore.GetByID(ctx, assetID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return 0, errors.New(errors.CodeAssetNotFound)
|
||||
}
|
||||
return 0, errors.Wrap(errors.CodeDatabaseError, err, "查询设备信息失败")
|
||||
}
|
||||
return device.Generation, nil
|
||||
default:
|
||||
return 0, errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *ClientOrderHandler) loadOrderItemMap(ctx context.Context, orderIDs []uint) (map[uint][]*model.OrderItem, error) {
|
||||
result := make(map[uint][]*model.OrderItem)
|
||||
if len(orderIDs) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
var items []*model.OrderItem
|
||||
if err := h.db.WithContext(ctx).Where("order_id IN ?", orderIDs).Order("id ASC").Find(&items).Error; err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询订单明细失败")
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
result[item.OrderID] = append(result[item.OrderID], item)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (h *ClientOrderHandler) getOrderVirtualNo(ctx context.Context, order *model.Order) (string, error) {
|
||||
if order == nil {
|
||||
return "", errors.New(errors.CodeNotFound, "订单不存在")
|
||||
}
|
||||
|
||||
switch order.OrderType {
|
||||
case model.OrderTypeSingleCard:
|
||||
if order.IotCardID == nil || *order.IotCardID == 0 {
|
||||
return "", errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
card, err := h.iotCardStore.GetByID(ctx, *order.IotCardID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return "", errors.New(errors.CodeAssetNotFound)
|
||||
}
|
||||
return "", errors.Wrap(errors.CodeDatabaseError, err, "查询卡信息失败")
|
||||
}
|
||||
return card.VirtualNo, nil
|
||||
case model.OrderTypeDevice:
|
||||
if order.DeviceID == nil || *order.DeviceID == 0 {
|
||||
return "", errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
device, err := h.deviceStore.GetByID(ctx, *order.DeviceID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return "", errors.New(errors.CodeAssetNotFound)
|
||||
}
|
||||
return "", errors.Wrap(errors.CodeDatabaseError, err, "查询设备信息失败")
|
||||
}
|
||||
return device.VirtualNo, nil
|
||||
default:
|
||||
return "", errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
}
|
||||
|
||||
func formatClientOrderTime(t time.Time) string {
|
||||
if t.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return t.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func formatClientOrderTimePtr(t *time.Time) *string {
|
||||
if t == nil || t.IsZero() {
|
||||
return nil
|
||||
}
|
||||
formatted := formatClientOrderTime(*t)
|
||||
return &formatted
|
||||
}
|
||||
|
||||
@@ -2,14 +2,13 @@ package callback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/valyala/fasthttp/fasthttpadaptor"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
orderService "github.com/break/junhong_cmp_fiber/internal/service/order"
|
||||
@@ -26,11 +25,18 @@ type AgentRechargeServiceInterface interface {
|
||||
HandlePaymentCallback(ctx context.Context, rechargeNo string, paymentMethod string, paymentTransactionID string) error
|
||||
}
|
||||
|
||||
// WechatConfigServiceInterface 支付配置服务接口
|
||||
type WechatConfigServiceInterface interface {
|
||||
GetActiveConfig(ctx context.Context) (*model.WechatConfig, error)
|
||||
}
|
||||
|
||||
type PaymentHandler struct {
|
||||
orderService *orderService.Service
|
||||
rechargeService *rechargeService.Service
|
||||
agentRechargeService AgentRechargeServiceInterface
|
||||
wechatPayment wechat.PaymentServiceInterface
|
||||
wechatConfigService WechatConfigServiceInterface
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewPaymentHandler(
|
||||
@@ -38,12 +44,16 @@ func NewPaymentHandler(
|
||||
rechargeService *rechargeService.Service,
|
||||
agentRechargeService AgentRechargeServiceInterface,
|
||||
wechatPayment wechat.PaymentServiceInterface,
|
||||
wechatConfigService WechatConfigServiceInterface,
|
||||
logger *zap.Logger,
|
||||
) *PaymentHandler {
|
||||
return &PaymentHandler{
|
||||
orderService: orderService,
|
||||
rechargeService: rechargeService,
|
||||
agentRechargeService: agentRechargeService,
|
||||
wechatPayment: wechatPayment,
|
||||
wechatConfigService: wechatConfigService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +140,7 @@ func (h *PaymentHandler) AlipayCallback(c *fiber.Ctx) error {
|
||||
return c.SendString("success")
|
||||
}
|
||||
|
||||
// FuiouPayCallback 富友支付回调
|
||||
// FuiouPayCallback 富友支付回调(带签名验证)
|
||||
// POST /api/callback/fuiou-pay
|
||||
func (h *PaymentHandler) FuiouPayCallback(c *fiber.Ctx) error {
|
||||
body := c.Body()
|
||||
@@ -139,63 +149,60 @@ func (h *PaymentHandler) FuiouPayCallback(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
ctx := c.UserContext()
|
||||
c.Set("Content-Type", "text/xml; charset=gbk")
|
||||
|
||||
// TODO: 按 payment_config_id 加载配置创建 fuiou.Client 验签
|
||||
// 当前留桩:解析但不验签
|
||||
|
||||
// 解析 req= 参数
|
||||
formValue := string(body)
|
||||
if strings.HasPrefix(formValue, "req=") {
|
||||
formValue = formValue[4:]
|
||||
activeConfig, err := h.wechatConfigService.GetActiveConfig(ctx)
|
||||
if err != nil || activeConfig == nil {
|
||||
h.logger.Error("富友回调:加载支付配置失败", zap.Error(err))
|
||||
return c.Send(fuiou.BuildNotifyFailResponse("payment config unavailable"))
|
||||
}
|
||||
|
||||
decoded, err := url.QueryUnescape(formValue)
|
||||
client, err := fuiou.NewClient(
|
||||
activeConfig.FyInsCd,
|
||||
activeConfig.FyMchntCd,
|
||||
activeConfig.FyTermID,
|
||||
activeConfig.FyAPIURL,
|
||||
activeConfig.FyNotifyURL,
|
||||
activeConfig.FyPrivateKey,
|
||||
activeConfig.FyPublicKey,
|
||||
h.logger,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.New(errors.CodeFuiouCallbackInvalid, "回调数据解码失败")
|
||||
h.logger.Error("富友回调:构造客户端失败", zap.Error(err))
|
||||
return c.Send(fuiou.BuildNotifyFailResponse("client init failed"))
|
||||
}
|
||||
|
||||
utf8Data, err := fuiou.GBKToUTF8([]byte(decoded))
|
||||
notify, err := client.VerifyNotify(body)
|
||||
if err != nil {
|
||||
return errors.New(errors.CodeFuiouCallbackInvalid, "GBK 转 UTF-8 失败")
|
||||
if notify != nil {
|
||||
h.logger.Warn("富友回调:非成功结果",
|
||||
zap.String("result_code", notify.ResultCode),
|
||||
zap.String("result_msg", notify.ResultMsg))
|
||||
return c.Send(fuiou.BuildNotifySuccessResponse())
|
||||
}
|
||||
h.logger.Error("富友回调:验签或解析失败", zap.Error(err))
|
||||
return c.Send(fuiou.BuildNotifyFailResponse(err.Error()))
|
||||
}
|
||||
|
||||
xmlStr := strings.Replace(string(utf8Data), `encoding="GBK"`, `encoding="UTF-8"`, 1)
|
||||
|
||||
var notify fuiou.NotifyRequest
|
||||
if err := xml.Unmarshal([]byte(xmlStr), ¬ify); err != nil {
|
||||
return errors.New(errors.CodeFuiouCallbackInvalid, "解析回调 XML 失败")
|
||||
}
|
||||
|
||||
if notify.ResultCode != "000000" {
|
||||
c.Set("Content-Type", "text/xml; charset=gbk")
|
||||
return c.Send(fuiou.BuildNotifySuccessResponse())
|
||||
}
|
||||
|
||||
// 按订单号前缀分发
|
||||
orderNo := notify.MchntOrderNo
|
||||
switch {
|
||||
case strings.HasPrefix(orderNo, "ORD"):
|
||||
if err := h.orderService.HandlePaymentCallback(ctx, orderNo, "fuiou"); err != nil {
|
||||
c.Set("Content-Type", "text/xml; charset=gbk")
|
||||
return c.Send(fuiou.BuildNotifyFailResponse(err.Error()))
|
||||
}
|
||||
case strings.HasPrefix(orderNo, constants.AssetRechargeOrderPrefix):
|
||||
if err := h.rechargeService.HandlePaymentCallback(ctx, orderNo, "fuiou", notify.TransactionId); err != nil {
|
||||
c.Set("Content-Type", "text/xml; charset=gbk")
|
||||
return c.Send(fuiou.BuildNotifyFailResponse(err.Error()))
|
||||
}
|
||||
case strings.HasPrefix(orderNo, constants.AgentRechargeOrderPrefix):
|
||||
if h.agentRechargeService != nil {
|
||||
if err := h.agentRechargeService.HandlePaymentCallback(ctx, orderNo, "fuiou", notify.TransactionId); err != nil {
|
||||
c.Set("Content-Type", "text/xml; charset=gbk")
|
||||
return c.Send(fuiou.BuildNotifyFailResponse(err.Error()))
|
||||
}
|
||||
}
|
||||
default:
|
||||
c.Set("Content-Type", "text/xml; charset=gbk")
|
||||
return c.Send(fuiou.BuildNotifyFailResponse("unknown order prefix"))
|
||||
}
|
||||
|
||||
c.Set("Content-Type", "text/xml; charset=gbk")
|
||||
return c.Send(fuiou.BuildNotifySuccessResponse())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user