PAYATHON 2026

新建购物网站如何绑定支付宝支付?

支付阿杰

结论

购物网站接入支付宝,并不是填入一个支付宝账号就能完成。整个接入过程包括:

  1. 使用企业或个体工商户主体开通支付宝商家账号。
  2. 创建网页应用,申请相应的支付产品。
  3. 配置应用私钥、支付宝公钥或应用证书。
  4. 由网站服务端调用支付宝支付接口。
  5. 接收并验证支付宝发送的异步通知。
  6. 查询订单结果并更新支付状态。

PC 网站通常使用 alipay.trade.page.pay,手机浏览器中的 H5 商城通常使用 alipay.trade.wap.pay。如果网站同时支持电脑和手机,应根据访问终端分别调用对应的接口。

一、准备接入条件

正式接入前,通常需要准备:

  • 支付宝商家账号;
  • 已完成实名认证的企业或个体工商户主体;
  • 已上线或能够正常访问的购物网站;
  • 网站域名及相关经营资质;
  • 服务端开发环境;
  • 可用于同步跳转和异步通知的 HTTPS 地址;
  • 与实际经营内容一致的商品、服务和页面信息。

商户主体、经营类目以及支付宝平台当时的审核规则,会影响可申请的支付产品。后台菜单名称也可能发生变化,具体以支付宝开放平台的实际页面为准。

二、创建支付宝应用

登录支付宝开放平台,在控制台中创建网页或移动应用。应用审核通过后,平台会分配一个 app_id,也就是网站在支付宝侧的应用编号。

接下来需要为应用申请支付能力:

  • PC 商城申请电脑网站支付;
  • 手机 H5 商城申请手机网站支付;
  • 如果需要退款、订单查询等功能,还要确认应用已取得相应的接口权限。

创建应用和签约支付产品是两个独立环节。取得 app_id 并不代表可以立即收款。如果支付产品尚未签约或未通过审核,正式环境中的支付仍然无法使用。

三、配置签名密钥

支付宝接口通常使用 RSA 签名。常见的配置方式有公钥模式和证书模式,应按照开放平台提供的接入方式选择,两种模式不能混用。

以公钥模式为例,配置过程如下:

  1. 在安全工具或可信环境中生成 RSA2 密钥对;
  2. 将应用公钥上传到支付宝开放平台;
  3. 保存平台返回的支付宝公钥;
  4. 将应用私钥安全地配置在购物网站服务端。

以下几个名称容易混淆:

  • 应用私钥:由网站保存,用于为请求签名;
  • 应用公钥:上传给支付宝,供支付宝验证网站的签名;
  • 支付宝公钥:由支付宝提供,网站用它验证支付通知;
  • app_id:支付宝应用编号,不是商户登录账号。

不要把应用私钥放进 JavaScript、HTML、App 安装包或公开代码仓库,也不应直接写死在源码中。生产环境可以通过密钥管理服务、加密配置或受权限控制的环境变量读取私钥。

四、确定支付流程

一次正常的网页支付流程如下:

用户提交订单
    ↓
网站服务端生成本地订单
    ↓
服务端调用支付宝支付接口
    ↓
浏览器跳转到支付宝收银台
    ↓
用户完成付款
    ↓
支付宝向 notify_url 发送异步通知
    ↓
网站验签并核对订单信息
    ↓
网站更新订单为已支付

return_url 是用户付款后浏览器跳转的页面。用户关闭页面或网络中断时,这个地址可能不会被访问,因此不能只凭 return_url 把订单标记为已支付。

支付结果应以验签成功的异步通知为主。如有必要,再调用订单查询接口主动核实。

五、创建本地订单

调用支付宝接口之前,网站应先创建自己的订单,至少保存以下信息:

  • 商户订单号;
  • 用户编号;
  • 商品信息;
  • 应付金额;
  • 订单状态;
  • 创建时间;
  • 支付渠道;
  • 支付宝交易号;
  • 支付完成时间。

每个商户订单号都必须唯一。金额应由服务端根据商品价格、优惠规则和运费重新计算,不能直接采用浏览器提交的金额。

数据库中的金额建议使用定点小数,或者用以“分”为单位的整数保存。不要使用二进制浮点数直接计算货币金额。

六、服务端发起支付

下面以支付宝 Java SDK 和公钥模式为例,演示 PC 网站支付的基本结构。依赖版本、SDK 包名和构造方法可能随官方 SDK 调整,实际项目应参考当前所用版本的官方说明。

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;

public class AlipayPaymentService {

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

    private final AlipayClient alipayClient;

    public AlipayPaymentService(
            String appId,
            String appPrivateKey,
            String alipayPublicKey) {

        this.alipayClient = new DefaultAlipayClient(
                GATEWAY,
                appId,
                appPrivateKey,
                "json",
                "UTF-8",
                alipayPublicKey,
                "RSA2"
        );
    }

    public String createPagePay(
            String orderNo,
            String totalAmount,
            String subject) throws Exception {

        AlipayTradePagePayRequest request =
                new AlipayTradePagePayRequest();

        request.setReturnUrl(
                "https://shop.example.com/payment/alipay/return"
        );
        request.setNotifyUrl(
                "https://shop.example.com/api/payment/alipay/notify"
        );

        String bizContent = String.format(
                "{\"out_trade_no\":\"%s\","
                        + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\","
                        + "\"total_amount\":\"%s\","
                        + "\"subject\":\"%s\"}",
                escapeJson(orderNo),
                escapeJson(totalAmount),
                escapeJson(subject)
        );

        request.setBizContent(bizContent);

        AlipayTradePagePayResponse response =
                alipayClient.pageExecute(request);

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

        return response.getBody();
    }

    private String escapeJson(String value) {
        return value
                .replace("\\", "\\\\")
                .replace("\"", "\\\"");
    }
}

response.getBody() 通常包含支付宝收银台的表单内容。服务端可以把它作为 HTML 返回给浏览器,再由浏览器自动提交表单并跳转。

实际开发时,建议使用 JSON 序列化库构建 biz_content,避免手工拼接 JSON。示例中的 escapeJson 仅用于说明基本思路,不能代替成熟的序列化组件。

手机网站支付的整体流程相同,但需要改用 AlipayTradeWapPayRequest,并按照手机网站支付接口的要求设置业务参数。

七、处理异步通知

异步通知是支付接入中最需要谨慎处理的部分。推荐按照以下顺序处理:

  1. 读取支付宝提交的全部参数;
  2. 使用支付宝公钥或证书验签;
  3. 检查 app_id 是否属于当前应用;
  4. 检查 out_trade_no 是否存在;
  5. 核对通知金额和数据库中的订单金额;
  6. 核对商户身份信息;
  7. 判断交易状态;
  8. 使用数据库事务更新订单;
  9. 返回支付宝要求的成功响应。

公钥模式下的验签示例:

import com.alipay.api.internal.util.AlipaySignature;

import java.util.Map;

public boolean verifyNotify(
        Map<String, String> params,
        String alipayPublicKey) throws Exception {

    return AlipaySignature.rsaCheckV1(
            params,
            alipayPublicKey,
            "UTF-8",
            "RSA2"
    );
}

验签通过后不能直接发货,还要核对订单号、金额、应用编号和交易状态。例如,只有确认 trade_status 属于业务允许的成功状态后,才能更新订单。

通知处理必须具备幂等性。支付宝可能针对同一笔交易重复发送通知,所以更新数据库前,应先判断订单是否已经支付,防止重复扣减库存、发放优惠券或创建发货单。

处理成功后,通知接口应按照支付宝协议返回以下纯文本:

success

如果接口超时或返回其他内容,支付宝可能继续重试通知。

八、主动查询支付结果

出现以下情况时,可以调用 alipay.trade.query 主动查询交易结果:

  • 用户付款后,页面没有正常跳回;
  • 异步通知出现延迟;
  • 通知已经验签,但还需要进一步确认订单信息;
  • 定时任务发现订单长期停留在“支付中”状态;
  • 客服需要核实某笔交易。

查询时可以使用网站自己的 out_trade_no,也可以使用已经保存的支付宝 trade_no。只有当查询结果与本地订单号、金额等信息一致时,才能更新支付状态。

不要根据前端显示的“付款成功”页面直接修改订单状态,因为页面内容和请求参数都可能被伪造。

九、先在沙箱环境联调

正式上线前,应先在支付宝沙箱环境中完成联调。沙箱环境和生产环境通常使用不同的:

  • 网关地址;
  • app_id;
  • 应用密钥;
  • 支付宝公钥或证书;
  • 测试账号。

切换到生产环境时,所有相关配置都要成套更换,不能把沙箱的 app_id 和生产环境的密钥混在一起。

至少需要测试以下场景:

  • 正常付款;
  • 用户取消付款;
  • 重复点击支付;
  • 重复收到异步通知;
  • 支付成功,但同步页面没有打开;
  • 通知金额与本地订单金额不一致;
  • 通知验签失败;
  • 已关闭订单再次支付;
  • 网络超时后主动查询;
  • 退款后的订单状态变化。

十、常见问题

支付页面提示“应用未签约”

常见原因包括支付产品尚未申请成功、应用还未上线,或者使用了错误的 app_id 和运行环境。

提示签名错误

可以依次检查:

  • 应用私钥是否完整;
  • 是否错误地使用了支付宝公钥;
  • RSA2 配置是否一致;
  • 密钥换行和头尾标记是否正确;
  • 字符编码是否为 UTF-8;
  • 是否混用了公钥模式和证书模式;
  • 是否混用了沙箱与生产环境的配置。

异步通知收不到

检查 notify_url 是否满足以下条件:

  • 可以从公网访问;
  • 使用完整的 HTTPS 地址;
  • 不依赖用户登录状态;
  • 没有被防火墙或网关拦截;
  • 不会返回登录页面或重定向页面;
  • 可以在较短时间内完成处理并响应。

通知接口不宜执行耗时过长的业务。确认支付后,可以先更新订单状态,再通过消息队列异步处理发货、积分和短信等操作。

支付成功但订单仍未支付

先检查通知日志和验签结果,然后调用订单查询接口核实交易状态。不要让客服直接手工将订单改为已支付,否则可能造成账务不一致。

十一、上线前的安全检查

正式开放支付前,应确认:

  • 私钥没有出现在前端代码或代码仓库中;
  • 所有支付金额都由服务端计算;
  • 异步通知已经验签;
  • 通知中的订单号、金额和应用信息均已核对;
  • 订单更新具备事务和幂等控制;
  • 支付、退款和异常通知都有日志;
  • 日志中没有记录私钥、完整证书或敏感身份信息;
  • 已配置订单超时关闭和支付结果补偿查询;
  • 可以根据商户订单号和支付宝交易号完成对账;
  • 测试环境与生产环境的配置完全隔离。

如果网站使用现成的商城系统,也可以安装该系统官方或可信服务商提供的支付宝支付插件,但商家签约、应用创建和密钥配置仍然必不可少。不要使用来源不明的“免签支付”或个人收款码轮询方案,这些方式通常存在资金、安全和合规风险。

备注:内容仅供参考。