fix(v2): jiu 反馈波——端型透传(wap/page)+ alipay qr(当面付移植)+ 单号增熵/挡板限流
1. CreateOrderInput/RetryOrder 加 Metadata 通道,handler 白名单过滤(is_mobile/render)
后原样传给 provider.CreateRequest;alipay adapter 据 is_mobile 选 wap/page。
2. alipay adapter 移植 v1 当面付(TradePreCreate):Metadata["render"]=="qr" → 二维码
render_type,payload={qr_content,display_amount,currency},默认 2 小时窗口。
3. NewOutTradeNo 随机部分 8→16 hex 防生日碰撞(仍 <=64 字符,合规 DB 列/支付宝上限);
v2 改状态端点(下单/重试/取消)加 per-IP 内存令牌桶限流,默认开 30/min,
config.rate_limit.disabled 可关;callback/GET 查询不限。
顺带修:internal/reconcile/sync_test.go 的 gateway.New 调用漏传 refunds store,
预先存在的编译期回归(与本次改动无关,但挡住 go test ./... 全绿,一并修掉)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -60,6 +60,9 @@ type CreateOrderInput struct {
|
||||
BizSystem string
|
||||
BizRef string
|
||||
ReturnURL string
|
||||
// Metadata 透传给 provider.CreateRequest(如 alipay 用 is_mobile 选 wap/page、
|
||||
// render=qr 选当面付)。handler 层已按白名单过滤,这里原样传,nil 安全。
|
||||
Metadata map[string]string
|
||||
}
|
||||
|
||||
type SessionView struct {
|
||||
@@ -111,7 +114,7 @@ func (g *Gateway) CreateOrder(ctx context.Context, in CreateOrderInput) (*OrderR
|
||||
|
||||
sess, err := prov.Create(ctx, provider.CreateRequest{
|
||||
OutTradeNo: outNo, Subject: subject, AmountMinor: amountMinor,
|
||||
Currency: currency, Account: acct, ReturnURL: in.ReturnURL,
|
||||
Currency: currency, Account: acct, ReturnURL: in.ReturnURL, Metadata: in.Metadata,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -152,7 +155,8 @@ func (g *Gateway) GetOrder(outTradeNo string) (*OrderStatusView, error) {
|
||||
|
||||
// RetryOrder spawns a fresh attempt (possibly a different method) on a still-pending
|
||||
// order; old pending attempts are expired. attempt 超时 ≠ order 关闭(设计 §3.2)。
|
||||
func (g *Gateway) RetryOrder(ctx context.Context, outTradeNo, method string) (*OrderResult, error) {
|
||||
// metadata 同 CreateOrderInput.Metadata,原样透传给新尝试的 CreateRequest(nil 安全)。
|
||||
func (g *Gateway) RetryOrder(ctx context.Context, outTradeNo, method string, metadata map[string]string) (*OrderResult, error) {
|
||||
o, err := g.orders.GetOrder(outTradeNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -188,7 +192,7 @@ func (g *Gateway) RetryOrder(ctx context.Context, outTradeNo, method string) (*O
|
||||
}
|
||||
sess, err := prov.Create(ctx, provider.CreateRequest{
|
||||
OutTradeNo: outTradeNo, Subject: o.Subject, AmountMinor: o.AmountMinor,
|
||||
Currency: o.Currency, Account: acct,
|
||||
Currency: o.Currency, Account: acct, Metadata: metadata,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user