创建可调用Google Pay等UPI支付应用的HTML页面及获取交易状态方法
实现UPI支付唤起与交易状态查询的HTML方案
一、HTML页面实现UPI支付唤起
UPI支付应用支持通过标准URL协议唤起,你可以直接在HTML中创建按钮,点击后跳转至对应UPI URL。以下是包含Google Pay、Paytm、PhonePe按钮的示例代码:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>UPI支付页面</title> <style> .pay-btn { padding: 12px 24px; margin: 10px; font-size: 16px; border: none; border-radius: 4px; cursor: pointer; color: #fff; } .gpay-btn { background-color: #4285F4; } .paytm-btn { background-color: #00BFA5; } .phonepe-btn { background-color: #5F6368; } </style> </head> <body> <h3>选择支付方式</h3> <button class="pay-btn gpay-btn" onclick="initUPIPayment('gpay')">Google Pay</button> <button class="pay-btn paytm-btn" onclick="initUPIPayment('paytm')">Paytm</button> <button class="pay-btn phonepe-btn" onclick="initUPIPayment('phonepe')">PhonePe</button> <script> // 替换为你的收款方信息和后端生成的唯一交易ID const UPI_CONFIG = { pa: 'merchant@upi', // 收款方UPI ID pn: '商家名称', am: '100.00', // 交易金额 tn: '订单编号:ORD123456', tr: 'UNIQUE_TRANSACTION_ID', // 后端生成的唯一交易ID,用于后续查询 cu: 'INR' }; function initUPIPayment(appType) { // 拼接标准UPI唤起URL let upiUrl = `upi://pay?pa=${UPI_CONFIG.pa}&pn=${encodeURIComponent(UPI_CONFIG.pn)}&am=${UPI_CONFIG.am}&tn=${encodeURIComponent(UPI_CONFIG.tn)}&tr=${UPI_CONFIG.tr}&cu=${UPI_CONFIG.cu}`; // 部分应用可添加额外参数优化唤起体验 if (appType === 'gpay') { upiUrl += '&mc=1234'; // 商家代码,可选 } else if (appType === 'phonepe') { upiUrl += '&mode=02'; // PhonePe特定参数,可选 } // 唤起支付应用 window.location.href = upiUrl; // 或者使用window.open(upiUrl, '_blank'),但部分设备可能拦截弹窗 } </script> </body> </html>
关键说明
tr参数必须是后端生成的唯一交易ID,这是后续查询状态的核心标识。- 所有含中文的参数(如
pn、tn)必须用encodeURIComponent编码,避免URL解析错误。 - 不同UPI应用支持的额外参数略有差异,可根据官方文档调整,但标准参数已能兼容绝大多数应用。
二、交易状态查询实现
前端直接唤起UPI应用后,无法直接获取支付结果(UPI应用不会主动回调前端页面),必须依赖后端服务对接UPI网关/支付服务商API来实现状态查询。具体流程如下:
1. 后端核心逻辑
- 发起支付前,后端生成唯一交易ID,关联订单信息并存储到数据库。
- 支付完成后,后端通过以下两种方式获取状态:
- 主动轮询UPI网关:调用NPCI官方UPI查询API(需商家资质),或Paytm/PhonePe等第三方服务商提供的交易查询接口,传入交易ID获取状态。
- 接收异步回调:部分支付服务商支持配置回调URL,当交易状态变更时,主动推送结果到后端接口,后端更新订单状态。
2. 前端状态查询实现
前端可通过轮询后端接口或WebSocket实时推送获取状态,以下是轮询的示例代码:
// 支付唤起后,启动轮询查询状态 function checkPaymentStatus() { const transactionId = UPI_CONFIG.tr; const interval = setInterval(async () => { try { const response = await fetch(`/api/check-payment-status?tr=${transactionId}`); const data = await response.json(); if (data.status === 'SUCCESS') { clearInterval(interval); alert('支付成功!'); // 跳转到订单成功页面 window.location.href = '/success'; } else if (data.status === 'FAILED') { clearInterval(interval); alert('支付失败,请重试!'); } // 状态为PENDING时继续轮询 } catch (error) { console.error('查询状态失败:', error); } }, 3000); // 每3秒查询一次 } // 在唤起支付后调用 initUPIPayment('gpay'); checkPaymentStatus();
注意事项
- 前端轮询需设置合理的间隔(3-5秒),避免频繁请求导致后端压力过大。
- 必须由后端验证交易状态,前端仅做展示,不能直接信任前端传来的状态(防止篡改)。
- 若使用第三方支付服务商,需先完成商家资质认证,获取API调用权限。
内容的提问来源于stack exchange,提问作者Athang Meher
相关产品推荐
相关产品推荐

