feat(v2): crypto 孤儿到账发现——OrphanScanner 扫链核对 + orphan_payments 落表告警(对账兜底)

This commit is contained in:
wangjia
2026-07-10 17:52:10 +08:00
parent 04c3f4f31a
commit 727ed74899
12 changed files with 370 additions and 7 deletions
+25
View File
@@ -176,3 +176,28 @@ func TestListOrdersByStatus(t *testing.T) {
t.Fatalf("命中集合不对: %+v", got)
}
}
// TestListAttemptsByChannelSince 供 orphan 扫描构造"已知期望金额集":同渠道、
// created_at>=since、任意状态的 attempt(pending/paid/expired 都算——凡 pay
// 合法签发过的金额都不算孤儿)。
func TestListAttemptsByChannelSince(t *testing.T) {
db := model.OpenTestDB(t)
s := store.NewOrderStore(db)
now := time.Date(2026, 7, 10, 12, 0, 0, 0, time.UTC)
mk := func(no, ch string, ago time.Duration) {
_ = s.CreateAttempt(&model.Attempt{OutTradeNo: no, Channel: ch, ProviderRef: "R-" + no,
AmountMinor: 100, Currency: "USDT", Status: model.AttemptPending})
_ = db.Model(&model.Attempt{}).Where("out_trade_no = ?", no).Update("created_at", now.Add(-ago)).Error
}
mk("C1", "crypto", 10*time.Minute)
mk("C2", "crypto", 5*time.Hour) // 太旧
mk("A1", "alipay", 1*time.Minute)
got, err := s.ListAttemptsByChannelSince("crypto", now.Add(-time.Hour), 100)
if err != nil {
t.Fatalf("list: %v", err)
}
if len(got) != 1 || got[0].OutTradeNo != "C1" {
t.Fatalf("只应含近期 crypto, got %+v", got)
}
}