> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pagamentos.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar um provedor

> Como adicionar suporte a um novo gateway de pagamento

## Visão geral

Provedores são a espinha dorsal do **pagamentos.dev**. Cada provedor
implementa a interface `Provider` e expõe os recursos (clientes, cobranças,
checkout, webhooks) que o SDK gerencia de forma unificada.

Para criar um novo provedor, você precisa:

1. Definir os métodos de pagamento suportados
2. Implementar os recursos (clientes, cobranças, checkout, webhooks)
3. Criar a função factory que instancia o provedor
4. Exportar os tipos para os consumidores

## Estrutura básica

```
src/provider/meu-provedor/
├── meu-provedor.ts    # Implementação principal
└── ...                # Testes, tipos auxiliares, etc.
```

## Passo a passo

### 1. Defina os métodos de pagamento suportados

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
// src/provider/meu-provedor/meu-provedor.ts
import type { MetodoPagamento } from 'pagamentos'

export type MeuProvedorSupportedMethods = 'pix' | 'boleto'
```

### 2. Defina os recursos suportados

Cada provedor declara quais operações de cada recurso ele implementa:

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
const MEU_PROVEDOR_RESOURCES = {
  clientes: ['create', 'get', 'update', 'list', 'delete'] as const,
  cobrancas: ['create', 'get', 'update', 'list', 'cancel'] as const,
  checkout: ['create'] as const,
  webhooks: [
    'signatureHeader',
    'verifySecret',
    'verifySignature',
    'decodePayload',
    'verifyAndDecode'
  ] as const
} as const
```

### 3. Implemente os recursos

Cada recurso é um objeto com funções que seguem os tipos definidos no SDK:

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { Provider } from 'pagamentos'
import type { Cliente, Cobranca, Checkout } from 'pagamentos'

const resources = {
  clientes: {
    async create(input) {
      const response = await fetch('https://api.meuprovedor.com/clientes', {
        method: 'POST',
        headers: { Authorization: `Bearer ${apiKey}` },
        body: JSON.stringify(input)
      })
      return response.json() as Promise<Cliente>
    },
    async get(id) {
      const response = await fetch(
        `https://api.meuprovedor.com/clientes/${id}`,
        { headers: { Authorization: `Bearer ${apiKey}` } }
      )
      return response.json() as Promise<Cliente>
    },
    async update(id, input) { /* ... */ },
    async list(input) { /* ... */ },
    async delete(id) { /* ... */ }
  },
  cobrancas: {
    async create(input) {
      // Implemente a criação de cobrança
    },
    async get(id) { /* ... */ },
    async update(id, input) { /* ... */ },
    async list(input) { /* ... */ },
    async cancel(id) { /* ... */ }
  },
  checkout: {
    async create(input) { /* ... */ }
  },
  webhooks: {
    signatureHeader: 'x-meu-provedor-signature',
    verifySecret(secretFromQuery, expectedSecret) {
      return secretFromQuery === expectedSecret
    },
    async verifySignature(rawBody, signatureFromHeader, publicHmacKey) {
      // Valide a assinatura do webhook
    },
    async decodePayload(payload) {
      // Decodifique o payload do webhook para o formato do SDK
    },
    async verifyAndDecode({ rawBody, signatureFromHeader, publicHmacKey }) {
      // Valide e decodifique em um único passo
    }
  }
}
```

### 4. Crie o tipo do provedor

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export type MeuProvedor<ID extends string = 'default'> = Provider<
  ID,
  'meuProvedor',
  MeuProvedorSupportedMethods,
  MeuProvedorWebhookPayload,
  typeof MEU_PROVEDOR_RESOURCES
>
```

### 5. Crie a função factory

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export type MeuProvedorParams = {
  id?: string
  apiKey: string
  signingSecret?: string
  taxa?: import('pagamentos').Taxa
}

export function meuProvedor<const ID extends string>(
  params: MeuProvedorParams & { id: ID }
): MeuProvedor<ID>
export function meuProvedor(
  params?: MeuProvedorParams & { id?: never }
): MeuProvedor<'default'>
export function meuProvedor<ID extends string = 'default'>(
  params: MeuProvedorParams = {} as MeuProvedorParams
): MeuProvedor<ID> {
  return new Provider({
    id: params.id,
    provider: 'meuProvedor',
    taxa: params.taxa,
    resources,
    webhookConfig: params.signingSecret
      ? { signingSecret: params.signingSecret }
      : undefined
  }) as MeuProvedor<ID>
}
```

## Exemplo real: Mock Provider

Consulte a implementação completa do [Mock Provider](https://github.com/pagamentosdev/pagamentos/blob/main/src/provider/mock/mock.ts)
para ver um exemplo funcional de provedor com suporte a todos os métodos de
pagamento e webhooks.

## Boas práticas

### Tratamento de erros

Converta os erros da API do provedor para `Error` do JavaScript:

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
async get(id: string) {
  const response = await fetch(`https://api.provedor.com/${id}`)

  if (!response.ok) {
    throw new Error(
      `MeuProvedor: erro ao buscar cliente (${response.status})`
    )
  }

  return response.json()
}
```

### Taxas

Se o provedor for usado com [roteamento inteligente](/features/roteamento-inteligente),
aceite uma configuração de `taxa` opcional:

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export type MeuProvedorParams = {
  taxa?: Taxa // Aceita flat, percentage ou async
  // ...
}
```

### Webhooks

Para que o handler automático de webhooks funcione, implemente:

* `signatureHeader`: nome do header que contém a assinatura
* `verifyAndDecode`: valida a assinatura e decodifica o payload
* Aceite `signingSecret` nos parâmetros e passe no `webhookConfig`

### Tipagem forte

Exporte os tipos do seu provedor para que os consumidores tenham autocomplete:

```ts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export type { MeuProvedor, MeuProvedorParams, MeuProvedorSupportedMethods }
```

## Publicando

1. Crie um pacote npm com o nome `pagamentos-provider-nome`
2. Declare `pagamentos` como `peerDependency`
3. Publique no npm

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{
  "name": "pagamentos-provider-meu-provedor",
  "peerDependencies": {
    "pagamentos": "^0.x"
  }
}
```
