alexmart / laravel-flow
Laravel 6 package para la integración de pagos con Flow (https://www.flow.cl)
Requires
- php: >=5.4.0
- illuminate/support: ~6.0
This package is not auto-updated.
Last update: 2025-06-23 15:38:06 UTC
README
Laravel 6 package para la integración de pagos con Flow
Testeado con Laravel 6
Estimado desarrollador, este paquete fué rescrito para su funcionalidad con la nueva api de FLOW, esto en consideración que el anterior paquete estaba desactualizado y no funcionaba en las nuevas versiones de laravel.
Instalación
Paso 1: Instalar a través de Composer
$ composer require alexmart/laravel-flow
Paso 2: Agregar el Service Provider [Solo Laravel < 5.5]
En el archivo config/app.php
, agregar la siguiente línea al array providers
:
'providers' => [
AlexMart\LaravelFlow\FlowServiceProvider::class,
],
Paso 3: Agregar el alias [Solo Laravel < 5.5]
En el mismo archivo, agregar la siguiente línea al array aliases
:
'aliases' => [
…
'Flow' => AlexMart\LaravelFlow\Facades\Flow::class,
…
],
Paso 4: Publicar el archivo de configuración
$ php artisan vendor:publish --provider="AlexMart\LaravelFlow\FlowServiceProvider" --force
Paso 5: Configura tu .env
o modifica tu config/flow.php
…
FLOW_URL_PAGO=https://sandbox.flow.cl/app/web/pay.php
FLOW_COMERCIO=emailFlow@comercio.com
FLOW_API_KEY=Tu_api_key_aqui
FLOW_SECRET_KEY=Tu_api_secreta_aqui
Utilización
Este package actúa prácticamente como un simple Service Provider para el Kit de Integración de Flow, por lo tanto, me limitaré a ejemplificar solo las diferencias de su utilización dentro de Laravel.
Importante: Excluye la protección CSRF para las páginas de éxito, fracaso y confirmación, ya que Flow no sabrá qué token CSRF enviar a tus rutas.
Proyecto de demostración
NOTA: El proyecto demostración para este paquete aún no se encuentra disponible...
Antes de ver los ejemplos que vienen a continuación, quizás prefieras echarle un vistazo al proyecto de demostración del package implementado en Laravel 6, o bien analizarlo en conjunto para una mayor comprensión de cómo utilizarlo.
Formulario de Compra
View: resources/views/index.blade.php
@extends('layouts._master')
@section('content')
<form method="POST" action="{{ route('orden') }}">
@csrf
Orden N°: <input type="text" name="orden" id="orden" placeholder="1000" required><br>
Monto: <input type="text" name="monto" id="monto" placeholder="20000" required><br>
Descripción: <input type="text" name="concepto" id="concepto" placeholder="Pago de Orden N° 1000" required><br>
Email pagador (opcional): <input type="email" name="pagador" id="pagador" placeholder="usuario@email.com"><br>
<br>
<button type="submit">Aceptar</button>
</form>
@endsection
Creando una nueva Orden
Controller: Http/Controllers/FlowController.php
[Ejemplo]
<?php
namespace App\Http\Controllers;
use Flow;
use Illuminate\Http\Request;
class FlowController extends Controller
{
/**
* Creando una nueva Orden
*
* @param Request $request
* @return \Illuminate\View\View
*/
public function orden(Request $request)
{
$orden = [
//SEGUIR EL ORDEN Y NOMBRE DE CLAVES COMO SE MUESTRA A CONTINUACION
'commerceOrder' => $request->orden,
'subject' => $request->concepto,
'amount' => $request->monto,
'email' => $request->pagador,
// Opcional: El medio de pago correspondera al ubicado en la configuracion
];
// Genera una nueva Orden de Pago, Flow la firma y retorna un paquete de datos firmados
$orden_generada = Flow::GenerateFlowOrder($orden);
// Si desea enviar el medio de pago usar la siguiente línea
//$orden['flow_pack'] = Flow::new_order($orden['orden_compra'], $orden['monto'], $orden['concepto'], $orden['email_pagador'], $orden['medio_pago']);
return view('orden')->with(['order'=>$generated_order]);
}
…
View: resources/views/orden.blade.php
@extends('layouts._master')
@section('content')
<!-- Formulario HTML que envía la nueva Orden -->
Confirme su orden antes de proceder al pago via Flow<br>
<br>
Orden N°: {{ $order['commerceOrder'] }}<br>
Orden FLOW N°: {{ $order['response']->flowOrder }}<br>
Monto: {{ $order['amount'] }}<br>
Descripción: {{ $order['subject'] }}<br>
Email pagador (opcional): {{ $order['email'] }}<br>
<br>
<form method="POST" action="{{ config('flow.url_pago') }}">
@csrf
<input type="hidden" name="token" value="{{ $order['response']->token }}">
<button type="submit">Pagar en Flow</button>
</form>
@endsection
Página de Éxito
Controller: Http/Controllers/FlowController.php
…
/**
* Página de éxito del Comercio
*
* Esta página será invocada por Flow cuando la transacción resulte exitosa
* y el usuario presione el botón para retornar al comercio desde Flow.
*
* @return \Illuminate\View\View
*/
public function exito(Request $request)
{
// Lee los datos enviados por Flow
$GetFlowOrder = \Flow::getStatus($request->token);
// Recupera los datos enviados por Flow
// Lista completa del retorno de datos: https://www.flow.cl/docs/api.html#tag/payment/paths/~1payment~1getStatus/get
$orden = [
'flowOrder' => $GetFlowOrder->flowOrder,
'commerceOrder' => $GetFlowOrder->commerceOrder,
'subject' => $GetFlowOrder->subject,
'payer' => $GetFlowOrder->payer,
];
return view('flow.exito')->with(["FlowOrder" => $orden]);
}
…
View: resources/views/flow/exito.blade.php
@extends('layouts._master')
@section('content')
<h1>Página de éxito de Comercio</h1>
Su pago se ha realizado exitosamente<br>
<br>
Orden de Compra: {{ $FlowOrder['flowOrder'] }}<br>
<br>
Gracias por su compra
@endsection
Página de Fracaso [FALTA IMPLEMENTACIÓN]
Controller: Http/Controllers/FlowController.php
…
/**
* Página de fracaso del Comercio
*
* Esta página será invocada por Flow cuando la transacción no se logre pagar
* y el usuario presione el botón para retornar al comercio desde Flow.
*
* @return \Illuminate\View\View
*/
public function fracaso()
{
// Lee los datos enviados por Flow
Flow::read_result();
// Recupera los datos enviados por Flow
$orden = [
'orden_compra' => Flow::getOrderNumber(),
'monto' => Flow::getAmount(),
'concepto' => Flow::getConcept(),
'email_pagador' => Flow::getPayer(),
'flow_orden' => Flow::getFlowNumber(),
];
return view('flow.fracaso', $orden);
}
…
View: resources/views/flow/fracaso.blade.php
@extends('layouts._master')
@section('content')
<h1>Página de fracaso de Comercio</h1>
Su pago ha sido rechazado<br>
<br>
Orden de Compra: {{ $orden_compra }}<br>
Monto: {{ $monto }}<br>
Descripción: {{ $concepto }}<br>
Pagador: {{ $email_pagador }}<br>
Flow Orden N°: {{ $flow_orden }}<br>
<br>
<a href="{{ url('/') }}">Intente nuevamente</a>
@endsection
Página de Confirmación
Controller: Http/Controllers/FlowController.php
…
/**
* Página de confirmación del Comercio
*
* @return void
*/
public function confirmacion()
{
try {
// Lee los datos enviados por Flow
Flow::read_confirm();
} catch (Exception $e) {
// Si hay un error responde false
echo Flow::build_response(false);
return;
}
// Recupera los valores de la Orden
$flow_status = Flow::getStatus(); // El resultado de la transacción (EXITO o FRACASO)
$orden_numero = Flow::getOrderNumber(); // N° de Orden del Comercio
$monto = Flow::getAmount(); // Monto de la transacción
$orden_flow = Flow::getFlowNumber(); // Si $flow_status = 'EXITO' el N° de Orden de Flow
$pagador = Flow::getPayer(); // El email del pagador
/**
* Aquí puede validar la Orden
*
* Si acepta la Orden responder Flow::build_response(true)
* Si rechaza la Orden responder Flow::build_response(false)
*/
if ($flow_status == 'EXITO') {
// La transacción fue aceptada por Flow
// Aquí puede actualizar su información con los datos recibidos por Flow
echo Flow::build_response(true); // Comercio acepta la transacción
} else {
// La transacción fue rechazada por Flow
// Aquí puede actualizar su información con los datos recibidos por Flow
echo Flow::build_response(false); // Comercio rechaza la transacción
}
}
…
Routes
…
Route::get('/', function () {
return view('index');
});
Route::post('orden', 'FlowController@orden')->name('orden');
Route::post('flow/exito', 'FlowController@exito')->name('flow.exito');
Route::post('flow/fracaso', 'FlowController@fracaso')->name('flow.fracaso');
Route::post('flow/confirmacion', 'FlowController@confirmacion')->name('flow.confirmacion');
…