gordalina/easypay-php
PHP library for integrating Easypay payments into your application, with helpers for creating payment references, handling callbacks, and working with Easypay’s API in a simple, framework-agnostic way.
composer require gordalina/easypay-php — there is no Laravel service provider and no package discovery. Nothing registers itself; the wiring is entirely on you.src/Easypay.php (the public method surface — this is what you actually call), src/Config.php (credentials and base URL), then src/Request/ (one class per operation: reference, card, direct debit, status).cin (client identification number), user, password, and the account's base_url. Production is typically https://www.easypay.pt/_s/; confirm test endpoints with your account manager before assuming they exist.Minimal wiring:
// config/services.php
'easypay' => [
'cin' => env('EASYPAY_CIN'),
'user' => env('EASYPAY_USER'),
'password' => env('EASYPAY_PASSWORD'),
'base_url' => env('EASYPAY_BASE_URL', 'https://www.easypay.pt/_s/'),
],
// AppServiceProvider::register()
$this->app->singleton(\Easypay\Config::class, fn () => new \Easypay\Config(config('services.easypay')));
$this->app->singleton(\Easypay\Easypay::class, fn ($app) => new \Easypay\Easypay($app->make(\Easypay\Config::class)));
Your first use case should be the checkout → Multibanco reference flow: create a payment, render entity/reference/amount to the customer, store the raw response, then poll or receive a notification to mark the order paid. It exercises config, request building, response parsing, and status lookup in one path, which is a good smoke test before touching card or direct debit.
Easypay\Easypay in a controller. Build App\Services\Payments\EasypayGateway with your own method signatures (createReference(Order $order): Reference, status(string $id): PaymentStatus) returning your own DTOs. The library's return types are loose array/object shapes; the wrapper is what gives you a stable seam if you ever move to easypay v3 or another PSP.MockHandler in feature tests without hitting the network.CreateMultibancoReference, CreateCardPayment, CreateDirectDebit, each with handle() that builds the payload from an order. Keeps your domain out of the transport layer.payments table with order_id, method, reference, entity, amount, status, raw_request, raw_response. When easypay support asks what happened, this is the only thing that answers the question.PaymentInitiated, PaymentConfirmed, PaymentExpired; listeners update the order and send mail. The gateway should never queue mail or touch invoices.everyFiveMinutes) that calls getPaymentStatus on open references and transitions them. Callbacks are best-effort; the schedule is what actually reconciles.dispatch() behind a Redis queue keeps checkout responsive and gives you retry semantics you control.web middleware group — no CSRF, no session. Match the payload's reference and amount against your stored row, then transition idempotently.MockHandler for the HTTP layer, and assert the events fired. Add a "test credentials" block under services.easypay and switch on app()->environment() so no feature test ever reaches production._s/ API. easypay has been pushing their v3/Checkout API for years. Confirm your CIN still works against the legacy endpoints, and make the wrapper your only entry point so the eventual swap is one class.vendor/ to lean on for idiomatic Laravel wiring."10.00" — not integer cents, not a float, not 10. Format with number_format($cents / 100, 2, '.', '') and fail loudly on more than two decimals.base_url trailing slash matters. The library concatenates paths onto it; missing or doubled slashes produce 404s that surface looking like authentication errors.status field and an error message. Check status !== 'ok' explicitly and read the message.o_id / order reference on every create call. Timeouts and queue redeliveries can produce two references for one order otherwise; dedupe on your side before retrying.application/x-www-form-urlencoded, not JSON. Use $request->post(); don't validate against a JSON shape.paid boolean; store easypay's own status string.Log::withContext(['easypay' => $payload]); you will want the correlation details when reconciling.How can I help you explore Laravel packages today?