Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pagarme Sdk Laravel Package

quantumtecnology/pagarme-sdk

A lightweight Laravel/PHP SDK for the Pagar.me payment gateway, offering a simple integration layer for transactions, customers, cards, plans, subscriptions, and webhooks. Add Brazilian payment processing to your app quickly with a fluent API and Laravel service provider support.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this package as unvetted until you have read its source. It has 0 stars, 0 dependents, and no community, so the first hour is due diligence, not integration.

1. Verify what you are actually installing. The repo name and the Composer name frequently diverge on low-adoption packages. Confirm the Packagist entry before running anything:

composer show quantumtecnology/pagarme-sdk --all   # does it exist, what versions?

If it is not on Packagist, add it as a VCS repository in composer.json:

"repositories": [{ "type": "vcs", "url": "https://github.com/Quantum-Tecnology/Pagarme-SDK" }]

2. Read these four things, in order, before writing code:

  • composer.json — PHP constraint, illuminate/* constraints (does it support your Laravel version?), PSR-4 autoload map, and whether extra.laravel.providers exists (auto-discovery) or not (manual registration).
  • src/ — is it a real client with typed request/response objects, or a file_get_contents-style cURL wrapper over the Pagar.me REST API? This determines everything downstream.
  • tests/ — no tests on a payments SDK is a red flag, not a blocker; it means you own the correctness.
  • Last commit date and open issues — an unmaintained SDK against a live payment API will break when Pagar.me versions its endpoints.

3. Sandbox first, always. Pagar.me keys are environment-prefixed (sk_test_… / ak_test_… vs sk_live_…). Put them in .env only:

PAGARME_API_KEY=sk_test_xxxxxxxxxxxxxxxx
PAGARME_BASE_URL=https://api.pagar.me/core/v5

4. First use case — a throwaway artisan tinker or command, not a controller. Prove the auth and a single read call before touching money:

// Verify the real namespace from src/ first; this is the shape, not gospel.
$client = app(\QuantumTecnology\PagarmeSDK\Client::class);
$customer = $client->customers()->create([
    'name'     => 'Test Customer',
    'email'    => '[email protected]',
    'document' => '12345678909',
    'type'     => 'individual',
]);
dump($customer);

Once a customer round-trips in sandbox, do a card token + charge in sandbox, and only then wire it into application code.

5. Have an exit ramp. If the source audit shows a thin, untested wrapper, prefer the official pagarme/pagarme-php SDK (maintained, documented, same API) and keep this package out of your dependency graph entirely. Wrapping the gateway behind your own interface (below) makes that swap a one-file change.

Implementation Patterns

Never call the SDK from a controller. Put it behind a small service layer and bind it in a provider. This is the single highest-value pattern here, because it makes the unvetted dependency replaceable.

// app/Contracts/PaymentGateway.php
interface PaymentGateway
{
    public function charge(array $payload): ChargeResult;
    public function refund(string $transactionId, ?int $amount = null): ChargeResult;
}
// app/Providers/PaymentServiceProvider.php
public function register(): void
{
    $this->app->singleton(PaymentGateway::class, fn () => new PagarmeGateway(
        client: new \QuantumTecnology\PagarmeSDK\Client(config('services.pagarme.key')),
    ));
}

Config, not literals. Add a config/services.php entry and read from it — never env() outside config files (it returns null once config:cache runs):

'pagarme' => [
    'key'      => env('PAGARME_API_KEY'),
    'base_url' => env('PAGARME_BASE_URL', 'https://api.pagar.me/core/v5'),
],

Two-step charge, not one. The only card data that should ever touch your server is a token produced client-side by Pagar.me's checkout/SDK. The server pattern is: create/upsert customer → attach card_token → create transaction. Store card_token, brand, last four, and holder name — never the PAN, never the CVV.

Idempotency is non-negotiable. Network timeouts on POST /transactions are ambiguous: the charge may have succeeded. Send an idempotency key (your own UUID stored on the order) with every create call, and on timeout query by key rather than retrying blind. Retrying a charge without this is how customers get double-billed.

Webhooks: fast 200, then a queued job.

Route::post('/webhooks/pagarme', PagarmeWebhookController::class)
    ->withoutMiddleware(['csrf'])
    ->middleware('throttle:120,1');

In the controller: verify the signature/auth, dispatch(new ProcessPagarmeEvent($payload)), return 200 immediately. In the job: be idempotent — key on the Pagar.me transaction id, and insertOrIgnore / check-before-act so replayed deliveries are harmless. Never trust the webhook body's status as authoritative without re-fetching the transaction when the amount matters.

Split and recipients (marketplaces). If you use split, model recipients as first-class records in your DB with the Pagar.me recipient_id, and compute the split rules in your domain layer — the SDK just transports the array.

Testing. Because the package has no test suite, your tests are the safety net. Fake at the PaymentGateway boundary, not at the HTTP layer:

$this->mock(PaymentGateway::class, fn ($m) => $m
    ->shouldReceive('charge')->once()->andReturn(new ChargeResult('tr_123', 'paid')));

Add one or two sandbox integration tests behind a @group gateway tag and a CI secret, so a Pagar.me API change fails loudly in CI rather than in production.

Logging. Wrap the client in a decorator that logs request/response with card_number, card_cvv, and document redacted. Payments debugging without logs is guesswork; payments logging without redaction is a compliance incident.

Gotchas and Tips

  • Zero dependents means zero field reports. You are the first person to hit every bug. Pin the exact version in composer.lock, and consider vendoring ("prefer-dist" off, commit the lock) so an upstream force-push cannot silently change payment behaviour.
  • Auto-discovery may be absent. If composer.json has no extra.laravel.providers, register the service provider and any facade manually in bootstrap/providers.php (Laravel 11+) or config/app.php.
  • env() in the package's own config file will bite you. If the package ships a config/pagarme.php that calls env() at load time, publishing it and then running config:cache can freeze a stale or null key. Verify the value after caching.
  • API version drift. Pagar.me's current core is v5; older SDKs target v4 payload shapes (amount in cents vs. different nesting, payment_method casing). If calls 404 or 422 on fields you know exist, check the base URL and the API version the package was written against — the repo's last commit date is your clue.
  • Amounts are integers in cents. R$ 19,90 is 1990. Passing 19.90 silently creates a R$ 0,19 charge on some endpoints.
  • Brazilian validation happens server-side and fails ugly. CPF/CNPJ must be digits-only or Pagar.me rejects it; phone numbers are +55 format. Validate locally (e.g. laravel-validation-rules/ptbr) so customers get a useful message instead of a gateway 400.
  • Errors are not exceptions by default. Most thin wrappers return the decoded body regardless of HTTP status, so a declined card and a 500 look identical. Check for an errors key / status code explicitly and map to a domain exception (CardDeclined, InsufficientFunds, GatewayUnavailable) so retry logic can distinguish "retry" from "do not retry."
  • Do not retry non-idempotent calls. Queue retries belong on webhooks and refunds, not on create transaction, unless you have an idempotency key.
  • Webhook verification differs by version. Some Pagar.me setups use HTTP Basic auth embedded in the postback URL, others sign the body. Read src/ for a verifier; if there isn't one, implement it yourself — an unauthenticated webhook endpoint lets anyone mark orders as paid.
  • Timeouts. Set a connect timeout (~5s) and read timeout (~15s) on the HTTP client. The PHP default can hang a worker until max_execution_time, and under load that exhausts your FPM pool during exactly the traffic spike you care about.
  • Extension points are limited — wrap, don't extend. If the client class is final or its methods are private, subclassing is a dead end. Keep the PaymentGateway interface and adapt; that also lets you add circuit-breaking, metrics, and redacted logging without forking.
  • Maintenance risk is the headline. Budget for the package being abandoned: no security patches, no new Pagar.me features (Pix automatic, newer 3DS flows). Write the adapter so switching to pagarme/pagarme-php is a single class swap, and revisit the dependency each time Pagar.me ships an API change.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource