docs(v2): P2 计划 settle 代码段同步 T5 修复(瞬时读库错误→SettleFailed)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -1321,7 +1321,9 @@ func (g *Gateway) Settle(ctx context.Context, ev *provider.PaidEvent) (SettleRes
|
||||
if errors.Is(err, store.ErrAttemptNotFound) {
|
||||
return SettleNotFound, nil
|
||||
}
|
||||
return SettleNotFound, err
|
||||
// 读库瞬时失败是可重试态(SettleFailed),不能与"查无此单"(终态,ack 即弃)
|
||||
// 混淆——否则按 result 决定 ack 的调用方会让渠道停止重投,已付单永不入账。
|
||||
return SettleFailed, err
|
||||
}
|
||||
// 金额/币种核对:币种须一致,实付须 ≥ 应收(允许 crypto 多付,拒少付)。
|
||||
if ev.PaidCurrency != att.Currency || ev.PaidAmountMinor < att.AmountMinor {
|
||||
@@ -2158,13 +2160,19 @@ func (h *GatewayHandler) Callback(c *gin.Context) {
|
||||
res, err := h.g.HandleCallback(c.Request.Context(), method, provider.CallbackInput{
|
||||
Raw: raw, Headers: headers,
|
||||
})
|
||||
if err != nil {
|
||||
// 验签失败等:回 400 让渠道按策略重投(或人工排障)。
|
||||
// 按 SettleResult(而非只看 err)分终态/可重试:amount_mismatch 是终态——
|
||||
// 重投同一回调永远解决不了,必须回 200 让渠道停投(差错单归 P6 对账/人工);
|
||||
// SettleFailed/验签失败才是可重试态,回 400 让渠道重投。
|
||||
switch {
|
||||
case err == nil:
|
||||
c.JSON(http.StatusOK, gin.H{"result": string(res)})
|
||||
case res == gateway.SettleAmountMismatch:
|
||||
log.Printf("[v2 callback] method=%s 金额/币种不符(终态,已受理停投): %v", method, err)
|
||||
c.JSON(http.StatusOK, gin.H{"result": string(res)})
|
||||
default:
|
||||
log.Printf("[v2 callback] method=%s result=%s err=%v", method, res, err)
|
||||
util.RespondError(c, http.StatusBadRequest, "callback_failed", "回调处理失败")
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"result": string(res)})
|
||||
}
|
||||
|
||||
func (h *GatewayHandler) writeCreateErr(c *gin.Context, action, method string, err error) {
|
||||
|
||||
Reference in New Issue
Block a user