Search by

gabrieldevro / laravel-netopia

Gabrieldevro

NETOPIA Payments (API v2) for Laravel: card payments, transaction status and signed IPN verification.

Package info

github.com/Gabrieldevro/laravel-netopia

pkg:composer/gabrieldevro/laravel-netopia

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-10-21 11:59 UTC

This package is auto-updated.

Last update: 2026-10-28 00:13:31 UTC


README

Plăți cu cardul prin NETOPIA Payments (API v2) în Laravel: pornirea plății, statusul tranzacției și IPN verificat prin semnătură.
NETOPIA Payments API v2 for Laravel — card payments, transaction status and signed IPN verification.

tests Laravel PHP License

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.

Făcut de Gabriel Dev. Integrez plăți online (NETOPIA, Stripe) în magazine și platforme Laravel.
Ai nevoie de integrare? Programează o consultație.