codetech/laravel-eupago

Eupago payment gateway integration for Laravel — Multibanco, MB WAY, PayShop and PaysafeCard payments.

Maintainers

Package info

github.com/CodeTechAgency/laravel-eupago

pkg:composer/codetech/laravel-eupago

Transparency log

Statistics

Installs: 48

Dependents: 0

Suggesters: 0

Stars: 3

Open Issues: 1

v3.6.0 2026-07-15 16:49 UTC

README

Laravel Eupago

Laravel Eupago

Latest version Total downloads Tests GitHub license

Eupago is a Portuguese payment gateway that lets businesses accept the payment methods used in Portugal — Multibanco references, MB WAY, PayShop, and more — through a single API. This package integrates that gateway into Laravel, end to end:

  • Create payments for Multibanco (MB), MB WAY, PayShop, and PaysafeCard.
  • Persist payment references as Eloquent models, attached to any model of yours (an Order, an Invoice, …) through ready-made traits.
  • Handle Eupago's webhooks out of the box: the package ships the callback endpoints, validates the payload, marks the reference as paid, and fires an event (MBReferencePaid, MBWayReferencePaid, PayShopReferencePaid, PaysafeCardReferencePaid) you can hook your business logic on.
  • Query a reference's status on demand, for reconciliation or missed callbacks.

You can use it as a full integration (traits, models, webhooks) or as a thin API client (payment classes only) — see Routes for how to switch.

Table of contents

Requirements

Package version Laravel PHP Status
3.x (master) 10 – 13 ≥ 8.1 Active
2.x (2.x) 9 / 10 ≥ 8.0.2 Security fixes
1.x (1.x) 8 ≥ 8.0 End of life

Upgrading from an older version? See the upgrade guide.

Installation

Add the package to your Laravel application using Composer:

composer require codetech/laravel-eupago

The service provider is registered automatically via package discovery.

Publish and run the migrations:

php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=migrations
php artisan migrate

Optionally, publish the configuration file and the translations:

php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=config
php artisan vendor:publish --provider="CodeTech\EuPago\Providers\EuPagoServiceProvider" --tag=translations

Configuration

The package is configured through environment variables (see config/eupago.php):

EUPAGO_ENV=test
EUPAGO_API_KEY=demo-xxxx-xxxx-xxxx-xxx
EUPAGO_CHANNEL=demo
EUPAGO_ROUTES=true

Environment

Two environments are available: test and prod. Use test (the Eupago sandbox, sandbox.eupago.pt) while developing, and switch to prod (clientes.eupago.pt) when your application is ready to take real payments.

API key and channel

EUPAGO_API_KEY is the API key of your Eupago channel — you find it in the Eupago backoffice, where each channel has its own key. EUPAGO_CHANNEL is the channel name; incoming callbacks are validated against it.

Routes

The package supports two levels of usage:

  • Full integration (default): use the traits and models to persist references, and let the package handle Eupago's webhooks — it registers the callback routes (/eupago/*/callback) automatically.
  • Thin API client: use only the payment classes (e.g. new MB(...)->create()) and handle persistence and webhooks yourself.

If you only need the thin client, disable the automatic route registration:

EUPAGO_ROUTES=false

With the routes disabled you can still mount the package's callback controllers on routes of your own, giving you full control over the path and middleware:

use CodeTech\EuPago\Http\Controllers\MBController;

Route::get('webhooks/eupago/mb', [MBController::class, 'callback'])
    ->middleware('web')
    ->name('eupago.mb.callback');

Note: if your application caches routes, run php artisan route:clear after changing this setting.

Usage

Every payment method follows the same pattern: build the payment object, call create() to run the request against the Eupago API, and persist the returned reference data — or let the method's trait do the create-and-persist in a single call. When Eupago confirms the payment, the package handles the callback and fires the method's *ReferencePaid event.

Multibanco (MB)

Create an MB reference:

use CodeTech\EuPago\MB\MB;

$order = Order::find(1);

$mb = new MB(
    $order->value,        // payment value
    $order->id,           // your identifier, echoed back in the callback
    now(),                // start date
    now()->addDays(3),    // end date (payment limit)
    $order->value,        // minimum accepted value
    $order->value,        // maximum accepted value
    false                 // allow duplicated payments
);

try {
    $mbReferenceData = $mb->create();

    if ($mb->hasErrors()) {
        // handle errors
    }

    $order->mbReferences()->create($mbReferenceData);
} catch (\Exception $e) {
    // handle exception
}

$mbReferenceData contains the normalized payment information:

[
    'success' => true,
    'state' => 0,
    'response' => "OK",
    'entity' => "82167",
    'reference' => "000001236",
    'value' => "3.00000",
]

Alternatively, use the HasMultibancoReferences trait on the models for which you want to generate MB references:

use CodeTech\EuPago\Traits\HasMultibancoReferences;

class Order extends Model
{
    use HasMultibancoReferences;
}

With the trait applied, you can create and persist a reference in a single call. It returns the persisted reference on success, or the errors on failure:

$reference = $order->createMbReference($value, $id, $startDate, $endDate, $minValue, $maxValue);

Retrieve the MB references:

$mbReferences = $order->mbReferences;

When the reference is paid, the callback fires an MBReferencePaid event.

MB WAY

Create an MB WAY payment request — the customer confirms it on their phone through the MB WAY app:

use CodeTech\EuPago\MBWay\MBWay;

$order = Order::find(1);

$mbway = new MBWay(
    $order->value,     // payment value
    $order->id,        // your identifier (int), echoed back as `identificador` in the callback
    '912345678',       // the customer's MB WAY alias (phone number)
    'Order #1'         // optional description
);

try {
    $mbwayReferenceData = $mbway->create();

    if ($mbway->hasErrors()) {
        // handle errors
    }

    $order->mbwayReferences()->create($mbwayReferenceData);
} catch (\Exception $e) {
    // handle exception
}

Alternatively, use the HasMbWayReferences trait:

use CodeTech\EuPago\Traits\HasMbWayReferences;

class Order extends Model
{
    use HasMbWayReferences;
}
$reference = $order->createMbwayReference($value, $id, $alias);

Retrieve the MB WAY references:

$mbwayReferences = $order->mbwayReferences;

When the payment is confirmed, the callback fires an MBWayReferencePaid event.

PayShop

Create a PayShop reference:

use CodeTech\EuPago\PayShop\PayShop;

$order = Order::find(1);

$payShop = new PayShop(
    $order->value,   // payment value
    $order->id       // your identifier, echoed back in the callback
);

try {
    $payShopReferenceData = $payShop->create();

    if ($payShop->hasErrors()) {
        // handle errors
    }

    $order->payShopReferences()->create($payShopReferenceData);
} catch (\Exception $e) {
    // handle exception
}

$payShopReferenceData contains the normalized payment information:

[
    'success' => true,
    'state' => 0,
    'response' => "OK",
    'reference' => 1800000132722,
    'value' => "10.00000",
]

Alternatively, use the HasPayShopReferences trait:

use CodeTech\EuPago\Traits\HasPayShopReferences;

class Order extends Model
{
    use HasPayShopReferences;
}
$reference = $order->createPayShopReference($value, $id);

Retrieve the PayShop references:

$payShopReferences = $order->payShopReferences;

When the reference is paid, the callback fires a PayShopReferencePaid event.

PaysafeCard

Unlike the reference-based methods above, PaysafeCard is a redirect flow: Eupago returns a payment url that you must redirect the customer to, along with a reference for the payment (there is no entity). You also pass your own id (e.g. the order id), which Eupago echoes back in the callback as identificador, and you may optionally pass a url_retorno to control where the customer lands after paying.

use CodeTech\EuPago\PaysafeCard\PaysafeCard;

$order = Order::find(1);

$paysafeCard = new PaysafeCard(
    $order->value,
    $order->id,
    route('checkout.return') // optional url_retorno
);

try {
    $paysafeCardReferenceData = $paysafeCard->create();

    if ($paysafeCard->hasErrors()) {
        // handle errors
    }

    $reference = $order->paysafeCardReferences()->create($paysafeCardReferenceData);

    // Redirect the customer to PaysafeCard to complete the payment
    return redirect()->away($reference->url);
} catch (\Exception $e) {
    // handle exception
}

$paysafeCardReferenceData contains the normalized payment information:

[
    'success' => true,
    'state' => 0,
    'response' => "OK",
    'identifier' => "order-49",
    'reference' => "000017428",
    'url' => "https://clientes.eupago.pt/paysafecard/pay/...",
    'value' => 25.00,
]

Alternatively, use the HasPaysafeCardReferences trait:

use CodeTech\EuPago\Traits\HasPaysafeCardReferences;

class Order extends Model
{
    use HasPaysafeCardReferences;
}

With the trait applied, you can create and persist a reference in a single call. It returns the persisted reference (whose url you redirect to) on success, or the errors on failure:

$reference = $order->createPaysafeCardReference($value, $id, $returnUrl);

Retrieve the PaysafeCard references:

$paysafeCardReferences = $order->paysafeCardReferences;

When the payment is completed, the callback fires a PaysafeCardReferencePaid event.

Callbacks

Eupago notifies your application of confirmed payments through a webhook — configure the callback URL in the Eupago backoffice for your channel. The package registers one endpoint per payment method:

Payment method Callback endpoint Event fired
Multibanco GET /eupago/mb/callback MBReferencePaid
MB WAY GET /eupago/mbway/callback MBWayReferencePaid
PayShop GET /eupago/payshop/callback PayShopReferencePaid
PaysafeCard GET /eupago/paysafecard/callback PaysafeCardReferencePaid

Each callback validates the payload (including the channel and API key), matches the pending reference on referencia and value, marks it as paid, and fires the corresponding event with the reference as payload.

All callbacks receive the same query parameters:

Name Type Required
valor float yes
canal string yes
referencia string yes
transacao string yes
identificador string yes
mp string yes
chave_api string yes
data date time (Y-m-d:H:i:s) yes
entidade string yes
comissao float yes
local string no

Querying reference status

Besides the callback, you can query a reference's current status on demand — useful for reconciliation or when a callback is missed or delayed. Eupago resolves any reference type (MB, MB WAY, PayShop) through a single reference-info endpoint, so the same call works regardless of how the reference was created:

use CodeTech\EuPago\EuPago;

$eupago = new EuPago;

try {
    $status = $eupago->status($reference, $entity);

    if ($eupago->hasErrors()) {
        // handle errors
    }
} catch (\Exception $e) {
    // handle exception
}

The $entity argument is optional. $status is mapped to normalized keys, where reference_state holds the payment status (e.g. "pendente", "pago"):

[
    'success' => true,
    'state' => 0,
    'response' => "OK",
    'entity' => "81921",
    'reference' => "800152011",
    'identifier' => "order-123",
    'reference_state' => "pendente",
    'created_date' => "2026-06-27",
    'created_time' => "00:22:49",
    'archived' => false,
]

Testing & code quality

Run the test suite, static analysis, and code-style checks via Composer:

composer test      # Pest test suite
composer analyse   # PHPStan/Larastan static analysis
composer lint      # Pint code-style check (run `composer format` to fix)

Upgrading

Please see UPGRADE.md for information on how to upgrade between versions.

Changelog

Every release is documented on the GitHub releases page.

Contributing

Contributions are welcome! Please read the contributing guidelines before opening an issue or pull request.

Security

If you discover a security vulnerability, please follow the security policy — do not report it publicly.

Support

If this package helps you, consider starring the repository — it helps other developers discover it.

License

codetech/laravel-eupago is open-sourced software licensed under the MIT license.

About CodeTech

CodeTech is a web development agency based in Matosinhos, Portugal. Oh, and we LOVE Laravel!