集成Razorpay支付网关时,向API发转账请求遇400错误
解决Razorpay转账API的400 Bad Request问题
我来帮你排查这个问题,你遇到的400错误主要是因为请求格式和API要求不匹配,还有几个关键细节没处理对,咱们一步步来解决:
问题根源分析
Razorpay的这个转账API不接受JSON格式的请求体,它要求的是x-www-form-urlencoded格式的表单数据(对应你贴的curl里的-d参数)。而你用angular.toJson()把数据转成了JSON字符串发送,API无法解析这种格式,所以返回400错误。另外你的请求还缺少两个关键部分:符合API要求的transfers数组结构,以及必要的身份认证。
正确的实现步骤
1. 构造符合API要求的数据结构
首先需要按照官方文档的要求,把数据组织成包含transfers数组的对象,每个数组元素对应一笔转账的信息:
// 示例数据,替换成你的实际值 let payData = { transfers: [ { account: 'acc_BYYYYJRfs1234S', // 关联账户ID amount: parseInt($scope.amountPayingNow * 100), // 注意:Razorpay用最小货币单位,比如1000代表10 INR currency: 'INR', notes: { roll_no: 'IEC2011025', name: 'Gaurav Kumar' }, linked_account_notes: ['roll_no'] // 可选,按需添加 } // 如果有多笔转账,继续添加数组元素 ] };
2. 配置Angular $http请求
需要做三个关键配置:
- 设置请求头为
application/x-www-form-urlencoded - 使用
$httpParamSerializerJQLike序列化数据(它能把嵌套对象/数组转成API要求的transfers[0][account]这种格式) - 添加Basic Auth身份认证(对应curl里的
-u参数)
完整的请求代码:
// 确保注入$httpParamSerializerJQLike到你的控制器/服务中 $http({ method: "POST", url: 'https://api.razorpay.com/v1/payments/' + transaction.razorpay_payment_id + '/transfers', data: payData, headers: { 'Content-Type': 'application/x-www-form-urlencoded', // 替换成你的API密钥和密钥,用btoa做Base64编码 'Authorization': 'Basic ' + btoa('YOUR_API_KEY' + ':' + 'YOUR_SECRET_KEY') }, // 用JQLike序列化器处理嵌套结构 transformRequest: $httpParamSerializerJQLike }) .then(function(response) { console.log('转账成功:', response.data); }) .catch(function(error) { console.error('请求失败:', error.data); });
关键注意事项
- 货币单位:Razorpay的金额参数需要用最小货币单位(比如1 INR对应100),你的代码里已经做了
parseInt($scope.amountPayingNow*100),这个是对的。 - 身份认证:不要把API密钥暴露在前端代码里!如果这是前端应用,建议通过你的后端服务器中转请求,避免密钥泄露。
- 数据结构:必须包含
transfers数组,不能直接把account、amount等字段放在顶层,否则API无法识别。
内容的提问来源于stack exchange,提问作者Le guy
相关产品推荐
相关产品推荐

