PAYATHON 2026

自研APP或支付宝小程序能否实现用户间支付宝转账?

支付阿杰

明确结论

自研 APP 或支付宝小程序通常不能直接实现”用户 A 通过支付宝余额或银行卡,向用户 B 的个人支付宝账户自由转账”。

支付宝开放平台提供的是商户支付能力,也就是用户向签约商户付款,并未向第三方平台开放个人用户之间的任意转账通道。平台不能只凭两个用户的支付宝账号,代替双方完成点对点转账。

业务确实需要实现类似效果时,通常有两种合规方案:

  1. 先支付给平台,再由平台结算给收款方
    用户 A 向平台商户付款。平台记录订单,等业务条件满足后,再通过支付宝允许的转账、分账或结算能力向用户 B 付款。

  2. 使用支付宝的分账或资金结算产品
    这类产品适用于电商平台、服务撮合、佣金结算等有明确交易背景的场景。能否开通,要看主体资质、所属行业、业务模式以及支付宝的审核结果。

APP 可以只在支付环节调起支付宝,支付完成后再返回 APP。支付宝小程序则可以直接在小程序内唤起收银台。无论采用哪种形式,都应以服务端收到的异步通知或主动查询结果确认支付状态,不能只依赖客户端回传。

为什么不能直接做用户间转账

支付宝面向商户开放的支付接口,一般要求收款方是签约商户,并且每笔支付都有对应的真实订单。普通用户在平台内注册账号后,并不会自动成为支付宝开放平台认可的收款商户。

如果平台先把钱收进自己的账户,再根据内部账本允许用户自由提现或互转,还可能产生以下风险:

  • 平台形成资金池;
  • 涉及代收代付或变相清算;
  • 缺少真实交易背景;
  • 用户资金与平台自有资金混同;
  • 退款、投诉和账户冻结的责任不清;
  • 触及支付结算、反洗钱、税务和实名管理要求。

所以,即使技术上可以拼接出一条资金链路,也不代表支付宝允许这种业务上线。接入前应向支付宝确认相关产品的适用范围,并请合规或法律人员审查资金流设计。

推荐的业务流程

常见的实现流程如下:

用户 A 提交付款
    ↓
平台服务端创建业务订单
    ↓
平台服务端调用支付宝支付接口
    ↓
APP 调起支付宝,或小程序唤起支付宝收银台
    ↓
用户完成支付
    ↓
支付宝向平台服务端发送异步通知
    ↓
平台验签、核对订单并更新支付状态
    ↓
达到结算条件
    ↓
平台调用获准开通的分账、转账或结算能力
    ↓
资金结算给用户 B

这套流程包含两笔性质不同的资金操作:

  • 用户 A 向平台商户支付;
  • 平台根据真实业务订单向用户 B 结算。

这并不是两个支付宝个人账户之间的直接转账。

APP 如何实现仅支付时调起支付宝

在 APP 场景中,通常由服务端调用支付宝 APP 支付接口,例如 alipay.trade.app.pay,生成客户端可使用的订单字符串。APP 将该字符串交给支付宝 SDK,由支付宝客户端展示收银台。

下面的代码只表示整体结构。密钥加载、异常处理和不同 SDK 版本对应的具体类名,应以接入时的支付宝开放平台文档为准。

AlipayClient alipayClient = new DefaultAlipayClient(
    gatewayUrl,
    appId,
    merchantPrivateKey,
    "json",
    "UTF-8",
    alipayPublicKey,
    "RSA2"
);

AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
request.setNotifyUrl("https://example.com/api/alipay/notify");

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo("ORDER_202609090001");
model.setSubject("平台服务订单");
model.setTotalAmount("100.00");
model.setProductCode("QUICK_MSECURITY_PAY");

request.setBizModel(model);

AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
String orderString = response.getBody();

服务端将 orderString 返回给 APP,再由客户端调用支付宝 SDK。支付结束后,支付宝通常可以把用户带回 APP。不过,客户端返回值只适合用来更新页面提示,不能作为发货、记账或结算的依据。

小程序中的支付方式

支付宝小程序通常先由平台服务端创建支付宝交易,再由小程序调用支付能力打开收银台。示意代码如下:

my.tradePay({
  tradeNO: tradeNo,
  success(result) {
    // 这里只更新页面提示。
    // 最终支付状态仍需向平台服务端查询。
    console.log(result);
  },
  fail(error) {
    console.error(error);
  }
});

tradeNo 应由平台服务端通过支付宝相应的交易创建能力取得,不能由小程序前端自行伪造。

支付完成后,用户一般仍在支付宝环境中,可以返回原来的小程序页面。但这笔支付仍然是用户向商户订单付款,不是普通用户之间的直接转账。

服务端如何确认支付结果

收到支付宝异步通知后,服务端至少要完成以下检查:

  • 验证支付宝签名;
  • 核对 app_id;
  • 核对平台订单号 out_trade_no;
  • 核对订单金额 total_amount;
  • 核对收款主体;
  • 判断交易状态;
  • 做幂等处理,避免重复记账;
  • 必要时调用交易查询接口再次确认。

下面是简化后的处理逻辑:

@PostMapping("/api/alipay/notify")
public String handleNotify(HttpServletRequest request) {
    Map<String, String> params = extractAlipayParameters(request);

    boolean valid = AlipaySignature.rsaCheckV1(
        params,
        alipayPublicKey,
        "UTF-8",
        "RSA2"
    );

    if (!valid) {
        return "failure";
    }

    String outTradeNo = params.get("out_trade_no");
    String tradeStatus = params.get("trade_status");
    String totalAmount = params.get("total_amount");
    String appIdFromNotify = params.get("app_id");

    Order order = orderService.findByOrderNo(outTradeNo);
    if (order == null) {
        return "failure";
    }

    if (!expectedAppId.equals(appIdFromNotify)) {
        return "failure";
    }

    if (!order.getAmount().toPlainString().equals(totalAmount)) {
        return "failure";
    }

    if ("TRADE_SUCCESS".equals(tradeStatus)
            || "TRADE_FINISHED".equals(tradeStatus)) {
        orderService.markPaidIdempotently(outTradeNo, params);
    }

    return "success";
}

实际项目还应核对卖家信息和支付宝交易号,并保存原始通知与验签结果。支付宝可能重复发送异步通知,因此更新订单和生成结算记录时必须保证幂等。

如何把资金结算给用户 B

应根据业务性质选择结算能力:

  • 存在明确的平台交易,并且有多个收款参与方时,可以评估分账类产品;
  • 平台向服务提供者发放佣金、报酬或退款时,可以评估商家转账类产品;
  • 用户 B 是平台入驻商户时,可以评估平台型商户结算方案;
  • 如果只是社交用户之间互相转钱,通常不适合包装成商户支付和结算业务。

在部分历史场景或特定业务中,可能会看到 alipay.fund.trans.uni.transfer 等接口名称。但这些接口当前能否申请、支持哪些收款对象、是否需要额外签约产品,都应以接入时控制台可申请的产品和官方文档为准。在确认权限之前,不要只按接口名称设计上线方案。

账户体系应如何设计

平台余额不能直接等同于用户的支付宝余额。以下概念应分开管理:

  • 业务订单金额:用户实际购买商品或服务的金额;
  • 待结算金额:订单已经支付,但尚未满足结算条件的金额;
  • 可结算金额:已经满足履约、退款期等条件的金额;
  • 已结算金额:支付宝已经受理并确认完成的金额;
  • 退款金额:通过原支付订单退回付款人的金额。

数据库也应分别保存业务订单、支付宝交易、退款单和结算单,不要用一张余额表记录所有资金变化。

需要特别注意的问题

不要让前端决定收款人和金额

服务端必须根据业务数据生成订单金额、收款关系和结算金额。前端提交的金额、用户 ID 或支付宝账号都要重新校验。

不要只看客户端支付成功

客户端结果可能被篡改,也可能因为网络中断而不完整。最终支付状态应以验签后的异步通知或服务端查询结果为准。

收款人信息需要合规获取

不要让用户随意填写支付宝登录账号后直接打款。可以使用哪些收款标识,是否需要实名信息和授权,应以已开通转账产品的要求为准。

处理退款和结算冲突

如果订单已经结算给用户 B,之后用户 A 又申请退款,平台可能需要承担资金追回风险。平台应设置合理的待结算期,并明确退款、争议和拒付规则。

正式开发前先提交业务方案

正式开发前,建议先整理以下材料,再向支付宝开放平台或服务商确认:

  • 平台经营主体和所属行业;
  • 用户 A 与用户 B 的关系;
  • 付款对应的商品或服务;
  • 平台是否收取佣金;
  • 资金是否经过平台商户账户;
  • 结算时间以及是否允许退款;
  • 收款人是个人还是企业;
  • 预计交易金额、频率和风控措施。

只有确认业务场景和产品权限后,才能最终确定使用哪些接口。如果核心需求只是让两个普通用户自由互转支付宝资金,通常应引导用户使用支付宝自身的转账功能,而不是让第三方 APP 或小程序代为完成。

备注:内容仅供参考。