PAYATHON 2026

PC 网站如何使用 Factory.Payment.FaceToFace().preCreate() 生成支付二维码?

支付阿杰

结论

Factory.Payment.FaceToFace().preCreate() 对应支付宝当面付中的“扫码支付”,底层调用 alipay.trade.precreate。接口返回二维码内容 qr_code,商户网站将其生成二维码图片后,用户便可使用支付宝扫码付款。

当面付的产品介绍虽然主要针对实体门店,但接口没有要求二维码必须展示在实体收银台,因此 PC 网站也能使用。商户账号需要先签约并开通当面付,网站的业务场景也要符合支付宝的产品和风控要求。

使用支付宝 Easy SDK 时,可以通过 Factory.Payment.FaceToFace().preCreate() 简化调用。也可以使用支付宝开放平台的通用 Java SDK,直接调用 alipay.trade.precreate。

实现流程

常见的实现流程如下:

  1. PC 网站前端请求服务端创建支付订单。
  2. 服务端生成唯一的商户订单号 out_trade_no。
  3. 服务端调用 Factory.Payment.FaceToFace().preCreate()。
  4. 从接口响应中读取 qr_code。
  5. 前端通过二维码组件将 qr_code 渲染成二维码图片。
  6. 用户使用支付宝扫码付款。
  7. 服务端根据异步通知或主动查询结果确认支付状态。
  8. 前端轮询商户系统中的订单状态,支付成功后更新页面。

支付接口必须由服务端调用。商户私钥不能放在浏览器中,前端也不应直接请求支付宝接口。

Easy SDK 示例

下面是 Java Easy SDK 的常见调用方式。不同 SDK 版本的配置字段和响应对象访问方式可能略有差异,请以项目实际依赖中的类定义为准。

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;

public class AlipayQrCodeService {

    public static void init() {
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = "openapi.alipay.com";
        config.signType = "RSA2";

        config.appId = "你的应用AppId";
        config.merchantPrivateKey = "你的应用私钥";
        config.alipayPublicKey = "支付宝公钥";

        // 建议配置可被支付宝公网访问的异步通知地址
        config.notifyUrl = "https://www.example.com/alipay/notify";

        Factory.setOptions(config);
    }

    public static String createQrCode(
            String subject,
            String outTradeNo,
            String totalAmount) throws Exception {

        AlipayTradePrecreateResponse response =
                Factory.Payment.FaceToFace()
                        .preCreate(subject, outTradeNo, totalAmount);

        if ("10000".equals(response.code)) {
            return response.qrCode;
        }

        throw new IllegalStateException(
                "创建支付宝二维码失败,code=" + response.code
                        + ", msg=" + response.msg
                        + ", subCode=" + response.subCode
                        + ", subMsg=" + response.subMsg
        );
    }
}

调用示例:

public static void main(String[] args) throws Exception {
    AlipayQrCodeService.init();

    String qrCode = AlipayQrCodeService.createQrCode(
            "网站订单支付",
            "ORDER_202609090001",
            "99.00"
    );

    System.out.println(qrCode);
}

部分版本可能需要通过 getter 读取字段,例如:

String qrCode = response.getQrCode();

请根据当前 Easy SDK 生成的响应类,选择 response.qrCode 或 response.getQrCode(),不要只参照示例判断。

在网页中显示二维码

接口返回的 qr_code 通常是供支付宝客户端识别的二维码内容,不一定是 PNG 图片。服务端可以将它返回给前端,再由前端二维码库渲染:

<div id="alipay-qrcode"></div>

<script src="https://cdn.example.com/qrcode.min.js"></script>
<script>
  async function createPayment() {
    const response = await fetch("/api/payment/alipay/pre-create", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        orderId: "ORDER_202609090001"
      })
    });

    const result = await response.json();

    new QRCode(document.getElementById("alipay-qrcode"), {
      text: result.qrCode,
      width: 220,
      height: 220
    });
  }

  createPayment();
</script>

示例中的 CDN 地址仅为占位符。实际项目应使用经过审核并固定版本的二维码组件。服务端也可以将 qr_code 生成 PNG,再把图片地址或图片数据返回给前端。

如何判断支付成功

二维码创建成功不等于用户已经付款。处理支付结果时应注意:

  • 主要以支付宝异步通知为准;
  • 对通知内容进行验签;
  • 校验 app_id、out_trade_no、金额和收款方等字段;
  • 以幂等方式更新订单;
  • 必要时调用交易查询接口补偿确认;
  • PC 页面只轮询商户系统中的订单状态,不能直接信任前端提交的“支付成功”结果。

如果长时间没有收到通知,可以通过 Easy SDK 查询交易状态:

import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;

AlipayTradeQueryResponse response =
        Factory.Payment.Common().query("ORDER_202609090001");

if ("TRADE_SUCCESS".equals(response.tradeStatus)) {
    // 再次核对订单号、金额等信息后,以幂等方式更新业务订单
}

具体的字段访问方式也可能随 SDK 版本变化。

是否应该改用电脑网站支付

支付宝电脑网站支付通常调用 alipay.trade.page.pay,标准流程是跳转至支付宝收银台,或向收银台提交表单。如果业务要求用户留在当前 PC 页面,并用手机支付宝扫码付款,alipay.trade.precreate 更符合这种交互方式。

两种方式的主要区别如下:

方式接口用户体验
当面付扫码支付alipay.trade.precreate网站展示二维码,用户用支付宝扫码
电脑网站支付alipay.trade.page.pay浏览器进入支付宝收银台完成支付

具体选择取决于商户已签约的产品、应用权限,以及支付宝对实际业务场景的审核结果。

其他可选 SDK

除了 Easy SDK,也可以使用支付宝开放平台对应语言的通用 SDK,直接构造 alipay.trade.precreate 请求。在 Java 中,通常需要创建 AlipayTradePrecreateRequest,再通过 AlipayClient.execute() 发起调用。

AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setNotifyUrl("https://www.example.com/alipay/notify");
request.setBizContent("""
{
  "out_trade_no": "ORDER_202609090001",
  "total_amount": "99.00",
  "subject": "网站订单支付"
}
""");

AlipayTradePrecreateResponse response = alipayClient.execute(request);

if (response.isSuccess()) {
    String qrCode = response.getQrCode();
}

这里省略了通用 SDK 的配置和异常处理代码。通用 SDK 更接近原始接口,适合需要传入更多业务参数、统一封装支付宝接口或细化响应处理的项目。

注意事项

  • out_trade_no 在商户系统中必须唯一。
  • 金额应由服务端根据订单计算,不能直接使用前端传入的金额。
  • total_amount 应使用十进制金额字符串,例如 "99.00"。
  • 不要自行拼接二维码内容,应完整使用支付宝返回的 qr_code。
  • 商户私钥只能保存在服务端,并通过安全配置或密钥管理系统加载。
  • 异步通知地址必须能从公网访问,并且需要正确处理重复通知。
  • 支付完成后必须验签并核对订单信息,不能只根据页面轮询结果发货。
  • 应为二维码设置合理的业务有效期,超时后关闭订单或重新创建订单。
  • 该接口能否正式使用,取决于商户签约状态、应用配置和支付宝当前的产品准入要求。

备注:内容仅供参考。