Guia de Expansão

Padrão arquitetural para adicionar novos gateways de pagamento e expandir o ecossistema Multi-Checkout.

1. Estrutura de Pastas e Arquivos

Cada gateway deve ter sua própria pasta dentro de /gateways. Padrão recomendado:

/gateways
  /{novo_gateway}/
    /config/
      notification.php ← Webhook: recebe e processa callbacks do gateway
      processa.php ← Lógica para cartão de crédito
      gerar_pix.php ← Lógica para gerar QR Code PIX
    pagamento.php ← UI de checkout (formulário/seleção para o cliente)
    status.php ← Verificação de status em tempo real (opcional)
    obrigado.php ← Página de sucesso após pagamento
2. Passo a Passo para Implementação
1Credenciais no config_defaults.php

Adicione os valores padrão do novo gateway no array de config_defaults.php:

// Em config_defaults.php — adicionar as novas chaves:
'NOVO_GW_API_KEY'    => '',
'NOVO_GW_SECRET_KEY' => '',
'NOVO_GW_API_URL'    => 'https://api.novogateway.com/v1',

Em seguida, registre as constantes em config.php (seção de gateways, após os existentes):

// Em config.php — definir constantes:
if (!defined('NOVO_GW_API_KEY'))
    define('NOVO_GW_API_KEY', $CFG['NOVO_GW_API_KEY'] ?? '');
if (!defined('NOVO_GW_SECRET_KEY'))
    define('NOVO_GW_SECRET_KEY', $CFG['NOVO_GW_SECRET_KEY'] ?? '');
2Interface de Configuração (configuracao.php)

Adicione um card novo em configuracao.php seguindo o padrão dos gateways existentes. Use type="password" para tokens sensíveis e inclua a URL do webhook como campo readonly com botão de cópia:

<!-- Em configuracao.php — novo card para o gateway -->
<div class="card">
    <div class="card-header">Novo Gateway</div>
    <div class="card-body">
        <div class="row g-3">
            <div class="col-md-6">
                <label>API Key</label>
                <div class="input-group">
                    <input type="password" name="NOVO_GW_API_KEY"
                        value="<?= htmlspecialchars($v('NOVO_GW_API_KEY')) ?>">
                    <button onclick="togglePassword('novo_gw_key')">👁</button>
                </div>
            </div>
            <!-- URL do Webhook (readonly + cópia) -->
            <div class="col-12">
                <label>URL do Webhook</label>
                <div class="input-group webhook-url-group">
                    <input type="text" class="form-control" readonly
                        value="<?= BASE_URL ?>/gateways/novo_gateway/config/notification.php">
                    <button class="btn-copy-webhook">📋</button>
                </div>
            </div>
        </div>
    </div>
</div>
Importante: Nenhuma configuração salva em configuracao.php deve incluir ou sobrescrever a chave ACTIVE_API_KEY — ela é gerenciada exclusivamente pelo card "Chave de API Ativa" no topo da página de configurações.
3UI de Checkout do Gateway

Crie /gateways/{novo_gateway}/pagamento.php. Ele deve:

  • Incluir o config da raiz: require_once '../../config.php';
  • Buscar os dados do pedido via $_GET['id'] usando buscarPedido()
  • Apresentar as opções de pagamento ao cliente (PIX, Boleto, Cartão)
  • Carregar os scripts do SDK/API do gateway
// Padrão mínimo de um arquivo de checkout:
require_once '../../config.php';

$pedido = buscarPedido($_GET['id'] ?? 0);
if (!$pedido) {
    header('Location: ../../index');
    exit;
}

// Atualizar o gateway no pedido:
$pdo->prepare("UPDATE pedido SET gateway='novo_gateway' WHERE id=:id")
    ->execute([':id' => $pedido['id']]);
4Lógica de Processamento

Crie os arquivos de processamento dentro de /config/. Use cURL para comunicar com a API do gateway. Padrão recomendado:

// /gateways/novo_gateway/config/processa.php
require_once '../../../config.php';

$curl = curl_init();
curl_setopt_array($curl, [
    CURLOPT_URL            => NOVO_GW_API_URL . '/charges',
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . NOVO_GW_API_KEY],
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => AMBIENTE === 'production',
]);
$response = json_decode(curl_exec($curl), true);

if (curl_getinfo($curl, CURLINFO_HTTP_CODE) !== 200) {
    registrarLogSistema(json_encode($response), 'Novo Gateway', 'ERROR');
}
5Registro na Página de Seleção (pagamento.php)

No arquivo pagamento.php da raiz, adicione o botão do novo gateway na seção de seleção para que o cliente possa escolhê-lo:

<!-- Em pagamento.php, na seção de botões de gateway -->
<div class="col-md-4">
    <a href="gateways/novo_gateway/pagamento.php?id=<?= $resultado_pedido['id'] ?>"
       class="payment-btn">
        <i class="bi bi-credit-card"></i> Pagar com Novo Gateway
    </a>
</div>

Adicione também o novo gateway no ENUM da coluna gateway na tabela pedido:

-- No banco de dados:
ALTER TABLE pedido
    MODIFY gateway ENUM('efi','asaas','mercadopago','stripe','pagarme','novo_gateway');
3. Autenticação da API Multi-Checkout ATUALIZADO

O sistema usa um modelo de chave única ativa: a chave configurada em configuracao.php (campo "Chave de API Ativa") é exigida em todas as requisições JSON aos endpoints públicos.

Como funciona: A chave ativa é armazenada em config_custom.json como ACTIVE_API_KEY e lida pelo config.php. A validação ocorre via a função validarApiKeyCompleta(), que consulta a tabela api_keys no banco.
Chaves de Sandbox vs Produção
🧪 Sandbox / Homologação
Ativa imediatamente quando criada pelo usuário. Faz bypass total de todas as validações: sem limite de requisições, sem restrição de IP, sem verificação de permissão. Ideal para desenvolvimento e testes.
🔐 Produção
Fica pendente até o admin aprovar. O admin define: permissões por endpoint, limite diário/mensal de requisições, IP whitelist e data de expiração. Só fica ativa após aprovação.

Ao criar endpoints que se integrem com o sistema, sempre use a função de validação central — nunca faça validação manual de chave:

// Em qualquer endpoint que precise de autenticação:
require_once 'config.php';

$chave = $_SERVER['HTTP_X_API_KEY'] ?? $_GET['api_key'] ?? null;

if ($chave) {
    $v = validarApiKeyCompleta($pdo, $chave, 'nome_do_endpoint', $_SERVER['REMOTE_ADDR'] ?? null);
    if (!$v['valida']) {
        http_response_code(401);
        echo json_encode(['success' => false, 'error' => $v['erro']]);
        exit;
    }
    // Registrar uso para controle de limites:
    if ($v['key_id']) {
        registrarUsoChave($pdo, $v['key_id'], '/meu_endpoint.php');
    }
}
Sandbox no seu gateway: Para simular o ambiente de homologação de um gateway de pagamento (ex: Stripe test mode), avalie a constante AMBIENTE === 'development' do config base. As chaves sandbox do sistema de API são independentes do modo de ambiente do gateway.
4. Webhooks (Notificações de Pagamento)

O arquivo notification.php é obrigatório. Ele recebe callbacks do gateway e atualiza o status do pedido automaticamente. Padrão de atualização:

// notification.php — padrão mínimo obrigatório:
require_once '../../../config.php';

$payload = file_get_contents('php://input');
$data    = json_decode($payload, true);

// Registrar o webhook recebido:
registrarLogSistema($payload, 'Novo Gateway - Webhook', 'INFO');

// Atualizar o pedido:
$pdo->prepare("UPDATE pedido SET status=:s, id_transacao=:t WHERE id=:id")
    ->execute([':s' => $novoStatus, ':t' => $transacaoId, ':id' => $pedidoId]);

http_response_code(200);
echo 'OK';
Efeito automático: Ao atualizar a tabela pedido, o endpoint consultar_status.php refletirá a mudança imediatamente para qualquer sistema integrado — incluindo grupos multicheckout_id.
URL do Webhook: Sempre exponha a URL em configuracao.php como campo readonly com botão de cópia. Padrão da URL: https://pay.versianecode.com.br/gateways/novo_gateway/config/notification.php
5. Sistema de Logs Unificado

Todos os eventos (erros, respostas de API, webhooks recebidos) devem ser registrados via registrarLogSistema(). Nunca use error_log() ou arquivos .log manuais.

/**
 * @param string $mensagem  Texto ou JSON stringificado do evento
 * @param string $gateway   Nome legível: "Stripe", "PayPal", "Novo Gateway"
 * @param string $level     "INFO" | "WARNING" | "ERROR"
 */

// Erro crítico:
registrarLogSistema("Token inválido na resposta da API", 'Novo Gateway', 'ERROR');

// Webhook processado com sucesso:
registrarLogSistema(json_encode($webhookData), 'Novo Gateway - Webhook', 'INFO');

// Alerta (ex: pagamento em análise):
registrarLogSistema("Pagamento em análise: pedido #{$pedidoId}", 'Novo Gateway', 'WARNING');
Todos os logs aparecem em Painel de Logs com cores por nível, filtros e visualização completa do payload. Os logs vinculados a uma chave de API também aparecem em Minhas Chaves e Gerenciar Chaves → Logs.
6. Banco de Dados Consolidado

O arquivo mestre de banco é pedido.sql na raiz. Toda tabela auxiliar de um novo gateway deve ser adicionada a ele, garantindo que qualquer instalador precise importar apenas esse único arquivo.

-- Exemplo: tabela auxiliar para um novo gateway
CREATE TABLE `novo_gateway_transactions` (
    `id`         int(11) NOT NULL AUTO_INCREMENT,
    `pedido_id`  int(11) DEFAULT NULL,
    `charge_id`  varchar(100) NOT NULL,
    `status`     varchar(50) DEFAULT 'pending',
    `amount`     int(11) NOT NULL COMMENT 'Valor em centavos',
    `created_at` datetime DEFAULT current_timestamp(),
    PRIMARY KEY (`id`),
    CONSTRAINT FOREIGN KEY (`pedido_id`) REFERENCES `pedido`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Migrações incrementais: Se o sistema já estiver em produção, crie também um arquivo migracao_vX.X.sql separado com apenas o ALTER TABLE ou CREATE TABLE do que é novo — para não exigir reimportação completa.
7. Checklist de Integração
Estrutura

Pasta em /gateways, pagamento.php, /config/notification.php criados seguindo o padrão.

Credenciais

Defaults em config_defaults.php, constantes em config.php, campos em configuracao.php.

Logs & Erros

Todos os eventos passam por registrarLogSistema(). Nenhum error_log() ou arquivo manual.

SQL

Tabelas auxiliares adicionadas ao pedido.sql + arquivo de migração incremental separado.

Webhook

URL exposta em configuracao.php como campo readonly com cópia. notification.php atualiza tabela pedido.

UI/UX

Bootstrap 5, sanitize_input() em dados do cliente, header.php e footer.php incluídos via include.

Autenticação: Se seu novo endpoint precisar de autenticação, use sempre validarApiKeyCompleta() + registrarUsoChave(). O sistema de chaves suporta produção (com aprovação do admin) e sandbox (ativação imediata, sem restrições).

Multi-Checkout © 2026 - Todos os direitos reservados