odinizfilho / infinitepay-php
SDK PHP server-side para o Checkout Integrado da InfinitePay
Requires
- php: ^8.1
- ext-curl: *
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.64
- phpstan/phpstan: ^1.12 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-07 15:53:41 UTC
README
SDK PHP server-side para criar links do Checkout Integrado e confirmar pagamentos da InfinitePay sem receber dados de cartão no seu sistema.
Este projeto é um SDK comunitário e não oficial. A integração usa o checkout hospedado da InfinitePay.
Por que este package existe?
A API do Checkout Integrado da InfinitePay é simples, mas uma integração de pagamento segura envolve mais do que enviar uma requisição HTTP. Cada projeto precisaria implementar novamente validação de valores, serialização do payload, tratamento de erros, timeouts, verificação TLS e confirmação de webhooks.
Este package concentra essas responsabilidades em uma API PHP pequena e tipada. A aplicação cria o pedido no backend, envia somente os dados necessários para a InfinitePay e recebe uma URL de checkout hospedado. Os dados de cartão são preenchidos diretamente no ambiente da InfinitePay e nunca passam pelo servidor ou pelo frontend da loja.
Ele também resolve um ponto importante da integração: um webhook ou os parâmetros recebidos na URL de retorno não devem ser considerados prova de pagamento. O SDK permite reconciliar a notificação com o pedido salvo e consultar o endpoint payment_check antes de liberar um produto ou serviço.
Por que usar?
- Menos código repetido: criação de links, consulta de pagamentos e leitura de webhooks usam objetos prontos e reutilizáveis.
- Valores monetários seguros: os preços são inteiros em centavos, evitando erros de arredondamento causados por
float. - Validação antes da requisição: itens, InfiniteTag, cliente, endereço, URLs e identificadores são validados antes de chegar à API.
- Webhook reconciliado: pedido e valor são comparados com os dados locais e o pagamento é confirmado server-to-server.
- Transporte protegido: TLS é verificado, redirects não são seguidos e existem limites de tempo e tamanho de resposta.
- Erros previsíveis: falhas de validação, comunicação e respostas da API possuem exceções separadas.
- Fácil de testar: o transporte HTTP pode ser substituído por uma implementação simulada, sem criar cobranças reais nos testes.
- Independente de framework: pode ser usado em PHP puro, Laravel, Symfony ou qualquer projeto com Composer.
O package reduz erros comuns e oferece uma base consistente, mas não substitui as responsabilidades da aplicação. O sistema consumidor ainda deve autenticar o comprador, carregar produtos e preços do banco, proteger a rota contra abuso e processar cada transaction_nsu de forma idempotente.
Requisitos
- PHP 8.1 ou superior
- extensoes
curl,jsonembstring - Checkout Integrado habilitado na conta InfinitePay
Instalacao
Enquanto o pacote ainda nao estiver publicado no Packagist, adicione o repositorio ao projeto consumidor:
{
"repositories": [
{ "type": "vcs", "url": "https://github.com/odinizfilho/infinitepay-php" }
],
"require": {
"odinizfilho/infinitepay-php": "dev-main"
}
}
Depois execute composer update odinizfilho/infinitepay-php.
Criar um checkout
Este codigo deve rodar em uma rota do backend. O frontend recebe somente a URL pronta do checkout; valores e itens devem sempre vir do banco de dados, nunca do corpo enviado pelo navegador.
<?php use InfinitePay\CheckoutRequest; use InfinitePay\InfinitePayClient; use InfinitePay\Value\Customer; use InfinitePay\Value\Item; require __DIR__ . '/vendor/autoload.php'; // Pode vir de INFINITEPAY_HANDLE no ambiente. Nunca aceite a handle do request. $client = new InfinitePayClient($_ENV['INFINITEPAY_HANDLE']); // Busque o pedido autenticado no banco e recalcule o total no servidor. $order = $orders->findForCustomer($orderId, $authenticatedCustomerId); $checkout = new CheckoutRequest( items: array_map( fn ($line) => new Item($line->name, $line->unitPriceInCents, $line->quantity), $order->lines, ), orderNsu: (string) $order->publicId, redirectUrl: 'https://loja.example.com/pagamento/retorno', webhookUrl: 'https://loja.example.com/webhooks/infinitepay', customer: new Customer($order->customerName, $order->customerEmail, $order->customerPhone), ); $link = $client->createPaymentLink($checkout); // Em uma API JSON: devolva $link->url. Em MVC: emita um redirect 303. header('Location: ' . $link->url, true, 303);
price e sempre um inteiro em centavos: R$ 10,00 deve ser 1000. Nao use float para dinheiro.
Webhook seguro
A documentacao publica da InfinitePay nao informa uma assinatura criptografica para o webhook. Por isso, receber um POST nao e prova de pagamento. O metodo verifyWebhook() compara pedido e valor locais e confirma a transacao diretamente na API antes de retornar sucesso.
A InfinitePay recomenda responder em menos de 1 segundo: use um transporte com timeout subsegundo no fluxo sincrono. Se qualquer etapa falhar, responda 400 para solicitar uma nova tentativa; responda 200 somente depois de assumir responsabilidade pelo evento.
<?php use InfinitePay\Exception\ValidationException; use InfinitePay\Http\CurlTransport; use InfinitePay\InfinitePayClient; use InfinitePay\WebhookEvent; $client = new InfinitePayClient( $_ENV['INFINITEPAY_HANDLE'], new CurlTransport(timeoutMilliseconds: 800, connectTimeoutMilliseconds: 300), ); try { $rawBody = file_get_contents('php://input'); $event = WebhookEvent::fromJson($rawBody === false ? '' : $rawBody); // Localize o pedido somente pelo identificador; ainda nao altere seu status. $order = $orders->findByPublicId($event->reference->orderNsu); if ($order === null) { throw new ValidationException('Pedido desconhecido.'); } // Consulta /payment_check e exige paid=true e o mesmo valor do pedido local. $status = $client->verifyWebhook( event: $event, expectedOrderNsu: (string) $order->publicId, expectedAmount: $order->totalInCents, ); // Use transaction_nsu como chave UNIQUE e atualize de forma idempotente/transacional. $orders->markPaidOnce($order->id, $event->reference->transactionNsu, $status); http_response_code(200); } catch (Throwable $exception) { // Registre apenas o tipo/identificador interno, nunca o payload ou dados pessoais. $logger->warning('Falha ao processar webhook InfinitePay', ['exception' => $exception]); http_response_code(400); // A documentacao informa que este codigo gera nova tentativa. }
Para maior resiliencia, prefira uma fila duravel: valide a sintaxe, persista o evento e agende o trabalho na mesma transacao; depois responda 200. O worker chama verifyWebhook() e atualiza o pedido de forma idempotente. Se nao for possivel persistir ou enfileirar, responda 400. Assim a rota responde rapidamente sem perder eventos, e o worker pode repetir falhas temporarias da consulta payment_check.
Conferir o retorno do navegador
Parametros de redirect_url tambem nao sao prova de pagamento. Construa uma PaymentReference e consulte a API no backend:
use InfinitePay\PaymentReference; $reference = new PaymentReference( orderNsu: (string) $_GET['order_nsu'], transactionNsu: (string) $_GET['transaction_nsu'], slug: (string) $_GET['slug'], ); $status = $client->checkPayment($reference);
Antes de exibir o resultado, confira que order_nsu pertence ao usuario autenticado e que paid, success e amount correspondem ao pedido salvo.
Checklist de producao
- Nunca envie handle, itens internos, logica de preco ou chamada a
payment_checkpelo JavaScript do navegador. - Nunca colete numero, CVV ou validade de cartao; redirecione ao checkout hospedado.
- Derive itens e total do banco no backend; nao confie em preco enviado pelo cliente.
- Use HTTPS, CSRF e autenticacao na rota que cria o checkout.
- Use um
order_nsualeatorio ou nao enumeravel e limite tentativas por IP/usuario. - Torne
transaction_nsuunico no banco e processe webhooks de forma idempotente. - Nao registre dados pessoais, payload completo de cliente ou respostas integrais em logs.
- Responda ao webhook em menos de 1 segundo:
200apos confirmar ou persistir duravelmente;400para solicitar nova tentativa. - Mantenha dependencias atualizadas e rode
composer auditno CI.
Testes
composer install composer check
composer check executa os testes, a analise estatica e a verificacao de estilo.
Os testes nao fazem chamadas reais nem geram cobrancas.
As versoes PHP 8.1, 8.2, 8.3 e 8.4 sao verificadas continuamente pelo CI.