saba-ab / rapyd
Full-featured Laravel SDK for the Rapyd fintech API
Fund package maintenance!
Requires
- php: ^8.2
- illuminate/contracts: ^11.0||^12.0||^13.0
- illuminate/http: ^11.0||^12.0||^13.0
- nesbot/carbon: ^3.11
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.6
- orchestra/testbench: ^9.0||^10.0||^11.0
- pestphp/pest: ^2.0|^3.0|^4.0
- pestphp/pest-plugin-arch: ^2.0|^3.0|^4.0
- pestphp/pest-plugin-laravel: ^2.0|^3.0|^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
This package is auto-updated.
Last update: 2026-05-21 21:43:13 UTC
README
A full-featured Laravel package for the Rapyd fintech API covering payments, payouts, wallets, card issuing, verification, and fraud protection.
Features
- HMAC-SHA256 request signing handled automatically
- Typed DTOs for all API response objects with enum status fields
- Resource classes covering all 6 Rapyd domains (100+ endpoints)
- Webhook signature verification with Laravel event dispatch (50+ event types)
- Auto-pagination via LazyCollection for memory-efficient iteration
- 24 PHP 8.2+ backed enums for all status and type fields
- Artisan commands for testing connectivity and exploring payment methods
- Built on spatie/laravel-package-tools for clean Laravel integration
Requirements
- PHP 8.2+
- Laravel 11.x, 12.x, or 13.x
- Rapyd API keys (get them at dashboard.rapyd.net)
Installation
Install the package via Composer:
composer require saba-ab/rapyd
Publish the configuration file:
php artisan vendor:publish --tag="rapyd-config"
Add your API keys to .env:
RAPYD_ACCESS_KEY=rak_your_access_key RAPYD_SECRET_KEY=rsk_your_secret_key RAPYD_SANDBOX=true
Quick Start
Create a payment
use Sabaab\Rapyd\Facades\Rapyd; $payment = Rapyd::payments()->create([ 'amount' => 100, 'currency' => 'USD', 'payment_method' => [ 'type' => 'us_visa_card', 'fields' => [ 'number' => '4111111111111111', 'expiration_month' => '12', 'expiration_year' => '25', 'cvv' => '123', 'name' => 'John Doe', ], ], ]); echo $payment->id; // "payment_abc123" echo $payment->status; // PaymentStatus::Active echo $payment->amount; // 100.0
List customers with auto-pagination
// Lazy iteration - fetches pages on demand, memory-efficient foreach (Rapyd::customers()->all() as $customer) { echo $customer->name . "\n"; } // Eager collection $customers = Rapyd::customers()->list(['limit' => 50])->collect();
Retrieve a payment
$payment = Rapyd::payments()->get('payment_abc123'); echo $payment->paid; // true echo $payment->currencyCode; // "USD"
Available Resources
Collect (Payments)
| Accessor | Description |
|---|---|
Rapyd::payments() |
Create, retrieve, update, cancel, capture payments |
Rapyd::refunds() |
Create, retrieve, update refunds |
Rapyd::customers() |
Manage customers and payment methods |
Rapyd::checkout() |
Create and retrieve checkout pages |
Rapyd::paymentMethods() |
List payment methods by country, get required fields |
Rapyd::paymentLinks() |
Create and manage payment links |
Rapyd::subscriptions() |
Manage subscriptions |
Rapyd::plans() |
Manage subscription plans |
Rapyd::products() |
Manage products |
Rapyd::invoices() |
Create, manage, finalize, and pay invoices |
Rapyd::disputes() |
Retrieve and list disputes |
Rapyd::escrows() |
Release escrow funds |
Disburse (Payouts)
| Accessor | Description |
|---|---|
Rapyd::payouts() |
Create, confirm, cancel payouts |
Rapyd::payoutMethods() |
List payout method types and required fields |
Rapyd::beneficiaries() |
Manage payout beneficiaries |
Rapyd::senders() |
Manage payout senders |
Wallet
| Accessor | Description |
|---|---|
Rapyd::wallets() |
Create and manage e-wallets |
Rapyd::walletContacts() |
Manage wallet contacts |
Rapyd::walletTransfers() |
Transfer between wallets |
Rapyd::walletTransactions() |
View wallet transactions |
Rapyd::virtualAccounts() |
Issue and manage virtual accounts |
Issuing (Cards)
| Accessor | Description |
|---|---|
Rapyd::cards() |
Issue, activate, manage cards |
Rapyd::cardPrograms() |
Manage card programs |
Verify (KYC/KYB)
| Accessor | Description |
|---|---|
Rapyd::identities() |
Create and check identity verifications |
Rapyd::verification() |
Create hosted verification pages |
Protect & Data
| Accessor | Description |
|---|---|
Rapyd::fraud() |
Get and update fraud settings |
Rapyd::data() |
List countries, currencies, FX rates |
Webhooks
The package auto-registers a POST route at /rapyd/webhook (configurable) with automatic signature verification.
Configure in Rapyd Dashboard
Set your webhook URL in the Rapyd Client Portal to:
https://your-app.com/rapyd/webhook
Listen for events
use Sabaab\Rapyd\Webhooks\Events\PaymentCompletedEvent; Event::listen(PaymentCompletedEvent::class, function (PaymentCompletedEvent $event) { $payment = $event->payment; // Hydrated Payment DTO Order::where('payment_id', $payment->id)->update(['status' => 'paid']); });
Catch-all listener
use Sabaab\Rapyd\Webhooks\Events\RapydWebhookReceived; Event::listen(RapydWebhookReceived::class, function (RapydWebhookReceived $event) { Log::info("Rapyd webhook: {$event->type}", $event->data); });
Available event types
Events are dispatched for all 65 Rapyd webhook types, grouped by domain:
- Payment: PaymentCompleted, PaymentSucceeded, PaymentFailed, PaymentExpired, PaymentUpdated, PaymentCaptured, PaymentCanceled
- Refund: RefundCompleted, RefundFailed, RefundRejected, PaymentRefundCompleted, PaymentRefundFailed, PaymentRefundRejected
- Customer: CustomerCreated, CustomerUpdated, CustomerDeleted, CustomerPaymentMethodCreated/Updated/Deleted/Expiring
- Subscription: SubscriptionCreated, SubscriptionUpdated, SubscriptionCompleted, SubscriptionCanceled, SubscriptionPastDue, SubscriptionTrialEnd, SubscriptionRenewed
- Invoice: InvoiceCreated, InvoiceUpdated, InvoicePaymentCreated/Succeeded/Failed
- Payout: PayoutCompleted, PayoutUpdated, PayoutFailed, PayoutExpired, PayoutCanceled, PayoutReturned
- Wallet: WalletTransaction, WalletFundsAdded/Removed, WalletTransferCompleted/Failed/ResponseReceived
- Card Issuing: CardIssuingAuthApproved/Declined, CardIssuingSale, CardIssuingCredit, and more
- Verify: VerifyApplicationSubmitted/Approved/Rejected
- Virtual Account: VirtualAccountCreated/Updated/Closed/Transaction
Artisan Commands
# Test API connectivity php artisan rapyd:test-connection # List payment methods for a country php artisan rapyd:list-payment-methods US # View webhook configuration php artisan rapyd:webhook-info
Configuration
After publishing, the configuration file is at config/rapyd.php:
return [ // API credentials 'access_key' => env('RAPYD_ACCESS_KEY', ''), 'secret_key' => env('RAPYD_SECRET_KEY', ''), // Set to false for production 'sandbox' => env('RAPYD_SANDBOX', true), // Base URLs (override only if needed) 'base_url' => [ 'sandbox' => 'https://sandboxapi.rapyd.net', 'production' => 'https://api.rapyd.net', ], // Webhook settings 'webhook' => [ 'path' => env('RAPYD_WEBHOOK_PATH', '/rapyd/webhook'), 'tolerance' => env('RAPYD_WEBHOOK_TOLERANCE', 60), // seconds 'middleware' => [], ], // HTTP timeout in seconds 'timeout' => env('RAPYD_TIMEOUT', 30), // Retry on 5xx errors 'retry' => [ 'times' => env('RAPYD_RETRY_TIMES', 3), 'sleep' => env('RAPYD_RETRY_SLEEP', 100), // milliseconds ], ];
DTOs and Enums
All API responses are returned as typed DTOs with readonly properties:
$payment = Rapyd::payments()->get('payment_abc'); $payment->id; // string $payment->amount; // float $payment->status; // ?PaymentStatus enum $payment->createdAt; // ?Carbon $payment->paid; // bool $payment->address; // ?Address (nested DTO)
Use enums for type-safe comparisons:
use Sabaab\Rapyd\Enums\PaymentStatus; if ($payment->status === PaymentStatus::Closed) { // Payment completed successfully }
Available enums: PaymentStatus, PaymentMethodCategory, PaymentFlowType, NextAction, RefundStatus, DisputeStatus, PayoutStatus, PayoutMethodCategory, SubscriptionStatus, InvoiceStatus, WebhookStatus, CardStatus, CardBlockReasonCode, EntityType, FeeCalcType, FixedSide, WalletContactType, CouponDuration, PlanInterval, CheckoutPageStatus, EscrowStatus, IssuingTxnType, Environment, WebhookEventType.
Pagination
// Lazy iteration - pages fetched on demand foreach (Rapyd::customers()->all() as $customer) { echo $customer->name; } // Eager collection $all = Rapyd::payments()->list(['limit' => 50])->collect(); // First item only (fetches just 1 item) $first = Rapyd::payments()->list()->first(); // Convert to array $array = Rapyd::customers()->list()->toArray();
Error Handling
use Sabaab\Rapyd\Exceptions\ApiException; use Sabaab\Rapyd\Exceptions\AuthenticationException; use Sabaab\Rapyd\Exceptions\ValidationException; use Sabaab\Rapyd\Exceptions\RapydException; try { $payment = Rapyd::payments()->create([...]); } catch (AuthenticationException $e) { // Invalid API keys } catch (ValidationException $e) { // Invalid fields - $e->fields contains details } catch (ApiException $e) { // API error - $e->errorCode, $e->operationId } catch (RapydException $e) { // Base exception for all Rapyd errors }
Testing
Use Http::fake() to mock Rapyd API responses in your tests:
use Illuminate\Support\Facades\Http; use Sabaab\Rapyd\Facades\Rapyd; Http::fake([ 'sandboxapi.rapyd.net/v1/payments' => Http::response([ 'status' => ['status' => 'SUCCESS', 'error_code' => ''], 'data' => ['id' => 'payment_test', 'amount' => 100, 'paid' => true], ]), ]); $payment = Rapyd::payments()->create(['amount' => 100, 'currency' => 'USD']);
Run the package test suite:
composer test # Run Pest tests composer test-coverage # Run tests with coverage composer format # Fix code style with Laravel Pint composer analyse # Run PHPStan + Larastan
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.