PAYATHON 2026

安卓 App 接入支付宝二维码付款需要申请什么权限?

支付老李

明确结论

这种场景通常需要开通支付宝的 当面付 产品,并调用 扫码支付(预下单) 接口 alipay.trade.precreate 生成二维码。

已经开通的 App 支付、手机网站支付(H5) 和 电脑网站支付(PC) 是不同的支付产品,无法直接提供当面付的付款二维码能力。

不同的 VIP 套餐不用分别申请权限。每次购买时,服务端创建一笔独立订单,设置对应的金额、标题和业务参数,即可生成相应的付款二维码。

为什么需要当面付

这几种支付方式适用于不同场景:

  • App 支付:唤起用户手机中的支付宝 App 完成付款。
  • 手机网站支付:在手机浏览器或 WebView 中进入支付宝收银台。
  • 电脑网站支付:主要用于 PC 网页收银台。
  • 当面付-扫码支付:商户服务端创建订单,支付宝返回二维码内容,再由商户展示给用户扫码付款。

如果需要由服务端生成订单,再由客户端展示付款二维码,应使用当面付的预下单接口,不能从 App 支付接口中获取二维码。

能否开通当面付,取决于商户主体、签约地区、经营类目以及支付宝当前的产品准入规则。产品名称和入口可能随开放平台调整,请以商户后台实际可签约的产品为准。

接入步骤

1. 开通当面付

登录支付宝开放平台或商家平台,在对应的应用和商户主体下检查是否可以签约 当面付。

签约后还要确认以下配置:

  • 应用已绑定正确的商户账号。
  • 应用具有 alipay.trade.precreate 接口权限。
  • 应用公钥或支付宝公钥配置正确。
  • 应用的签名方式、网关环境和应用 ID 配置一致。

创建开放平台应用不代表已经签约相应的支付产品。

2. 由服务端创建订单

Android 客户端不能保存应用私钥,也不应直接调用预下单接口。完整流程如下:

  1. Android App 将 VIP 套餐编号提交给业务服务端。
  2. 服务端根据套餐编号查询真实价格。
  3. 服务端生成唯一的商户订单号。
  4. 服务端调用 alipay.trade.precreate。
  5. 支付宝返回 qr_code。
  6. 服务端将二维码内容返回给 Android App。
  7. Android App 将该内容编码成二维码并展示。
  8. 服务端通过异步通知或主动查询确认付款结果。

套餐价格必须由服务端确定,不能直接采用客户端上传的金额。

Java 服务端示例

下面是使用支付宝 Java SDK 创建预下单的简化示例。不同版本的 SDK 可能采用不同的构造方式,请以当前支付宝开放平台文档为准。

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;

public class AlipayQrService {

    private final AlipayClient alipayClient;

    public AlipayQrService(
            String appId,
            String merchantPrivateKey,
            String alipayPublicKey) {

        this.alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do",
                appId,
                merchantPrivateKey,
                "json",
                "UTF-8",
                alipayPublicKey,
                "RSA2"
        );
    }

    public String createQrCode(
            String outTradeNo,
            String totalAmount,
            String subject,
            String notifyUrl) throws AlipayApiException {

        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setOutTradeNo(outTradeNo);
        model.setTotalAmount(totalAmount);
        model.setSubject(subject);
        model.setTimeoutExpress("15m");

        AlipayTradePrecreateRequest request =
                new AlipayTradePrecreateRequest();

        request.setBizModel(model);
        request.setNotifyUrl(notifyUrl);

        AlipayTradePrecreateResponse response =
                alipayClient.execute(request);

        if (!response.isSuccess()) {
            throw new IllegalStateException(
                    "支付宝预下单失败: code=" + response.getCode()
                            + ", msg=" + response.getMsg()
                            + ", subCode=" + response.getSubCode()
                            + ", subMsg=" + response.getSubMsg()
            );
        }

        return response.getQrCode();
    }
}

response.getQrCode() 返回的是二维码内容,不一定是图片地址。Android 客户端需要使用二维码库将这个字符串生成二维码图片。

不同的 VIP 套餐只需传入不同的订单信息,例如:

String qrCode = alipayQrService.createQrCode(
        "VIP_ORDER_202609090001",
        "99.00",
        "年度 VIP",
        "https://example.com/payment/alipay/notify"
);

Android 展示二维码示例

以下代码以 ZXing 为例:

import android.graphics.Bitmap;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;

public Bitmap createQrBitmap(String content, int size) throws Exception {
    BitMatrix matrix = new MultiFormatWriter().encode(
            content,
            BarcodeFormat.QR_CODE,
            size,
            size
    );

    Bitmap bitmap = Bitmap.createBitmap(
            size,
            size,
            Bitmap.Config.ARGB_8888
    );

    for (int x = 0; x < size; x++) {
        for (int y = 0; y < size; y++) {
            bitmap.setPixel(
                    x,
                    y,
                    matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF
            );
        }
    }

    return bitmap;
}

客户端从业务服务端取得 qrCode 后,将其显示到 ImageView:

Bitmap bitmap = createQrBitmap(qrCode, 800);
imageView.setImageBitmap(bitmap);

支付结果不能以客户端页面为准

二维码展示后,不能因为用户关闭页面、跳转回来或点击”我已付款”,就在客户端直接发放 VIP。

服务端需要完成以下处理:

  • 接收支付宝异步通知。
  • 验证通知签名。
  • 校验 app_id、out_trade_no、金额和收款商户信息。
  • 确认交易状态符合业务要求。
  • 必要时调用 alipay.trade.query 主动查询。
  • 使用幂等逻辑发放 VIP,避免重复通知引起重复处理。

向支付宝的异步通知返回成功前,必须完成验签和订单校验。

同一部手机展示二维码的限制

如果二维码显示在用户当前使用的手机上,而这部手机没有安装支付宝,用户就无法直接在同一部手机上使用支付宝扫码。通常只有以下几种处理方式:

  • 使用另一台安装了支付宝的设备扫码。
  • 截图后在支付宝中识别图片,但仍然需要安装支付宝。
  • 改用手机网站支付或其他能在浏览器中完成的支付方式。

因此,“未安装支付宝时显示二维码”不代表用户能在同一设备上完成支付宝付款。二维码更适合显示在 PC 页面、收银台屏幕或另一台设备上。

如果业务要求用户仅用一部没有安装支付宝的手机完成付款,应优先评估手机网站支付,而不是当面付二维码。

注意事项

  • 不要为不同的 VIP 套餐制作长期固定且写死金额的收款码。
  • 每次付款都要创建新的商户订单号和二维码。
  • 订单金额使用字符串传递,例如 "99.00",并由服务端校验。
  • 为二维码设置合理的订单有效期,过期后重新创建订单。
  • 应用私钥只能保存在服务端,不能打包进 APK。
  • 正式环境与沙箱环境的网关、应用 ID 和密钥不能混用。
  • 开通当面付后仍无法调用接口时,检查签约状态、应用授权关系以及接口返回的 sub_code 和 sub_msg。这些字段通常会说明具体原因。

备注:内容仅供参考。