# Primeira chamada

Crie uma cobrança no servidor e obtenha o código PIX.

## Pré-requisitos

Rode o exemplo no backend, com as chaves da empresa só no servidor.

A empresa precisa estar ativa e com KYC aprovado.

## Faça a requisição

O JavaScript abaixo é código de servidor. Sucesso do checkout é HTTP 200.

**Requisição de checkout**

```bash title="cURL"
curl --request POST 'https://api-gateway.grandepay.com.br/v1/checkout' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'X-Public-Key: pk_sua_empresa' \
  --header 'X-Secret-Key: sk_sua_empresa' \
  --data '{"amount":1500,"paymentMethod":"pix","postbackUrl":"https://empresa.example/api/grandepay/postback","items":[{"title":"Assinatura mensal","unitPrice":1500,"quantity":1,"externalRef":"plan-pro-001"}],"customer":{"name":"Maria de Souza","email":"maria@example.com","phone":"11999999999","document":{"number":"12345678901","type":"cpf"}},"pix":{"expiresInDays":2}}'
```

```javascript title="Node"
const publicKey = process.env.GRANDEPAY_PUBLIC_KEY;
const secretKey = process.env.GRANDEPAY_SECRET_KEY;

if (!publicKey || !secretKey) {
  throw new Error("Defina GRANDEPAY_PUBLIC_KEY e GRANDEPAY_SECRET_KEY no servidor.");
}

const response = await fetch("https://api-gateway.grandepay.com.br/v1/checkout", {
  method: "POST",
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json",
    "X-Public-Key": publicKey,
    "X-Secret-Key": secretKey,
  },
  body: JSON.stringify({
    amount: 1500,
    paymentMethod: "pix",
    postbackUrl: "https://empresa.example/api/grandepay/postback",
    items: [
      {
        title: "Assinatura mensal",
        unitPrice: 1500,
        quantity: 1,
      },
    ],
    customer: {
      name: "Maria de Souza",
      document: {
        number: "12345678901",
        type: "cpf",
      },
    },
    pix: {
      expiresInDays: 2,
    },
  }),
});

if (!response.ok) {
  const errorBody = await response.json().catch(() => null);
  const message = errorBody && errorBody.error ? errorBody.error : "resposta não JSON";
  throw new Error("Checkout recusado (" + response.status + "): " + message);
}

const data = await response.json();
```

```php title="PHP"
<?php
$publicKey = getenv('GRANDEPAY_PUBLIC_KEY');
$secretKey = getenv('GRANDEPAY_SECRET_KEY');

if ($publicKey === false || $secretKey === false) {
    throw new RuntimeException('Defina GRANDEPAY_PUBLIC_KEY e GRANDEPAY_SECRET_KEY no servidor.');
}

$payload = [
    'amount' => 1500,
    'paymentMethod' => 'pix',
    'postbackUrl' => 'https://empresa.example/api/grandepay/postback',
    'items' => [
        [
            'title' => 'Assinatura mensal',
            'unitPrice' => 1500,
            'quantity' => 1,
        ],
    ],
    'customer' => [
        'name' => 'Maria de Souza',
        'document' => [
            'number' => '12345678901',
            'type' => 'cpf',
        ],
    ],
    'pix' => [
        'expiresInDays' => 2,
    ],
];

$ch = curl_init('https://api-gateway.grandepay.com.br/v1/checkout');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Accept: application/json',
        'Content-Type: application/json',
        'X-Public-Key: ' . $publicKey,
        'X-Secret-Key: ' . $secretKey,
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_SLASHES),
]);

$result = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($result === false) {
    throw new RuntimeException('Falha de rede ao criar o checkout.');
}

$data = json_decode($result, true);

if ($status < 200 || $status >= 300) {
    $message = is_array($data) && isset($data['error']) ? $data['error'] : 'resposta não JSON';
    throw new RuntimeException('Checkout recusado (' . $status . '): ' . $message);
}
```

CPF e QR dos exemplos são sintéticos.

## Leia a resposta

A resposta 200 traz oito campos. `status` inicial é `0`; `pix_code` pode ser nulo.

Renderize o código PIX sem alterar o conteúdo.

```json title="200.json"
{
  "uuid": "4d78d8ca-a9f1-4c2a-bf15-7f8ca71e3a70",
  "status": 0,
  "amount_cents": 1500,
  "pix_code": "00020101021226870014br.gov.bcb.pix2565qrcodes.example.com/pix/4d78d8ca",
  "pix_expiration": "2026-03-15T17:00:00.000Z",
  "provider_transaction_id": "prov_tx_123",
  "external_id": "GP-9a5f1eb3-6885-4f26-93f3-3c0954d0f42f",
  "created_at": "2026-03-13T17:00:00.000Z"
}
```

## Confirme por postback

A criação não marca o pedido como pago. O evento `transaction.paid` confirma o pagamento. Valide a assinatura e persista o evento conforme [Recebendo postbacks](https://www.grandepay.com.br/docs/guides/receiving-postbacks) e [HMAC](https://www.grandepay.com.br/docs/guides/hmac-signature).
