@
支付提交增加 Tx 预校验:提交前链上验签收款地址与金额,防止转错地址;409 错误展示友好中文提示并自动对账恢复
- 新增 validate_intent_tx 方法及 POST /api/payments/intents/{id}/validate 端点,
在提交前查链上 receipt 对比收款地址和金额,mismatch 直接拦截
- 新增 handleSubmit409 辅助函数,根据后端错误详情分流处理:
已支付→自动 reconcile,已过期→提示重下单,其他→透传具体原因
- submit/validate 路由透传后端 detail 字段,生产环境也能看到具体错误
- 手动转账面板粘贴 tx hash 后自动触发验证,绿色/红色提示,
验证不通过时禁用提交按钮
Tested: tsc --noEmit + ruff check . 均通过
@
This commit is contained in:
@@ -376,6 +376,10 @@ class SubmitPaymentTxRequest(BaseModel):
|
||||
from_address: Optional[str] = None
|
||||
|
||||
|
||||
class ValidatePaymentTxRequest(BaseModel):
|
||||
tx_hash: str = Field(..., min_length=10)
|
||||
|
||||
|
||||
class ConfirmPaymentTxRequest(BaseModel):
|
||||
tx_hash: Optional[str] = None
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from web.core import (
|
||||
ConfirmPaymentTxRequest,
|
||||
CreatePaymentIntentRequest,
|
||||
SubmitPaymentTxRequest,
|
||||
ValidatePaymentTxRequest,
|
||||
WalletChallengeRequest,
|
||||
WalletUnbindRequest,
|
||||
WalletVerifyRequest,
|
||||
@@ -21,6 +22,7 @@ from web.services.payment_api import (
|
||||
reconcile_latest_payment,
|
||||
submit_payment_tx as submit_payment_tx_service,
|
||||
unbind_payment_wallet,
|
||||
validate_payment_tx,
|
||||
verify_payment_wallet,
|
||||
)
|
||||
|
||||
@@ -67,6 +69,15 @@ async def payment_get_intent(request: Request, intent_id: str):
|
||||
return get_payment_intent(request, intent_id)
|
||||
|
||||
|
||||
@router.post("/api/payments/intents/{intent_id}/validate")
|
||||
async def payment_validate_tx(
|
||||
request: Request,
|
||||
intent_id: str,
|
||||
body: ValidatePaymentTxRequest,
|
||||
):
|
||||
return validate_payment_tx(request, intent_id, body)
|
||||
|
||||
|
||||
@router.post("/api/payments/intents/{intent_id}/submit")
|
||||
async def payment_submit_tx(
|
||||
request: Request,
|
||||
|
||||
@@ -11,6 +11,7 @@ from web.core import (
|
||||
ConfirmPaymentTxRequest,
|
||||
CreatePaymentIntentRequest,
|
||||
SubmitPaymentTxRequest,
|
||||
ValidatePaymentTxRequest,
|
||||
WalletChallengeRequest,
|
||||
WalletUnbindRequest,
|
||||
WalletVerifyRequest,
|
||||
@@ -155,6 +156,22 @@ def submit_payment_tx(
|
||||
_raise_payment_error(exc)
|
||||
|
||||
|
||||
def validate_payment_tx(
|
||||
request: Request,
|
||||
intent_id: str,
|
||||
body: ValidatePaymentTxRequest,
|
||||
) -> Dict[str, Any]:
|
||||
identity = _require_payment_identity(request)
|
||||
try:
|
||||
return legacy_routes.PAYMENT_CHECKOUT.validate_intent_tx(
|
||||
user_id=identity["user_id"],
|
||||
intent_id=intent_id,
|
||||
tx_hash=body.tx_hash,
|
||||
)
|
||||
except legacy_routes.PaymentCheckoutError as exc:
|
||||
_raise_payment_error(exc)
|
||||
|
||||
|
||||
def confirm_payment_tx(
|
||||
request: Request,
|
||||
intent_id: str,
|
||||
|
||||
Reference in New Issue
Block a user