表单提交时如何保证输入整数类型不变?支付网关集成报错排查
你遇到的问题本质是HTML表单默认会以application/x-www-form-urlencoded格式提交键值对数据,但Dusupay的API期望接收的是application/json格式的请求体——这就是两次尝试失败的核心原因,我来帮你拆解并解决:
为什么两次提交都失败?
第一次表单提交的错误原因
你使用了type="number"的input,但HTML表单提交时,所有字段都会被自动转换成字符串类型发送给API。即使你输入的是数字,API接收到的amount是字符串值,不符合它要求的float/integer类型,因此触发"Parameter 'amount' should be a float/integer"错误。另外,你还漏掉了account_number字段,这也是后续需要补充的。
第二次提交的错误原因
你把完整的JSON放在了一个没有name属性的input里,表单提交时只会发送带有name属性的字段。这个无name的input不会被包含在请求中,导致API完全没收到任何参数,自然报错"Parameter 'api_key' missing"。
正确的解决方案:用JavaScript提交JSON格式请求
HTML表单无法直接发送JSON请求,需要通过JavaScript拦截表单提交事件,手动处理数据格式后发送。下面是完整的可运行代码:
第一步:完善HTML表单
给表单添加id方便JS获取,补充缺失的account_number字段:
<form id="paymentForm"> <input type="hidden" name="api_key" value="pkabcd12345" required> <input type="number" name="amount" value="150" step="0.01" required> <input type="hidden" name="currency" value="USD" required> <input type="hidden" name="method" value="MOBILE_MONEY" required> <input type="hidden" name="provider_id" value="airtel_ug" required> <input type="text" name="account_number" value="256777111000" required> <input type="hidden" name="merchant_reference" value="12346" required> <input type="hidden" name="narration" value="diamond1"> <input type="hidden" name="redirect_url" value=""> <button type="submit">Submit Payment</button> </form>
第二步:用JavaScript处理JSON提交
拦截表单提交,将数据转换为JSON格式,设置正确的请求头后发送:
document.getElementById('paymentForm').addEventListener('submit', async function(e) { e.preventDefault(); // 阻止表单默认的键值对提交行为 // 收集表单数据并转换为JSON const formData = new FormData(this); const payload = {}; for (const [key, value] of formData.entries()) { // 针对amount字段做类型转换,确保是数字类型 if (key === 'amount') { payload[key] = parseFloat(value); // 如果需要强制整数,可替换为parseInt(value, 10),同时添加整数验证 } else { payload[key] = value; } } try { const response = await fetch('https://api.dusupay.com/v1/collections', { method: 'POST', headers: { 'Content-Type': 'application/json', // 关键:告诉API接收JSON格式 }, body: JSON.stringify(payload), }); const result = await response.json(); console.log('Payment Response:', result); // 根据API返回结果处理后续逻辑(比如跳转) if (result.success && payload.redirect_url) { window.location.href = payload.redirect_url; } } catch (error) { console.error('Payment Error:', error); alert('Payment failed, please try again.'); } });
如何确保输入的整数保持整数类型?
如果你的业务需要amount字段有时是整数,可在JS转换时添加验证和处理:
if (key === 'amount') { const numValue = parseFloat(value); // 验证是否为整数,是则转成int类型,否则保留float payload[key] = Number.isInteger(numValue) ? parseInt(value, 10) : numValue; }
另外,前端可以通过给number input添加step="1"来限制用户只能输入整数,但这只是辅助验证,最终还是要靠JS的类型转换来保证API收到正确的数字类型。
内容的提问来源于stack exchange,提问作者Chimdi

