Primeiros passos

Credenciais

client_id e client_secret são fornecidos no cadastro.

O client_secret é exibido uma única vez, no momento da geração, e não é recuperável. Perdido o valor, é necessário rotacionar.

Obter um token

curl -X POST https://api-crpay.deskhotel.com.br/oauth/token \
  -u "$CRPAY_CLIENT_ID:$CRPAY_CLIENT_SECRET" \
  -d grant_type=client_credentials
{
  "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImtfMWFhYTI5MDRmNTFiIiwidHlwIjoiSldUIn0...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "payments:write payments:read"
}

Validade de 900 segundos. Reutilize o token durante a validade — este endpoint aceita 10 requisições por minuto por client_id.

Usar o token

curl https://api-crpay.deskhotel.com.br/v1/... \
  -H "Authorization: Bearer $TOKEN"

Cliente com cache de token

Renove antes do vencimento para evitar usar um token que expira em trânsito.

let cache = { token: null, expiraEm: 0 };

async function obterToken() {
  if (cache.token && Date.now() < cache.expiraEm) return cache.token;

  const basic = Buffer.from(
    `${process.env.CRPAY_CLIENT_ID}:${process.env.CRPAY_CLIENT_SECRET}`
  ).toString('base64');

  const res = await fetch('https://api-crpay.deskhotel.com.br/oauth/token', {
    method: 'POST',
    headers: {
      Authorization: `Basic ${basic}`,
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: 'grant_type=client_credentials'
  });

  if (!res.ok) throw new Error(`crpay: falha ao obter token (${res.status})`);

  const { access_token, expires_in } = await res.json();
  cache = { token: access_token, expiraEm: Date.now() + (expires_in - 60) * 1000 };
  return access_token;
}
import base64, os, time, requests

_cache = {"token": None, "expira_em": 0}

def obter_token():
    if _cache["token"] and time.time() < _cache["expira_em"]:
        return _cache["token"]

    basic = base64.b64encode(
        f'{os.environ["CRPAY_CLIENT_ID"]}:{os.environ["CRPAY_CLIENT_SECRET"]}'.encode()
    ).decode()

    r = requests.post(
        "https://api-crpay.deskhotel.com.br/oauth/token",
        headers={"Authorization": f"Basic {basic}"},
        data={"grant_type": "client_credentials"},
        timeout=15,
    )
    r.raise_for_status()
    d = r.json()
    _cache.update(token=d["access_token"], expira_em=time.time() + d["expires_in"] - 60)
    return _cache["token"]
<?php
function crpayToken(): string {
    static $cache = ['token' => null, 'expiraEm' => 0];
    if ($cache['token'] && time() < $cache['expiraEm']) return $cache['token'];

    $basic = base64_encode(getenv('CRPAY_CLIENT_ID') . ':' . getenv('CRPAY_CLIENT_SECRET'));
    $ch = curl_init('https://api-crpay.deskhotel.com.br/oauth/token');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ["Authorization: Basic $basic"],
        CURLOPT_POSTFIELDS => 'grant_type=client_credentials',
        CURLOPT_TIMEOUT => 15,
    ]);
    $resposta = json_decode(curl_exec($ch), true);
    curl_close($ch);

    $cache = [
        'token'    => $resposta['access_token'],
        'expiraEm' => time() + $resposta['expires_in'] - 60,
    ];
    return $cache['token'];
}

Ambientes

Determinados pelo prefixo do client_id, não por URL.

Prefixo Ambiente
test_ Sandbox das adquirentes
live_ Produção

Referência