准备接入 Stripe 收款,打开文档却先遇到一串名字:SDK、Elements、Checkout Session、PaymentIntent。换到 Checkout.com、Adyen 或 Antom,又会碰到 Flow、Drop-in、Payment Element。它们有的指页面,有的指代码包,有的指服务端保存的支付对象。
这种感觉像走进几家餐厅,同一道番茄炒蛋写出了几种菜名。不过,支付产品的名字相近,也可能有不同的功能边界。例如 Flow、Drop-in 和 Elements 都能用于嵌入支付界面,提供的组件、支付方式和接入流程却不完全相同;Mobile Web、H5、WAP 也不能按字面当成同一个技术标准。
把这些词按「在哪里填卡号、运行在什么终端、服务器怎样通信、支付过程由谁管理」分开,才容易看懂一份接入文档。这里讨论的是商户如何接入支付服务商(Payment Service Provider,PSP)。
先把四个问题分开
可以把接入支付想成开一家店:先摆柜台,再选柜台放在哪种环境里,接着搭好通信管道,最后决定怎样组织结账和付款。
这四个维度需要一起看,但图中的顺序只是理解概念的顺序。例如,商户可以在手机网页中嵌入支付组件,后端通过 SDK 创建 Checkout Session;「用了 SDK」这一句话,还没有说明 SDK 运行在哪里,更没有说明买家看到哪种收银台。
第一步:摆柜台,决定在哪里输入付款信息
前端交互(Frontend Interaction)决定买家在哪里选择支付方式、填写卡号,以及这些数据会经过谁的页面和系统。界面体验和支付卡行业数据安全标准(PCI DSS)的验证工作量,都与这条数据路径有关。
托管收银台:跳到 PSP 的页面付款
托管收银台(Hosted Payment Page)可以理解为「跳出式支付」:买家在商户页面点击付款,浏览器跳到 PSP 提供的收银台,完成支付后再回到商户页面。
在正确集成的托管流程中,原始卡号由 PSP 页面收集,不经过商户自己的输入框和服务器,可以减少商户直接处理卡数据的范围。代价是支付过程中切换了页面;页面加载速度、品牌辨识和返回路径都会影响体验。跳转对转化率的影响需要用实际支付漏斗衡量,不能套用一个固定损失比例。
Antom 的 Hosted Checkout Page 就有两种页面路径:一种在 Antom 页面完成支付操作;另一种先进入 Antom,再跳到所选支付方式的第三方页面。
电脑和手机都可以走这类流程。手机端可能依次出现商品页、托管收银台、付款码或外部支付页面、结果页,最后回到订单页。页面回来了,只能说明买家完成了某段交互;订单的最终付款结果仍要通过服务端通知或查询确认。
嵌入式组件:在商户页面里放入支付窗口
嵌入式组件(Embedded Components)把 PSP 提供的支付界面放进商户页面。对于使用跨域 iframe 的托管卡输入框,买家感觉自己仍在商户网站上,原始卡信息则由 PSP 的独立文档收集;商户页面脚本不能直接读取其中的卡号。
嵌入的范围可以很小。桌面页面可以保留商户自己的商品和账单区,只嵌入付款方式、卡号输入框或付款码。手机页面也可以沿用这个结构:商品区由商户控制,支付区由 PSP 组件提供。
也可以嵌入一整套收银台。例如,Stripe 的 Embedded Checkout 把完整结账界面放在商户页面中。外层页面留在商户网站,不代表所有认证和支付动作都不会离开当前页面;具体支付方式仍可能要求跳转到银行、钱包或认证页面。
Drop-in、Hosted Fields、Elements 这些名字,需要结合产品文档区分:有的提供整套付款方式选择与表单,有的只提供几个托管字段。组件能定制哪些样式、是否处理 3DS(3-D Secure,持卡人认证)、怎样返回结果,也要逐项确认。
前端直接收集卡信息:商户自己搭前台
Client-to-API 可以用「自建前台」来理解:商户编写 HTML 输入框,直接收集卡号,再通过允许这种接入方式的接口换取 Token。Token 是后续调用使用的替代标识,可以减少继续传递原始卡号的需要。
这种做法给了商户更多界面与交互控制,但原始卡信息先进入了商户控制的页面。页面脚本一旦被篡改,就可能在生成 Token 之前读走卡号;之后再换成 Token,也不会消除先前的数据接触。是否开放这种接口、需要怎样验证合规,应在接入前与 PSP 和收单机构确认。
PCI DSS(Payment Card Industry Data Security Standard,支付卡行业数据安全标准)规定了支付卡数据的安全要求。Visa、Mastercard、American Express、JCB 等卡业务会涉及 PAN(主账号)、有效期、CVV/CVC 等字段,但它们的分类与存储要求不同,不能统称为一种可以任意保存的数据。
PCI DSS 的适用性也不能简化成「只有碰到卡号才需要一张 PCI 资质」。采用托管页面或合规的托管字段可以缩小评估范围,商户仍有相应责任;适用哪种 Self-Assessment Questionnaire(SAQ,自评问卷)或评估方式,要由接收合规材料的机构确认。PCI SSC 对嵌入式支付表单的 SAQ A 条件还专门说明了页面脚本攻击防护要求。
自建表单之后,也可能出现额外认证:电脑或手机端填写卡信息,按需进入 3DS 流程,再回到商户结果页。还要区分卡数据是否经过商户后端;「前端直接提交给 PSP」与「先传到商户服务器再转发」具有不同的数据路径,不能只凭「API 直连」四个字判断。
第二步:选容器,确认支付运行在哪种终端
终端环境(Terminal & Environment)影响屏幕布局、设备信息采集、钱包唤起,以及 3DS 2 认证的展示与返回。一个支付组件能在桌面浏览器使用,不代表它在 App 内的 WebView 或小程序中也有同样的能力。
电脑网页(PC Web):显示空间较大,可以同时呈现多种本地支付方式、商品信息和详细账单。
手机网页(Mobile Web):在手机浏览器里运行,需要控制输入量和页面长度;支持条件满足时,可以接入 Apple Pay、Google Pay 等钱包。产品文档中的 H5、WAP 有时也指这一终端类别。
原生应用(Native App):运行在 iOS 或 Android 中,可以集成 Mobile SDK。指纹、面容或其他认证方式取决于设备、钱包和银行流程,不能保证每次都无感,也不能据此断言转化率最高。
小程序(Mini Program):运行在微信或其他 Super App 的平台环境里,需要遵守宿主对页面跳转、支付 API 和返回路径的规则。
终端选择需要和支付方式一起确认。例如,同样一个 Apple Pay 按钮,在网页和原生 App 中使用的接口与前置条件可能不同;不能把桌面网页的实现原样搬到所有环境。
第三步:搭管道,决定服务器怎样调用 PSP
后端通信(Backend Integration)回答的是商户服务器怎样与 PSP 服务器对话。这里的服务端 SDK,与前面负责展示输入框、唤起钱包的前端 SDK,是不同位置的代码。
服务端 SDK
服务端 SDK 像一套现成工具:把 PSP 提供的依赖包放进项目,调用对应的方法创建支付、查询状态或处理其他业务。
它可以封装请求参数、身份验证、响应解析等重复工作。有的还提供请求签名、重试、webhook(服务端事件通知)验签或特定数据的加解密能力,但具体覆盖范围取决于 SDK。开发者仍需要配置密钥、超时和重试策略,并接好业务流程;不能假定装上 SDK 后所有安全工作都会自动完成。
直接调用服务端 API
Server-to-Server API 可以理解为「手动搭管道」:不使用 PSP 的服务端 SDK,由商户代码构造 HTTP 请求,按协议完成身份验证、必要的签名、数据校验和错误处理。
如果 PSP 没有提供团队所用语言的 SDK,或者项目已有统一的网络与中间件封装,这是一种可选方式。它减少了对特定 PSP 代码包的依赖,也把协议适配、重试语义、超时和版本兼容工作交给了团队。底层仍可能依赖 HTTP 客户端、TLS 和加密库,不能称为系统「零依赖」。
SDK 与直接 API 的取舍
| 评估维度 | 服务端 SDK | 直接调用服务端 API |
| 开发效率 | 复用现成请求与响应封装,减少重复代码 | 自行实现协议适配与错误解析 |
| 项目体积 | 引入 SDK 及其依赖,大小取决于具体实现 | 可以只封装需要的接口,也需要维护自己的代码 |
| 环境稳定性 | 需要关注依赖版本、升级和冲突 | 少一套 PSP SDK,但仍需维护底层网络与安全依赖 |
| 代码可控性 | 受公开接口和扩展点约束,开源实现可以审查 | 自己控制封装,同时承担协议正确性的责任 |
| 安全审查 | 审查 SDK、依赖及使用方式 | 审查自研签名、验证和重试逻辑,不会自动更简单 |
| 性能调优 | 看 SDK 是否开放连接池、超时等配置 | 可以自行组织连接池、超时和熔断,但要负责验证 |
| 多通道扩展 | 可能需要维护多套 SDK 和调用风格 | 可以统一接口外形,仍要分别处理各 PSP 的协议差异 |
| 团队适配 | 需要快速接入且官方库满足需求时较省事 | 有明确定制需求及长期维护能力时可以考虑 |
用哪一种方式发请求,与前端是否托管、后端是否创建 Session,没有必然绑定关系。同一个创建支付接口,既可以通过 SDK 调用,也可以直接发送 HTTP 请求。
第四步:选模式,分清结账会话与支付对象
支付模型(Payment Model)决定 PSP 帮商户管理多少结账上下文,以及商户自己控制多少支付流程。它会影响状态跟踪和订单更新;授权后何时 Capture,则是另一个需要单独配置的问题。
支付会话:让 PSP 记住结账上下文
Session / Checkout Flow 的思路是先在服务端创建支付会话,再让前端依据返回的 URL、会话数据或客户端密钥启动付款。Session ID、客户端密钥和跳转 URL 各有用途,不能互换使用,也不能把服务端 Secret Key 当作客户端密钥传到浏览器。
「上下文」(Context)就是完成一件事时需要记住的背景信息和进度。以配置了相应功能的 Stripe Checkout Session 为例,它可以关联:
买什么:商品列表、单价、数量。
按什么条件结账:币种、税费、运费、折扣和优惠券。
谁在付款:客户 Email、账单地址、配送地址等信息。
进行到哪一步:会话是否仍开放、是否已完成或已过期,以及相关支付对象的进度。
后续操作可以引用已创建的上下文,不必每次从头提交全部背景信息。但不同 PSP 的 Session 保存范围不同;名字都叫 Session,也不代表都内置商品目录、增值税或商品与服务税(VAT/GST)的计算功能,以及优惠引擎。
从买家的视角看,过程可能是「开始结账 → 输入卡信息 → 按需完成 3DS → 看到结果」,也可能中途退出或会话过期。这些交互步骤不一定各自对应 Session 的一个状态值。例如,Stripe Checkout Session 的 status 与 payment_status 是不同字段;会话已经 complete 时,付款仍可能在处理中。
直接管理支付对象:商户掌握更多结账逻辑
更底层的 Payment API 让商户自己组织商品、折扣、运费和税费,再把最终金额交给 PSP 处理。Stripe 的 PaymentIntent 就属于这种支付对象,它负责跟踪支付及所需认证,商户需要自行组织更多结账逻辑。
可以类比超市收银:商品和优惠由收银系统算好,POS 机接收待付金额,再处理卡付款。这个比喻帮助区分「算出该付多少」和「执行这笔支付」;真实的 PaymentIntent 仍有生命周期,可能等待支付方式、要求认证或处于处理中。
卡支付还可以区分两种 Capture 策略:自动 Capture,或先完成 Authorization(授权,占用可用额度或资金),再由商户发起 Capture(请款)。后者可以理解为先预授权,再完成扣款请求,具体支持范围和授权有效期由支付方式及规则决定。
这两种策略不专属于某一种接口模型。Stripe 的 Checkout Sessions 和 Payment Intents 都能为支持的支付方式配置手动 Capture。「Direct」或「Direct Charge」在不同平台也可能有别的含义,不能把名字直接翻译成「一定立即扣款」。
会话模型究竟托管了什么
| 能力 | 使用结账会话时 | 直接管理更底层支付对象时 |
| 状态与生命周期 | PSP 管理会话生命周期,商户仍要同步订单状态 | PSP 仍管理支付对象状态,商户组织结账步骤与订单关联 |
| 购物车、税费与折扣 | 某些产品可处理商品、运费、VAT/GST 和优惠,需启用对应功能 | 商户或所接业务系统先计算最终金额,再提交付款 |
| 支付界面与方式选择 | 可结合托管页或嵌入组件,按产品支持展示卡、钱包、先买后付(BNPL)等方式 | 也可以结合预制组件;例如 Payment Element 支持 Payment Intents |
| 设备与风控上下文 | 可能由前端组件采集部分浏览器信息,并关联会话;商户仍需传必要数据 | 同样可能需要 IP、设备和浏览器信息,不能只发送一个金额就省略全部终端交互 |
| 重定向与异步结果 | 产品可以协助衔接银行或钱包页面,商户接收服务端通知 | 也可能发生重定向和异步处理,同样要取得可靠支付结果 |
四个维度如何组合
具体产品会限制可用组合。判断时需要看它实际提供什么接口、组件和支付方式,而不能只看 Hosted、Session 或 API 这些标签。
| 场景 | 需要确认的组合关系 |
| 使用 Hosted Payment Page | 先创建平台要求的结账或付款记录,再取得支付页。Stripe Checkout 使用 Checkout Session;PayerMax 的托管流程则通过创建付款请求返回收银台 URL,接口不必叫 Session |
| 使用嵌入式组件 | 查组件支持哪些服务端流程。例如 Stripe Payment Element 可以配 Checkout Sessions 或 Payment Intents;Adyen 的客户端库也有不同服务端接法 |
| 接 Apple Pay / Google Pay | 需要终端侧的钱包交互,可以使用 PSP 组件,也可以按钱包官方前端 API 接入;仅发一个服务端 HTTP 请求无法代替用户确认付款 |
| 接 Boleto、网银或 BNPL | 分别确认是否跳转、展示付款凭证、要求后续操作,以及结果何时确定;这些支付方式不能全部归为「必须离开商户页面」 |
| 运行在 Native App / 小程序 | 核对 Mobile SDK、内嵌页面、外部浏览器和回跳的支持条件,不能一概认定 Hosted 页面不可用 |
| 自建输入框收集原始卡信息 | 同时评估前端安全、数据经过的系统和 PCI DSS 范围。后端不用 SDK,并不要求前端也自行收卡号 |
| 可能发生 3DS 或其他异步交互 | 前端返回可用于展示进度,服务端按 PSP 文档接收并校验 webhook 或查询结果;买家关掉页面不应让订单永远失去付款结果 |
| 希望由 PSP 处理税费与优惠 | 选择确实提供这些功能的产品,并配置适用规则;仅创建一个名为 Session 的对象并不能保证平台替商户算税 |
例如,使用 Stripe 提供的 Payment Element,可以让卡信息留在托管字段中;商户后端仍可以直接调用 HTTP API 创建 PaymentIntent。前端组件、服务端 SDK 与支付对象分别解决各自的问题。
附录:平台名称与基础术语
平台里的名字怎么对照
下表列出各家文档中的入口和名称,便于查找;同一格内的产品不代表具有完全相同的功能。产品名称与能力核对日期为 2026 年 9 月 18 日。
| 平台 | 托管或嵌入式界面 | 服务端流程与接口名称 | 链接支付入口 |
| Antom | Checkout Page(CKP)、Payment Element | 创建支付会话、API-only 等接入路径 | 按具体产品文档确认 |
| Adyen | Drop-in、Components;另有链接进入的托管支付页 | Sessions flow、Advanced flow | Pay by Link,用于补充网店的主支付集成 |
| Checkout.com | Hosted Payments Page、Flow | 按 Hosted 或 Flow 的集成文档创建所需支付记录 | Payment Links |
| PayerMax | PayerMax Checkout、Drop-In | Checkout 创建付款、Direct API | PayByLink |
| Stripe | Stripe-hosted Checkout、Embedded Checkout、Payment Element | Checkout Sessions、Payment Intents | Payment Links |
链接支付(Payment Link)就是生成一个链接,再让客户通过链接进入支付页。它描述的是付款入口;客户打开链接后,仍要经过相应的收银台与支付流程。
还要避免把表格横向读成固定绑定。例如,PaymentIntent 本身不要求商户直接读取原始卡号;Elements 也可以结合 Checkout Sessions。看到「API-only」时,应继续查看卡信息由谁收集、买家在哪里操作,以及是否需要重定向。
缩写速查
| 缩写 | 英文全称 | 在这里的含义 |
| API | Application Programming Interface | 应用程序编程接口;可以用于前端、服务端或系统内部,不限于服务器之间 |
| SDK | Software Development Kit | 软件开发工具包;具体可能提供组件、接口封装和辅助工具 |
| PC | Personal Computer | 个人电脑,PC Web 指桌面浏览器环境 |
| H5 | 来自 HTML5:HyperText Markup Language 5 | 中文产品语境中用来称呼移动网页,不是独立的支付协议 |
| WAP | Wireless Application Protocol | 无线应用协议,源自早期移动上网技术;某些支付文档沿用它标记移动网页,不等于 HTML5 |
| App | Application | 应用程序;在本文的终端语境中主要指移动应用,例如手机上的微信 |
| vs | Versus | 表示对比或相对 |
组件是一块可复用的积木
UI 组件(Component)把一项界面功能及其交互封装起来,供其他页面复用。可以把它想成乐高里的轮胎或方向盘:拼一辆车时,拿现成零件组合,不必每次重新制作。
卡号输入框、支付按钮、优惠券弹窗都可以做成组件。组件的价值在于把重复的结构与行为组织起来,让开发者在不同地方使用同一套实现。
功能内聚:把相关的 HTML 结构、CSS 样式和 JavaScript 交互组织在一起,减少调用方需要了解的细节。
可以复用:同一个支付确认按钮,可以出现在购物车、结算页和订单详情页。
参数与状态分开管理:以 React 为例,Props 接收外部参数,例如商品金额;State 保存内部状态,例如按钮是否正在加载、能否继续点击。
组件封装属于代码组织方式。Props 与 State 不构成安全隔离,普通组件也不会自动让页面脚本读不到其中的数据。
iframe 是嵌入另一张网页的窗口
iframe 让一张网页在自己的区域里显示另一份网页文档。支付场景中,外层可以是商户的商品与订单页面,内层则是 PSP 托管的付款输入区域。
可以把它想成客厅里的一扇窗口:透过窗口能看到隔壁房间的电视和沙发,但它们属于另一套装修。对应到网页里,外层和内层各有自己的文档;脚本能否直接访问彼此,还要看是否同源以及采取了哪些限制。
这里有三个需要分开的特征:
独立文档:iframe 内外的 HTML 与 CSS 分属不同文档,外层样式不会直接套用到内层元素。它不等于默认启用了完整沙箱;
sandbox是另外的限制机制,同源文档也可能相互访问。跨域访问受限:当 PSP 输入框来自不同的源时,浏览器的 Same-origin policy(同源策略)限制商户脚本直接访问它的 DOM。跨域托管卡字段正是利用了这种边界。
嵌入和通信受规则约束:对方可以通过
frame-ancestors或X-Frame-Options等策略限制被嵌入;允许嵌入后,双方仍可使用postMessage按约定交换必要信息。
iframe 可以限制对内层卡字段的直接读取,但商户页面本身仍需防护脚本篡改和伪造输入界面。确认一个支付组件的安全边界时,要看真实的数据路径与跨域设计,不能仅凭页面里出现了 iframe 就认定风险已经消失。