Claude
Skills
Sign in
Back

payment-provider-framework

Included with Lifetime
$97 forever

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.

Sales & CRM

What this skill does


# 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`, and `PaymentProviderService` in `node/index.ts`
- Configuring the `paymentProvider` builder, `configuration.json` (payment methods, `customFields`, feature flags)
- Implementing `this.retry(request)` for Gateway retry semantics on IO
- Extending `SecureExternalClient` and passing `secureProxy` on 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`](../payment-provider-protocol/SKILL.md)
- Idempotency and duplicate `paymentId` handling — use [`payment-idempotency`](../payment-idempotency/SKILL.md)
- Async `undefined` status, `callbackUrl` notification vs retry (IO vs non-IO) — use [`payment-async-flow`](../payment-async-flow/SKILL.md)
- PCI rules, logging, and token semantics beyond IO wiring — use [`payment-pci-security`](../payment-pci-security/SKILL.md)

## 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 `node` folder, add `@vtex/payment-provider` (for example `1.x` in `package.json`). Keep `@vtex/api` in `devDependencies` (for example `6.x`); linking may bump it beyond `6.x`, which is acceptable. If types break, delete `node_modules` and `yarn.lock` in the project root and in `node`, then run `yarn install -f` in both.
- **`paymentProvider` builder**: In `manifest.json`, include `"paymentProvider": "1.x"` next to `node` so policies for Payment Gateway callbacks and PPP routes apply.
- **`configuration.json`**: Declare `paymentMethods` so 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 extra `routes` / `clients` when 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 as `implementsOAuth`, `implementsSplit`, `usesProviderHeadersName`, `usesBankInvoiceEnglishName`, `usesSecureProxy`, `requiresDocument`, `acceptSplitPartialRefund`, `usesAutoSettleOptions`. Set `name` and rely on auto-generated `serviceUrl` on IO unless documented otherwise. **Do not invent fields** — unknown keys (such as `usesTestSuite`) cause builder validation errors. See the "configuration.json schema" constraint below for the canonical list and `customFields` format.
- **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 `SecureExternalClient` with `secureProxy: secureProxyUrl` from Create Payment; destination must be allowlisted." Supported `Content-Type` values for Secure Proxy: `application/json` and `application/x-www-form-urlencoded` only. **Important:** only the Create Payment (authorize) request carries `secureProxyUrl`. Post-authorization operations (cancel, capture, refund) do not transport card data and must call the PSP API directly via `ExternalClient` with credentials and `outbound-access` policies.
- **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 `billingOptions` per 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**

```typescript
// 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:

```typescript
// WRONG — if callbackUrl is not used, build fails
const { paymentId, callbackUrl, value } = authorization

// CORRECT
const { paymentId, value } = authorization
```

**Safe 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.

```json
{
  "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 |
| `@types/express` | `4.17.10` | `4.17.11+` | Depends on `@types/express-serve-static-core@^4.17.

Related in Sales & CRM