laravel-pagoflash maintained by gerarjos14
PagoFlash SDK para Laravel
SDK oficial de PagoFlash para Laravel. Integra facilmente la comprobacion de Pago Movil, la pasarela de pagos y la gestion de billeteras en tu aplicacion.
Caracteristicas
- Comprobacion de Pago Movil (P2P-IN) - Verifica pagos moviles realizados por tus clientes
- Pasarela de Pagos - Crea ordenes de pago con redireccion a la interfaz de PagoFlash
- Pagos P2P (Wallet) - Envia pagos movil usando el saldo de tu billetera
- Webhooks - Recibe notificaciones en tiempo real de pagos exitosos y fallidos
- DTOs Tipados - Toda la API usa objetos tipados para mayor seguridad
- Validacion Integrada - Los DTOs validan los datos antes de enviarlos a la API
- Reintentos Automaticos - El cliente HTTP reintenta ante fallos de conexion
- Logging Configurable - Registra todas las operaciones para debugging
- Laravel Native - Facade, Service Provider, Events, Commands y Auto-Discovery
Requisitos
- PHP 8.1 o superior
- Laravel 9.x, 10.x, 11.x o 12.x
- Extensiones PHP:
json,mbstring
Instalacion
1. Instalar via Composer
composer require gerarjos14/laravel-pagoflash
El package usa Laravel Auto-Discovery, por lo que el Service Provider y el Facade se registran automaticamente.
2. Publicar la configuracion
php artisan vendor:publish --tag=pagoflash-config
3. Configurar variables de entorno
Agrega estas variables a tu archivo .env:
# Entorno: sandbox o production
PAGOFLASH_ENVIRONMENT=sandbox
# Credenciales de tu cuenta de comercio en PagoFlash
PAGOFLASH_EMAIL=tu-email@comercio.com
PAGOFLASH_PASSWORD=tu-password
# Moneda por defecto (USD o VES)
PAGOFLASH_CURRENCY=USD
# URLs de webhook (donde PagoFlash notificara los pagos)
PAGOFLASH_WEBHOOK_SUCCESS_URL=https://tudominio.com/webhooks/pagoflash/success
PAGOFLASH_WEBHOOK_ERROR_URL=https://tudominio.com/webhooks/pagoflash/error
# Clave secreta para verificar webhooks (opcional pero recomendado)
PAGOFLASH_WEBHOOK_SECRET=tu-clave-secreta
# URLs de redireccion despues del pago
PAGOFLASH_REDIRECT_SUCCESS_URL=https://tudominio.com/pago-exitoso
PAGOFLASH_REDIRECT_ERROR_URL=https://tudominio.com/pago-fallido
4. Verificar la conexion
php artisan pagoflash:test
Para crear una orden de prueba real:
php artisan pagoflash:test --with-payment
Uso Rapido
Crear una orden de pago
use PagoFlash;
// Crear la orden
$order = PagoFlash::createOrder(
amount: 25.50,
description: 'Compra #1234 - Zapatos deportivos',
orderId: '1234', // Tu ID interno
payerEmail: 'cliente@email.com', // Email del cliente
payerName: 'Juan Perez', // Nombre completo
payerDocument: 'V12345678', // Cedula (V, E, P, J, G)
payerPhone: '4241234567', // Telefono (10 digitos)
);
// Redirigir al cliente a la pasarela de pago
return redirect($order->getPaymentUrl());
Usar el DTO completo (mas opciones)
use Gerarjos14\PagoFlash\DTOs\Requests\CreateOrderRequest;
use Gerarjos14\PagoFlash\Facades\PagoFlash;
$request = new CreateOrderRequest(
amount: 50.00,
description: 'Membresia Premium',
orderId: 'MEMB-5678',
payerEmail: 'cliente@email.com',
payerName: 'Maria Garcia',
payerDocument: 'V87654321',
payerPhone: '4147654321',
currency: 'USD', // USD se convierte a Bs automaticamente
minAmount: null, // null = monto exacto obligatorio
expiresAt: null, // null = 30 minutos por defecto
successRedirectUrl: 'https://mitienda.com/gracias',
errorRedirectUrl: 'https://mitienda.com/error',
successCallbackUrl: 'https://mitienda.com/webhook/pago',
errorCallbackUrl: 'https://mitienda.com/webhook/error',
);
// No disponible directamente, usar PagoFlash::createOrder con opciones array
$order = PagoFlash::createOrder(
amount: 50.00,
description: 'Membresia Premium',
orderId: 'MEMB-5678',
payerEmail: 'cliente@email.com',
payerName: 'Maria Garcia',
payerDocument: 'V87654321',
payerPhone: '4147654321',
options: [
'currency' => 'USD',
'successRedirectUrl' => 'https://mitienda.com/gracias',
'successCallbackUrl' => 'https://mitienda.com/webhook/pago',
]
);
Flujo de Pago Completo
Flujo por Redireccion (Recomendado para web)
[ Tu App ] [ PagoFlash ] [ Cliente ]
| | |
|--- crearOrden() ---->| |
|<-- URL pasarela -----| |
| | |
|-- redirect() -------------------------------->|
| |<-- cliente paga -----|
| | |
|<-- Webhook (POST) ---| |
|-- marcar como pagado | |
| |--- redirect -------->|
| | a tu URL success |
Flujo por API (Recomendado para apps moviles)
// Paso 1: Crear la orden
$order = PagoFlash::createOrder(
amount: 25.05,
description: 'Compra App',
orderId: 'APP-001',
payerEmail: 'user@app.com',
payerName: 'Usuario App',
payerDocument: 'V12345678',
payerPhone: '4241234567',
);
// Paso 2: Obtener proveedor de Pago Movil
$provider = PagoFlash::findPagoMovilProvider();
$bankDetails = $provider->getBankDetails();
// Paso 3: Mostrar datos al usuario para que haga el Pago Movil
// Banco: {$bankDetails['Bank']}
// Telefono: {$bankDetails['Phone']}
// Documento: {$bankDetails['Document']}
// Concepto/Referencia: {$order->getReferenceCode()} <- IMPORTANTE
// Paso 4: El usuario hace el Pago Movil desde su banco
// Paso 5a: Verificar por polling (consultar estado cada X segundos)
$isPaid = PagoFlash::isOrderPaid($order->getOrderId());
// Paso 5b: O verificar manualmente con datos del pago
$response = PagoFlash::verifyPagoMovilSimple(
orderId: $order->getOrderId(),
phoneCode: '424',
phone: '1234567',
bankCode: '0191',
amount: 25.05,
token: '123456', // OTP del usuario
fullDocument: 'V12345678',
wallet: $provider->walletId ?? '',
provider: $provider->strongId,
);
if ($response->isSuccessful()) {
// Pago confirmado!
}
Verificar Estado de Orden
Por Polling (consulta periodica)
use PagoFlash;
// Verificar si fue pagada
if (PagoFlash::isOrderPaid('uuid-de-la-orden')) {
// Activar servicio, enviar email, etc.
}
// Obtener detalle completo
$order = PagoFlash::getOrder('uuid-de-la-orden');
echo $order->status; // "Pagado", "Pendiente", "Expirado", "Anulado"
echo $order->amount; // 25.05
echo $order->isPaid(); // true/false
echo $order->isExpired(); // true/false
Por Webhook (notificacion push)
Crea un listener para el evento PaymentReceived:
// app/Listeners/MarkOrderAsPaid.php
namespace App\Listeners;
use Gerarjos14\PagoFlash\Events\PaymentReceived;
class MarkOrderAsPaid
{
public function handle(PaymentReceived $event): void
{
$orderId = $event->getOrderId(); // Tu ID interno
$amount = $event->getAmount(); // Monto en USD
$amountBs = $event->getAmountBs(); // Monto en Bs
$rate = $event->getExchangeRate(); // Tasa de cambio
$payer = $event->getPayerName(); // Quien pago
$reference = $event->getReference(); // Referencia PagoFlash
// Buscar tu orden y marcarla como pagada
$order = Order::where('external_id', $orderId)->first();
if ($order && ! $order->isPaid()) {
$order->update([
'status' => 'paid',
'amount_bs' => $amountBs,
'exchange_rate' => $rate,
'paid_at' => now(),
'reference' => $reference,
'payer_name' => $payer,
]);
}
}
}
Registra el listener en EventServiceProvider:
protected $listen = [
\Gerarjos14\PagoFlash\Events\PaymentReceived::class => [
\App\Listeners\MarkOrderAsPaid::class,
\App\Listeners\SendPaymentConfirmationEmail::class,
\App\Listeners\ActivateSubscription::class,
],
\Gerarjos14\PagoFlash\Events\PaymentFailed::class => [
\App\Listeners\NotifyPaymentFailed::class,
],
];
Gestion de Billeteras
use PagoFlash;
// Listar billeteras
$wallets = PagoFlash::listWallets();
foreach ($wallets as $wallet) {
echo $wallet->service; // "MiBanco"
echo $wallet->balance; // 1051534.66
echo $wallet->isCustodiable; // true/false
echo $wallet->strongId; // GUID
}
// Saldo total
$total = PagoFlash::getTotalBalance();
echo "Saldo total: {$total} Bs";
// Enviar Pago Movil desde wallet (vuelto digital)
$response = PagoFlash::sendPagoMovil(
wallet: 'uuid-billetera-origen',
bankCode: '0191', // BNC
phoneCode: '424',
phone: '1234567',
fullDocument: 'V12345678',
amount: 10.00,
description: 'Vuelto digital',
);
if ($response->isSuccessful()) {
echo "Pago enviado! Ref: " . $response->result['reference'];
}
Comandos Artisan
# Verificar conexion y credenciales
php artisan pagoflash:test
# Verificar conexion y crear orden de prueba
php artisan pagoflash:test --with-payment
# Ver billeteras y saldos
php artisan pagoflash:wallets
# Enviar Pago Movil desde comando
php artisan pagoflash:wallets --send \
--wallet=uuid-aqui \
--bank=0191 \
--phone=4241234567 \
--doc=V12345678 \
--amount=10 \
--description="Pago de prueba"
Configuracion Avanzada
El archivo config/pagoflash.php tiene todas las opciones documentadas:
return [
// Entorno: 'sandbox' o 'production'
'environment' => env('PAGOFLASH_ENVIRONMENT', 'sandbox'),
// Credenciales
'credentials' => [
'email' => env('PAGOFLASH_EMAIL'),
'password' => env('PAGOFLASH_PASSWORD'),
],
// Token JWT (opcional - si ya tienes uno)
'token' => env('PAGOFLASH_TOKEN'),
// Moneda por defecto
'currency' => env('PAGOFLASH_CURRENCY', 'USD'),
// URLs webhook
'webhook' => [
'success_url' => env('PAGOFLASH_WEBHOOK_SUCCESS_URL'),
'error_url' => env('PAGOFLASH_WEBHOOK_ERROR_URL'),
'secret' => env('PAGOFLASH_WEBHOOK_SECRET'),
'middleware' => ['api', 'throttle:60,1'],
'prefix' => 'webhooks',
],
// URLs de redireccion
'redirect' => [
'success' => env('PAGOFLASH_REDIRECT_SUCCESS_URL'),
'error' => env('PAGOFLASH_REDIRECT_ERROR_URL'),
],
// Logging
'logging' => [
'enabled' => true,
'channel' => 'stack',
'level' => 'debug',
],
// Reintentos HTTP
'retry' => [
'attempts' => 3,
'delay_ms' => 500,
'multiplier' => 2.0, // 500ms, 1000ms, 2000ms
],
// Timeouts
'timeout' => [
'connection' => 10,
'request' => 30,
],
];
Datos de Prueba (Sandbox)
En el ambiente de sandbox puedes probar con estos datos:
| Campo | Valor |
|---|---|
| Banco | BNC 0191 |
| Telefono | 0424 1234567 |
| Cedula | V123456789 |
| Token OTP | Cualquiera (en sandbox no se valida) |
Manejo de Errores
El SDK lanza excepciones especificas que puedes capturar:
use Gerarjos14\PagoFlash\Exceptions\AuthenticationException;
use Gerarjos14\PagoFlash\Exceptions\OrderException;
use Gerarjos14\PagoFlash\Exceptions\PaymentVerificationException;
use Gerarjos14\PagoFlash\Exceptions\PagoFlashException;
use Gerarjos14\PagoFlash\Exceptions\WalletException;
try {
$order = PagoFlash::createOrder(...);
} catch (AuthenticationException $e) {
// Credenciales invalidas o token expirado
Log::error('Auth error: ' . $e->getMessage());
} catch (OrderException $e) {
// Orden no encontrada, ya pagada, expirada, etc.
if ($e->getContext()['type'] === 'order_already_paid') {
// La orden ya fue pagada anteriormente
}
} catch (PaymentVerificationException $e) {
// El pago movil no pudo ser verificado
Log::error('Payment verification failed: ' . $e->getMessage());
} catch (WalletException $e) {
// Saldo insuficiente, billetera no encontrada
if ($e->getContext()['type'] === 'insufficient_balance') {
$available = $e->getContext()['available'];
Log::error("Saldo insuficiente. Disponible: {$available}");
}
} catch (PagoFlashException $e) {
// Error generico de la API
Log::error('PagoFlash error: ' . $e->getMessage());
}
Referencia de la API del SDK
Ordenes
// Crear orden
PagoFlash::createOrder(float $amount, string $description, string $orderId, string $payerEmail, string $payerName, string $payerDocument, string $payerPhone, array $options = []): OrderResponse
// Obtener orden
PagoFlash::getOrder(string $orderId): OrderDetailResponse
// Listar ordenes (paginado)
PagoFlash::listOrders(int $page = 1, array $filters = []): PaginatedResponse
// Anular orden
PagoFlash::cancelOrder(string $orderId): bool
// Revertir orden pagada
PagoFlash::revertOrder(string $orderId): bool
// Notificar orden manualmente
PagoFlash::notifyOrder(string $orderId): bool
// Verificar si esta pagada
PagoFlash::isOrderPaid(string $orderId): bool
Pago Movil
// Verificar Pago Movil con DTO
PagoFlash::verifyPagoMovil(string $orderId, VerifyPagoMovilRequest $request): ApiResponse
// Verificar Pago Movil con parametros simples
PagoFlash::verifyPagoMovilSimple(string $orderId, string $phoneCode, string $phone, string $bankCode, float $amount, string $token, string $fullDocument, string $wallet, string $provider): ApiResponse
Billeteras
// Listar billeteras
PagoFlash::listWallets(): array<WalletResponse>
// Saldo total
PagoFlash::getTotalBalance(): float
// Buscar billetera
PagoFlash::findWallet(string $walletId): ?WalletResponse
// Enviar Pago Movil desde wallet
PagoFlash::sendFromWallet(SendWalletRequest $request): ApiResponse
PagoFlash::sendPagoMovil(string $wallet, string $bankCode, string $phoneCode, string $phone, string $fullDocument, float $amount, ?string $description = null): ApiResponse
Proveedores
// Listar proveedores
PagoFlash::listProviders(): array<ProviderResponse>
// Encontrar proveedor P2P-IN (comprobacion de pago movil)
PagoFlash::findPagoMovilProvider(): ?ProviderResponse
// Obtener datos bancarios para mostrar al cliente
PagoFlash::getPagoMovilBankDetails(): ?array
Transacciones
// Listar transacciones
PagoFlash::listTransactions(int $page = 1, array $filters = []): PaginatedResponse
Cuentas Bancarias
// Agregar cuenta bancaria
PagoFlash::addBankAccount(string $bankCode, string $number, ?string $fiscalRegistry = null, ?string $alias = null): ApiResponse
Devoluciones
// Solicitar devolucion por dispersion
PagoFlash::requestRefundDispersion(RefundDispersionRequest $request): ApiResponse
Desarrollo
# Clonar
gh repo clone gerarjos14/laravel-pagoflash
cd laravel-pagoflash
# Instalar dependencias
composer install
# Ejecutar tests
composer test
# Ejecutar con coverage
composer test-coverage
# Analisis estatico
composer analyse
# Formatear codigo
composer format
# Verificar formato
composer format-dry-run
Seguridad
Si descubres algun problema de seguridad, por favor envia un email a gerarjos14@gmail.com en lugar de crear un issue publico.
Soporte
- Documentacion de la API: docs.pagoflash.com
- Dashboard: pagoflash.com/comercio
- Email de soporte PagoFlash: api@unidigital.global
- Issues del SDK: GitHub Issues
Licencia
Este paquete es software de codigo abierto bajo la Licencia MIT.