tear/moip-bundle
A Symfony bundle that integrates the MoIP payment gateway into your application, providing services and configuration for handling payments, transactions, and MoIP API communication through a clean, bundle-based setup.
Before writing a single line, understand the mismatch: tear/moip-bundle is a Symfony bundle, not a Laravel package. As a Laravel developer you cannot composer require this and get a service provider auto-wired — Symfony bundles rely on Extension, CompilerPass, and a DependencyInjection container that Laravel does not share. The bundle's real value is a thin factory wrapping the underlying MoIP PHP SDK (moip/moip-sdk-php), and that SDK is what you should evaluate first.
Minimal steps if you still want to inspect or adapt it:
git clone https://github.com/leonnleite/moip-bundle and open src/ — read MoipBundle.php, the DependencyInjection/Configuration.php, and the service definitions in Resources/config/services.yml. That config file tells you exactly which services and parameters (credentials, environment) the bundle exposes.environment = sandbox|production). MoIP uses HTTP Basic auth over token:key, so those two strings are your whole auth story.moip.customer, moip.order, and moip.payment services (or the single moip client exposed by the SDK). For Laravel you would replicate that with the raw SDK:$moip = new Moip(new MoipBasicAuth(config('services.moip.token'), config('services.moip.key')), Moip::ENDPOINT_SANDBOX);
$customer = $moip->customers()->create()->setEmail('...')->setOwnId('...');
Treat the bundle purely as documentation of how MoIP's SDK was intended to be composed — service names, config keys, environment toggles — and lift that into a Laravel service provider yourself.
Adapter pattern (the realistic path). Bind the SDK client into Laravel's container in a MoipServiceProvider and mirror the bundle's config shape so any existing Symfony code you're porting maps 1:1:
$this->app->singleton(Moip::class, function () {
$endpoint = config('services.moip.env') === 'production'
? Moip::ENDPOINT_PRODUCTION
: Moip::ENDPOINT_SANDBOX;
return new Moip(
new MoipBasicAuth(config('services.moip.token'), config('services.moip.key')),
$endpoint
);
});
Config parity. The bundle's Configuration.php will show a tear_moip: tree with keys like token, key, environment, possibly account_id. Recreate that as config/services.php → 'moip' => ['token' => env('MOIP_TOKEN'), ...]. Never hardcode — MoIP sandbox and production tokens differ and a leaked production token lets anyone move money.
Repository-style wrapping. The SDK is fluent and stateless-ish; wrap it in a domain service (PaymentGateway) so controllers never touch MoIP types directly. This is the pattern the bundle encourages (services, not facades) and it's also the pattern that survives if you later swap gateways (Pagar.me, Stone, Asaas — all common in the Brazilian market).
Webhook handling. MoIP posts async notifications for order/payment status. The bundle doesn't give you an event subscriber for this out of the box, so in Laravel add a route (POST /webhooks/moip), verify by re-fetching the order via $moip->orders()->get($id) rather than trusting the payload, and queue the processing. This is the single most important integration tip: never mutate local state from the webhook body alone.
Job/queue split. Payment creation and webhook reconciliation belong in queued jobs. MoIP's API is synchronous but slow (500ms–2s per call in Brazil), and failure/timeout retries are common. Use DB::transaction around your local order record but keep the HTTP call outside the transaction.
Idempotency. MoIP supports an ownId on orders and customers — use your own UUID there. This is your defense against duplicate orders when a network blip forces a retry.
laravel tag, no facade, no auto-discovery. Attempting composer require tear/moip-bundle in Laravel installs it and then does nothing — the bundle only activates through Symfony's kernel.Moip::ENDPOINT_PRODUCTION still resolves to a live host.each(), create_function, possibly mcrypt references, and Symfony 2/3 service definitions that fail on modern containers. If you vendored any of it, audit line by line.Authorization: Basic base64(token:key). A common bug is passing only the token — you will get 401s that look like permission errors but are actually malformed Basic headers.Moip::ENDPOINT_* constant mismatch silently routes sandbox traffic to production or vice versa. Guard this with a hard fail in your service provider if env is unset.1000). String "10.00" will be rejected or silently misparsed. Always cast: (int) round($amount * 100).Guzzle client with retry middleware. In Laravel you'd skip this and wrap the SDK yourself with a RetryableHttpClient.X-MOIP-REQUEST-ID header — log it on every call. When a 4xx comes back with a cryptic { "errors": [...] } body, that ID is what MoIP support asks for first.moip/moip-sdk-php directly (or switch to a maintained Brazilian gateway — Asaas, Pagar.me, and Mercado Pago all have healthier Laravel integrations) and use this repository only as a reference for credential/config shape.How can I help you explore Laravel packages today?