以下是印度支付平台常见错误代码及解决方案的整理,供参考:
1. 通用错误码
错误码 | 原因 | 解决方案 |
---|---|---|
INVALID_REQUEST | 请求参数缺失/格式错误 | 检查API文档,确保所有必填字段(如txn_id 、amount )正确。 |
AUTH_FAILED | API密钥或认证失败 | 重新生成密钥;检查IP白名单;确认商户ID是否正确。 |
TXN_AMOUNT_MISMATCH | 订单金额与实际支付金额不符 | 核对用户支付的金额与订单金额是否一致。 |
2. UPI特有错误
失败类
-
UPI_TIMEOUT (Code: U30)
原因:银行服务器响应超时(常见于高峰期)。
解决:提示用户重试或换其他UPI ID。 -
BENEFICIARY_LIMIT_EXCEEDED (Code: U53)
原因:收款方当日交易限额已满。
解决:建议用户次日再付或更换收款账户。
需用户操作的错误
- (Code: U15) / "Pending"状态
原因:付款已发起但未完成(如等待输入MPIN)。
解决:提醒用户在银行APP内完成授权,超时后自动失效。
3. NetBanking/卡支付问题
-
(Code: NB10) – Invalid IFSC/Account
原因:输入的银行信息有误。
解决:验证IFSC和账号,尤其注意大小写敏感问题。 -
(Code: C05) – Card Declined by Bank
原因:发卡行拒绝交易(余额不足、风控拦截等)。
解决:联系银行确认卡片状态;建议使用其他卡/方式。
4. RBI合规相关报错
-
(Error: RBI_OTP_EXPIRED)
触发条件:OTP超过有效时间(通常5分钟)。
解决:重新发起交易生成新OTP。 -
(Error: DAILY_LIMIT_REACHED)
原因:(如BBPS账单支付超过₹1万限额)
解决分拆付款或改用其他渠道.
⚠️注意事项:
- Idempotency Key处理重复请求时可能返回
(409 CONFLICT)
。 - Webhook延迟导致订单状态不同步?通过
order_status_api
二次校验。 - PCI DSS合规要求——切勿在客户端日志记录完整卡号!
需要具体平台的代码示例?(例如Razorpay/Paytm回调验签逻辑)可进一步补充说明。
以下是针对印度支付平台的进一步补充内容,涵盖 具体平台示例、调试技巧及高级场景解决方案:
5. 平台特定错误处理(Razorpay/Paytm/PhonePe)
Razorpay 常见问题
错误码 | 场景 | 解决方案 |
---|---|---|
BAD_REQUEST_ERROR |
Webhook签名验证失败 | 使用X-Razorpay-Signature 和服务器密钥验签,官方代码示例 |
PAYMENT_LINK_EXPIRED |
动态链接超时(默认30分钟) | 通过API重新生成链接并通知用户。 |
Paytm UPI Intent调用失败
- (Code: P160) – App Not Installed
原因:用户手机未安装指定UPI APP(如Paytm App)。
解决:降级为通用UPI Intent或提示用户安装。
6. Webhook &异步通知陷阱
- 问题:订单状态在数据库显示"pending",但银行已扣款。
- 根因:Webhook未触发/商户服务器响应慢导致超时。
- 排查步骤:
- Check Payload日志(如
order_id
,payment_id
)。 - 手动调用Status API补偿查询。
- Check Payload日志(如
# Razorpay Webhook验签伪代码
def verify_webhook_signature(payload, signature):
generated_signature = hmac.new(api_key.encode(), payload, 'sha256').hexdigest()
return hmac.compare_digest(generated_signature, signature)
7. PCI DSS敏感数据处理规范
当集成卡支付时需注意:
- ⛔️禁止前端直接传输完整卡号到服务器——必须使用Razorpay.js等加密表单。
- Token化替代方案:存储银行返回的
token_id
而非卡号,用于后续定期付款。
8. Debugging Pro Tips 🛠️
1️⃣ 模拟测试工具:
- PhonePe沙箱环境:开发者面板支持模拟"Payment Failed"场景。
2️⃣ Log全链路追踪:
关键字段记录:
{
"gateway": "UPI",
"error_code": "U53",
"bank_response": "{原始响应}",
"timestamp": "ISO格式时间戳"
}
3️⃣ 限流保护:
高频触发风控?添加指数退避重试逻辑:
import time
def retry_payment(max_retries=3):
for attempt in range(max_retries):
try:
process_payment()
break
except RateLimitError:
time.sleep(2 attempt) # Exponential backoff
🔥 高阶问题:如何处理「部分退款」冲突?
当原交易已部分退款,再次请求可能报错(REFUND_AMOUNT_EXCEEDED
)——需通过以下API检查累计退款金额:
GET /v1/payments/{payment_id}/refunds
返回参数中的 total_refunded_amount
决定可退余额。
需要更详细的某类错误流程说明?请指定方向(如BBPS账单错误码解析、国际卡3DS失败等)。
发表回复