Search by

odinizfilho / infinitepay-php

odinizfilho

SDK PHP server-side para o Checkout Integrado da InfinitePay

Package info

github.com/odinizfilho/infinitepay-php

pkg:composer/odinizfilho/infinitepay-php

Statistics

Installs: 25

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-07-13 21:29 UTC

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, json e mbstring
  • 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_check pelo 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_nsu aleatorio ou nao enumeravel e limite tentativas por IP/usuario.
  • Torne transaction_nsu unico 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: 200 apos confirmar ou persistir duravelmente; 400 para solicitar nova tentativa.
  • Mantenha dependencias atualizadas e rode composer audit no 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.

Referencia da API