mcpField
I
integrate-apple-pay

integrate-apple-pay

github.com/payroc开发044 次安装4 周前更新
代码仓库

关于 integrate-apple-pay

为开发者提供 Payroc Apple Pay 集成指导,从商户域名设置到 UAT 测试交易。内容涵盖 Apple Pay JS API 与 Payroc Payments API 的配合,并用本地参考资料核对接口形状和值。

主要功能

  1. 01指导域名验证与商户设置
  2. 02衔接 Apple Pay 会话和支付 API
  3. 03处理加密支付令牌
  4. 04按资料核对 API 与 JS 字段
  5. 05检查支付按钮可用性
  6. 06诊断集成错误

适用场景

  1. 01为现有 Payroc 结账添加 Apple Pay
  2. 02构建独立的 Apple Pay 支付流程
  3. 03在 UAT 验证会话和付款步骤

MCP 相关

README 提到可选运行 MCP 连接检查工具;未说明该技能提供 MCP 服务或管理 MCP 服务器。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/payroc/skills --skill integrate-apple-pay

安装后在 Claude Code 中输入/integrate-apple-pay确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
_sources.md
add-apple-pay-to-your-integration.md
api-schema.md
error-response-format.md
idempotency.md
identity-call.md
set-up-apple-pay-for-a-merchant.md
references/third-party/
apple-applepaysession.md
apple-pay-button.md
apple-payment-token.md
apple-server-setup.md

详细介绍

Payroc Apple Pay 集成

版本检查(请先运行)

在发布任何消息或开始流程之前,请确认此技能是最新版本:

  1. 从上方 frontmatter 的 metadata.version 字段读取此技能的版本。
  2. 获取已发布的副本并读取其 metadata.version: https://raw.githubusercontent.com/payroc/skills/main/plugins/payroc/transaction/skills/integrate-apple-pay/SKILL.md
  3. 按语义版本比较两者:
    • 此版本 >= 已发布版本 → 静默继续,不发送消息。(开发者使用尚未发布的较新版本是正常且可以接受的。)

    • 此版本 < 已发布版本 → 告知开发者:

      ⚠️ 此技能已有更新版本(v<published>)发布 — 你正在运行 v<current>。建议升级以获得最佳效果。

      然后询问他们是要继续使用当前版本,还是先停止并升级,并尊重他们的选择。

    • 无法获取(离线、网络错误、404)→ 简要说明无法验证版本,然后继续。


首次调用时,向开发者介绍:

Payroc Apple Pay 集成 我将指导你完成从商户设置到成功执行 UAT 测试交易的全过程。 本指南介绍如何在结账页面上使用 Apple Pay 作为支付方式 — 通过 Apple Pay JS API 显示支付表单,并使用 Payroc Payments API 处理加密支付数据。

Apple Pay 与 Payroc 的工作方式(分为四个部分):

  1. 通过 Self-Care Portal 向 Apple 验证你的域名,并获取域名 ID
  2. 客户轻点 Apple Pay 按钮时,Apple Pay JS API 会触发 onvalidatemerchant 事件 — 你的服务器调用 Payroc API 启动会话,并将响应返回给 Apple。有两个可用的端点变体:适用于新集成的新版 POST /v1/payments/apple-pay/sessions(首选),以及原始的 POST /v1/processing-terminals/{processingTerminalId}/apple-pay-sessions。
  3. Apple 显示支付表单;客户通过 Face ID / Touch ID 授权
  4. onpaymentauthorized 事件会携带加密支付数据触发 — 你的服务器将其转换为十六进制,并 POST 到 Payroc 支付端点

重要: Apple Pay 仅适用于 Apple 设备(iPhone、iPad、Mac),并且需要 Safari 或基于 WebKit 的浏览器。务必使用 ApplePaySession.canMakePayments() 有条件地显示 Apple Pay 按钮。

Apple Pay 与 Hosted Fields / HPP 的区别: Apple Pay 是独立的支付流程 — 它不使用 Hosted Fields JS 库或 HPP 表单。它是这些集成的补充,而非替代方案。

[如果有可用的 MCP 连接检查工具,请在此处运行,并在继续之前展示结果。]


快速参考

# Identity service (Bearer token — server-side only)
POST https://identity.uat.payroc.com/authorize
x-api-key: <api-key>

# Apple Pay JS API — provided by Safari / WebKit; there is no script tag to load

# Apple Pay session start — payments-path variant (PREFERRED for new integrations)
# processingTerminalId is a body field; no path parameter needed
POST https://api.uat.payroc.com/v1/payments/apple-pay/sessions
Authorization:  Bearer <token>
Content-Type:   application/json

# Apple Pay session start — terminal-path variant (original; still supported)
POST https://api.uat.payroc.com/v1/processing-terminals/{processingTerminalId}/apple-pay-sessions
Authorization:  Bearer <token>
Content-Type:   application/json

# Payments API (server-side — process the hex-encoded Apple Pay token)
POST https://api.uat.payroc.com/v1/payments
Authorization:  Bearer <token>
Content-Type:   application/json

# Production base URLs (swap when going live — see Completion)
#   identity.payroc.com/authorize   |   api.payroc.com/v1/...

确切的值、枚举集以及请求/响应结构不包含在此区块中 — 请按照各步骤的指引,从 references/ 文件中读取。这是端点的速览图,不能替代参考文件。


参考资料

所有枚举值、架构和 Apple Pay JS API 接口都记录在下方的本地 references/ 文件中—— 此技能依据这些文件生成内容,不使用实时查询或记忆。每个文件负责解答不同类型的问题;用错资料来源是已知的失败模式:

  • references/api-schema.md — Payroc API 中传输的值和结构的权威来源。 字段名称、枚举值、必填字段、请求和响应架构(会话启动和支付请求)。需要了解 Payroc API 字段叫什么 或 接受哪些值 时,请阅读此文件。它是此技能的权威副本。
  • Payroc 叙述指南(本地副本)— 实施方法的权威来源。 如何安排调用顺序、Apple Pay 流程如何与 Payroc 的会话启动和支付端点组合,以及端到端的整体结构。使用这些指南了解 如何组合 集成。
  • Apple 衍生说明(位于本地 references/third-party/ 下)— Apple Pay JS API 的权威来源。 ApplePaySession 构造函数、事件名称(onvalidatemerchant、onpaymentauthorized、oncancel)、方法(canMakePayments、completeMerchantValidation、completePayment)、状态常量和 Apple Pay 支付令牌格式均由 Apple 定义,而非 Payroc。这些说明用我们自己的文字记录了 API 的实际情况。Payroc 叙述指南说明这些内容 如何与 Payroc 端点交互,但不负责定义 Apple API 本身的结构。

如果你想问“如何构造 Payroc 会话启动或支付请求?”,答案在 references/api-schema.md。如果你想问“调用的顺序是什么?”,答案在 Payroc 叙述指南中。如果你想问“ApplePaySession 的构造函数签名是什么?”或“客户授权时会触发哪个事件?”,答案在 Apple 衍生说明中。Payroc 负责其解密端点和 Apple 支付令牌的封装;浏览器端支付界面的一切则由 Apple 负责。

来源本地文件用途
API 架构参考references/api-schema.md所有 Payroc 枚举值、必填字段、请求/响应架构(两种会话启动方式 + 支付)。包含新的 POST /v1/payments/apple-pay/sessions 支付路径端点(新集成首选)和原有的 POST /v1/processing-terminals/{processingTerminalId}/apple-pay-sessions 终端路径端点。
错误响应格式references/error-response-format.md错误封装(RFC 7807)+ Payroc errors[] + 标准错误类型目录
为商户设置 Apple Pay(Payroc 叙述指南)references/set-up-apple-pay-for-a-merchant.md域名验证/Self-Care Portal 设置、获取域名 ID
在集成中添加 Apple Pay(Payroc 叙述指南)references/add-apple-pay-to-your-integration.mdBearer 令牌、会话启动调用、销售流程组合
Apple — ApplePaySession(衍生说明)references/third-party/apple-applepaysession.mdJS API 构造函数、事件/方法名称、状态常量
Apple — Apple Pay 按钮(衍生说明)references/third-party/apple-pay-button.md如何渲染按钮(CSS 与 Web 组件 + SDK 脚本),以及如何正确控制按钮是否可用
Apple — 支付令牌格式(衍生说明)references/third-party/apple-payment-token.md为 Payroc 进行十六进制编码的令牌 JSON 字段名称
Apple — 服务器/商户验证设置(衍生说明)references/third-party/apple-server-setup.md商户验证流程相关事实、域名关联文件

这些文件是本地快照,是此技能的权威资料来源。其来源 URL 和上次同步日期记录在 references/_sources.md 中—— 如果内容看起来过时,请从该文件重新生成。


核心原则

  1. 先检查,再提问——提问前先阅读代码库;根据所发现的内容跳过显而易见的问题,并提出有针对性的问题。
  2. 先提问,再编码——编写实现代码前,通过提问了解未知信息。
  3. 先验证,再推进——当前步骤的检查点通过 UAT 并获得开发者确认前,不要进入下一步。
  4. 阅读参考资料,不要猜测——并为问题选择正确的参考资料。 此集成有 三个 信息来源,而不是两个。针对问题使用错误的来源,会导致记住但错误的值混入实现。
    • Payroc API 架构、字段名称、枚举、必填字段 → references/api-schema.md。 任何传输到 Payroc API 的内容都适用此项。接受特定字符串的字段值(channel、paymentMethod.type、paymentMethod.serviceProvider、币种以及其他枚举类型参数)应来自架构参考资料,而不是训练数据。即使某个字符串听起来合理,只要它不在参考资料中,就会导致 API 错误。
    • 方案、调用顺序、Apple Pay 与 Payroc 的配合方式 → Payroc 叙述指南。“哪个调用先执行?”和“Payroc 对会话启动请求体有何要求?”这类问题应参考指南。
    • Apple Pay JS API 结构、事件名称、方法名称 → references/third-party/ 下 Apple 的派生说明。 ApplePaySession、其构造函数签名、事件处理程序(onvalidatemerchant、onpaymentauthorized、oncancel)、方法(canMakePayments、completeMerchantValidation、completePayment)以及状态常量均由 Apple 定义。Payroc 叙述指南会引用这些内容,但并非其结构的权威来源——如需确认 JS API 的任何细节,请阅读 Apple 的派生说明。
    • 请求和响应架构并不相同——两者都要查。 不要假设 Payroc 响应与 Payroc 请求的结构相同;请在 references/api-schema.md 中分别查询。
    • 不要混淆来源。 channel 属于 Payroc 支付请求,不属于 Apple Pay 会话对象。Apple 的支付网络常量(例如 "visa"、"masterCard")来自 Apple 的派生说明,属于 ApplePaySession 请求,而不是 Payroc 支付请求。每个值都要查阅正确的参考资料。
  5. 逐个值先查阅,再输出。 输出任何枚举值(Payroc:channel、paymentMethod.type、paymentMethod.serviceProvider、币种;Apple:支付网络、商户功能、状态常量)、任何 ApplePaySession 构造函数选项,或 Apple Pay JS API 上的任何事件或方法名称前,都要先从相关的本地参考资料中查阅。不要凭记忆输出。不要把此技能的失败模式提示(见步骤 3、步骤 5、错误分类)当作权威依据——它们的作用是帮助你根据症状识别错误,而不是让你跳过参考资料查阅。听起来合理的英文值是此类错误最常见的形式。
  6. 绝不硬编码凭据——API 密钥和终端 ID 必须来自环境变量或机密管理器,绝不能写入源代码。
  7. 继续前先诊断——如果某个步骤失败,请暂停并根据错误分类排查后再继续。

信息收集

首先,扫描代码库。 查找以下内容:

  • 服务端使用的语言和框架
  • 现有的结账或支付相关路由和处理程序
  • 任何现有的 Payroc 集成(HF 或 HPP)——API 密钥和终端 ID 可能已经配置
  • 环境变量或配置的管理方式
  • 域名是否已为 Apple Pay 配置(.well-known 目录、现有的 Apple Pay JS 代码)

根据查找结果,避免询问你已经可以推断的信息。

然后询问你仍需要了解的内容。至少确认:

问题 1 — Apple Pay 是合适的产品吗?这是新增功能还是独立构建?

Apple Pay(此技能)Hosted FieldsHosted Pages(HPP)
客户体验轻点 Apple Pay 按钮;通过 Face ID / Touch ID 授权——无需输入卡片信息在你自己的表单中输入卡片信息,使用嵌入的 Payroc 小组件重定向到 Payroc 托管的页面完成支付,然后返回你的网站
卡片数据存放位置Apple 钱包;你的服务器会收到加密令牌页面中的 Payroc 小组件Payroc 托管的页面
可用性仅限使用 Safari / WebKit 的 Apple 设备——始终通过 canMakePayments() 进行检查任何现代浏览器任何现代浏览器
此技能✓ 涵盖独立技能独立技能

Apple Pay 是卡片输入方式的补充,而不是替代方案——因为它只适用于 Apple 设备,大多数集成都会同时提供 Hosted Fields 或 HPP,以供其他用户使用。明确这一点后,确认这是新增功能还是独立构建:

  • 将 Apple Pay 添加到现有的 Payroc 集成(HF 或 HPP) → API 密钥和终端 ID 很可能已经配置;重点关注 Apple Pay 专属步骤
  • 全新集成,仅使用 Apple Pay → 从头开始,包括配置凭据

问题 2 — 域名配置状态:

Apple Pay 要求通过 Payroc Self-Care Portal 向 Apple 验证商户域名。询问是否已完成验证,以及开发者是否有域名 ID。

  • 域名已验证,且有域名 ID → 跳过商户配置步骤
  • 尚未完成 → 从步骤 1(商户配置)开始

等待开发者回答后再继续。


先决条件

这些条件是运行和端到端测试 Apple Pay 所必需的,并非编写代码所需。如果开发者已经具备这些条件,那很好。如果没有,也不要停下来:将代码接入环境变量以读取每个值,然后继续构建。开发者可以在测试前提供真实值。

  1. API 密钥 — 用于从 Payroc 的身份服务获取 Bearer 令牌。与 Hosted Fields 使用的是同一凭据;该凭据由 Payroc Integrations 团队提供。
  2. 处理终端 ID — 由 Payroc Integrations 团队提供的 UAT 终端 ID。
  3. 域 ID — 商户通过 Self-Care Portal(见步骤 1)向 Apple 验证域名后返回;每个 Apple Pay 会话请求都需要包含此 ID。代码可以从 APPLE_PAY_DOMAIN_ID 这样的变量读取它。
  4. 在处理终端上启用 Apple Pay — Payroc 必须先为商户的处理终端启用 Apple Pay,之后才能在 Self-Care Portal(步骤 1)中为商户进行设置。请 Payroc Integrations 团队启用此功能。
  5. 可公开访问的 HTTPS 域名 — Apple Pay 域验证需要 Apple 的服务器能够访问相应 URL。localhost 不足以用于验证和实时测试;必须使用暂存或生产域名。这不会阻止编写集成代码,但会阻止验证和测试。

如果缺少任何条件——提醒,但不要阻止。 扫描代码库,查找现有的环境变量命名惯例并沿用;否则,建议使用 PAYROC_API_KEY、PAYROC_TERMINAL_ID 和 APPLE_PAY_DOMAIN_ID 这样的名称。编写代码以从环境中读取这些值,然后明确告知开发者:

⚠️ 我已接入代码,使其从 <VAR names> 读取 API 密钥、终端 ID 和 Apple Pay 域 ID。要实际运行或测试 Apple Pay,你需要 Payroc UAT 终端和 API 密钥(请联系 Payroc Integrations 团队),以及通过可公开访问的 HTTPS URL 验证的域名(步骤 1)。与此同时,我可以继续构建。

主动提出帮助他们获取缺少的条件;如果他们愿意,就继续开发。

检查点

凭据和域名均已确认,或者开发者已了解尚缺少哪些条件、如何获取,以及代码从哪些环境变量读取这些值,并已选择继续。不要对缺少的条件只字不提,但也不要因此阻止开发。


步骤 1 — 为商户设置 Apple Pay

阅读:references/set-up-apple-pay-for-a-merchant.md

开始操作前先阅读该页面。确认参考文档中的确切步骤——但在撰写本文时,步骤如下:

  1. 确认 Payroc 已在商户的处理终端上启用 Apple Pay。否则无法完成设置
  2. 登录 UAT 终端对应的 Self-Care Portal
  3. 前往 Settings → Apple Pay Domains
  4. 下载 Apple Pay 域验证文件
  5. 将文件放在商户域名下的 /.well-known/apple-developer-merchantid-domain-association 路径中(必须可通过 HTTPS 公开访问)
  6. 在门户中添加域名并保存
  7. 记下显示的域 ID——安全存储;每个 Apple Pay 会话请求都需要使用它

必须先确保域验证文件可访问,再在门户中添加域名。 Apple 会在域注册步骤中验证该文件。

这是可以与开发并行进行的门户/托管任务。如果域名尚未验证,不要因此停下来——继续构建会话和支付代码,并使用 APPLE_PAY_DOMAIN_ID 变量;同时提醒开发者,必须完成验证后才能进行 Apple Pay 实时测试。

检查点

保存后,Self-Care Portal 中是否显示域 ID?能否通过 HTTPS 在 /.well-known/ 路径获取验证文件?如果还不能,请将其记为测试时需要完成的事项,并继续构建。


步骤 2 — 进行身份验证:获取 Bearer 令牌

阅读:references/identity-call.md——Bearer 令牌交换的权威参考。不要猜测身份验证端点 URL、请求头名称或响应结构——只输出此文件中记录的内容。 阅读:references/add-apple-pay-to-your-integration.md——Payroc 说明;确认 Bearer 身份验证如何融入 Apple Pay 流程。

开始编写前,请阅读这两份参考资料。根据参考资料,确认:

  • 身份服务端点
  • 必需的请求头及其格式
  • 包含访问令牌的响应字段

实现一个服务端函数,使用 API 密钥向身份服务发送 POST 请求并返回访问令牌。此函数必须在服务端运行——绝不能将 API 密钥发送到浏览器。

检查点

此调用是否返回状态码 200 和 access_token?


步骤 3 — 实现 Apple Pay 按钮和支付界面

开始编写前,请阅读两份参考资料:

  • Payroc 说明(组合方式): references/add-apple-pay-to-your-integration.md——客户端部分。你将在此了解 Payroc 对 JS 事件与服务器之间交互的要求。
  • Apple 的 JS API 接口(结构): references/third-party/apple-applepaysession.md——关于 ApplePaySession 构造函数、每个事件名称、每个方法名称以及每个状态常量的衍生说明。Payroc 说明会按名称引用这些内容,但并非其准确拼写、签名或集合的权威来源。
  • Apple Pay 按钮渲染(结构): references/third-party/apple-pay-button.md——如何实际绘制按钮。这里有两种方法,不能互换:CSS -webkit-appearance: -apple-pay-button 方法(无需脚本)和 <apple-pay-button> Web 组件(必须加载 Apple 的 apple-pay-sdk.js 脚本,否则不会渲染)。此说明还涵盖下方的条件判断陷阱。apple-applepaysession.md 不涉及按钮渲染——请阅读此文件了解相关内容。
在发出 new ApplePaySession(...) 或任何 session.* 调用之前——对照 Apple 派生说明进行确认
  1. 要阅读的内容。 Apple ApplePaySession 派生说明(references/third-party/apple-applepaysession.md)。还要从该说明中确认构造函数所需的 paymentRequest 结构,而不是依赖训练数据。
  2. 要核实的内容。
    • 构造函数签名(new ApplePaySession(version, paymentRequest))以及当前适用的 version 值。
    • 会话实际触发的事件处理程序(onvalidatemerchant、onpaymentauthorized、oncancel 等),以及各事件载荷的确切结构。
    • 会话公开的方法(completeMerchantValidation、completePayment、abort 等)。
    • 状态常量(STATUS_SUCCESS、STATUS_FAILURE,以及你要用于分支判断的其他常量)。
  3. 确认后再发出代码。 为每个事件处理程序使用 Apple 派生说明中记录的确切名称。只调用文档所述接口中的方法。如果你假设某个方法存在,但派生说明中没有记录,不要另造一个名称再试——Apple 可能已将该职责移至其他位置(例如移入某个付款请求属性)。

实现客户端集成:

  1. 检查可用性并渲染按钮——将所有内容放在 ApplePaySession.canMakePayments() 的判断中。仅当此方法返回 true 时才渲染 Apple Pay 按钮;否则显示其他付款方式。阅读 references/third-party/apple-pay-button.md,了解如何渲染按钮——选择一种方案并完整输出:要么使用 CSS -webkit-appearance: -apple-pay-button 按钮(无需加载任何内容),要么使用 <apple-pay-button> Web 组件,并添加其必需的 apple-pay-sdk.js 脚本标签(没有该脚本时,Web 组件不会渲染任何内容)。**确保隐藏操作确实生效:**如果你自己的 CSS 为按钮设置了 display,HTML hidden 属性会被悄然覆盖(作者 CSS 的优先级高于用户代理的 [hidden] 规则),因此要在 JS 中通过 style.display/类切换可见性,或确保按钮的基础 CSS 不设置 display,并确认 ApplePaySession 不存在时按钮确实处于隐藏状态。不要假设 hidden 的优先级高于你的样式表。
  2. 使用所需的 paymentRequest 对象创建 ApplePaySession(包括商户名称、支持的网络、商户能力、国家/地区代码、货币代码和总金额)——从 Apple 派生说明中读取确切的属性名称,包括支持网络常量的拼写(例如 "visa" 还是 "Visa"——对于此技能,以派生说明为准)。
  3. 处理商户验证事件——此事件会在付款表单打开时触发。客户端必须调用你的服务器(例如 POST /checkout/apple-pay/session),并传入事件中的验证 URL。你的服务器调用 Payroc API 启动会话(第 4 步),并返回会话响应。客户端将该响应传给 Apple 文档所述的完成方法(从 Apple 派生说明中读取其确切名称和签名)。
  4. 处理付款授权事件——客户通过 Face ID / Touch ID 授权时会触发此事件。事件包含加密付款数据。客户端将其发送给你的服务器(第 5 步)进行处理,然后使用文档所述的成功/失败状态常量调用文档所述的付款完成方法。
  5. 调用会话的启动方法以显示付款表单(从 Apple 派生说明中读取其确切名称)。
已知的 Apple Pay JS 形态故障模式

列出这些模式是为了便于识别症状——修复方法始终是阅读 Apple 派生说明(references/third-party/apple-applepaysession.md),并按其记录的内容实现,而不是“使用下面的值”。

  • **症状:**假定的处理程序名称始终不会触发;支付表单会打开,但商户验证步骤被悄然跳过。**过去的错误做法:**臆造类似方法调用的写法,例如 session.validateMerchant(),而实际 API 是基于事件的(在 session 上设置 on* 处理程序)。**验证:**派生说明列出了各个事件;请根据文档中的事件名称,将处理程序设为 session 的属性。
  • 症状:completePayment 接受了调用,但表单未能正确关闭,或状态常量被拒绝。**过去的错误做法:**臆造状态常量(例如 STATUS_OK)或使用了错误的参数形式。**验证:**派生说明列出了 ApplePaySession 类导出的状态常量,请使用这些确切名称。
  • **症状:**浏览器端在 session 构造函数或按钮渲染时出现 TypeError。**过去的错误做法:**构造函数参数数量错误,或调用了类中不存在的方法。**验证:**派生说明记录了构造函数签名和完整的方法列表。
  • **症状:**即使在有可用卡片的 Safari 中,Apple Pay 按钮也始终不显示(高度为零或没有图标)。**过去的错误做法:**输出 <apple-pay-button> Web 组件,却未加载 Apple 的 apple-pay-sdk.js 脚本,因此自定义元素从未注册。**验证:**查看 references/third-party/apple-pay-button.md——要么为 Web 组件加载 SDK 脚本,要么改用 CSS -webkit-appearance: -apple-pay-button 方式。
  • **症状:**Apple Pay 按钮在非 Apple 浏览器中也会显示(本应隐藏),尽管门控逻辑设置了 hidden 属性。**过去的错误做法:**作者 CSS 规则为按钮设置了 display,覆盖用户代理的 [hidden] { display: none } 规则,导致门控失效。**验证:**查看 references/third-party/apple-pay-button.md——通过 JS 切换 style.display 或类来控制显示,而不要只依赖 hidden 属性;并确认在 ApplePaySession 不存在时按钮确实处于隐藏状态。
检查点

在 Apple 设备或模拟器上点击按钮时,Apple Pay 支付表单是否会显示?商户验证事件是否会触发?


步骤 4 — 启动 Apple Pay 会话

阅读:references/api-schema.md(applePaySessions 的两个 schema 部分——terminal-path 变体和 payments-path 变体)以及 references/add-apple-pay-to-your-integration.md(会话启动说明)。

不要使用来自训练知识的任何 endpoint URL、字段名或响应结构。在选择实现方案之前,请先阅读 references/api-schema.md 中的两个会话启动 endpoint schema。

目前有两个受支持的 endpoint 可用于启动 Apple Pay 会话——在编写任何代码之前,请阅读 references/api-schema.md,确认每个 endpoint 的确切 schema:

变体EndpointprocessingTerminalId 位置使用时机
Payments-path(新 — 首选)POST /v1/payments/apple-pay/sessions请求体新集成
Terminal-path(原有)POST /v1/processing-terminals/{processingTerminalId}/apple-pay-sessionsURL 路径已在使用此路径的现有集成

对于新集成,请实现 payments-path 变体。对于已在使用 terminal-path 变体的现有集成,无需迁移——两者都受支持。

触发 onvalidatemerchant 时,你的服务器必须调用 Payroc API,与 Apple 验证会话。请从参考资料中确认:

  • 使用哪个 endpoint 变体(以及测试环境和生产环境的确切 URL)
  • 所选变体所需的请求体字段(请阅读 references/api-schema.md 中相关的 schema 部分)
  • 要传回 completeMerchantValidation 的响应对象

Payments-path 变体请求体(从 references/api-schema.md 中的 applePaySessions (payments-path variant) 读取):

  • processingTerminalId — 必填(从 URL 路径移至请求体)
  • appleDomainId — 步骤 1 中的域 ID
  • appleValidationUrl — 事件中的 validationURL,原样传入

Terminal-path 变体请求体(从 references/api-schema.md 中的 applePaySessions (start-session request body) 读取):

  • appleDomainId — 步骤 1 中的域 ID
  • appleValidationUrl — 事件中的 validationURL,原样传入
  • processingTerminalId — 位于 URL 路径中,不在请求体内

两种变体都返回相同的 applePayResponseSession 结构:{ startSessionResponse: "..." }。将未包装的 startSessionResponse 传给 completeMerchantValidation。

实现一个服务器端 endpoint,以便:

  1. 接收来自客户端的 validationURL
  2. 生成(或复用)有效的 Bearer 令牌
  3. 使用正确的请求体字段,向所选的 Payroc 会话启动 endpoint 发送 POST 请求
  4. 将响应体返回给客户端
检查点

completeMerchantValidation 是否成功(未抛出错误)?支付界面是否保持打开并继续显示支付卡?


步骤 5 — 处理支付

此步骤涉及两个来源——Apple 负责事件中加密令牌的格式;Payroc 负责你将 POST 到 /v1/payments 的包装结构和枚举值。请阅读这两份参考资料:

  • Apple Pay 支付令牌格式(Apple 整理的说明): references/third-party/apple-payment-token.md — 授权事件中 payment.token.paymentData 载荷的结构。这些说明记录了令牌的 JSON 结构;你需要先将此 JSON 编码为十六进制,再发送给 Payroc。
  • Payroc 说明与 schema: 组合方式请参阅 references/add-apple-pay-to-your-integration.md,确切的字段名和枚举值请参阅 references/api-schema.md(paymentRequest、paymentMethod 的 digitalWallet 变体)。

不要使用来自训练知识的任何字段名、endpoint URL 或加密数据格式。 两种转换分别对应两个来源:Apple 的令牌格式见 references/third-party/apple-payment-token.md,Payroc 的支付请求结构见 references/api-schema.md。编写代码之前请先阅读两者。 当支付授权事件触发时,事件中包含来自 Apple 的加密支付数据。你的服务器必须:

  1. 从事件中提取加密支付数据(其结构来自 Apple 支付令牌衍生说明,而非训练数据)。
  2. 将其转换为十六进制格式(Payroc API 要求采用此格式——请从 Payroc 叙述性文档中读取确切要求;如果没有明确说明,请检查 references/api-schema.md 中 encryptedData 字段的文档约束)。
  3. 向 Payroc 支付端点发送 POST 请求。要发送的结构(从 references/api-schema.md 中读取)通常类似于:
    • paymentMethod.type — 从 references/api-schema.md 中读取数字钱包的当前枚举值(paymentMethod.type 枚举);不要凭记忆假定为 "digitalWallet"。
    • paymentMethod.serviceProvider — 从 references/api-schema.md 中读取 Apple Pay 的当前枚举值;不要凭记忆假定为 "apple"。
    • paymentMethod.encryptedData — 第 2 步中经过十六进制编码的令牌。
    • 以及标准的 channel、processingTerminalId、order 字段(均须先读取再写入;参见下方的枚举提示)。
    • order.orderId — 为每笔支付生成的唯一标识符,长度限制为 1–24 个字符(从 references/api-schema.md 中读取此约束)。参见下方的 orderId 提示。
  4. 收到 HTTP 201 时 — 使用客户端上文档记录的成功状态常量,调用文档记录的支付完成方法(从 Apple 衍生说明中读取)。
  5. 出现任何错误时 — 使用文档记录的失败状态常量调用同一方法,以便支付界面顺利关闭。

从 references/api-schema.md 中读取 Payroc 的 channel 枚举。 channel 属于 Payroc 支付请求,而不是 Apple Pay 会话。过往已知失败案例(来自同类集成): 某个模型因为 channel: "internet" 听起来适合浏览器内结账,就输出了这个值——Payroc 返回 HTTP 400,错误详情中列出了枚举值。正确做法不是在这里记住正确值,而是在构造请求体时从架构参考中读取 channel。听起来合理的相近值(internet、online、ecommerce、card-not-present)是此类失败最常见的形式。

根据 responseCode 判断支付是否成功,不要猜测 transactionResult.status 的取值子集。 请阅读 references/api-schema.md。批准信号是 responseCode === 'A'(成功响应还包含 approvalCode 和值为 OK 的 responseMessage)。transactionResult.status 表示生命周期状态:当 responseCode 为 A 时,ready(已排队/已捕获)和 pending(已授权,等待捕获——例如预授权或 autoCapture: false)都表示授权成功;declined/expired 等状态则不是,且 approved 不属于该枚举。过往已知失败案例(来自同类集成和基准测试): 某个模型构建了批准状态列表(或只在 "approved" 时分支),因此悄然将真实授权判定为失败。不要凭记忆列举状态集合——成功分支应以 responseCode === 'A' 为依据,并用 status 判断生命周期。应有意处理 E(延迟处理)和 P(部分批准);将 D/R/C 视为拒绝。

确保 order.orderId 不超过 24 个字符。 从 references/api-schema.md 中读取此约束(order.orderId 长度为 1–24)。过往已知失败案例: 某个模型生成了 order-${uuidv4()}(42 个字符)或原始的 crypto.randomUUID()(36 个字符),Payroc 因 HTTP 400 "orderId size must be between 1 and 24" 拒绝了每笔支付,因此成功分支始终无法触发。原始 UUID/GUID 不符合长度限制。请使用始终符合限制的方案:较短的十六进制 ID(例如 crypto.randomBytes(8).toString('hex') → 16 个字符)、加上几个随机字符的 base36 时间戳,或商家自有的短订单号。在完整集成中,orderId 只是众多字段之一,因此很容易出错——务必有意生成符合要求的值。

检查点

支付 API 在 UAT 中是否返回 HTTP 201?Apple Pay 支付界面是否显示成功确认信息?


本地测试策略

Apple Pay 有两项 localhost 无法满足的可访问性要求——上文已分别介绍,这里汇总起来以便查阅:

  • 需要一台装有 Wallet 卡片的真实 Apple 设备或模拟器,并使用 Safari / WebKit,才能显示按钮并呈现支付界面(否则 canMakePayments() 会返回 false——参见错误分类)。
  • 需要一个可公开访问的 HTTPS 域名来进行域名验证(前提条件和第 1 步):Apple 的服务器会直接获取 /.well-known/apple-developer-merchantid-domain-association 文件,因此无法验证 localhost。请使用暂存域名,或使用可通过 HTTPS 提供验证文件的隧道(ngrok、VS Dev Tunnels、Cloudflare Tunnel),并在 Self-Care Portal 中注册该域名。

此流程中没有入站 Webhook——唯一需要公开可访问的是域名关联文件。


错误分类

症状可能原因解决方法
Apple Pay 按钮始终不显示canMakePayments() 返回 false在已将卡片添加到 Wallet 的 Apple 设备或模拟器上测试;如果配对的 iPhone 已启用 Apple Pay,macOS 上的 Safari 也可以使用
即使在已添加卡片的 Apple 设备上,Apple Pay 按钮也只显示为空白(高度为零/没有图标)使用了 <apple-pay-button> Web 组件,但没有加载 Apple 的 apple-pay-sdk.js 脚本,因此自定义元素从未注册阅读 references/third-party/apple-pay-button.md;添加 apple-pay-sdk.js 脚本标签,或改用 CSS -webkit-appearance: -apple-pay-button 方案
Apple Pay 按钮在非 Apple 浏览器上可见(本应隐藏)作者 CSS 规则为按钮设置了 display,覆盖了用户代理的 [hidden] { display: none } 规则,导致隐藏条件失效阅读 references/third-party/apple-pay-button.md;通过在 JS 中切换 style.display/类名来控制显示,或避免在按钮的基础 CSS 中设置 display;确认在 ApplePaySession 不存在时按钮确实处于隐藏状态
Payments API 返回 400 "orderId size must be between 1 and 24"order.orderId 超过 24 个字符——通常是原始 uuidv4()/crypto.randomUUID()(36 个字符)或带前缀的 UUID阅读 references/api-schema.md 中对 order.orderId 的 1–24 个字符限制;使用始终符合限制的方案(短十六进制字符串、base36 时间戳加短随机字符串,或较短的商户订单号)
onvalidatemerchant 触发,但 completeMerchantValidation 抛出异常会话启动 API 调用失败,或响应不是原始 Apple 会话对象记录完整的 Payroc 响应;确认直接将响应正文(而非包装后的对象)传递给 completeMerchantValidation
会话启动返回 404端点 URL 错误,或路径中的 processingTerminalId 不正确(终端路径变体)重新查阅 references/api-schema.md 中的端点 URL;确认终端 ID 是 UAT 终端
会话启动返回 400,错误提示缺少 processingTerminalId使用 Payments 路径变体(POST /v1/payments/apple-pay/sessions),但请求正文中未包含 processingTerminalId——此端点不再将其用作路径参数阅读 references/api-schema.md(Payments 路径变体架构);将 processingTerminalId 添加到请求正文中
会话启动返回 400appleDomainId 或 appleValidationUrl 缺失或无效在 Self-Care Portal 中确认域名 ID;确认 validationURL 未经修改,直接从事件传入
在 Self-Care Portal 中域名验证失败无法通过 HTTPS 访问验证文件确认文件路径准确为 /.well-known/apple-developer-merchantid-domain-association,且没有扩展名;添加域名之前,先用 curl 测试
Payment API 返回 401Bearer 令牌已过期,或 API 密钥错误重新获取 Bearer 令牌;验证 x-api-key 的值
Payment API 返回 400encryptedData 不是十六进制格式,或缺少必填字段重新查阅 encryptedData 格式要求;检查 Apple 支付数据转换为十六进制格式的过程是否正确
Payment sheet 在 STATUS_SUCCESS 后显示失败Payment API 返回的状态不是 201,却被错误地当作成功处理仅将 HTTP 201 分支视为成功;其他所有状态均视为失败
Payments API 返回 HTTP 400,错误详情中指出 "channel"(或其他枚举类型字段),并列出可接受的值输出了非枚举值(同类集成过去曾出现:channel: "internet"、"online"、"ecommerce");用听起来合理的近似值替代了文档中的值从 references/api-schema.md 中查阅 channel(或相关字段),并输出列出的值之一。不要根据英语表达是否合理来推断枚举值。
Payroc API 拒绝 paymentMethod.type 或 paymentMethod.serviceProvider技能输出了训练数据中记住的 digitalWallet/apple 值,而不是从 references/api-schema.md 中查阅所得的值从 references/api-schema.md 中查阅当前的 paymentMethod.type 和 paymentMethod.serviceProvider 枚举,并输出其中列出的值。即便记住的值碰巧正确,不查阅参考资料本身也是造成问题的原因。
Apple Pay 会话构造函数抛出 TypeError,或 on<event> 处理程序从未被调用构造函数签名或事件名称取自训练数据,而非 Apple 衍生说明;自行假定的名称与文档所述的接口不符阅读 Apple 的 ApplePaySession 衍生说明(references/third-party/apple-applepaysession.md)。确认构造函数签名、要绑定的每个事件名称以及要调用的每个方法。不要杜撰或重命名——如果衍生说明中没有你假定的名称,说明 Apple 已将相应职责移至其他位置。
应用记录了支付失败,但银行实际上已批准——Payroc 响应显示 responseCode: "A",并带有 approvalCode/OK 消息成功分支根据猜测的 transactionResult.status 子集进行判断(过去曾出现的问题:只接受 "approved"——它甚至不是枚举成员;或批准状态列表遗漏了 pending 等已授权状态)根据 references/api-schema.md,以 responseCode === 'A' 作为成功分支条件;将 ready 和 pending 视为已授权状态,而 status 仅表示生命周期。不要凭记忆列出批准状态。

验证清单

  • 从环境变量读取 API 密钥和终端 ID,而不是写在源代码中
  • 在服务器端生成 Bearer 令牌,而不是暴露给浏览器
  • 仅当 ApplePaySession.canMakePayments() 返回 true 时才渲染 Apple Pay 按钮,并验证 Apple Pay 不可用时按钮确实隐藏(不能让作者 CSS 覆盖 hidden 属性,从而绕过门控)
  • 通过有文档说明的方式绘制 Apple Pay 按钮:CSS -webkit-appearance: -apple-pay-button,或使用 <apple-pay-button> 并加载其 apple-pay-sdk.js 脚本标签
  • order.orderId 生成的字符数为 1–24,而不是原始 UUID/GUID
  • 域名验证文件可通过 HTTPS 在 /.well-known/apple-developer-merchantid-domain-association 访问
  • 安全存储域名 ID(环境变量或配置),而不是硬编码
  • onvalidatemerchant:将 validationURL 从事件原样传递给服务器;将服务器响应原样传递给 completeMerchantValidation
  • onpaymentauthorized:在发送到 Payroc API 之前,将加密数据转换为十六进制格式
  • 使用 Apple Pay 测试交易时,支付 API 在 UAT 中返回 HTTP 201
  • 支付 API 响应后,使用正确的状态调用 session.completePayment()

反模式

无条件渲染 Apple Pay 按钮——它会在非 Apple 设备或非 Safari 浏览器上静默失败。务必使用 canMakePayments() 进行门控。

使用 hidden 属性进行门控,同时 CSS 强制按钮显示——作者 CSS(例如 .apple-pay-button { display: block })会覆盖用户代理的 [hidden] { display: none } 规则,因此即使门控设置了 hidden,按钮仍会显示。改为在 JS 中切换 style.display 或类,并验证缺少 ApplePaySession 时按钮确实隐藏。请参阅 references/third-party/apple-pay-button.md。

使用 <apple-pay-button> Web 组件,却不加载其 SDK 脚本——只有加载 https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js 后,才会注册此自定义元素;否则按钮不会渲染任何内容。请加载该脚本,或使用 CSS -webkit-appearance: -apple-pay-button 方式。请参阅 references/third-party/apple-pay-button.md。

将原始 UUID 用于 order.orderId——uuidv4()/crypto.randomUUID()(36 个字符)及带前缀的变体都会超过 1–24 个字符的限制,导致 Payroc 以 HTTP 400 拒绝支付。请使用始终符合限制的方案。

修改 validationURL——应将其从 Apple 事件中原样传递。任何修改(编码、去除首尾空格)都会导致商户验证失败。

包装会话启动响应——Apple 的 completeMerchantValidation 需要 Payroc API 返回的原始会话对象。不要再将其包装进另一个对象,也不要再次进行 JSON 编码。

在支付 API 响应前调用 completePayment(STATUS_SUCCESS)——务必等待 Payroc API 响应后再调用 completePayment。提前调用会使会话处于未定义状态。

硬编码域名 ID——UAT 与生产门户中的域名 ID 不同;请从环境变量读取。


完成

确认 HTTP 201 且所有检查项均已通过后:

**集成完成。**你已完成以下工作:

  • 域名验证 — 你的域名已通过 Self-Care Portal 在 Apple 注册;域名 ID 用于授权会话请求。
  • 商户验证 — Apple Pay 支付界面打开时,你的服务器会调用 Payroc,与 Apple 验证会话;客户将获得可信赖的支付体验。
  • 支付处理 — 客户通过 Face ID / Touch ID 授权;你的服务器会将加密的支付数据转换为十六进制,并将其发送到 Payroc 支付端点。
  • 已在 UAT 中验证 — 已确认 Apple Pay 端到端交易。

**上线前:**将会话启动调用和支付 API 调用中的 UAT 端点 URL 替换为生产环境 URL(api.uat.payroc.com → api.payroc.com)。如果使用 payments-path 变体,请将 https://api.uat.payroc.com/v1/payments/apple-pay/sessions → https://api.payroc.com/v1/payments/apple-pay/sessions。在生产环境的 Self-Care Portal 中注册生产域名,并获取其域名 ID。

可提供的后续步骤:

  • Google Pay — 将 Google Pay 添加为并行的数字钱包选项;流程类似,但使用 Google Pay JS API 和不同的 serviceProvider 值
  • Hosted Fields — 如果开发者还需要为非 Apple 用户提供银行卡信息输入表单作为备用方案,请使用 Hosted Fields 技能

评论

支持 Markdown