mcpField
I
integrate-hosted-payment-pages

integrate-hosted-payment-pages

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

关于 integrate-hosted-payment-pages

这是一个指导开发者集成 Payroc Hosted Payment Page 的技能,覆盖一次性销售、预授权和重复扣款。它以本地参考文件为字段、枚举和 API 形状的依据,并包含可选的后台验证 Webhook 指引。

主要功能

  1. 01集成 Hosted Payment Page 支付流程
  2. 02处理销售与预授权
  3. 03配置保存卡片及重复扣款
  4. 04参考本地 API 模式和字段说明
  5. 05实现可选后台验证 Webhook

适用场景

  1. 01为网站接入 Payroc 托管支付页
  2. 02先授权后调用捕获 API
  3. 03保存卡片并设置订阅扣款
  4. 04验证服务器到服务器通知

安装

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

$npx skills add https://github.com/payroc/skills --skill integrate-hosted-payment-pages

安装后在 Claude Code 中输入/integrate-hosted-payment-pages确认已加载。

包含的文件

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

references/
_sources.md
api-schema.md
authenticate-your-requests.md
build-receipt-page.md
error-response-format.md
identity-call.md
implement-background-validation.md
load-hosted-payment-page.md
pre-auth.md
recurring.md
repeat-payments-api-schema.md
sale.md
references/save-payment-details/
authenticate-your-requests.md
build-receipt-page.md
load-hosted-payment-page.md

详细介绍

# Payroc Hosted Pages 集成

范围:CNP(无卡支付)Hosted Pages — 单次销售交易、预授权,以及定期计费(在 Hosted Page 上保存客户的银行卡,然后通过 Payroc 的网关订阅或您自己的商户发起扣款进行重复扣款)。

版本检查(请先执行)

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

  1. 从上方 frontmatter 的 metadata.version 字段读取此技能的版本。
  2. 获取已发布的副本并读取其 metadata.version: https://raw.githubusercontent.com/payroc/skills/main/plugins/payroc/transaction/skills/integrate-hosted-payment-pages/SKILL.md
  3. 将两个版本按语义化版本进行比较:
    • 此版本 >= 已发布版本 → 静默继续,不发送消息。(开发者运行尚未发布的较新版本是预期情况,且没有问题。)

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

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

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

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


首次调用时,向开发者说明:

Payroc Hosted Pages 集成 我将指导您完成从凭据设置到成功执行 UAT 测试交易的全过程。 本指南涵盖通过 Payroc Hosted Payment Page 进行的无卡支付——销售交易、预授权(现在冻结资金,稍后请款),以及定期计费(保存银行卡以供日后使用,然后按计划或按需扣款)。

HPP 的工作原理(分为三个部分):

  1. 您的结账流程向 Payroc 的 HPP 端点提交 POST 请求——这会加载支付页面
  2. 客户在 Payroc 托管的页面上完成付款(或保存银行卡)
  3. Payroc 将客户的浏览器重定向回您的收据 URL,并在查询参数中附加交易详情

注意:还有一个可选的 Background Validation webhook——Payroc 服务器向您配置的单独 URL 发送的服务器端 POST 请求。这是扩展步骤,不属于上述主要流程。

HPP 与 Hosted Fields: 如果您需要将银行卡输入控件嵌入自己的表单,且不进行页面重定向,则应使用 Hosted Fields——这是本技能未涵盖的另一款产品。如果开发者似乎在询问嵌入式银行卡表单,请指出这一点。

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


快速参考

实施任何 REST API 调用(请款、订阅、MIT 付款)时,请阅读 references/identity-call.md,了解 Bearer 令牌交换详情。不要猜测身份端点 URL、标头名称或响应结构——只能使用参考文档中说明的内容。

# Identity service (Bearer token — used for REST APIs: capture, repeat payments)
# UAT/test: identity.uat.payroc.com · Production: identity.payroc.com (note: UAT has the .uat segment, prod does not)
POST https://identity.uat.payroc.com/authorize
x-api-key: <api-key>

# Hosted Payment Page — sale (form POST, loads the payment page)
POST https://payments.uat.payroc.com/merchant/paymentpage
Content-Type: application/x-www-form-urlencoded

# Hosted Payment Page — pre-auth (form POST)
POST https://payments.uat.payroc.com/merchant/preauthpage

# Hosted Payment Page — save a card / tokenize (form POST; ACTION=register|update)
POST https://payments.uat.payroc.com/merchant/securecardpage

# Capture API (pre-auth only)
POST https://api.uat.payroc.com/v1/payments/{uniqueRef}/capture
Authorization:  Bearer <token>
Content-Type:   application/json

# Repeat payments — gateway path (Bearer token)
POST https://api.uat.payroc.com/v1/processing-terminals/{terminalId}/payment-plans
POST https://api.uat.payroc.com/v1/processing-terminals/{terminalId}/subscriptions

# Repeat payments — your-own-software / MIT path (Bearer token; paymentMethod.type=secureToken)
POST https://api.uat.payroc.com/v1/payments

参考资料

所有值和结构都位于下方本地 references/ 文件中——本技能只依据这些文件生成内容,不依赖实时查询,也不依赖记忆。这里有三个互补的信息来源,各自负责不同类型的问题——对问题使用错误的信息来源是已知的失败模式:

- **API 架构引用**(`references/api-schema.md`、`references/repeat-payments-api-schema.md`)——**Payroc JSON API 中各项值和结构的事实来源**:`api-schema.md` 涵盖预授权的捕获 API,以及 `transactionResult` 架构(包括 `responseCode` 和 `status` 枚举);`repeat-payments-api-schema.md` 涵盖 Secure Tokens、Payment Plans 和 Subscriptions 资源,以及商户发起扣款时 Payments 的 `secureToken` / `standingInstructions` 结构。有关 REST API 侧的枚举和架构问题,请查阅这些文件。 - **HPP 说明指南**(`references/authenticate-your-requests.md`、`references/load-hosted-payment-page.md`、`references/build-receipt-page.md`,以及 `references/save-payment-details/` 下的保存卡片变体)——**HPP 表单 POST 界面的事实来源**:HMAC 字段顺序和算法、AMOUNT 和 DATETIME 格式、POST 字段名称和可接受的枚举值(PAYMENTMETHOD、ACTION、STOREDCREDENTIALUSE、country、language 等),以及回执回调查询参数结构(包括 `RESPONSECODE` 和 `CARDREFERENCE`)。HPP 表单 POST **不**在 OpenAPI 规范中;这些说明文档是权威来源。**保存卡片流程有其专属副本**,因为它的端点、哈希计算方法、表单字段和回执 `RESPONSECODE` 枚举都与销售流程不同。 - **后台验证指南**(`references/implement-background-validation.md`)——**服务器到服务器 webhook 的事实来源**:已提交字段的名称、签名验证。

如果你的问题是“捕获 API 请求正文是什么样的,以及会返回哪些 transactionResult 值?”——请查阅 references/api-schema.md。如果你的问题是“要设置订阅或使用已保存的令牌执行商户发起扣款,需要哪些端点/字段/枚举?”——请查阅 references/repeat-payments-api-schema.md。如果你的问题是“HPP 表单 POST 中需要哪些字段,哈希计算方法是什么?”——请查阅 HPP 说明文档(保存卡片流程请查阅 save-payment-details/ 下的副本)。如果你的问题是“回执回调可以携带哪些 RESPONSECODE 值?”——销售/预授权请查阅 references/build-receipt-page.md,保存卡片请查阅 references/save-payment-details/build-receipt-page.md(不要依赖记忆中的列表,即使本技能列举了示例也一样)。

来源本地文件用途
API 架构参考references/api-schema.md交易 API、transactionResult 架构,以及任何 Payroc REST API 字段/枚举
错误响应格式references/error-response-format.md错误封装(RFC 7807)+ Payroc errors[] + 标准错误类型目录
重复付款 API 架构references/repeat-payments-api-schema.mdSecure Tokens、Payment Plans、Subscriptions 端点/枚举;Payments secureToken + standingInstructions(MIT)
身份验证(HMAC 字段顺序、AMOUNT/DATETIME 格式)references/authenticate-your-requests.mdSale/预授权哈希方案——权威来源
加载托管支付页面(POST 字段 + 枚举)references/load-hosted-payment-page.mdSale/预授权 HPP 表单 POST 字段名称和可接受的枚举值——权威来源
构建收据页面(RESPONSECODE 枚举 + 收据回调字段)references/build-receipt-page.mdSale/预授权收据回调查询参数——RESPONSECODE 值及其他收据字段的权威来源
保存卡片——身份验证references/save-payment-details/authenticate-your-requests.md保存卡片(注册/更新)哈希方案——权威来源(不含 AMOUNT;使用 MERCHANTREF + ACTION)
保存卡片——加载页面references/save-payment-details/load-hosted-payment-page.md保存卡片表单 POST——securecardpage 端点、ACTION、STOREDCREDENTIALUSE(大写)——权威来源
保存卡片——收据references/save-payment-details/build-receipt-page.md保存卡片收据回调——CARDREFERENCE、STOREDCREDENTIALTXTYPE、A/E14/E43/E44 RESPONSECODE 枚举——权威来源
Sale 流程(步骤 2–4)references/sale.mdSale 流程(读取上述叙述性副本以核验字段/枚举)
预授权流程(步骤 2–4)references/pre-auth.md预授权流程(读取叙述性副本 + api-schema.md 以了解 capture)
定期付款流程(保存卡片 + 重复付款)references/recurring.md定期付款流程(读取 save-payment-details/ 副本 + repeat-payments-api-schema.md)
后台验证references/implement-background-validation.mdWebhook 验证流程
Bearer 令牌交换(REST API 调用)references/identity-call.md身份服务端点 URL、x-api-key 标头、响应结构——capture + 订阅身份验证的权威来源

这些是本技能的本地快照,也是权威来源。其源 URL 和最后同步日期记录在 references/_sources.md 中——如果内容看起来已过时,请从那里重新生成。


核心原则

  1. 先检查,再提问 — 提问前先阅读代码库;利用查到的信息跳过显而易见的问题,并提出有针对性的问题。
  2. 先提问,再编码 — 编写实现代码前,通过提问了解未知事项;错误的假设会浪费开发者的时间。
  3. 先验证,再推进 — 在开发者确认当前步骤的检查点通过 UAT 前,不要进入下一步。
  4. 阅读参考资料,不要猜测——并为问题选对参考资料。 HPP 有 三个 源信息面,而非两个——针对问题使用了错误的参考资料,就会让记忆中看似正确、实际错误的值混入内容。第 1 步的哈希规则已经严格遵守了这一原则;请将其推广到其他每一步。
    • HPP 表单 POST 和收据回调(PAYMENTMETHOD、RESPONSECODE、AMOUNT/DATETIME 格式、哈希字段顺序)→ HPP 说明文档副本。 这些内容属于表单 POST 信息面,references/api-schema.md 中没有。references/authenticate-your-requests.md、references/load-hosted-payment-page.md、references/build-receipt-page.md 这几个说明文档副本是权威来源。输出表单 POST 字段或根据收据回调值进行分支判断前,先阅读相关说明文档副本。
    • Capture API 及其他 Payroc REST API 信息面 → references/api-schema.md;重复付款 REST 信息面 → references/repeat-payments-api-schema.md。 预授权的 capture 端点、transactionResult 架构(包括完整的 responseCode 和 status 枚举值)位于 api-schema.md 中。Secure Tokens / Payment Plans / Subscriptions 端点以及 Payments 的 secureToken + standingInstructions 结构位于 repeat-payments-api-schema.md 中。字段名、枚举值、必填字段、请求/响应结构。
    • 保存卡片流程是销售流程的同级流程,不是销售流程加一个字段。 它的端点(/merchant/securecardpage)、哈希规则(TERMINALID:MERCHANTREF:DATETIME:ACTION:SECRET — 不含 AMOUNT,使用 MERCHANTREF + ACTION)、表单字段(ACTION、STOREDCREDENTIALUSE)、收据字段(CARDREFERENCE、STOREDCREDENTIALTXTYPE)以及收据 RESPONSECODE 枚举(A/E14/E43/E44)都有所不同。请从 references/save-payment-details/ 中查阅;切勿原样套用销售流程的规则。
    • 不同信息面中,储存凭证使用方式的大小写不同。 HPP 表单 POST 使用大写 STOREDCREDENTIALUSE(RECURRING);REST API 使用小写 mitAgreement / processingModel(recurring)。请根据所在信息面使用相应大小写。
    • 订阅依赖于预先创建的付款计划和安全令牌。 在网关流程中,先创建 Payment Plan,再创建将计划关联到令牌的 Subscription(令牌是 HPP CARDREFERENCE)。计划尚不存在时,不要 POST 订阅。
    • 步骤顺序、验证模式 → 流程文件。 何时调用验证端点、以何种顺序验证 webhook 签名、收据重定向如何与后台验证配合、保存卡片→重复付款的顺序。流程文件(sale.md、pre-auth.md、recurring.md)涵盖流程;api-schema.md / repeat-payments-api-schema.md 涵盖 JSON-API 侧的值;HPP 说明文档副本涵盖表单 POST 侧的值。
    • 请求和响应架构并不相同 — 需要响应结构(例如 capture 响应、订阅响应)时,请单独查阅,不要从请求架构推断响应结构。
    • 不要类比推断枚举值。 看似合理但不在文档枚举中的字符串会导致 API 错误。第 1 步中“不要使用训练知识中的任何算法名称”这一要求适用于所有值 — PAYMENTMETHOD、RESPONSECODE 分支、transactionResult.status、capture 响应代码等,不只是哈希规则。
  5. 逐个值先查阅,再输出。 输出任何 POST 字段枚举值(PAYMENTMETHOD、国家、语言)、任何 RESPONSECODE 分支、任何 capture API 枚举(transactionResult.status、transactionResult.responseCode)或任何哈希输入字段名之前,先阅读相关本地参考资料(表单 POST 值请查阅 HPP 说明文档副本;capture 和 transactionResult 请查阅 references/api-schema.md)。不要将本技能中的示例(例如表示批准的 RESPONSECODE=A、表示拒绝的 RESPONSECODE=D)视为完整列表——它们只是示例,并非权威清单。参考资料记载了完整列表;不阅读参考资料,就无法知道完整列表。
  6. 绝不硬编码凭证 — 终端 ID、密钥和 API 密钥必须来自环境变量或密钥管理器,不得写入源代码。
  7. 先诊断,再继续 — 如果某个步骤失败,请暂停,并先根据错误分类法排查。

初步了解

首先,扫描代码库。 查找:

  • 服务端使用的语言和框架
  • 现有的结账、订单或支付相关路由和处理程序
  • 任何部分实现的 HPP(哈希函数、向支付 URL 提交表单、收据端点)
  • 环境变量或配置的管理方式
  • 订单或交易的标识方式(以便了解 ORDERID 策略)

利用你发现的信息,避免询问可以推断出的内容,并用开发者自己的术语提出后续问题。然后询问仍需了解的信息——不要想当然。

在继续之前,至少要得到以下三个路由问题的答案:

问题 1 — 集成类型:

Hosted Pages(托管页面)Hosted Fields(托管字段)
客户体验客户会暂时离开你的网站,在 Payroc 托管页面上付款,然后返回客户始终留在你的网站上——Payroc 卡片输入控件嵌入你自己的表单中
你的收据页面接收带有查询参数的浏览器 GET 重定向完全不同的流程
本技能✓ 此处涵盖阶段 2 — 尚未涵盖
  • Hosted Pages → 继续使用本技能
  • Hosted Fields → 尚未涵盖;说明其中的区别,并提出改用 Hosted Pages 继续,或停止

问题 2 — 定期扣款 / 保存卡片: 此集成是否需要保存客户的卡片以供后续使用,或进行定期 / 订阅 / 分期付款?

  • 否 → 继续使用下方的一次性 CNP 流程(销售和/或预授权)。

  • 是 → 这是定期扣款流程,分为两个阶段:在 Hosted Page 上保存卡片(令牌化 → 获取 CARDREFERENCE),然后进行重复付款。询问他们想采用哪种重复付款方式:

    • 使用 Payroc 的网关 — Payroc 保存计划并收取付款(Payment Plans + Subscriptions)。适合希望由 Payroc 管理账单周期的情况。
    • 使用他们自己的软件 — 他们的系统使用已保存的令牌安排并执行每笔商户发起的扣款(POST /payments,其中 paymentMethod.type: secureToken)。适合他们已有账单逻辑的情况。

    如果涉及定期扣款,下面的步骤 1–3 将变为保存卡片方案,并新增步骤 5 — 设置重复付款。到达步骤 1 时,阅读 references/recurring.md。

问题 3 — 交易类型: 此集成是否需要预授权(现在冻结资金,稍后扣款)、标准销售(立即授权并扣款),或两者都需要?

  • 仅销售 → 继续使用下方的标准流程
  • 预授权或两者都需要 → 注意,收据处理程序之后需要额外的 Capture 步骤,并确认商户账户支持预授权(双重定价、附加费计划或便利费均不支持)。到达步骤 2 时,除标准步骤外,还要阅读 references/pre-auth.md。

确认以上三项需求后,继续阅读“先决条件”。


前置条件

这些条件是运行和测试 UAT 集成所需的,不是编写代码所需的。如果开发者已经具备这些条件,那很好。如果没有,也不要停下:让代码从环境变量读取各项值(并从配置读取回执 URL),然后继续开发。开发者可以在测试前补齐所有信息。

  1. 终端 ID — Payroc Integrations 团队分配的 UAT 终端 ID。UAT 是 Payroc 的测试环境;凭据由团队手动提供(没有自助注册)。
  2. 终端密钥 — 在 Self-Care Portal 中为该 UAT 终端创建。
  3. 回执 URL — 应用中的一个 URL,Payroc 的 HPP 会在付款后将客户的浏览器重定向到该 URL,并附加交易详情作为查询参数。由于这是浏览器重定向(而不是 Payroc 服务器发起的调用),测试此步骤时可以正常使用 localhost。要使实时测试中的重定向成功,必须先在 Self-Care Portal 中为 UAT 终端注册该 URL,但你现在就可以构建回执处理路由,并从配置中读取 URL。

如果缺少任何信息,请提醒,不要因此阻塞开发。 检查代码库中是否已有环境变量命名规范,并遵循该规范;否则,可以使用 PAYROC_TERMINAL_ID、PAYROC_TERMINAL_SECRET 和 PAYROC_RECEIPT_URL 等名称。编写代码,从环境变量/配置中读取这些值,然后告知开发者还有哪些事项待办以及如何处理:

  • 终端 ID/UAT 访问权限 → 联系 Payroc Integrations 团队。
  • 终端密钥 → 获得 UAT 访问权限后,在 Self-Care Portal 中创建。
  • 回执 URL → 现在确定路由并构建处理程序;在测试实时重定向前,在 Self-Care Portal 中注册该 URL(并参考本地测试部分了解隧道方案)。

此时请询问其他所需信息,例如 UAT 凭据是否已存放在某处,或者是否有现成的结账处理程序可供修改,而不是从头编写。

如果开发者已确认终端凭据(例如,环境变量或配置中可见终端 ID 和密钥),请指出回执 URL 是实时测试前仍需注册的主要事项,但仍应针对配置的 URL 构建回执处理程序,而不是等待 URL 确认。

检查点

终端 ID、终端密钥和回执 URL 均已确认;或者开发者已了解待办事项、获取/注册方式,以及代码从哪些环境变量和配置中读取这些值,并已决定继续。不要对缺失事项只字不提,但也不要因此阻塞开发。

步骤 1 — 验证请求

阅读与你的流程对应的参考资料:

  • 销售 / 预授权: references/authenticate-your-requests.md
  • 保存卡片(定期付款): references/save-payment-details/authenticate-your-requests.md — 先阅读 references/recurring.md,了解完整的保存卡片 → 重复付款流程顺序。

此步骤中,不要使用训练知识中的任何算法名称、格式字符串或字段名称。请从与你的流程对应的本地参考资料中读取每个值——哈希算法、AMOUNT 格式、DATETIME 格式和字段顺序。

定期付款:保存卡片的哈希计算方式不同。 格式为 TERMINALID:MERCHANTREF:DATETIME:ACTION:SECRET — 不包含 AMOUNT,使用 MERCHANTREF 替代 ORDERID,并额外包含 ACTION。请复现该参考资料中的示例哈希,而不是销售交易的示例。直接照搬销售交易的哈希函数会导致所有保存卡片请求失败。

开始编写之前,请完整阅读参考资料。根据资料确认并使用:

  • 哈希算法
  • 哈希输入字符串中的确切字段及其顺序
  • AMOUNT 格式 — 请仔细阅读;这一点并不明显,格式错误会导致每个请求都失败,并返回晦涩的错误信息
  • DATETIME 格式及其时区要求
  • 用于验证的示例哈希 — 继续之前必须准确复现该哈希

使用开发者所用的语言和框架实现哈希函数。立即使用参考资料中提供的输入值对照示例进行测试。示例哈希是一份精确规范——如果你的函数无法与其匹配,说明存在错误。

检查点

哈希函数是否准确复现了参考资料中的示例哈希?如果没有,请先根据错误分类进行诊断,再继续。


步骤 2 — 加载托管支付页面

阅读与你的交易类型对应的参考资料:

  • 销售: references/sale.md — 步骤 2
  • 预授权: references/pre-auth.md — 步骤 2
  • 保存卡片(定期付款): references/recurring.md — 阶段 A,步骤 2(使用 ACTION 和 STOREDCREDENTIALUSE 向 /merchant/securecardpage 发送表单 POST)

对每个 POST 字段的枚举值,都遵循步骤 1 的做法。 正如编写哈希函数之前要先阅读验证请求的参考资料,在输出任何枚举类型的值之前,也要先阅读说明 HPP 表单 POST 字段的正文文档(销售 / 预授权:references/load-hosted-payment-page.md;保存卡片:references/save-payment-details/load-hosted-payment-page.md)——包括 PAYMENTMETHOD、ACTION、STOREDCREDENTIALUSE、国家、语言,以及任何其他只能接受特定字符串集合的字段。不要使用训练知识中的任何枚举值。已知的过往故障(来自其他集成): 模型输出了 channel: "internet",因为该值听起来适用于浏览器内结账——网关在错误详情中返回枚举列表并拒绝了请求。这种故障最常见的形式,就是使用听起来合理但实际不符的值(例如 internet、online、ecommerce、card-not-present);输出前请先阅读说明可接受值的参考资料。保存卡片提示: 此处的 STOREDCREDENTIALUSE 必须大写;端点是 securecardpage,而不是 paymentpage。

注意: HPP 的响应不包含交易类型。如果你的集成处理销售、预授权和 / 或保存卡片,请在提交 HPP 表单之前,在你自己的订单模型中记录交易类型。

检查点

提交表单后,浏览器是否会无错误地跳转到 Payroc UAT 页面(销售 / 预授权对应支付页面,保存卡片对应安全卡片页面)?如果没有,请先诊断,再继续。

第 3 步 — 构建收据页面

阅读与你的交易类型对应的参考文档:

  • 销售: references/sale.md — 第 3 步
  • 预授权: references/pre-auth.md — 第 3 步(收据响应与销售相同;UNIQUEREF 的持久化存储要求仍然适用)
  • 保存卡片(定期付款): references/recurring.md — 阶段 A,第 3 步(收据不同:需存储 CARDREFERENCE;A/E14/E43/E44 RESPONSECODE 枚举;单独的 Secure Token URL;响应哈希顺序不同)

将第 1 步的规范应用于 RESPONSECODE 分支判断和其他收据回调枚举。 编写处理程序前,先阅读收据说明文案——销售/预授权请看 references/build-receipt-page.md,保存卡片请看 references/save-payment-details/build-receipt-page.md。不要根据记忆中的部分 RESPONSECODE 值进行分支判断——本技能的错误分类中,A / D / R / C 是销售示例,并非权威全集;保存卡片的枚举则完全不同(A/E14/E43/E44,其中 A 表示“已存储”)。销售参考文档列出了 A 以外的批准代码(例如 E);参考文档才是权威依据。已知的过往失败模式: 将 RESPONSECODE == 'A' 视为唯一成功情况,因为权威集合比记忆中的值更大,导致真实批准被错误归类。请阅读参考文档,并依据其中记载的集合进行分支判断。

定期付款:持久化存储 CARDREFERENCE。 这是用于重复扣款的安全令牌——请将它(以及 MERCHANTREF)持久化到数据库中,切勿存入 session/TempData。信任响应前,请验证响应哈希(保存卡片的顺序:TERMINALID:RESPONSECODE:RESPONSETEXT:MERCHANTREF:CARDREFERENCE:DATETIME:SECRET)。

检查点

收据处理程序是否收到 Payroc 重定向、无错误地验证响应哈希,并正确解析收据字段(销售/预授权为 RESPONSECODE + UNIQUEREF;保存卡片为 RESPONSECODE + CARDREFERENCE,且已持久化存储)?如果没有,请先排查问题再继续。


第 4 步 — 测试交易

  • 销售: references/sale.md — 第 4 步
  • 预授权: 使用相同的销售测试流程(references/sale.md 中的步骤 1–5),然后还需: 6. 使用已存储的 UNIQUEREF 触发 capture 调用 7. 确认 HTTP 200,且响应正文中包含 transactionResult

对于预授权 capture:编写成功分支前,请先阅读 references/api-schema.md 中的 transactionResult 架构。 transactionResult.status 和 transactionResult.responseCode 都是枚举。已知的过往失败(来自同类集成): 模型仅在 status == "approved" 时进行分支判断,因实际值为 "ready"(已授权并排队等待 capture),且 responseCode: "A" / responseMessage: "APPROVAL",导致真实批准被错误地视为失败。请阅读完整的 transactionResult.status 枚举,找出所有与银行批准对应的值,并依据完整集合进行分支判断——不要根据记忆中的部分值编写成功检查。

对于保存卡片(定期付款),第 4 步的里程碑是“卡片已成功保存”——保存卡片的收据中 RESPONSECODE=A,并且已捕获及存储 CARDREFERENCE。然后继续执行第 5 步,设置实际的重复付款。

检查点

是否已通过测试卡确认 RESPONSECODE=A,且响应哈希验证通过?(预授权:capture 是否也返回 HTTP 200,且已根据完整枚举验证 transactionResult 成功分支?保存卡片:是否已捕获并持久化存储 CARDREFERENCE?)如果没有,请使用错误分类。在满足所有条件前,不要标记为完成。


第 5 步 — 设置重复付款(仅限定期付款)

如果集成不需要定期计费,请跳过此步骤。请阅读:references/recurring.md — 阶段 B,以及 references/repeat-payments-api-schema.md,了解所有端点、字段和枚举值。

此阶段使用基于 Bearer 令牌的身份验证调用 REST API(与预授权捕获相同,需从身份服务获取令牌),而不是 HPP HMAC 哈希。请选择开发者在需求收集阶段选定的路径:

  • 使用 Payroc 的网关 — 创建一个 Payment Plan(POST .../payment-plans),然后创建一个 Subscription(POST .../subscriptions),其 paymentMethod 为 { "type": "secureToken", "token": "<CARDREFERENCE>" }。网关会按计划自动扣款(automatic),或者由你通过 .../pay 扣款(manual)。
  • 使用他们自己的软件(MIT) — 每次扣款都使用 POST /payments,设置 paymentMethod.type: secureToken 和令牌,并添加 order.standingInstructions 区块(sequence:先为 first,然后为 subsequent;processingModel:unscheduled/recurring/installment)。

请根据具体值阅读对应的参考文档。 计划/订阅的枚举值(type、frequency — 注意 fortnightly/yearly、onUpdate、onDelete)以及 MIT 的 standingInstructions / channel 枚举值均见 references/repeat-payments-api-schema.md。请勿类比推断。还要注意大小写变化:表单中的协议为大写 STOREDCREDENTIALUSE;这里则是小写的 mitAgreement / processingModel。

创建订阅前,必须先创建对应的付款计划(以及令牌)。 请先创建计划,再创建订阅。令牌已存在,即 HPP 的 CARDREFERENCE。

检查点

网关路径:订阅是否已创建,并且 UAT 中的 currentState.status 是否为 active(如适用,manual /pay 是否成功)?MIT 路径:首次扣款是否返回 HTTP 200,且 transactionResult 的成功分支已根据 references/api-schema.md 中的完整枚举值验证(实际获批时可能为 status: "ready",responseCode: "A")?在生成端点/枚举值前,是否已阅读重复付款架构文档?如果没有,请参阅错误分类。


本地测试策略

步骤 1–3(哈希生成、HPP 重定向和收据页面 — 适用于销售、预授权和保存卡)都可以在 localhost 上测试。收据重定向由客户的浏览器触发,Payroc 的服务器不会直接调用收据 URL,因此无需满足可访问性要求。(保存卡使用单独的 Self-Care 字段 Secure Token URL 进行重定向 — 使用 localhost 仍然可行。)

**步骤 4 捕获(预授权)和步骤 5 重复付款(定期付款)**是应用向 Payroc 发起的服务器到服务器 REST 调用,因此也可以在 localhost 上运行 — 只需从身份服务获取 Bearer 令牌(x-api-key → access_token),而非 HMAC 哈希。这些操作不需要公共 URL 或隧道。

从后台验证开始的后续步骤需要公共 URL。Payroc 的服务器会向验证 Webhook 端点发送 POST 请求,因此 localhost 无法使用。可选方案如下,按从最简单到最稳健的顺序排列:

  • webhook.site — 在 Self-Care Portal 中将 webhook.site URL 注册为临时验证 URL;它会捕获原始 POST 请求,方便你在编写处理程序前检查确切的响应字段。即使之后计划使用隧道,这也是很好的第一步。
  • VS Dev Tunnels(内置于 Visual Studio 和 VS Code)— 对 .NET 应用来说是自然的选择;只需少量设置,即可创建一个持久的公共 HTTPS URL,并通过隧道连接到本地端口。
  • ngrok — 与语言无关,设置快捷,免费套餐可用于开发。
  • Cloudflare Tunnel — 更适合使用时间较长的环境。
  • 部署到预发布主机 — 如果无法使用隧道,请部署到任意可通过 UAT 访问的主机并在那里测试。

请将所用的公共 URL 注册到 Self-Care Portal 中,作为 UAT 终端的后台验证 URL(这是与收据 URL 不同的字段)。


错误分类

症状可能原因修复方法
重定向后立即收到来自 HPP 的错误哈希无效重新阅读 references/authenticate-your-requests.md;检查 AMOUNT 格式、DATETIME 格式和时区,以及字段顺序;根据参考文档中的示例哈希重新测试
RESPONSECODE=D交易被拒绝在 UAT 中属于预期情况 — 请使用 Payroc 测试卡
RESPONSECODE=R转介 — 客户应联系银行在 Phase 1 测试中将其视为拒绝
RESPONSECODE=C卡已报告丢失或被盗请换用其他测试卡
应用记录了失败,但实际上获批了 — RESPONSECODE 的值不是 A(过往出现过:E)收据页面分支将 RESPONSECODE == 'A' 视为唯一成功情况,并在未提示的情况下错误归类了其他获批结果阅读 references/build-receipt-page.md,了解完整的 RESPONSECODE 枚举。找出与银行批准结果相对应的所有值,并针对这些完整值进行分支处理 — A 只是示例,并非规范集合。
预授权:捕获 API 返回 HTTP 200,但应用记录了失败 — 响应显示 responseCode: "A" / responseMessage: "APPROVAL"服务端成功检查基于记忆中的 transactionResult.status 子集进行分支处理(过往故障:仅接受 "approved";将已授权且已排队等待捕获的 "ready" 默默当作失败处理)阅读 references/api-schema.md 中的 transactionResult.status 枚举,并针对与银行批准结果相对应的所有值进行分支处理。
付款后未重定向到收据页面收据 URL 未在 Self-Care Portal 中注册,或注册时有拼写错误收据结果通过浏览器 GET 重定向(查询参数)传递 — 而非服务端 POST。本地主机地址有效。最可能的原因是 URL 未注册或在 Self-Care Portal 中有拼写错误。请确认该 URL 与 UAT 终端注册的 URL 完全一致。
响应哈希验证失败验证哈希中的字段或顺序错误重新阅读 references/build-receipt-page.md;确认参与哈希计算的响应字段及其顺序完全正确
字段正确,但哈希仍不匹配字符编码或空白字符所有哈希输入都必须是纯 ASCII;检查任何字段值中是否包含 Unicode 字符、尾随空格或换行符
调用捕获 API 时出现 404UNIQUEREF 无效或预授权已过期验证 UNIQUEREF 与收据响应中的值一致;请注意,预授权有由发卡机构定义的保留期限,超时后会过期
调用捕获 API 时出现 409预授权已捕获尝试捕获前请检查订单状态;不要重试已完成的捕获
调用捕获/重复付款 API 时出现 401Bearer 令牌已过期或 API 密钥错误重新生成 Bearer 令牌;确认与身份服务搭配使用的 x-api-key 值
保存卡:重定向后立即收到来自 HPP 的错误,或哈希不匹配保存卡时重用了销售哈希配方(保留了 AMOUNT、使用了 ORDERID,或遗漏了 ACTION),或提交到了 paymentpage 而非 securecardpage重新阅读 references/save-payment-details/authenticate-your-requests.md;配方为 TERMINALID:MERCHANTREF:DATETIME:ACTION:SECRET(不含 AMOUNT)。确认端点为 /merchant/securecardpage。
保存卡:网关拒绝 STOREDCREDENTIALUSE(或 REST 拒绝 mitAgreement/processingModel)对应接口的大小写格式错误HPP 表单 POST 使用大写(RECURRING);REST API 使用小写(recurring)。请阅读与你所调用接口相对应的参考文档。
保存卡:收据处理程序始终未触发保存卡重定向注册在错误的 Self-Care 字段中保存卡收据使用独立于销售/预授权收据 URL 的 Secure Token URL 字段。请确认已在该字段中注册。
保存卡:应用记录了失败,但卡已保存使用了销售的 RESPONSECODE 集合进行分支处理,而非保存卡的集合阅读 references/save-payment-details/build-receipt-page.md:保存卡枚举为 A/E14/E43/E44;A = 已保存。
创建订阅时出现 4xx付款计划或安全令牌尚不存在,或 paymentPlanId/token 错误请先创建付款计划;将 paymentMethod 设为 { "type": "secureToken", "token": "<CARDREFERENCE>" }。阅读 references/repeat-payments-api-schema.md。
使用令牌的 MIT 付款被拒绝/顺序错误缺少 standingInstructions,或 sequence/processingModel 错误首次付款使用 sequence: first,后续付款使用 sequence: subsequent 和 referenceDataOfFirstTxn。如果发送 credentialOnFile.mitAgreement,则必须在 order 中发送 standingInstructions。
重复付款 REST 调用拒绝 channelchannel 值无效(例如 internet/online/ecommerce)PaymentRequestChannel 的取值为 pos/web/moto — 请阅读 references/repeat-payments-api-schema.md,不要类比推断。

验证清单

  • 终端 ID 和密钥从环境变量读取,而非写在源代码中
  • 收据 URL 已在 Self-Care Portal 中注册,且可公开访问
  • 已根据 references/authenticate-your-requests.md 中的示例哈希验证哈希函数
  • 加载 HPP 时已提供所有必需的 POST 字段
  • 在信任任何响应数据前,先验证响应哈希
  • 已在 UAT 中使用测试卡确认 RESPONSECODE=A
  • 已捕获并存储 UNIQUEREF
  • (仅预授权)已在订单模型中记录交易类型 — HPP 响应不包含该信息
  • (仅预授权)已将 UNIQUEREF 持久化到持久存储(数据库/订单记录),而非会话或 TempData
  • (仅预授权)已在 UAT 中测试 Capture API — 已确认 HTTP 200 和 transactionResult
  • 每个 POST 字段的枚举值(PAYMENTMETHOD、国家/地区、语言等)均从 references/load-hosted-payment-page.md 中读取,而非来自训练数据或此技能的示例
  • RESPONSECODE 分支涵盖 references/build-receipt-page.md 中列出的所有批准值 — 而非仅使用记忆中的子集(例如只有 A)
  • (仅预授权)Capture 响应的成功分支对 transactionResult.status 的处理涵盖 references/api-schema.md 枚举中的所有批准值(例如 "ready")
  • (仅保存卡片)已根据 references/save-payment-details/authenticate-your-requests.md 中的示例哈希验证哈希函数 — 此算法不包含 AMOUNT,且包含 ACTION
  • (仅保存卡片)表单 POST 到 /merchant/securecardpage;STOREDCREDENTIALUSE 使用大写
  • (仅保存卡片)收据分支使用保存卡片的 RESPONSECODE 集合(A/E14/E43/E44),且 CARDREFERENCE 已持久化到持久存储(而非会话/TempData)
  • (仅保存卡片)保存卡片的重定向 URL 已在 Self-Care 的 Secure Token URL 字段中注册
  • (仅周期性付款)已保存凭据使用方式的大小写形式与相应接口一致 — 表单中使用大写,REST API 中使用小写的 mitAgreement/processingModel
  • (仅周期性付款,网关)已在创建订阅前创建付款计划;订阅的 paymentMethod 为 { type: secureToken, token: <CARDREFERENCE> };已在 UAT 中确认 currentState.status 为 active
  • (仅周期性付款,MIT)首笔扣款使用 standingInstructions(sequence: first);后续扣款使用 sequence: subsequent 和 referenceDataOfFirstTxn;channel 是有效的枚举值
  • (仅周期性付款)重复付款的端点、字段和枚举值均从 references/repeat-payments-api-schema.md 中读取,而非凭记忆填写

反模式

将终端 ID 或密钥硬编码——凭据写入源代码后会留存在版本历史中,最终可能泄露。

跳过示例哈希验证——如果哈希函数有任何细微错误(字段顺序错误、AMOUNT 格式错误、时区错误),每笔交易都会失败。references/authenticate-your-requests.md 中的示例哈希是一项契约;在处理其他内容之前,先用它验证。

未验证响应哈希就信任 RESPONSECODE——如果不先验证哈希,攻击者可以伪造包含 RESPONSECODE=A 的 POST 请求,欺骗你的收据页面。

不存储 UNIQUEREF——没有它,你就无法退款或执行后续交易。

想当然地处理 AMOUNT 格式——正确格式已有文档说明,但并不显而易见。请仔细阅读。格式错误会导致每个请求的哈希都无效。

将 UNIQUEREF 存储在会话或 TempData 中——对于预授权集成,UNIQUEREF 必须在当前请求结束后仍然可用;临时存储会导致用户离开页面或会话过期后无法完成扣款。

认为第 1 步中“不要使用任何训练知识中的值”的要求只适用于第 1 步。 这项防护措施并非只针对哈希计算规则,而是适用于集成所输出或据此分支处理的所有文档值。POST 字段枚举(PAYMENTMETHOD)、RESPONSECODE 分支、扣款 API 的 transactionResult.status 值:每一项都有对应的本地参考文档(表单和收据相关内容请查阅 HPP 说明副本;扣款相关内容请查阅 references/api-schema.md)。在输出或据此分支处理值之前,请先阅读相关参考文档。哈希计算规则只是在早期迭代中最明显的失败点。

根据对枚举的片面印象编写成功判断。 这是 RESPONSECODE 和 transactionResult.status 判断失败背后的共同错误:凭记忆推断枚举值,或只参考此技能中的示例,而不阅读本地参考文档。每个授权判断都必须列出与银行授权对应的全部值,而不只是 A 或某个单独的状态值。

将销售哈希函数用于保存卡片。 保存卡片的计算规则是 TERMINALID:MERCHANTREF:DATETIME:ACTION:SECRET——不包含 AMOUNT,使用 MERCHANTREF 而不是 ORDERID,并且还要包含 ACTION。直接沿用销售哈希会导致每个保存卡片请求都因哈希错误而失败,且错误信息晦涩难懂。(这与想当然地处理 AMOUNT 格式属于同一类错误。)

在保存卡片/令牌化时收取 AMOUNT。 保存卡片是金额为 $0 的令牌化操作,而非销售交易——securecardpage 表单中没有 AMOUNT 字段。如果你发现自己在保存卡片请求中构造金额,说明你把它与销售流程混淆了。

将 CARDREFERENCE 存储在会话或 TempData 中。 安全令牌必须在当前请求结束后长期保留——下个月要向客户收费就要用到它。请将其持久化到可靠存储中,就像预授权的 UNIQUEREF 一样。

在付款计划(及令牌)创建之前调用 Subscriptions。 订阅会将计划关联到令牌,因此两者都必须先存在。使用 HPP 保存卡片时,令牌(CARDREFERENCE)已经存在;因此,先创建计划,再创建订阅。

混淆不同界面中已存储凭据的大小写。 HPP 表单使用大写的 STOREDCREDENTIALUSE;REST API 使用小写的 mitAgreement/processingModel。它们描述的是同一项协议,但网关会拒绝大小写与当前界面不匹配的值。


完成

确认 RESPONSECODE=A 且所有检查项均通过后:

集成完成。 以下是你已构建的内容:

  • 身份验证哈希 — 使用你的终端密钥为每个付款请求签名,防止篡改。
  • 结账处理程序 — 组装付款表单,并将其 POST 到 Payroc 的 Hosted Payment Page。
  • 收据处理程序 — 接收 Payroc 的浏览器重定向(包含查询参数的 GET 请求),验证响应哈希,根据完整的 RESPONSECODE 审批集合进行分支处理,并获取 UNIQUEREF。
  • 已在 UAT 中验证 — 已使用测试卡确认端到端交易。
  • 预授权 + 捕获(如适用)— 结账时冻结资金;准备结算时通过 REST API 捕获;UNIQUEREF 用于关联这两次调用;捕获响应分支涵盖完整的 transactionResult.status 审批集合。
  • 定期扣款(如适用)— 通过 securecardpage 在 Hosted Page 上保存卡片(使用独立的哈希计算方式和收据),持久化存储 CARDREFERENCE,并通过 Payroc 的网关(Payment Plan + Subscription)或你自己的商户发起扣款(secureToken + standingInstructions)设置重复付款,且已在 UAT 中验证。

上线前: 将 UAT 端点 URL 替换为生产 URL — 这适用于 HPP 端点(paymentpage / preauthpage / securecardpage)以及所有 REST 端点(capture、payment-plans、subscriptions、payments)— 请在参考资料中确认这些 URL。将凭据指向生产终端,确认收据 URL(如果保存卡片,也包括 Secure Token URL)已在生产 Self-Care Portal 中注册,并移除所有测试卡号。

后续步骤:

  • 后台验证 Webhook — 每笔交易都会触发服务器到服务器的 POST,与收据重定向相互独立;可用于对账,并在重定向失败时作为备用方案
  • 管理定期扣款生命周期(如适用)— 更新、停用或重新启用订阅,更新已保存的卡片(ACTION=update 或安全令牌更新端点),并处理逾期付款催收
  • Hosted Fields(第 2 阶段)— 将 Payroc 托管的卡片输入组件嵌入你自己的表单中;无需页面重定向

评论

支持 Markdown