PAYATHON 2026

支付宝是否支持移动端二维码扫码支付?

支付小周

结论

支持。通常应接入支付宝开放平台的“当面付”扫码支付,而不是直接调用 App 支付。

即使平板没有安装支付宝,也可以向业务服务端申请创建支付订单。服务端调用 alipay.trade.precreate 获取二维码内容,平板将其渲染成二维码,再由用户使用手机支付宝扫码付款。

这种方式能否用于实际业务,还要看商户是否签约了相应产品,以及具体场景能否通过支付宝的产品准入和风控审核。接口可用不等于所有应用都能直接上线。

推荐实现流程

  1. 用户在平板应用中确认购买。
  2. 应用根据支付方式或运行环境,选择“支付宝扫码支付”。
  3. 平板向自己的业务服务端提交下单请求。
  4. 服务端创建内部订单,并调用支付宝 alipay.trade.precreate。
  5. 支付宝返回 qr_code。
  6. 平板将 qr_code 渲染成二维码。
  7. 用户使用手机支付宝扫码并完成付款。
  8. 服务端接收支付宝异步通知,或调用 alipay.trade.query 查询订单状态。
  9. 服务端确认交易成功后,将支付结果返回平板,并交付商品或服务。

支付宝接口调用、私钥签名和支付结果验证都必须在服务端完成。

服务端创建二维码示例

以下示例使用支付宝 Java SDK。具体依赖版本和类名请以接入时的官方 SDK 文档为准:

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;

public class AlipayQrPayService {

    private static final String GATEWAY =
            "https://openapi.alipay.com/gateway.do";

    private static final String APP_ID = "your_app_id";
    private static final String APP_PRIVATE_KEY = "your_app_private_key";
    private static final String ALIPAY_PUBLIC_KEY = "alipay_public_key";
    private static final String NOTIFY_URL =
            "https://example.com/payment/alipay/notify";

    public String createQrCode(
            String outTradeNo,
            String subject,
            String totalAmount
    ) throws Exception {
        AlipayClient client = new DefaultAlipayClient(
                GATEWAY,
                APP_ID,
                APP_PRIVATE_KEY,
                "json",
                "UTF-8",
                ALIPAY_PUBLIC_KEY,
                "RSA2"
        );

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("subject", subject);
        bizContent.put("total_amount", totalAmount);
        bizContent.put("timeout_express", "5m");

        AlipayTradePrecreateRequest request =
                new AlipayTradePrecreateRequest();

        request.setNotifyUrl(NOTIFY_URL);
        request.setBizContent(bizContent.toJSONString());

        AlipayTradePrecreateResponse response = client.execute(request);

        if (!response.isSuccess()) {
            throw new IllegalStateException(
                    "创建支付宝二维码失败:" +
                    response.getSubCode() + " " +
                    response.getSubMsg()
            );
        }

        return response.getQrCode();
    }
}

response.getQrCode() 返回的是二维码内容,不一定是图片地址。平板应用需要通过二维码组件,将这个字符串编码成二维码图片。

业务接口可以向平板返回类似结果:

{
  "out_trade_no": "ORDER_202609130001",
  "qr_code": "https://qr.alipay.com/...",
  "expires_in": 300
}

平板端展示二维码

以前端页面为例,可以通过二维码组件渲染服务端返回的内容:

async function showAlipayQrCode(orderId) {
  const response = await fetch("/api/payment/alipay/precreate", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ orderId })
  });

  if (!response.ok) {
    throw new Error("创建支付订单失败");
  }

  const result = await response.json();

  QRCode.toCanvas(
    document.getElementById("alipay-qrcode"),
    result.qr_code,
    {
      width: 280,
      margin: 2
    }
  );

  pollPaymentStatus(result.out_trade_no);
}

客户端可以在短时间内轮询自己的服务端,但不能让平板直接调用支付宝查询接口:

function pollPaymentStatus(outTradeNo) {
  const timer = setInterval(async () => {
    const response = await fetch(
      `/api/payment/status?outTradeNo=${encodeURIComponent(outTradeNo)}`
    );

    const result = await response.json();

    if (result.status === "TRADE_SUCCESS") {
      clearInterval(timer);
      showPaymentSuccess();
    } else if (
      result.status === "CLOSED" ||
      result.status === "EXPIRED"
    ) {
      clearInterval(timer);
      showPaymentExpired();
    }
  }, 2000);
}

是否需要检测平板已安装支付宝

可以检测,但不宜把“是否安装支付宝”作为唯一的判断条件。

Android 的包可见性限制、不同厂商的系统差异,以及 iPadOS 的 URL Scheme 策略,都可能影响检测结果。更稳妥的做法是直接提供两个清楚的支付入口:

  • “打开支付宝支付”:适用于已经安装支付宝且已接入 App 支付的设备。
  • “使用手机支付宝扫码”:适用于平板未安装支付宝,或用户希望跨设备付款的情况。

如果检测到本机无法拉起支付宝,可以自动切换到二维码页面,同时保留手动切换入口。

支付结果必须由服务端确认

平板显示“扫码成功”,或者页面轮询到某个客户端状态,都不能作为最终交付依据。服务端需要完成以下确认:

  • 验证支付宝异步通知的签名。
  • 校验 app_id、out_trade_no、订单金额和收款方信息。
  • 确认交易状态允许交付,例如 TRADE_SUCCESS。
  • 必要时调用 alipay.trade.query 主动查单。
  • 通过幂等机制处理重复通知,防止重复发货或重复开通权益。

异步通知接口完成验签和业务处理后,应按照支付宝协议返回指定的成功响应。具体响应内容和验签方法,请以接入时的官方文档为准。

注意事项

  1. alipay.trade.precreate 是服务端接口,不能将应用私钥放入平板安装包或前端代码。

  2. 每个二维码都应对应一个内部订单。out_trade_no 必须唯一,订单金额不能由客户端直接决定。

  3. 二维码应设置合理的有效期。二维码过期后,需要关闭旧订单或重新创建支付订单,不能无限期重复展示。

  4. 轮询只用于改善用户体验,需要限制频率和持续时间。最终状态仍以服务端收到的可靠结果为准。

  5. 退款不能通过撤销二维码完成。支付成功后,通常需要调用对应的退款接口,例如 alipay.trade.refund。

  6. 需要防范截屏复用、订单串用和金额篡改。生成二维码前,服务端必须重新读取商品价格和订单状态。

  7. “当面付”主要用于扫码收款。应用内购买数字内容、会员权益或特定行业商品时,还可能受到平台规则、应用商店规则及支付宝产品准入要求的限制。正式接入前,应在支付宝开放平台确认商户签约状态,并请支付宝技术支持或业务人员确认“平板展示、手机扫码”的具体场景是否符合当前产品政策。

备注:内容仅供参考。