diff --git a/styleagent/controller/member_controller.go b/styleagent/controller/member_controller.go index a095f05..23e6346 100644 --- a/styleagent/controller/member_controller.go +++ b/styleagent/controller/member_controller.go @@ -90,7 +90,8 @@ func MemberNotify(r *ghttp.Request) { _ = dao.PayNotifyLog.Insert(ctx, &entity.PayNotifyLog{ OrderNo: orderNo, Body: body, Sign: hash, RemoteIp: remoteIP, Status: state, }) - if err != nil || state != "ok" { + // duplicate(幂等重复回调)同样返回 success,避免支付渠道无限重试 + if err != nil || state == "no_order" { r.Response.Write("fail") r.ExitAll() return diff --git a/styleagent/payment/gateway.go b/styleagent/payment/gateway.go index 6155187..422804d 100644 --- a/styleagent/payment/gateway.go +++ b/styleagent/payment/gateway.go @@ -5,6 +5,7 @@ import ( "crypto/md5" "crypto/rand" "encoding/hex" + "encoding/json" "errors" "fmt" "sort" @@ -65,7 +66,13 @@ func CreateOrder(ctx context.Context, orderNo string, amountFen int) (payURL str Errmsg string `json:"errmsg"` Url string `json:"url"` } - if _, err := g.Client().SetTimeout(10 * time.Second).Post(context.Background(), cfg.ApiBase+"/payment/do.html", params, &resp); err != nil { + // 注意:Post 的最后一个参数不会自动解析响应体,需手动读取后反序列化 + respRaw, err := g.Client().SetTimeout(10 * time.Second).Post(context.Background(), cfg.ApiBase+"/payment/do.html", params) + if err != nil { + return "", fmt.Errorf("虎皮棋下单失败: %w", err) + } + defer respRaw.Close() + if err := json.Unmarshal(respRaw.ReadAll(), &resp); err != nil { return "", fmt.Errorf("虎皮棋下单失败: %w", err) } if resp.Errcode != 0 { diff --git a/styleagent/service/member_service.go b/styleagent/service/member_service.go index 1864c1f..be78cdc 100644 --- a/styleagent/service/member_service.go +++ b/styleagent/service/member_service.go @@ -101,7 +101,11 @@ func (s *memberService) HandlePaidNotify(ctx context.Context, orderNo, tradeNo, days = plan.DurationDays } um, _ := dao.UserMember.GetByUser(ctx, order.UserId) - expireAt := NextExpire(um.ExpireAt, days) + var oldExpire *gtime.Time + if um != nil { + oldExpire = um.ExpireAt + } + expireAt := NextExpire(oldExpire, days) if err := dao.UserMember.Upsert(ctx, order.UserId, order.PlanId, expireAt, consts.MemberSourceVipPay); err != nil { return "no_order", err }