johnrivera7 / filament-flow
Filament plugin for Flow payments (Chile) — credentials UI, HMAC signing, create/status/refund helpers.
v1.0.2
2026-08-23 20:13 UTC
Requires
- php: ^8.2
- filament/filament: ^4.0|^5.0
- illuminate/contracts: ^11.28|^12.0|^13.0
- illuminate/http: ^11.28|^12.0|^13.0
- illuminate/support: ^11.28|^12.0|^13.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.18
- phpunit/phpunit: ^11.0
README
A Filament plugin that integrates Flow payments (Chile) into your Laravel application: credentials UI, HMAC-SHA256 signing, checkout redirects (url?token=), and create / status / refund helpers on the Flow REST API.
Open source (MIT). Free on Packagist.
Requirements
| Stack | Versions |
|---|---|
| PHP | 8.2+ |
| Laravel | 11.28+ / 12+ / 13+ |
| Filament | 4.x or 5.x |
| Livewire | 3.x (with Filament 4) / 4.x (with Filament 5) |
Installation
composer require johnrivera7/filament-flow
Optional publishes:
php artisan vendor:publish --tag=filament-flow-config
Register the plugin in your PanelProvider:
use JohnRivera7\FilamentFlow\FilamentFlowPlugin; public function panel(Panel $panel): Panel { return $panel ->plugin( FilamentFlowPlugin::make() ->navigationGroup('Pagos') ->navigationSort(41) ); }
Multi-tenant (recommended)
use JohnRivera7\FilamentFlow\Support\FlowCredentials; ->plugin( FilamentFlowPlugin::make() ->credentialsUsing(function (): FlowCredentials { $cfg = /* read from your DB */; return FlowCredentials::fromArray($cfg); }) ->persistCredentialsUsing(function (FlowCredentials $credentials): void { /* persist $credentials->toArray() or $credentials->toLegacyConfig() */ }) )
Single-tenant (.env)
FLOW_ENABLED=true FLOW_API_KEY=... FLOW_SECRET_KEY=... FLOW_ENVIRONMENT=sandbox # Optional override: # FLOW_API_URL=https://sandbox.flow.cl/api
Without persistCredentialsUsing(), the settings page does not write credentials to disk—wire persistence via the callbacks above (or manage .env yourself).
Gateway usage
use JohnRivera7\FilamentFlow\FilamentFlowPlugin; $gateway = FilamentFlowPlugin::get()->gateway(); $payment = $gateway->create( commerceOrder: 'ORD-123', subject: 'Reserva hotel', amount: 15990, email: 'guest@example.com', urlConfirmation: route('payments.flow.confirm'), urlReturn: route('payments.flow.return'), ); // Redirect the payer (GET url?token=...) return redirect()->away($payment['redirect_url']); // Or use the branded interstitial view: return response()->view('filament-flow::payment-redirect', [ 'url' => $payment['redirect_url'], ]);
On urlConfirmation / urlReturn (Flow POSTs token):
use JohnRivera7\FilamentFlow\Support\FlowPaymentReconciliation; $result = $gateway->confirm($request->except(['amount', 'total', 'monto'])); // $result['paid'] === true when status === 2 // $result['amount'] comes from Flow — never from the browser $check = FlowPaymentReconciliation::compare($expectedAmountFromYourDb, $result['amount']); if ($check['settlement'] === FlowPaymentReconciliation::SETTLEMENT_PARTIAL) { // Register as deposit/abono — do NOT mark the order fully paid } if ($check['settlement'] === FlowPaymentReconciliation::SETTLEMENT_NONE) { // Fail closed (missing/zero amount from Flow) }
Refund:
$refund = $gateway->refund( refundCommerceOrder: 'REF-123', receiverEmail: 'guest@example.com', amount: 15990, urlCallback: route('payments.flow.refund'), commerceTrxId: 'ORD-123', // or flowTrxId );
Reusable form schema
use JohnRivera7\FilamentFlow\Forms\Components\FlowCredentialsSchema; $schema->components([ ...FlowCredentialsSchema::make('payments.flow'), ]);
Integration notes
- Every request must be signed: sort params alphabetically, concatenate
key.value, thenhash_hmac('sha256', …, secretKey)→ parameters. See Flow API. - Checkout redirect: concatenate
url + "?token=" + token. - Sandbox base URL:
https://sandbox.flow.cl/api· Production:https://www.flow.cl/api - Payment status
2= paid. - After async confirmation, call
payment/getStatuswith the receivedtoken. - Amount security: compute and store the charge on the server when creating the payment. On callback, reconcile with
FlowPaymentReconciliation. Underpayment must remain a deposit (abono), not a full settlement.
Testing
composer install
composer test
Security
See SECURITY.md.
Changelog
See CHANGELOG.md.
License
MIT
