Skip to main content
Subotiz 支持在自有 iOS / Android App 内完成支付。本页介绍 App 内接入的整体方案、集成模式选择、支付方式支持范围、集成步骤与限制规则。
适用对象:需要在自有 iOS / Android App 内集成 Subotiz 支付的开发者(客户端 + 服务端)。您将完成:在 App 内唤起 Subotiz 支付页、接收支付结果、以 webhook 确认订单。关键前置:已开通 Subotiz 商户账户并获取 Secret API Key 与 Webhook 签名密钥;具备可接收 webhook 的服务端环境。范围:App 内支付集成。不含 Web / H5 集成,不含支付方式的商户后台配置。

方案概述

App 内支付采用 link-to-checkout 模式:您的服务端创建 Checkout Session,App 在应用内用系统浏览器打开 Subotiz 支付页。支付页以浮层形式呈现于 App 之上,用户全程不离开您的 App。支付完成后浏览器关闭并把控制权交回 App,订单状态以 webhook 为准。 整个集成由四步组成,各端职责如下。
该模式下您的 App 不包含任何支付逻辑——不持有 Secret API Key、不接触卡数据,不进入 PCI 合规范围支付方式由商户后台开通即生效,新增支付方式无需 App 发版;支付页由系统浏览器驱动,自动共享 Cookie 与完整 Web 平台能力,钱包与 3DS 的兼容性优于其他容器

三条设计原则

  1. Session 由服务端创建。 App 不持有 Secret API Key;金额与商品由服务端决定,防止客户端篡改。
  2. Webhook 为订单状态唯一权威来源。 发货与开通权益只依据 webhook,不依据 App 收到的返回。返回仅用于触发 UI。
  3. 必须使用系统 in-app 浏览器。 共享系统 Cookie、支持 Apple Pay / Google Pay;不要用可注入 JS 的裸 WebView 承载支付页。

先做选择:集成模式

App 场景有两种集成模式,两者的 Apple Pay 支持范围不同,请在开发前确定。
不支持 App 原生页面集成。 Subotiz Checkout 的三种集成形态均不提供在 App 原生页面内直接渲染支付表单或钱包按钮的能力,支付必须经由系统 in-app 浏览器承载。
App 场景统一推荐托管式。若您的用户中存在 iOS 17 以下设备,且 Apple Pay 是主要支付方式,必须使用托管式嵌入式还需您自建宿主页并实现跨窗口通信;而 App 内托管式本就以浮层呈现、用户不离开 App,嵌入式「不跳出自有页面」的价值在此场景并不成立。

支持的支付方式

下表为 App 内浏览器场景的支持情况。实际可用的支付方式由您的商户配置决定,请以创建 session 接口返回的 payment_methods 为准。
自有支付的底层清算通道不同,可用支付方式也不同——标注「视通道而定」的支付方式并非所有商户都可用。请务必以创建 session 接口返回的 payment_methods 为准,不要按本表硬编码支付方式列表。其他三方渠道(Airwallex、Checkout、Oceanpayment 等),App 内支持情况请联系 Subotiz 确认。

集成步骤

1

服务端准备

在服务端配置以下环境变量,不要打包进 App
2

第 1 步:创建 Checkout Session(服务端)

App 点击购买时,由您的服务端调用 Subotiz API 创建 Checkout Sessionreturn_urlcancel_url 请设为您自有域名下的返回地址。

关键参数

  • order_id:为接入方订单 ID,用于后续关联业务数据
  • integration_method:设置为 hosted,表示使用托管式页面模式接入
  • return_url:顾客支付成功之后跳转的页面,App 场景下应指向您的 Universal Link / App Link
  • cancel_url:顾客取消支付时跳转的页面
可观察结果:接口返回 session_url(即 checkoutUrl),形如 https://checkout.subotiz.com/m/{mid}/checkout/{sessionId}
Secret API Key 与 Webhook 签名密钥仅存于服务端,绝不打包进 App。金额与商品必须由服务端决定。
3

第 2 步:在应用内打开支付页(App)

App 拿到 session_url 后,用系统提供的 in-app 浏览器容器打开。
禁止使用 WKWebView / Android WebView 承载支付页。 原因:
  1. ApplePaySession 在 WKWebView 中因安全源(security origin)限制无法发起,Apple Pay 直接不可用
  2. 3DS、OAuth 等重定向类认证在 WebView 内不被推荐,受内核碎片化影响易失败或卡死;
  3. 宿主可注入 JS 窃取支付输入,会扩大您的 PCI 合规范围
  4. 不共享浏览器会话,多数支付方式不支持该场景——Link / PayPal / Klarna / Amazon Pay 在应用内 WebView 下均不可用,Google Pay 需额外完成 Android WebView 配置才可能支持。
可观察结果:支付页以浮层覆盖在 App 之上,用户可见支付方式列表。
4

第 3 步:接收返回(App)

支付完成后,Subotiz 会重定向到您创建 Session 时传入的 return_url(或 cancel_url),in-app 浏览器随即关闭、控制权回到 App。
  • iOS:在承载支付页的视图上实现 onOpenURL,收到返回后关闭 Safari 视图。
  • Android:在 AndroidManifest.xml 注册接收返回的 Activity(launchMode="singleTask" + autoVerifyintent-filter)。
5

第 4 步:确认订单(服务端 + App)

服务端实现 webhook 端点,这是订单状态的唯一权威来源。处理要点三项:
  1. 验签——按 Webhook 可靠性验证校验 X-Signature,验签需要原始 body,不要先做 JSON 解析;
  2. 幂等去重——按事件 id 去重,同一事件可能重复推送;
  3. 快速返回 200——业务处理耗时请异步化,不要阻塞响应。
App 侧实现轮询:收到返回后调用您的服务端接口查询订单状态,直到状态为终态或超时。
webhook 与返回是两条独立路径。即便返回未能触达(用户手动关闭浏览器、网络异常等),webhook 仍会把订单置为已支付,用户下次进入 App 时轮询即可获得正确状态。因此轮询不是可选项。

限制规则

强制要求

建议与说明

完成验证

集成完成后,请逐项确认:
  • 服务端能成功创建 Session 并返回 session_url
  • App 内打开支付页时以浮层呈现,用户未跳出 App
  • 支付页上可见预期的支付方式(与 payment_methods 一致)
  • iOS 真机上 Apple Pay 按钮可见并可唤起(测试金额需高于所在通道的最小扣款额,见 L2)
  • 支付成功后浏览器自动关闭并回到 App
  • 服务端能收到 webhook,验签通过,重复推送不产生重复发货
  • 手动关闭浏览器不触发返回时,App 重新进入后仍能通过轮询获得正确订单状态
  • 取消支付后订单状态正确,未误开权益