Looking to hire Laravel developers? Try LaraJobs
This package is not available.

laravel-netopia maintained by gabrieldevro

Description
NETOPIA Payments (API v2) for Laravel: card payments, transaction status and signed IPN verification.
Last update
2026/10/21 13:59 (dev-main)
License
Links
Downloads
0

Comments
comments powered by Disqus

Ce face

🔗 Pornire plată Netopia::startPayment() trimite comanda și întoarce URL-ul paginii de plată NETOPIA
🔎 Status Netopia::status() interoghează tranzacția, util ca verificare suplimentară
🔐 IPN securizat verifică JWT-ul Verification-token (RS512) cu cheia publică NETOPIA, emitentul, POS-ul, expirarea și hash-ul SHA-512 al corpului
📣 Evenimente fiecare IPN valid emite NetopiaPaymentUpdated, pe care îl asculți ca să marchezi comanda
🧪 Sandbox trecerea între test și producție se face dintr-o singură variabilă

Fără SDK extern: doar HTTP client-ul Laravel și OpenSSL.

Instalare

composer require gabrieldevro/laravel-netopia
php artisan vendor:publish --tag=netopia-config   # opțional

.env:

NETOPIA_API_KEY=cheia-din-panoul-netopia
NETOPIA_POS_SIGNATURE=XXXX-XXXX-XXXX-XXXX-XXXX
NETOPIA_SANDBOX=true
NETOPIA_PUBLIC_KEY=/cale/catre/netopia-public.cer   # sau conținutul PEM
NETOPIA_NOTIFY_URL="${APP_URL}/netopia/ipn"
NETOPIA_REDIRECT_URL="${APP_URL}/comanda/finalizata"

Utilizare

1. Pornești plata

use Gabrieldev\Netopia\Facades\Netopia;

$result = Netopia::startPayment([
    'orderID'     => $order->number,
    'amount'      => $order->total,          // 249.90 (lei, nu bani)
    'description' => "Comanda #{$order->number}",
    'billing'     => [
        'email' => $order->email, 'phone' => $order->phone,
        'firstName' => $order->first_name, 'lastName' => $order->last_name,
        'city' => $order->city, 'details' => $order->address,
    ],
    'products' => $order->items->map(fn ($i) => [
        'name' => $i->name, 'code' => $i->sku, 'category' => 'produse', 'price' => $i->price, 'vat' => 19,
    ])->all(),
]);

$order->update(['ntp_id' => $result->ntpId]);

return redirect()->away($result->paymentUrl);

2. Primești confirmarea (IPN)

Pachetul înregistrează automat POST /netopia/ipn. Ruta trebuie exclusă de la verificarea CSRF, pentru că NETOPIA nu trimite token:

// bootstrap/app.php
->withMiddleware(fn ($m) => $m->validateCsrfTokens(except: ['netopia/ipn']))

Asculți evenimentul:

use Gabrieldev\Netopia\Events\NetopiaPaymentUpdated;

Event::listen(function (NetopiaPaymentUpdated $event) {
    $order = Order::where('number', $event->orderId)->firstOrFail();

    match (true) {
        $event->status->isSuccessful() => $order->markAsPaid($event->ntpId),
        $event->status->isFailed()     => $order->markAsFailed($event->status->name),
        default                        => null, // în așteptare
    };
});

Un IPN cu semnătură greșită, corp modificat, alt POS sau token expirat primește 400 și nu emite evenimentul.

Statusuri

PaymentStatus este un enum cu toate statusurile API v2 (Paid, Confirmed, Pending, Declined, Canceled, Expired etc.) și metodele isSuccessful(), isFailed() și isPending().

Teste

composer test

Testele rulează offline:

  • HTTP-ul către NETOPIA e simulat cu Http::fake().
  • IPN-ul e semnat cu o pereche de chei RSA generată la rulare.
  • Cazurile acoperite: corp modificat, alt POS, alt emitent, token expirat, header lipsă și semnătură cu altă cheie.

Notă. Pachetul folosește API-ul v2 NETOPIA, cu endpoint-urile /payment/card/start și /operation/status. Testează întotdeauna în sandbox și verifică formatul exact al câmpurilor cu documentația oficială NETOPIA pentru contul tău înainte de a trece în producție.