Payment Provider Framework
Apply when designing or implementing a Payment Connector in VTEX IO. Covers PPF implementation, TypeScript 3.9.7 builder-hub constraints and safe dependency resolutions, configuration.json schema validation, PaymentProviderService clients wiring, Secure Proxy scope (authorize-only), ExternalClient vs SecureExternalClient patterns, IOContext access, PPF response helpers, PSP integration checklist, and vtex link debugging. Use for any implementation of a Payment Connector hosted in VTEX IO.
- Skill ID
- vtex/skills/payment-provider-framework
- Publisher
- vtex
- Repository
- skills
- Installs
- 0
- Files
- 1
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
vtex/skills/payment-provider-frameworkInstalls these files- SKILL.md
What this skill tells the agent
Payment Provider Framework (VTEX IO)
When this skill applies
Use this skill when:
- Creating or maintaining a payment connector implemented as a VTEX IO app (not a standalone HTTP service you host yourself)
- Wiring
@vtex/payment-provider,PaymentProvider, andPaymentProviderServiceinnode/index.ts - Configuring the
paymentProviderbuilder,configuration.json(payment methods,customFields, feature flags) - Implementing
this.retry(request)for Gateway retry semantics on IO - Extending
SecureExternalClientand passingsecureProxyon requests for card flows on IO - Testing via payment affiliation, workspaces, beta/stable releases, the VTEX App Store, and VTEX homologation
Do not use this skill for:
- PPP HTTP contracts, response field-by-field requirements, and the nine endpoints in the abstract — use `payment-provider-protocol`
- Idempotency and duplicate
paymentIdhandling — use `payment-idempotency` - Async
undefinedstatus,callbackUrlnotification vs retry (IO vs non-IO) — use `payment-async-flow` - PCI rules, logging, and token semantics beyond IO wiring — use `payment-pci-security`
Decision rules
- PPF on IO: "Payment Provider Framework is the VTEX IO–based way to build payment connectors." The app uses IO infrastructure; API routes, request/response types, and Secure Proxy are integrated per VTEX guides. Start from the example app described in the official Payment Provider Framework documentation.
- Prerequisites: Follow implementation prerequisites in the Payment Provider Protocol article and the guide on integrating a new payment provider on VTEX.
- Dependencies: In the app
nodefolder, add@vtex/payment-provider(for example1.xinpackage.json). Keep@vtex/apiindevDependencies(for example6.x); linking may bump it beyond6.x, which is acceptable. If types break, deletenode_modulesandyarn.lockin the project root and innode, then runyarn install -fin both. - `paymentProvider` builder: In
manifest.json, include"paymentProvider": "1.x"next tonodeso policies for Payment Gateway callbacks and PPP routes apply. - `configuration.json`: Declare
paymentMethodsso the builder can implement them without re-declaring everything on/manifest. Use names matching the List Payment Provider Manifest API reference; only invent a new name when the method is genuinely new. New methods in Admin may require a support ticket. - `PaymentProvider`: One class method per PPP route; TypeScript enforces shapes — see Payment Flow endpoints in the API reference.
- `PaymentProviderService`: Registers default routes
/manifest,/payments,/settlements,/refunds,/cancellations,/inbound; pass extraroutes/clientswhen needed. - Overriding `/manifest`: Only with an approved use case — open a ticket. See the Preferred pattern section for an example route override shape.
- Configurable options: Use
configuration.json/ builder options for flags such asimplementsOAuth,implementsSplit,usesProviderHeadersName,usesBankInvoiceEnglishName,usesSecureProxy,requiresDocument,acceptSplitPartialRefund,usesAutoSettleOptions. Setnameand rely on auto-generatedserviceUrlon IO unless documented otherwise. Do not invent fields — unknown keys (such asusesTestSuite) cause builder validation errors. See the "configuration.json schema" constraint below for the canonical list andcustomFieldsformat. - Gateway retry: In PPF, call
this.retry(request)where the protocol requires retry — see the Payment authorization section in the PPP article. - Card data on IO: "Prefer
SecureExternalClientwithsecureProxy: secureProxyUrlfrom Create Payment; destination must be allowlisted." SupportedContent-Typevalues for Secure Proxy:application/jsonandapplication/x-www-form-urlencodedonly. Important: only the Create Payment (authorize) request carriessecureProxyUrl. Post-authorization operations (cancel, capture, refund) do not transport card data and must call the PSP API directly viaExternalClientwith credentials andoutbound-accesspolicies. - Checkout testing: Account must be allowed for IO connectors (ticket with app name and account). Publish beta, install on
master, wait ~1 hour, open affiliation URL, enable test mode and workspace, configure payment condition (~10 minutes), place test order; then stable + homologation. - Publication: Configure
billingOptionsper the Billing Options guide; submit via Submitting your app. Prepare homologation artifacts (connector app name, partner contact, production endpoint, allowed accounts, new methods/flows) per the Integrating a new payment provider on VTEX guide (SLA often ~30 days). - Updates: Ship changes in a new beta, re-test affiliations, then stable; re-homologate if required.
Hard constraints
Constraint: Builder-Hub uses TypeScript 3.9.7 — code and dependencies MUST be compatible
The vtex.builder-hub compiles IO apps with TypeScript 3.9.7. It also ignores `skipLibCheck: true` in tsconfig.json — every .d.ts file in node_modules is type-checked. This means that even if your own code is valid, a transitive dependency shipping modern .d.ts syntax will break the build with hundreds of errors unrelated to your code.
Why this matters
Agents and developers regularly produce code with TS 4.x+ syntax or install the latest @types/* packages. The build fails with cryptic errors in files the developer never touched, causing many wasted iterations.
Prohibited syntax (incompatible with TS 3.9.7)
| Syntax | Minimum TS version | Example |
|---|---|---|
| Template literal types | 4.1 | ` type X = ${string}/${string} ` |
| Typed catch clause | 4.0 | catch (error: any) |
override keyword | 4.3 | override method() in classes |
import type ... = require() | 4.5 | import type X = require("pkg") |
satisfies operator | 4.9 | obj satisfies Type |
Correct catch block pattern
// CORRECT — TS 3.9.7 compatible
try {
// ...
} catch (error) {
const err = error as any
console.log(err.message)
}
// WRONG — TS 4.0+ only
try {
// ...
} catch (error: any) {
console.log(error.message)
}Unused variables are errors, not warnings. The builder-hub treats declared-but-unused variables as compilation errors. Avoid destructuring fields you do not use:
// WRONG — if callbackUrl is not used, build fails
const { paymentId, callbackUrl, value } = authorization
// CORRECT
const { paymentId, value } = authorizationSafe dependency versions (compatible with TS 3.9.7)
Use resolutions in node/package.json to pin transitive dependencies to versions that do not ship modern .d.ts syntax. The **/<package> pattern pins nested copies too.
{
"dependencies": {
"@vtex/payment-provider": "1.x"
},
"devDependencies": {
"@vtex/api": "6.50.1",
"@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",
"typescript": "3.9.7"
},
"resolutions": {
"@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/express-serve-static-core": "4.17.2",
"**/@types/koa": "2.15.0"
}
}| Package | Safe version | First broken version | Reason |
|---|---|---|---|
@types/node | 12.20.55 | 13.x+ (some APIs) | Modern syntax in .d.ts |
@types/express-serve-static-core | 4.17.2 | 4.17.13+ | Template literal types |
More from vtex
Use this skill in a project
Open any RiverX project, search the Skills panel for vtex/skills/payment-provider-framework, and install it in one click.
