金融与交易
在 VTEX IO 上实现支付连接器(Payment…
当你要在 VTEX IO 上开发或维护一个 Payment Provider Framework(PPF)支付连接器时,按此流程完成依赖固定、配置校验、路由注册、Secure Proxy 分流与上线测试。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 VTEX IO 上实现支付连接器(P特定
解决思路
- 从官方 Payment Provider Framework 文档描述的示例应用起步,按 Payment Provider Protocol 文章和「Integrating a new payment provider on VTEX」指南完成实现前置条件。
- 在 node 文件夹的 package.json 中加入 @vtex/payment-provider(如 1.x);把 @vtex/api 放在 devDependencies(如 6.x),link 时被升到 6.x 以上可接受;若类型报错,删除项目根目录和 node 下的 node_modules 与 yarn.lock,再在两处分别执行 yarn install -f。
- 在 manifest.json 的 builders 中加入 "paymentProvider": "1.x"(与 node 并列),以便应用 Payment Gateway 回调与 PPP 路由的 policy。
- 在 paymentProvider/configuration.json 中声明 paymentMethods,名称匹配 List Payment Provider Manifest API 参考;只有确实是新方法时才自创名称,Admin 中的新方法可能需要开 support ticket。
- 用 PaymentProvider 子类为每个 PPP 路由实现一个类方法,让 TypeScript 强制校验请求/响应形状(参见 API 参考的 Payment Flow endpoints)。
- 用 PaymentProviderService 注册默认路由 /manifest、/payments、/settlements、/refunds、/cancellations、/inbound;需要时再传额外的 routes / clients。
- 仅在获得批准的使用场景下覆盖 /manifest(需开 ticket),参考 Preferred pattern 中的路由覆盖示例。
- 可配置项通过 configuration.json / builder options 设置:implementsOAuth、implementsSplit、usesProviderHeadersName、usesBankInvoiceEnglishName、usesSecureProxy、requiresDocument、acceptSplitPartialRefund、usesAutoSettleOptions;设置 name,IO 上依赖自动生成的 serviceUrl,除非文档另有说明;不要自创字段(如 usesTestSuite 会导致 builder 校验错误)。
- 在协议要求重试的地方调用 this.retry(request),不要用自定义重试绕过框架。
- 卡片数据流程:优先使用 SecureExternalClient 并传入来自 Create Payment 的 secureProxy: secureProxyUrl,目标地址必须在 VTEX 白名单内;Secure Proxy 仅支持 application/json 和 application/x-www-form-urlencoded 两种 Content-Type。
- 注意只有 Create Payment(authorize)请求携带 secureProxyUrl;cancel、capture、refund 不传输卡片数据,必须用 ExternalClient 携带凭证并配合 outbound-access policy 直接调用 PSP API。
- 测试前先让账号被允许使用 IO 连接器(提交含 app 名称与账号的 ticket);发布 beta、安装到 master、等待约 1 小时、打开 affiliation URL、启用 test mode 与 workspace、配置支付条件(约 10 分钟)、下测试订单,然后再发 stable 并做 homologation。
- 按 Billing Options 指南配置 billingOptions,并通过 Submitting your app 提交;按「Integrating a new payment provider on VTEX」准备 homologation 材料(连接器 app 名称、合作方联系人、生产端点、允许的账号、新方法/流程),SLA 通常约 30 天。
- 更新时先发新 beta、重测 affiliation,再发 stable;如需要则重新 homologation。
- TS 3.9.7 兼容:禁止使用模板字面量类型(4.1)、catch 子句类型标注(4.0)、override 关键字(4.3)、import type ... = require()(4.5)、satisfies 运算符(4.9)。
- catch 块使用兼容写法:catch (error) { const err = error as any; console.log(err.message) },不要写 catch (error: any)。
- 未使用变量在 builder-hub 中是编译错误而非警告:不要解构用不到的字段,例如只取 const { paymentId, value } = authorization。
- 在 node/package.json 中用 resolutions 固定传递依赖到不含现代 .d.ts 语法的版本,并用 **/<package> 模式固定嵌套副本;安全版本包括 @types/node 12.20.55、@types/express-serve-static-core 4.17.2、@types/express 4.17.10、@types/serve-static 1.15.0、@opentelemetry/api 1.0.4、**/@types/koa 2.15.0。
- 若构建在 node_modules 的 .d.ts 中报错,从错误路径定位包,逐个测试更旧版本直到找到不含现代语法的版本,并同时加入 devDependencies 和 resolutions(含 **/<package> 模式)。
- configuration.json 只使用规范字段:name(必填)、serviceUrl(IO 上自动)、implementsOAuth、implementsSplit、usesProviderHeadersName、usesBankInvoiceEnglishName、usesSecureProxy、requiresDocument、acceptSplitPartialRefund、usesAutoSettleOptions、paymentMethods、customFields;不要使用 usesTestSuite 等会破坏构建的字段。
- customFields 中 select 类型的 options 必须用 text 和 value 键,绝不能用 label。
- manifest.json 必须包含 paymentProvider builder,且 configuration.json 的 name 不能是占位符(如 "MyConnector"),paymentMethods 必须准确。
- node/index.ts 必须通过 PaymentProviderService 包装继承 PaymentProvider 的类来注册 PPP 路由,不要手写同样的路由面。
- 向 PaymentProviderService 传 clients 时必须用 { implementation: Clients, options: { default: { retries, timeout } } } 形式,不能直接传类。
- 项目文件结构:根目录放 manifest.json、service.json;paymentProvider/configuration.json;node/ 下放 package.json、tsconfig.json、yarn.lock、index.ts、connector.ts、clients/(index.ts、psp.ts、pspSecure.ts)、typings/。
- node/ 下的 yarn.lock 是必需的,builder 缺它会拒绝构建,且不要把它加入 .vtexignore;service.json 放在项目根目录而不是 node/ 内;configuration.json 放在 paymentProvider/ 内。
- manifest.json 中按需声明 policy:vbase-read-write(使用 VBase 时必需,否则 vbase.saveJSON() 返回 403)以及针对 PSP 主机的 outbound-access(如 api.psp.com、api.sandbox.psp.com)。
- tsconfig.json 使用 target es2019、module commonjs、lib es2019、strict false、esModuleInterop true、skipLibCheck true;注意 builder-hub 会覆盖 outDir、rootDir、paths,且忽略 skipLibCheck,需靠 resolutions 控制依赖类型版本。
- 在 clients/index.ts 中用 IOClients 的 getOrSet 注册自定义客户端,例如 psp 与 pspSecure。
- 在连接器中通过 this.context.vtex.account / this.context.vtex.workspace 访问账号与 workspace(IOContext 嵌套在 .vtex 下,不是 this.context.account);自定义 clients 需要类型断言;VBase 可直接通过 this.context.clients.vbase 访问。
- 使用自定义路由时在项目根目录的 service.json 中注册(如 routes.myCallback.path 与 public: true);PPF builder 会把自己的 PPP 路由与你的路由合并,无需重复声明标准 PPP 路由。
- 凭证通过 affiliation 自动映射:X-PROVIDER-API-AppKey → this.apiKey,X-PROVIDER-API-AppToken → this.appToken;this.isTestSuite 表示是否为测试交易;customFields 中的自定义设置可从各请求的 authorization 对象获取(具体访问方式取决于 PPF 版本)。
- 使用 PPF 响应 helper 时注意自动填充:Authorizations.approve 自动填 paymentId;Authorizations.deny 自动填 paymentId 且不要传 nsu;Settlements.approve 自动填 paymentId 与 value,第二个参数只传 settleId;Refunds.approve 自动填 paymentId 与 value,第二个参数只传 refundId。
- 当 approveCard 的严格类型缺少 delayToCancel 时,用展开加类型断言:先取 Authorizations.approve(...) 的 baseResponse,再 { ...baseResponse, delayToCancel, delayToAutoSettle, delayToAutoSettleAfterAntifraud } as any 返回。
- PSP 集成前先打开 PSP 的 API Explorer / OpenAPI spec,确认各环境 base URL;不要在 baseURL 与操作路径间重复版本或路径段(如 base 为 https://checkout-test.psp.com/v71 时路径用 /payments 而非 /v71/payments);在收尾前先用测试调用(如创建支付)验证。
- 若 PSP 需要 OAuth token,实现内存缓存,因为 VTEX Gateway 某些流程有 2 秒超时,顺序的 token + API 调用会超时;缓存时用 expiresIn - 300 秒提前过期。
- 测试时使用 affiliation URL:https://{account}.myvtex.com/admin/affiliations/connector/Vtex.PaymentGateway.Connectors.PaymentProvider.PaymentProviderConnector_{connector-name}/,其中 {connector-name} 为 ${vendor}-${appName}-${appMajor}(如 vtex-payment-provider-example-v1)。
- 上线前替换所有示例 vendor 名、端点和凭证为真实应用的值。
- 用 vtex link 的 watch 模式查看完整编译错误,不要用 --no-watch 隐藏错误;不要在 master workspace 上 vtex link,改用开发 workspace(vtex use dev-workspace)。
适用边界 · 注意事项
- 不要用于 PPP HTTP 契约、逐字段响应要求与九个抽象端点(改用 payment-provider-protocol 技能)。
- 不要用于幂等性与重复 paymentId 处理(改用 payment-idempotency 技能)。
- 不要用于异步 undefined 状态、callbackUrl 通知与重试(IO vs 非 IO)以及重定向流程(改用 payment-async-flow 技能),也不要用它处理超出 IO 接线的 PCI 规则、日志与 token 语义(改用 payment-pci-security 技能)。