pc端的扫码支付

847 阅读2分钟

以下是PC端前端实现扫码支付及支付状态判定的技术实现详解,结合支付宝/微信支付等常见场景:


一、支付二维码的生成方式

1. ‌支付宝(前置模式)

// 1. 请求后端接口获取支付数据
async function getAlipayQRCode(orderId) {
  const res = await axios.post('/api/alipay/create', { orderId });
  // 返回的form数据示例: <form action="https://openapi.alipay.com/..." method="POST">...</form>
  return res.data.formHTML;
}

// 2. 通过iframe渲染支付宝返回的form数据
function renderAlipayQRCode(formHTML) {
  const iframe = document.createElement('iframe');
  iframe.srcdoc = formHTML; // 关键:将form数据嵌入iframe
  iframe.style.width = '300px';
  iframe.style.height = '300px';
  document.getElementById('qrcode-container').appendChild(iframe);
}

2. ‌微信支付(模式二)

// 1. 调用统一下单接口获取code_url
async function getWechatPayCodeUrl(orderId) {
  const res = await axios.post('/api/wechatpay/unifiedorder', { orderId });
  return res.data.code_url; // 示例: weixin://wxpay/bizpayurl?pr=xxxxx
}

// 2. 使用qrcode.js生成二维码
function generateWechatQRCode(codeUrl) {
  const qrcode = new QRCode(document.getElementById('qrcode-container'), {
    text: codeUrl,
    width: 200,
    height: 200
  });
}

二、支付状态轮询逻辑

1. ‌通用轮询方案(以支付宝为例)

let pollInterval;
function startPaymentPolling(orderId) {
  pollInterval = setInterval(async () => {
    const res = await axios.get(`/api/payment/status?orderId=${orderId}`);
    if (res.data.status === 'SUCCESS') {
      clearInterval(pollInterval);
      alert('支付成功');
      // 后续业务逻辑(如订单状态更新)
    } else if (res.data.status === 'CLOSED') {
      clearInterval(pollInterval);
      alert('支付超时');
    }
  }, 3000); // 每3秒轮询一次
}

// 页面卸载时清除轮询
window.addEventListener('beforeunload', () => {
  clearInterval(pollInterval);
});

2. ‌WebSocket实时通知(优化方案)

javascriptCopy Code
const socket = new WebSocket('wss://your-api/payment-ws');

socket.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.event === 'payment_success') {
    console.log('支付成功', data.orderId);
    // 更新UI状态
  }
};

三、关键实现细节

  1. 二维码有效期处理

    • 微信支付的code_url有效期通常为2小时,超时需重新生成6

    • 前端可通过setTimeout自动刷新:

      javascriptCopy Code
      setTimeout(() => {
        if (!paymentCompleted) {
          refreshQRCode(); 
        }
      }, 7200000); // 2小时
      
  2. 安全注意事项

    • 所有支付相关接口必须使用HTTPS
    • 禁止前端直接处理支付金额等敏感数据
  3. 移动端适配

    • 可通过navigator.userAgent识别移动端,自动切换为H5支付方案:

      if (/Mobile|Android/i.test(navigator.userAgent)) {
        redirectToMobilePayment(); 
      }
      

四、完整流程示例(微信支付)

// 1. 生成二维码
const codeUrl = await getWechatPayCodeUrl('ORDER123');
generateWechatQRCode(codeUrl);

// 2. 启动轮询
startPaymentPolling('ORDER123');

// 3. 支付成功后的处理
function onPaymentSuccess() {
  // 更新订单状态、跳转成功页等
  window.location.href = '/payment/success';
}

以上方案可根据实际业务需求调整轮询频率、超时时间等参数。对于高并发场景,推荐使用WebSocket替代轮询以降低服务器压力。