PHPackages                             rmirandasv/laravel-wompi - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. rmirandasv/laravel-wompi

ActiveLibrary[Payment Processing](/categories/payments)

rmirandasv/laravel-wompi
========================

A Laravel package to integrate with the Wompi payment gateway for El Salvador.

1.0.0(2mo ago)2271MITPHPPHP ^8.2CI passing

Since Oct 15Pushed 2mo agoCompare

[ Source](https://github.com/rmirandasv/laravel-wompi)[ Packagist](https://packagist.org/packages/rmirandasv/laravel-wompi)[ RSS](/packages/rmirandasv-laravel-wompi/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (12)Versions (5)Used By (0)

Laravel Wompi
=============

[](#laravel-wompi)

[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/e2df0db5111cc996698331f261bf2635d5d982b997163dd61bcd20b2f000f216/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e322d3838393242462e737667)](https://php.net)[![PHP 8.4](https://camo.githubusercontent.com/baf0a85636a322ff99514b39a158b0de14708c8758b3427397df0a09897c82f8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e342d626c75652e737667)](https://php.net)[![Laravel Version](https://camo.githubusercontent.com/bc021f1dee4f465613fc3b6a549fed9ed37d33569d472c90de11c5a982ea25bb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d3130253242253743313125324225374331322532422d4646324432302e737667)](https://laravel.com)

Un paquete de Laravel completo y robusto para integrar la pasarela de pago [Wompi](https://wompi.sv) de El Salvador en tus aplicaciones. Soporte oficial para PHP 8.2, 8.3, 8.4 y 8.5.

📋 Características
-----------------

[](#-características)

- ✅ **Enlace de Pago** - Genera URLs y códigos QR para pagos
- ✅ **Transacciones 3DS** - Soporte completo para pagos con 3D Secure
- ✅ **Tokenización** - Almacena tarjetas de forma segura para uso futuro
- ✅ **Cargos Recurrentes** - Procesa pagos recurrentes con tarjetas tokenizadas
- ✅ **Validación de Webhooks** - Verificación HMAC de notificaciones
- ✅ **Validación de Redirects** - Valida parámetros de URL de retorno
- ✅ **Datos del Aplicativo** - Consulta configuración y capacidades
- ✅ **Transacciones de Prueba** - Entorno de desarrollo/testing
- ✅ **Autenticación OAuth2** - Gestión automática de tokens con caché
- ✅ **Facade Laravel** - Interfaz limpia y expresiva

📦 Instalación
-------------

[](#-instalación)

Instala el paquete vía Composer:

```
composer require rmirandasv/laravel-wompi
```

El paquete se auto-registra automáticamente gracias al auto-discovery de Laravel.

### Publicar Configuración (Opcional)

[](#publicar-configuración-opcional)

```
php artisan vendor:publish --tag="wompi-config"
```

Esto creará el archivo `config/wompi.php` en tu aplicación.

⚙️ Configuración
----------------

[](#️-configuración)

Agrega las siguientes variables a tu archivo `.env`:

```
WOMPI_AUTH_URL=https://id.wompi.sv
WOMPI_API_URL=https://api.wompi.sv/v1
WOMPI_CLIENT_ID=tu_client_id
WOMPI_CLIENT_SECRET=tu_client_secret
WOMPI_WEBHOOK_SECRET=tu_webhook_secret
```

> 💡 **Nota**: Obtén tus credenciales desde tu dashboard de Wompi.

🚀 Uso
-----

[](#-uso)

### Crear Enlace de Pago

[](#crear-enlace-de-pago)

Genera un enlace de pago (Payment Link) para que tus clientes realicen pagos:

```
use Rmirandasv\Wompi\Facades\Wompi;

$response = Wompi::createPaymentLink([
    'identificadorEnlaceComercio' => 'ORDER-' . uniqid(),
    'monto' => 100.00,
    'nombreProducto' => 'Mi Producto',
    'formaPago' => [
        'permitirTarjetaCreditoDebido' => true,
        'permitirPagoConPuntoAgricola' => true,
        'permitirPagoEnCuotasAgricola' => false,
    ],
    'configuracion' => [
        'urlRedirect' => 'https://tudominio.com/payment/success',
        'urlRetorno' => 'https://tudominio.com/cart',
        'emailsNotificacion' => '[email protected]',
        'urlWebhook' => 'https://tudominio.com/webhooks/wompi',
        'notificarTransaccionCliente' => true,
    ],
]);

// Respuesta
$paymentUrl = $response['urlEnlace'];        // URL del enlace de pago
$qrCodeUrl = $response['urlQrCodeEnlace'];   // URL del código QR
$paymentId = $response['idEnlace'];          // ID del enlace
$isProduction = $response['estaProductivo']; // true/false

// Redirigir al usuario al enlace de pago
return redirect($paymentUrl);
```

### Crear Transacción 3DS

[](#crear-transacción-3ds)

Procesa una transacción directa con 3D Secure:

```
$response = Wompi::createTransaction3DS([
    'monto' => 100.00,
    'tarjeta' => [
        'numeroTarjeta' => '4111111111111111',
        'mesExpiracion' => '12',
        'anioExpiracion' => '2025',
        'cvv' => '123',
        'nombreTarjeta' => 'JUAN PEREZ',
    ],
    'urlRedirect' => 'https://tudominio.com/payment/success',
    'identificadorTransaccionComercio' => 'TXN-' . uniqid(),
]);

// Respuesta
$transactionId = $response['idTransaccion'];
$url3DS = $response['urlCompletarPago3Ds']; // URL para completar 3DS

// Redirigir al cliente a la URL de 3DS
return redirect($url3DS);
```

### Tokenización de Tarjetas

[](#tokenización-de-tarjetas)

Guarda tarjetas de forma segura para pagos futuros:

```
// Tokenizar una tarjeta
$response = Wompi::tokenizeCard([
    'numeroTarjeta' => '4111111111111111',
    'mesExpiracion' => '12',
    'anioExpiracion' => '2025',
    'cvv' => '123',
    'nombreTarjeta' => 'JUAN PEREZ',
    'identificadorCliente' => 'CUSTOMER-123',
]);

$tokenId = $response['idToken'];

// Obtener información de un token
$tokenInfo = Wompi::getTokenizedCard($tokenId);

// Eliminar un token
Wompi::deleteTokenizedCard($tokenId);
```

### Cargos Recurrentes

[](#cargos-recurrentes)

Realiza cargos con tarjetas previamente tokenizadas:

```
$response = Wompi::createRecurringCharge([
    'idToken' => 'token_abc123',
    'monto' => 50.00,
    'identificadorTransaccionComercio' => 'RECURRING-' . uniqid(),
    'descripcion' => 'Suscripción Mensual',
]);

$transactionId = $response['idTransaccion'];
$isApproved = $response['esAprobada'] ?? false;
```

### Consultar Datos del Aplicativo

[](#consultar-datos-del-aplicativo)

Obtén información sobre las capacidades de tu aplicativo:

```
$aplicativoData = Wompi::getAplicativoData();

// Información disponible:
$soportaPuntos = $aplicativoData['soportaPagoConPuntos'];
$soportaCuotas = $aplicativoData['soportaPagoEnCuotas'];
$cuotasDisponibles = $aplicativoData['cuotasDisponibles'];
```

🔔 Webhooks y Eventos
--------------------

[](#-webhooks-y-eventos)

Los webhooks son la forma principal de recibir notificaciones de transacciones exitosas. El paquete ofrece múltiples formas de manejar estas notificaciones: a través de **Eventos de Laravel** o usando tu propio controlador.

### 1. Usar Eventos de Laravel (Recomendado)

[](#1-usar-eventos-de-laravel-recomendado)

El paquete despacha eventos automáticamente cuando valida un webhook exitosamente. Puedes escucharlos en tu aplicación:

- `Rmirandasv\Wompi\Events\WompiWebhookReceived`: Se dispara siempre que se recibe y valida una notificación de Wompi, útil para guardar logs en crudo.
- `Rmirandasv\Wompi\Events\WompiPaymentProcessed`: Se dispara junto al anterior, pero incluye la propiedad `$isSuccessful` (booleano) facilitando saber si el pago fue aprobado o no.

**Ejemplo de Listener:**

```
namespace App\Listeners;

use Rmirandasv\Wompi\Events\WompiPaymentProcessed;

class ProcessWompiPayment
{
    public function handle(WompiPaymentProcessed $event): void
    {
        $payload = $event->payload;
        $orderId = $payload['enlacePago']['identificadorEnlaceComercio'] ?? null;

        if ($event->isSuccessful) {
            // Lógica para marcar orden como pagada...
            \Log::info("Pago exitoso procesado para la orden: {$orderId}");
        } else {
            // Lógica para marcar orden como fallida...
        }
    }
}
```

### 2. Middleware para validación

[](#2-middleware-para-validación)

Si decides crear tus propios endpoints y controladores para recibir los webhooks y no quieres llamar al método de validación manualmente, puedes usar el middleware incluido.

Primero aségurate de que tu ruta esté excluida del middleware CSRF y usa el alias `wompi.webhook`:

```
Route::post('/webhooks/wompi', [WompiWebhookController::class, 'handle'])
    ->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class])
    ->middleware('wompi.webhook'); // processSuccessfulPayment($webhookData);
            }

            // Siempre retornar 200 OK
            return response()->json(['status' => 'ok'], 200);

        } catch (PaymentGatewayException $e) {
            // Log del error pero retornar 200 para evitar reintentos
            \Log::error('Webhook validation failed: ' . $e->getMessage());
            return response()->json(['status' => 'ok'], 200);
        }
    }

    private function processSuccessfulPayment(array $data): void
    {
        $orderId = $data['enlacePago']['identificadorEnlaceComercio'];
        $transactionId = $data['idTransaccion'];
        $amount = $data['monto'];

        // Actualizar tu orden en la base de datos
        $order = Order::where('reference', $orderId)->first();

        if ($order && !$order->is_paid) {
            $order->update([
                'status' => 'paid',
                'transaction_id' => $transactionId,
                'payment_method' => $data['formaPagoUtilizada'],
                'paid_at' => now(),
            ]);

            // Disparar eventos, enviar emails, etc.
            event(new OrderPaid($order));
        }
    }
}
```

### 2. Registrar tu Ruta

[](#2-registrar-tu-ruta)

En `routes/api.php` o `routes/web.php`:

```
use App\Http\Controllers\WompiWebhookController;

Route::post('/webhooks/wompi', [WompiWebhookController::class, 'handle'])
    ->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
```

### 3. Configurar en Wompi Dashboard

[](#3-configurar-en-wompi-dashboard)

Configura tu webhook URL en el dashboard de Wompi:

```
https://tudominio.com/webhooks/wompi

```

### Datos Disponibles en el Webhook

[](#datos-disponibles-en-el-webhook)

```
$webhookData = [
    'idCuenta' => 'string',
    'fechaTransaccion' => 'string',
    'monto' => 100.00,
    'moduloUtilizado' => 'EnlacePago',
    'formaPagoUtilizada' => 'TarjetaCreditoDebito',
    'idTransaccion' => 'TXN123',
    'resultadoTransaccion' => 'ExitosaAprobada',
    'codigoAutorizacion' => 'AUTH123',
    'idIntentoPago' => 'string',
    'cantidad' => 1,
    'esProductiva' => true,
    'aplicativo' => [...],
    'enlacePago' => [
        'idEnlace' => 123,
        'identificadorEnlaceComercio' => 'ORDER-123',
        'nombreProducto' => 'Mi Producto',
    ],
    'cliente' => [
        'nombre' => 'Juan Pérez',
        'email' => '[email protected]',
        ...
    ],
];
```

🔄 Validación de Redirect URLs
-----------------------------

[](#-validación-de-redirect-urls)

Cuando el usuario regresa de Wompi, valida los parámetros:

```
use Rmirandasv\Wompi\Facades\Wompi;

public function paymentReturn(Request $request)
{
    $params = $request->all();
    $receivedHash = $request->input('hash');

    // Validar la firma
    if (Wompi::validateRedirectParams($params, $receivedHash)) {
        if ($params['esAprobada'] === 'true') {
            // Pago aprobado
            return view('payment.success', [
                'transactionId' => $params['idTransaccion'],
            ]);
        } else {
            // Pago rechazado
            return view('payment.failed', [
                'message' => $params['mensaje'],
            ]);
        }
    }

    // Firma inválida
    abort(403, 'Invalid signature');
}
```

🧪 Transacciones de Prueba
-------------------------

[](#-transacciones-de-prueba)

Para desarrollo y testing:

```
$response = Wompi::executeTestTransaction([
    'monto' => 100.00,
    'resultadoDeseado' => 'Aprobada', // o 'Rechazada'
    'identificadorTransaccionComercio' => 'TEST-' . uniqid(),
]);
```

🔧 Inyección de Dependencias
---------------------------

[](#-inyección-de-dependencias)

También puedes usar inyección de dependencias en lugar de la Facade. El paquete expone un contrato (`Interface`) para facilitar el testing y desacoplar tu código:

```
use Rmirandasv\Wompi\Contracts\WompiClientInterface;
use Rmirandasv\Wompi\DTOs\Requests\PaymentLinkRequestDTO;

class PaymentService
{
    public function __construct(private WompiClientInterface $wompi)
    {
    }

    public function createPayment(array $data)
    {
        // Puedes pasar un array tradicional o usar los nuevos DTOs para mayor seguridad:
        // $dto = PaymentLinkRequestDTO::fromArray($data);
        return $this->wompi->createPaymentLink($data);
    }
}
```

🛡️ Manejo de Excepciones
------------------------

[](#️-manejo-de-excepciones)

El paquete lanza excepciones específicas para diferentes escenarios:

```
use Rmirandasv\Wompi\Exceptions\ConfigurationException;
use Rmirandasv\Wompi\Exceptions\PaymentGatewayException;
use Rmirandasv\Wompi\Exceptions\WompiValidationException;

try {
    $response = Wompi::createPaymentLink($data);
} catch (WompiValidationException $e) {
    // Los datos proporcionados en los DTOs no son válidos
    \Log::error('Validation error: ' . $e->getMessage(), $e->getErrors());
} catch (ConfigurationException $e) {
    // Credenciales no configuradas correctamente
    \Log::error('Wompi configuration error: ' . $e->getMessage());
} catch (PaymentGatewayException $e) {
    // Error comunicándose con la API de Wompi (e.g. 400 Bad Request, 401 Unauthorized)
    \Log::error('Wompi API error: ' . $e->getMessage());

    // Puedes acceder a los detalles del error devueltos por Wompi
    $statusCode = $e->getStatusCode();
    $wompiErrorBody = $e->getResponseBody();
}
```

📚 Métodos Disponibles
---------------------

[](#-métodos-disponibles)

MétodoDescripción`createPaymentLink(array|PaymentLinkRequestDTO $data)`Crea un enlace de pago`createTransaction3DS(array|Transaction3DSRequestDTO $data)`Crea una transacción con 3DS`tokenizeCard(array|TokenizeCardRequestDTO $data)`Tokeniza una tarjeta`getTokenizedCard(string $tokenId)`Obtiene información de un token`deleteTokenizedCard(string $tokenId)`Elimina un token`createRecurringCharge(array $data)`Crea un cargo recurrente`getAplicativoData()`Obtiene datos del aplicativo`executeTestTransaction(array $data)`Ejecuta transacción de prueba`validateWebhookRequest(Request $request)`Valida un webhook`validateWebhookSignature(string $body, string $hash)`Valida firma HMAC`validateRedirectParams(array $params, string $hash)`Valida parámetros de redirect`isSuccessfulPayment(array $webhookData)`Verifica si es pago exitoso🧪 Testing
---------

[](#-testing)

Este paquete viene completamente testeado usando **[PEST PHP](https://pestphp.com)**. Incluye 31 tests que cubren todas las funcionalidades.

### Ejecutar Tests

[](#ejecutar-tests)

```
# Ejecutar todos los tests
composer test

# Ejecutar solo tests unitarios
composer test:unit

# Ejecutar solo tests de integración
composer test:feature

# Ver perfil de rendimiento
composer test:profile

# Generar reporte de cobertura
composer test:coverage
```

### Testing en tu Aplicación

[](#testing-en-tu-aplicación)

Puedes hacer mock del cliente Wompi en tus tests usando Laravel HTTP Fakes:

```
use Illuminate\Support\Facades\Http;

it('creates a payment successfully', function () {
    Http::fake([
        'https://id.wompi.sv/*' => Http::response([
            'access_token' => 'test_token',
            'expires_in' => 3600,
        ], 200),
        'https://api.wompi.sv/*/EnlacePago' => Http::response([
            'id' => 'payment_123',
            'url' => 'https://wompi.sv/pay/payment_123',
        ], 201),
    ]);

    $result = app(WompiClient::class)->createPaymentLink([
        'monto' => 100.00,
        'descripcion' => 'Test',
    ]);

    expect($result)->toHaveKey('url');
});
```

Para más ejemplos y guías completas, consulta:

- [TESTING.md](TESTING.md) - Guía completa de testing con PEST
- [examples/PaymentControllerTest.php](examples/PaymentControllerTest.php) - Ejemplos de tests de controladores

📖 Documentación Oficial
-----------------------

[](#-documentación-oficial)

Para más detalles sobre los parámetros y respuestas de cada endpoint, consulta la documentación oficial:

- [Documentación Wompi](https://docs.wompi.sv/)
- [Crear Enlace de Pago](https://docs.wompi.sv/metodos-api/enlace-de-pago)
- [Transacciones 3DS](https://docs.wompi.sv/metodos-api/crear-transaccion-compra-3ds)
- [Tokenización](https://docs.wompi.sv/metodos-api/tokenizacion)
- [Cargos Recurrentes](https://docs.wompi.sv/metodos-api/cargos-recurrentes)
- [Webhooks](https://docs.wompi.sv/webhook/definicion-webhook)

🤝 Contribuciones
----------------

[](#-contribuciones)

Las contribuciones son bienvenidas. Por favor:

1. Fork el proyecto
2. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
3. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
4. Push a la rama (`git push origin feature/AmazingFeature`)
5. Abre un Pull Request

📄 Licencia
----------

[](#-licencia)

Este paquete es software de código abierto licenciado bajo la [Licencia MIT](LICENSE).

👨‍💻 Autor
---------

[](#‍-autor)

**Ronald Miranda**

- GitHub: [@rmirandasv](https://github.com/rmirandasv)

🙏 Agradecimientos
-----------------

[](#-agradecimientos)

- [Wompi](https://wompi.sv) por su API de pagos
- La comunidad de Laravel

---

**⚠️ Nota de Seguridad**: Nunca compartas tus credenciales de Wompi. Mantenlas seguras en variables de entorno y nunca las commits a control de versiones.

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance87

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 88.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~72 days

Total

3

Last Release

65d ago

Major Versions

0.2.0 → 1.0.02026-03-08

### Community

Maintainers

![](https://www.gravatar.com/avatar/fa32a6def84a92f04edba2d37ebf371531f08ea8bfc1da7085b41bac2c2c1f19?d=identicon)[rmirandasv](/maintainers/rmirandasv)

---

Top Contributors

[![rmirandasv](https://avatars.githubusercontent.com/u/8462799?v=4)](https://github.com/rmirandasv "rmirandasv (31 commits)")[![semantic-release-bot](https://avatars.githubusercontent.com/u/32174276?v=4)](https://github.com/semantic-release-bot "semantic-release-bot (4 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/rmirandasv-laravel-wompi/health.svg)

```
[![Health](https://phpackages.com/badges/rmirandasv-laravel-wompi/health.svg)](https://phpackages.com/packages/rmirandasv-laravel-wompi)
```

###  Alternatives

[laraveldaily/laravel-invoices

Missing invoices for Laravel

1.5k1.3M4](/packages/laraveldaily-laravel-invoices)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[musahmusah/laravel-multipayment-gateways

A Laravel Package that makes implementation of multiple payment Gateways endpoints and webhooks seamless

852.2k1](/packages/musahmusah-laravel-multipayment-gateways)[asciisd/knet

Knet package is provides an expressive, fluent interface to KNet's payment services.

141.1k](/packages/asciisd-knet)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
