Skip to content

二维码支付接口

接口说明

二维码支付接口用于生成支付二维码,支持微信支付和支付宝。商户通过接口传入订单信息,平台返回 qrpay_url,用户扫描二维码完成支付。

接口信息

  • 接口地址: POST /v1/pay/qrpay
  • Content-Type: application/json
  • 字符编码: UTF-8
  • 签名方式: RSA-SHA256

认证信息

请在 HTTP Header 中携带 Authorization 字段,格式详见 接口概览

业务参数

参数名类型必填说明
merchant_noString商户号
out_trade_noString商户订单号,服务商自定义,商户系统内部唯一,建议 32 位以内
total_amountInteger订单总金额,单位:分
subjectString商品名称,显示在支付页面,128 字符以内
pay_methodString支付方式:wechat(微信)或 alipay(支付宝)
notify_urlString异步通知地址,必须为公网可访问的 HTTPS 地址
time_expireInteger订单过期时间(秒),从创建时开始计算,如 300 表示5分钟

请求示例

http
POST /v1/pay/qrpay
Content-Type: application/json
Authorization: RSA service_id=SVC1234567890,timestamp=1704067200,nonce_str=abc123,sign=签名值

{
  "merchant_no": "1234567890",
  "out_trade_no": "ORDER20240101120000",
  "total_amount": 100,
  "subject": "测试商品",
  "pay_method": "wechat",
  "notify_url": "https://your-domain.meepay.org/api/notify",
  "time_expire": 300
}

响应参数

成功响应

参数名类型说明
codeString响应码,00000 表示成功
msgString响应消息
dataObject业务数据
data.pay_trade_noString商户单号,对应用户支付凭证里的商户单号
data.out_trade_noString商户订单号,服务商自定义
data.transaction_idString交易单号(支付成功后返回)
data.pay_methodString支付方式: wechat 或 alipay
data.qrpay_urlString支付链接,商户用此生成二维码供用户扫码

响应示例

微信支付响应

json
{
  "code": "00000",
  "msg": "success",
  "data": {
    "out_trade_no": "ORDER20240101120000",
    "pay_trade_no": "QR20240101120000001",
    "pay_method": "wechat",
    "qrpay_url": "https://pay.meepay.org/q/QR20240101120000001"
  }
}

支付宝响应

json
{
  "code": "00000",
  "msg": "success",
  "data": {
    "out_trade_no": "ORDER20240101120000",
    "pay_trade_no": "ALI20240101120000001",
    "pay_method": "alipay",
    "qrpay_url": "https://pay.meepay.org/q/ALI20240101120000001"
  }
}

前端调用示例

生成二维码

javascript
// 1. 后端请求二维码支付接口
const response = await fetch('https://your-backend.meepay.org/api/pay/qrpay', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    out_trade_no: 'ORDER20240101120000',
    total_amount: 100,
    subject: '测试商品',
    pay_method: 'wechat',  // 或 'alipay'
    notify_url: 'https://your-domain.meepay.org/api/notify'
  })
});

const result = await response.json();

// 2. 使用 qrpay_url 生成二维码
if (result.code === '00000') {
  const qrpayUrl = result.data.qrpay_url;
  
  // 使用二维码库生成二维码
  // 例如使用 qrcode.js
  QRCode.toCanvas(document.getElementById('qrcode'), qrpayUrl, function (error) {
    if (error) console.error(error);
    console.log('二维码已生成!');
  });
  
  // 开始轮询支付状态
  startPolling(result.data.pay_trade_no);
}

// 轮询支付状态
function startPolling(payTradeNo) {
  const timer = setInterval(async () => {
    const response = await fetch('https://your-backend.meepay.org/api/pay/tradeQuery', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        pay_trade_no: payTradeNo
      })
    });
    
    const result = await response.json();
    
    if (result.code === '00000' && result.data.trade_state === 'SUCCESS') {
      clearInterval(timer);
      alert('支付成功!');
      window.location.href = 'https://your-domain.meepay.org/pay/success';
    }
  }, 2000); // 每2秒查询一次
}

异步通知

通知地址

商户需在请求参数中提供 notify_url,支付完成后平台将向该地址发送异步通知。

通知参数

json
{
  "service_id": "SVC1234567890",
  "merchant_no": "1234567890",
  "out_trade_no": "ORDER20240101120000",
  "trade_no": "MF20240101120000001",
  "total_amount": 100,
  "pay_amount": 100,
  "trade_state": "SUCCESS",
  "pay_method": "wechat",
  "pay_time": "20240101120000",
  "notify_time": "20240101120001"
}

处理流程

  1. 验证签名: 从 HTTP Header 中获取 Authorization,使用平台公钥验证通知签名
  2. 验证数据: 检查 out_trade_nototal_amount 等关键信息
  3. 处理业务: 更新订单状态、发货等
  4. 返回响应: 返回 success 字符串(不含引号)

通知重试机制

  • 通知频率:0s、15s、15s、30s、3min、10min、20min、30min、30min
  • 最多重试 10 次
  • 只有在接收到 success 响应后才停止重试

通知处理示例(Node.js)

javascript
const express = require('express');
const router = express.Router();

router.post('https://api.meepay.org/notify', async (req, res) => {
  try {
    const notifyData = req.body;
    const authorization = req.headers.authorization;
    
    // 1. 验证签名(从 Authorization Header 中)
    const isValid = verifySign(authorization, platformPublicKey);
    if (!isValid) {
      console.error('签名验证失败');
      res.send('failure');
      return;
    }
    
    // 2. 验证订单金额
    const order = await getOrder(notifyData.out_trade_no);
    if (order.total_amount !== notifyData.total_amount) {
      console.error('订单金额不匹配');
      res.send('failure');
      return;
    }
    
    // 3. 更新订单状态
    if (notifyData.trade_state === 'SUCCESS' || notifyData.trade_state === 'TRADE_FINISHED') {
      await updateOrderStatus(notifyData.out_trade_no, 'PAID');
      // 执行业务逻辑:发货、发送通知等
    }
    
    // 4. 返回成功
    res.send('success');
  } catch (error) {
    console.error('处理通知失败:', error);
    res.send('failure');
  }
});

module.exports = router;

支付流程

错误码

错误码说明处理建议
00000成功-
10001参数错误检查请求参数是否完整、格式是否正确
10002签名验证失败检查签名算法、密钥是否正确
10003服务商号不存在确认 service_id 是否正确
10004商户未开通该支付方式联系平台开通相应方式
10005订单号重复更换唯一的订单号
10006订单金额错误确认金额为正整数,单位:分
10007时间戳过期检查服务器时间是否同步
10008支付方式错误检查 pay_method 参数是否正确
10010系统繁忙稍后重试或联系客服

注意事项

  1. 订单号唯一性: out_trade_no 在商户系统内必须唯一,重复订单号将返回错误
  2. 金额单位: 金额单位统一为,避免浮点数精度问题
  3. 时间戳: 请求时间戳与服务器时间相差超过 5 分钟将被拒绝
  4. 签名安全: 私钥必须严格保密,不可在前端暴露
  5. 异步通知: 必须正确处理异步通知,不能仅依赖前端轮询
  6. 幂等性: 同一订单号多次请求将返回相同结果,确保接口幂等
  7. HTTPS: 所有接口必须使用 HTTPS 协议
  8. 通知地址: notify_url 必须为公网可访问的 HTTPS 地址
  9. 二维码生成: 商户需在前端使用二维码库将 qrpay_url 转换为二维码图片
  10. 状态轮询: 建议每2-3秒轮询一次支付状态,支付成功后停止轮询

常见问题

Q: 二维码支付和扫码支付有什么区别?

二维码支付是用户扫描商户生成的二维码完成支付,无需用户提供 sub_openid 或 sub_appid,适用于线下门店、PC网站等场景。

Q: 签名验证失败怎么办?

  1. 检查商户 API 密钥是否正确
  2. 确认签名算法是否为 RSA-SHA256
  3. 检查参数排序和拼接是否正确
  4. 确认时间戳是否与服务器时间同步

Q: 异步通知收不到怎么办?

  1. 确认 notify_url 是否为公网可访问地址
  2. 检查服务器防火墙是否拦截了请求
  3. 查看服务器日志,确认是否正常接收通知
  4. 可在商户平台查看通知发送记录

Q: 如何测试支付功能?

  1. 使用测试环境进行开发调试
  2. 微信支付可使用沙箱环境
  3. 支付宝可使用沙箱账号测试
  4. 测试完成后切换到生产环境

Q: 二维码生成失败怎么办?

  1. 确认 qrpay_url 是否正确返回
  2. 检查二维码库是否正确引入
  3. 确认 DOM 元素是否存在
  4. 查看浏览器控制台错误信息

Q: 轮询支付状态的最佳实践?

  1. 建议轮询间隔 2-3 秒
  2. 设置最大轮询次数(如 150 次,对应 5 分钟)
  3. 支付成功后立即停止轮询
  4. 订单超时后停止轮询并提示用户

米付科技版权所有,保留所有权利