Download the PHP package nexuspay/payment-made-easy without Composer
On this page you can find all versions of the php package nexuspay/payment-made-easy. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download nexuspay/payment-made-easy
More information about nexuspay/payment-made-easy
Files in nexuspay/payment-made-easy
Package payment-made-easy
Short Description A Laravel package for handling payments with multiple gateways (Paystack, Flutterwave, Stripe, Seerbit, etc.)
License MIT
Informations about the package payment-made-easy
Payment Made Easy
A comprehensive Laravel package for integrating multiple payment gateways with support for one-time payments, subscriptions/plans, disbursements/transfers, virtual accounts, and payment links — all behind a consistent interface.
Supported Gateways
| Gateway | One-Time | Subscriptions | Disbursements | Virtual Accounts | Payment Links |
|---|---|---|---|---|---|
| Paystack | ✅ | ✅ | ✅ | ✅ | ✅ |
| Flutterwave | ✅ | ✅ | ✅ | ✅ | ✅ |
| Stripe | ✅ | ✅ | — | — | ✅ |
| Seerbit | ✅ | ✅ | — | ✅ | — |
| Monnify | ✅ | ⚠️ n/a | ✅ | ✅ | — |
| Squad | ✅ | — | ✅ | ✅ | — |
| Remita | ✅ | — | ✅ | — | — |
| Budpay | ✅ | — | ✅ | ✅ | — |
| Interswitch | ✅ | — | — | — | — |
| PayPal | ✅ | ✅ | ✅ | — | ✅ |
| M-Pesa | ✅ | — | — | — | — |
| MTN MoMo | ✅ | — | ✅ | — | — |
| Razorpay | ✅ | ✅ | ✅ | — | ✅ |
| Paddle | ✅ | ✅ | — | — | ✅ |
⚠️ Monnify implements
SubscriptionDriverInterfacefor interface compatibility, but all subscription methods throwSubscriptionException— Monnify has no subscription API.Capability detection is done via
instanceof— drivers only implement the interfaces they support. No breaking changes when new capabilities are added.
For runtime checks without resolving the driver from the container, use NexusPay\PaymentMadeEasy\GatewayCapabilities:
Installation
1. Install via Composer
PHP: enable the bcmath extension (ext-bcmath); it is required by Composer for consistent amount conversion in drivers.
Stripe: the SDK is not installed with the package by default. If you use Payment::driver('stripe') or Stripe webhooks, add:
Without it, resolving the Stripe driver or handling Stripe webhooks throws a clear error pointing to this command.
Outbound gateway HTTP: drivers use Laravel’s Http facade (illuminate/http). Per-gateway http_timeout and http_verify in config apply to each request. For app-wide defaults (proxy, extra headers, timeouts), see the Laravel HTTP client documentation — Http::globalOptions() is available from Laravel 10.42 onward; on Laravel 8–10.41 rely on those config keys or extend drivers as needed.
Framework versions: this package supports Laravel 8.83+ through Laravel 13 on PHP 8.1+ (Laravel 13 requires PHP 8.3+). Match illuminate/* versions to your laravel/framework release.
2. Publish Configuration
3. (Optional) Publish & Run Migrations
The package ships with migrations for recording payment activity to your database. This is opt-in:
Then enable recording in your .env:
4. Verify Your Setup
After adding credentials to your .env, run the following to confirm all gateways are configured correctly:
Gateways with missing credentials will be highlighted in yellow.
One-Time Payments
Use the default gateway (PAYMENT_GATEWAY / config) or call driver(...) explicitly. Amounts are in major currency units unless a gateway note says otherwise.
Subscriptions & Plans
Available on: Paystack, Flutterwave, Stripe, Seerbit
Stripe plans and subscriptions
Stripe maps plans to Product + Price. createPlan() returns a Price ID in plan_code — pass that to createSubscription(). Supported interval values: day, week, month, year.
Disbursements & Transfers
Available on: Paystack, Flutterwave, Monnify, Squad, Remita, Budpay, PayPal, Razorpay, MTN MoMo. Paystack and Flutterwave use transfer recipients; Monnify, Squad, Remita, and Budpay typically use bank account fields. PayPal, Razorpay X, and MTN use different payloads — see Gateway-Specific Notes.
Bank-account style transfers (Monnify, Squad, Remita, Budpay)
Virtual Accounts
Available on: Paystack, Flutterwave, Seerbit, Monnify, Squad, Budpay
Payment Links
Available on: Paystack, Flutterwave, Stripe, Seerbit
Webhooks
Webhook routes are registered automatically:
Queueing: Set PAYMENT_WEBHOOK_QUEUE_EVENTS=true to return 202 immediately and process the payload on the queue. The raw body is preserved so signature verification still works in the worker.
Idempotency: Set PAYMENT_WEBHOOK_IDEMPOTENCY_ENABLED=true to ignore duplicate deliveries with the same body (cache key per gateway + payload hash). Failed processing releases the lock so the provider can retry.
Signing secrets: With PAYMENT_WEBHOOK_VERIFY_SIGNATURE and PAYMENT_WEBHOOK_REQUIRE_SIGNING_SECRET both true (defaults), gateways that use HMAC (or Stripe’s signing secret) return 400 if the secret is missing, so you never verify with an empty key. M-Pesa, MTN MoMo, Remita, and PayPal skip this check (no shared HMAC secret in the same sense).
Unexpected errors: On HTTP 500 from the webhook controller, only the error message is logged by default; stack traces are included when APP_DEBUG is true. Set PAYMENT_WEBHOOK_LOG_UNEXPECTED_TRACE=true only if you explicitly want traces in logs (e.g. staging).
Rate limiting: Publish config and add the package middleware to payment-gateways.webhooks.middleware:
payment:webhook-replay bypasses signature verification by design; keep it console-only in production.
Configure each gateway's dashboard to point to:
Available Events
| Event Class | Fired When |
|---|---|
PaymentSuccessful |
A payment completes successfully |
PaymentFailed |
A payment fails |
PaymentPending |
A payment is pending |
RefundProcessed |
A refund is processed |
SubscriptionCreated |
A subscription is activated |
SubscriptionCancelled |
A subscription is cancelled |
SubscriptionRenewed |
A subscription renews / invoice paid |
TransferSuccessful |
A transfer/payout succeeds |
TransferFailed |
A transfer/payout fails |
DisputeCreated |
A dispute is raised |
ChargebackCreated |
A chargeback is raised |
Listening to Events
Register listeners in app/Providers/EventServiceProvider.php (or Laravel 11+ AppServiceProvider / bootstrap/app.php event discovery as you prefer):
Subscription and transfer listeners receive typed payloads: $event->subscriptionData, $event->invoiceData (renewals), $event->transferData, $event->reason (cancellations / failed transfers), $event->disputeData, $event->chargebackData.
Manual processing with WebhookManager
For a custom route (e.g. non-standard path), resolve WebhookManager and pass the gateway slug plus the request. Catch WebhookException for invalid signatures or bad payloads.
Optional .env toggles (see the Installation env block for the full list):
Capability Detection
Check what a driver supports at runtime:
Note: Monnify implements
SubscriptionDriverInterfacebut all methods throwSubscriptionException. Always wrap in try/catch or check before calling.
Injecting PaymentManager
Use constructor injection when you need explicit gateway resolution or cleaner tests:
Gateway-Specific Notes
Monnify
Hosted checkout — redirect the customer to checkoutUrl in the response:
Monnify's primary use case is virtual accounts (reserved bank accounts). The package supports:
- Reserved account creation (
createVirtualAccount) via POST/api/v2/bank-transfer/reserved-accounts - Single and bulk disbursements
- Authentication is automatic — the driver fetches and caches a Bearer token via Basic Auth
Squad (GTCo)
Remita
Remita's payment flow uses a Remita Retrieval Reference (RRR). initializePayment() returns an RRR that you use to construct the checkout URL. Pass the RRR as $reference to verifyPayment().
Budpay
Budpay uses a dual-header auth: Bearer token + Encryption header (HMAC-SHA512). This is handled internally; no extra configuration required.
Interswitch (Webpay)
Interswitch uses OAuth2 client_credentials — the token is fetched and cached automatically. Amount is stored in kobo internally. Currency uses ISO 4217 numeric codes (e.g. 566 for NGN).
PayPal
PayPal uses OAuth2 client_credentials — the access token is fetched and cached automatically. Amounts are in major currency units (USD, EUR, etc.) as decimal strings. The driver covers payments, billing subscriptions, and Payouts (bulk disbursements).
PayPal webhooks use RSA-SHA256 certificate-based signing (not HMAC). The handler verifies that all required PayPal signature headers are present as a guard.
M-Pesa (Safaricom Kenya)
M-Pesa uses STK Push — a prompt is sent to the customer's phone. Payment is asynchronous; the result is delivered to your MPESA_CALLBACK_URL.
M-Pesa does not send HMAC signatures — secure your callback URLs via HTTPS.
MTN MoMo
MTN MoMo uses two separate products (Collections and Disbursements), each with their own API User + Key + Subscription Key. Payments are also asynchronous — a push is sent to the customer's wallet, and the result is delivered to your MTNMOMO_CALLBACK_URL.
Razorpay
Razorpay uses Basic Auth (key_id:key_secret) on every request. Amounts are in paise (1 INR = 100 paise), handled internally by convertAmount(). The driver supports payments, subscriptions, payouts (Razorpay X account required), and payment links.
Paddle
Paddle is a Merchant of Record for SaaS / digital goods. The driver targets the Paddle Billing API. Plans map to Prices, payments to Transactions, and payment links to Paddle's native Payment Links.
Paddle webhooks use HMAC-SHA256 with the Paddle-Signature: ts=...;h1=... format, verified automatically.
Security
Run composer audit regularly on consuming applications and keep gateway credentials in environment variables only (never commit secrets). Webhook replay (payment:webhook-replay) skips signature checks — restrict production use to trusted operators.
Vulnerability disclosure: do not use the public issue tracker for undisclosed security bugs. Follow SECURITY.md (private report and scope).
Testing
Run the package's own test suite:
The test suite covers:
| Test file | What it tests |
|---|---|
tests/Unit/PaymentManagerTest.php |
driver resolution, interface detection, alias binding |
tests/Unit/WebhookManagerTest.php |
handler resolution, unknown gateway exception |
tests/Unit/Drivers/PaystackDriverTest.php |
HTTP mock — initialize, verify, refund, error handling |
tests/Unit/Drivers/RazorpayDriverTest.php |
HTTP mock — order creation, verify, refund, errors |
tests/Feature/WebhookHandlingTest.php |
full HTTP webhook flow — signature check, event dispatch |
In your own application, you can mock the Payment facade or bind a fake driver:
Database Recording
When PAYMENT_RECORDING_ENABLED=true, use PaymentRecorder to persist activity:
With PAYMENT_RECORDING_AUTO_WEBHOOK_EVENTS=true, listeners also persist RefundProcessed (status refunded / partially_refunded + payment_refunds rows), DisputeCreated / ChargebackCreated (status disputed + payment_disputes rows), in addition to payment, transfer, and subscription outcomes.
Available Models
| Model | Table | Purpose |
|---|---|---|
PaymentTransaction |
payment_transactions |
One-time payment records |
PaymentRefund |
payment_refunds |
One row per refund (multi-refund history) |
PaymentDispute |
payment_disputes |
Dispute / chargeback events (linked to transaction when present) |
PaymentSubscription |
payment_subscriptions |
Subscription / billing records |
PaymentTransfer |
payment_transfers |
Disbursement / transfer records |
PaymentWebhookLog |
payment_webhook_logs |
Audit log for all incoming webhooks |
Use $transaction->refunds and $transaction->totalRefundedAmount() for reporting. Status partially_refunded is set when refunded sum is below the original amount; refunded when the sum covers the original (with a small float tolerance).
All models support polymorphic payable / subscriber / initiator relationships so you can link them to your own models (e.g. User, Order).
Artisan Commands
The package ships built-in Artisan commands for local development and debugging.
payment:gateways — List all configured gateways
Output shows a capability matrix (Payments, Subscriptions, Disbursements, Virtual Accounts, Payment Links), marks the default gateway with *, and colour-codes each gateway as ready (green) or missing env (yellow) based on whether credentials are present in your .env.
payment:verify — Verify a payment by reference
Useful for quickly checking a payment status from the command line without writing a temporary controller.
payment:webhook-replay — Replay a logged webhook event
Requires
PAYMENT_RECORDING_ENABLED=trueand migrations to have been run.
Looks up the PaymentWebhookLog row by its primary key, reconstructs the original request, and routes it back through the appropriate webhook handler. The log's status is updated to processed on success or failed on error.
payment:transactions — List recorded transactions
Requires the payment_transactions table (publish and run package migrations).
Contributing
Please read CONTRIBUTING.md for how to report issues, run tests, and submit pull requests.
License
This package is released under the MIT License.
All versions of payment-made-easy with dependencies
ext-bcmath Version *
illuminate/support Version ^8.83|^9.0|^10.0|^11.0|^12.0|^13.0
illuminate/http Version ^8.83|^9.0|^10.0|^11.0|^12.0|^13.0