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

# OAuth 2.0

OAuth 2.0 é um protocolo de autorização que oferece maior controle sobre o escopo de um aplicativo e permite fluxos de autorização em diferentes dispositivos. Ele possibilita a definição de escopos que concedem permissões específicas em nome de um cliente.

<Note>
  Para desenvolver aplicativos para a Yampi, é obrigatório o uso de autenticação com OAuth 2.0. Você pode localizar suas credenciais de acesso para OAuth ao criar seu aplicativo no [Painel de Parceiros Yampi.](https://partners.yampi.com.br)
</Note>

<Warning>
  Atualmente, o uso do OAuth 2.0 é restrito a aplicativos publicados na Loja de Aplicativos da Yampi.
</Warning>

## Fluxo de autorização

Para integrar seu aplicativo a uma loja Yampi, é necessário implementar um fluxo de autorização. Esse fluxo redireciona os lojistas Yampi para uma página onde seu aplicativo será integrado à loja.

```mermaid theme={"system"}
%%{init: {'themeVariables': {'fontSize': '28px', 'fontFamily': 'Inter'}}}%%
sequenceDiagram

    actor Lojista
    participant App as Seu Aplicativo
    participant Auth as auth.yampi.com.br
    participant API as api.dooki.com.br

    App->>App: 1. Gera Code Verifier e Code Challenge (PKCE)
    App->>Auth: 2. GET /oauth/authorize (client_id, code_challenge, state)
    Auth->>Lojista: Exibe tela de consentimento
    Lojista->>Auth: Autoriza as permissões
    Auth->>App: Redireciona com Authorization Code
    App->>Auth: 3. POST /oauth/token (code, code_verifier, client_id)
    Auth->>App: Retorna Access Token + Refresh Token
    App->>API: 4. Requisição autenticada (Authorization: Bearer ACCESS_TOKEN)
    API->>App: Resposta da API
    Note over App,Auth: 5. Quando o Access Token expirar (10 min)
    App->>Auth: POST /oauth/token (grant_type=refresh_token)
    Auth->>App: Novo Access Token + Refresh Token
```

### 1. Obtenha as credenciais de autorização no Painel de Parceiros

Acesse o Painel de Parceiros Yampi, crie sua conta, habilite seu Perfil de Parceiro Tech e registre um novo aplicativo.

Para obter o `Client ID` da sua integração, é necessário informar a `redirect_url` da integração. Essa URL será usada para redirecionar o usuário à sua aplicação, onde o processo de integração será concluído.

<Note>
  Durante o desenvolvimento do seu aplicativo, você pode usar `http://localhost/sua-url-de-redirecionamento` como URL de redirecionamento.
</Note>

### 2. Redirecionamento para autorização utilizando PKCE

Como essa concessão de autorização não utiliza um Client Secret, é necessário gerar o Code Verifier (verificador de código) e o Code Challenge (desafio de código) para solicitar um token.

#### Code Verifier

Uma string aleatória de 128 caracteres usada para gerar o `Code Challenge`, que será enviado no redirecionamento para autorização e na solicitação do `Access Token`.

<Info>
  O Code Challenge deve ser uma sequência aleatória de 43 a 128 caracteres contendo letras, números e os caracteres "-", ".", "\_", "\~". Ele deve ser codificado em Base64 com caracteres seguros para URL e nomes de arquivos. Os caracteres '=' finais devem ser removidos, e não devem haver quebras de linha, espaços em branco ou outros caracteres adicionais, conforme definido na especificação RFC 7636.
</Info>

Exemplo de função para gerar o `Code Challenge` usando o `Code Verifier`:

```php theme={"system"}
<?php
$code_verifier = bin2hex(random_bytes(128 / 2));

$encoded = base64_encode(hash('sha256', $code_verifier, true));
$codeChallenge = strtr(rtrim($encoded, '='), '+/', '-_');
```

#### Redirecionando para autorização

Seu aplicativo deve fazer uma solicitação de redirecionamento para a rota `https://auth.yampi.com.br/oauth/authorize`.

Você usará o `Client ID` gerado no passo 1, o Code Verifier e o Code Challenge para solicitar um `Authorization Code` ao Authorization Server da Yampi.

O *Authorization Server* retornará o `Authorization Code`, que será usado pelo seu aplicativo para requisitar o `Access Token`, o `Refresh Token` e o alias da loja integrada.

```php theme={"system"}
<?php

// Função para gerar uma string aleatória
function random_str($length) {
    return bin2hex(random_bytes($length / 2));
}

// Rota para '/redirect'
if ($_SERVER['REQUEST_URI'] === '/redirect') {
    session_start();

    // Gerar o estado e o code_verifier e armazená-los na sessão
    $state = random_str(40);
    $code_verifier = random_str(128);

    $_SESSION['state'] = $state;
    $_SESSION['code_verifier'] = $code_verifier;

    // Gerar o code_challenge
    $codeChallenge = strtr(rtrim(
        base64_encode(hash('sha256', $code_verifier, true))
    , '='), '+/', '-_');

    // Construir a query
    $query = http_build_query([
        'client_id' => 'client-id',
        'redirect_uri' => '<http://your-app-redirect-url.com/callback>',
        'response_type' => 'code',
        'state' => $state,
        'code_challenge' => $codeChallenge,
        'code_challenge_method' => 'S256',
    ]);

    // Redirecionar para a URL de autorização
    header('Location: https://auth.yampi.com.br/oauth/authorize?' . $query);
    exit;
}
```

```javascript theme={"system"}
const express = require('express');
const crypto = require('crypto');

const app = express();

// Função para gerar uma string aleatória
function randomStr(length) {
  return crypto.randomBytes(length / 2).toString('hex');
}

app.get('/redirect', (req, res) => {
  const state = randomStr(40);
  const codeVerifier = randomStr(128);

  req.session.state = state;
  req.session.code_verifier = codeVerifier;

  const codeChallenge = crypto
    .createHash('sha256')
    .update(codeVerifier)
    .digest('base64')
    .replace(/=/g, '')
    .replace(/\+/g, '-')
    .replace(/\//g, '_');

  const query = new URLSearchParams({
    client_id: 'client-id',
    redirect_uri: '<https://your-redirect-url.com/callback>',
    response_type: 'code',
    state: state,
    code_challenge: codeChallenge,
    code_challenge_method: 'S256',
  }).toString();

  res.redirect(`https://auth.yampi.com.br/oauth/authorize?${query}`);
});
```

#### Erros comuns

| Erro                                 | O que significa                                                                                                                  |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| Página de erro sem redirecionamento  | `client_id` inválido ou `redirect_uri` não cadastrada no Painel de Parceiros — o servidor não redireciona de volta por segurança |
| `?error=access_denied` no callback   | O usuário negou a autorização na tela de consentimento                                                                           |
| `?error=invalid_request` no callback | Parâmetro obrigatório ausente ou malformado (`code_challenge`, `code_challenge_method`, `response_type`)                         |

### 3. Obtenha um token de acesso do Authorization Server da Yampi

Com o `Authorization Code` gerado, seu aplicativo deve obter um `Access Token` antes de acessar dados de uma loja pela API Yampi.

O `Access Token` pode conceder uma ou mais permissões de acesso, configuradas no painel de parceiros por meio do scope (escopo). O scope define quais rotas da API podem ser acessadas.

Durante a instalação do aplicativo, o usuário será solicitado a conceder as permissões solicitadas. Esse processo é chamado de consentimento do usuário.

Se o usuário conceder permissão, o Authorization Server da Yampi redirecionará o usuário ao seu aplicativo com um `Authorization Code` e o `merchant` da loja integrada.

Formato da requisição para obter o `Access Token`:

```bash theme={"system"}
POST 'https://auth.yampi.com.br/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=your-app-client-id' \
--data-urlencode 'redirect_uri=your-redirect-url' \
--data-urlencode 'code=generated-code-verifier' \
--data-urlencode 'code_verifier=generated-code-verifier'
```

#### Erros comuns

| `error`           | `hint`                                  | O que significa                                                          |
| ----------------- | --------------------------------------- | ------------------------------------------------------------------------ |
| `invalid_client`  | —                                       | `client_id` inválido ou não corresponde ao app registrado                |
| `invalid_request` | `Cannot decrypt the authorization code` | Code malformado ou `code_verifier` ausente                               |
| `invalid_grant`   | `Authorization code has expired`        | O `authorization_code` expirou — reinicie o fluxo a partir da etapa 2    |
| `invalid_grant`   | `Authorization code has been revoked`   | O código já foi utilizado — cada código é de uso único                   |
| `invalid_grant`   | `Failed to verify 'code_verifier'`      | O `code_verifier` enviado não corresponde ao `code_challenge` da etapa 2 |
| `invalid_grant`   | `The redirect uri is incorrect.`        | A `redirect_uri` desta requisição difere da usada em `/oauth/authorize`  |

### 4. Use o Access Token para acessar a API Yampi

Após obter o `Access Token`, ele deve ser incluído no cabeçalho das chamadas HTTP do seu aplicativo.

Formato da requisição com os cabeçalhos obrigatórios: `access_token` e `X-Partner-Client-ID`:

```bash theme={"system"}
POST 'https://api.dooki.com.br/v2/{alias}/some-route' \
--header 'X-Partner-Client-ID: your-app-client-id' \
--header 'Authorization: Bearer {token}'
```

#### Erros comuns

| Erro retornado                       | O que significa                                                                                |
| ------------------------------------ | ---------------------------------------------------------------------------------------------- |
| `401 {"message":"Unauthenticated."}` | `Access Token` expirado (válido por 10 minutos) ou ausente no header `Authorization`           |
| `401` em rotas de parceiro           | Header `X-Partner-Client-ID` ausente — o servidor não consegue identificar o aplicativo        |
| `403 Forbidden`                      | A rota acessada está fora do escopo (`scope`) concedido pelo usuário na etapa de consentimento |

### 5. Atualize os tokens

O `Access Token` tem um tempo de vida limitado. Tokens gerados pelo fluxo PKCE Authorization Code permanecem válidos por *10 minutos*, enquanto o `Refresh Token` é válido por 30 dias.

Seu aplicativo deve obter novos tokens antes que o `Refresh Token` expire.

Formato da requisição para gerar um novo `Access Token`:

```bash theme={"system"}
POST 'https://auth.yampi.com.br/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'refresh_token=your-refresh-token' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=your-app-client-id'
```

#### Erros comuns

| `error`           | `hint`                                    | O que significa                                                                       |
| ----------------- | ----------------------------------------- | ------------------------------------------------------------------------------------- |
| `invalid_client`  | —                                         | `client_id` não corresponde ao que gerou o `Refresh Token`                            |
| `invalid_request` | `Cannot decrypt the refresh token`        | Token malformado — valor truncado ou corrompido                                       |
| `invalid_request` | `Check the \`refresh\_token\` parameter\` | Parâmetro `refresh_token` ausente na requisição                                       |
| `invalid_grant`   | `Token has been revoked`                  | `Refresh Token` expirado (30 dias) ou revogado — reinicie o fluxo a partir da etapa 2 |

## Escopos

Os escopos permitem definir acessos granulares ao seu aplicativo, garantindo que ele tenha apenas as permissões necessárias. Consulte os detalhes de cada escopo em [Permissões de um aplicativo](/apps/criacao-e-configuracao/permissoes-de-um-aplicativo).
