Padrão arquitetural para adicionar novos gateways de pagamento e expandir o ecossistema Multi-Checkout.
Cada gateway deve ter sua própria pasta dentro de /gateways. Padrão recomendado:
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'] ?? '');
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>
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.
Crie /gateways/{novo_gateway}/pagamento.php. Ele deve:
require_once '../../config.php';$_GET['id'] usando buscarPedido()// 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']]);
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');
}
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');
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.
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.
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');
}
}
AMBIENTE === 'development' do config base. As chaves sandbox do sistema de API são independentes do modo de ambiente do gateway.
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';
pedido, o endpoint consultar_status.php refletirá a mudança imediatamente para qualquer sistema integrado — incluindo grupos multicheckout_id.
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
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');
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;
migracao_vX.X.sql separado com apenas o ALTER TABLE ou CREATE TABLE do que é novo — para não exigir reimportação completa.
Pasta em /gateways, pagamento.php, /config/notification.php criados seguindo o padrão.
Defaults em config_defaults.php, constantes em config.php, campos em configuracao.php.
Todos os eventos passam por registrarLogSistema(). Nenhum error_log() ou arquivo manual.
Tabelas auxiliares adicionadas ao pedido.sql + arquivo de migração incremental separado.
URL exposta em configuracao.php como campo readonly com cópia. notification.php atualiza tabela pedido.
Bootstrap 5, sanitize_input() em dados do cliente, header.php e footer.php incluídos via include.
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