Integra con vexpay/laravel
Paquete para Laravel 12/13: facade, webhooks verificados como eventos, checkouts Billable con registro de pago sincronizado, vendedores de marketplace, checkout en Blade y fakes de prueba.
Instalación
composer require vexpay/laravel
php artisan vexpay:install
php artisan migrate| Requisito | Compatible |
|---|---|
| Laravel | 12 o 13 (cada versión que aún recibe parches de seguridad) |
| PHP | 8.2 o superior (Laravel 13 requiere 8.3) |
| Cliente HTTP | El Guzzle 7 u 8 que ya tiene tu app |
| Paquete | vexpay/laravel en Packagist (packagist.org/packages/vexpay/laravel); instala vexpay/vexpay-php |
VEXPAY_API_KEY=vk_test_replace_me
VEXPAY_WEBHOOK_SECRET=whsec_replace_meRegistra https://tu-app.example/vexpay/webhook como endpoint de webhooks en el portal y verifica la entrega con php artisan vexpay:webhook-test. El facade VexPay (o un VexPay\VexPayClient inyectado) expone el SDK de PHP completo.
Acepta pagos con Billable
use VexPay\Laravel\Billable;
class Order extends Model
{
use Billable;
}
// En un controlador: redirige (303) al checkout alojado, o devuelve
// { id, url, clientSecret } en solicitudes JSON.
return $order->checkout($order->total_usd, [
'description' => "Pedido #{$order->number}",
'successUrl' => route('orders.thanks', $order),
]);checkout() crea una sesión de checkout y guarda una fila PENDING en vexpay_payments vinculada al modelo. Para incrustar en lugar de redirigir usa <x-vexpay-checkout :checkout="$checkout" />, que solo envía al navegador el client secret de la sesión.
Cumple desde los eventos de cobro
Los webhooks payment.* verificados actualizan el registro local. El estado solo avanza (PENDING → COMPLETED / FAILED / CANCELED, COMPLETED → REVERSED), así que reintentos y entregas fuera de orden son inofensivos y los eventos de cobro se disparan exactamente una vez por transición.
use VexPay\Laravel\Events\Billing\PaymentSucceeded;
Event::listen(function (PaymentSucceeded $event) {
$event->billable()->markPaid($event->payment->payment_id);
});Vendedores de marketplace
use VexPay\Laravel\HasVexPayMerchant;
class Seller extends Model
{
use HasVexPayMerchant;
}
$seller->createAsVexPayMerchant([
'name' => 'María Pérez',
'identification' => 'V12345678',
'contactEmail' => 'maria@example.com',
'contactPhone' => '04141234567',
]);
$seller->payout(1523.40, 'Venta #991', 'order-991'); // la misma referencia nunca paga dos vecesPruebas
use VexPay\Laravel\Facades\VexPay;
use VexPay\Laravel\Testing\InteractsWithVexPay;
VexPay::fake();
$this->post(route('orders.pay', $order))->assertRedirect();
VexPay::assertCheckoutCreated(25.00);
$this->postVexPayPaymentWebhook($order->vexpayPayments()->first(), 'payment.completed')
->assertNoContent();