serenity_technologies / nowpayments
Laravel package for NOWPayments cryptocurrency payment processing API
Package info
gitlab.com/serenity-technologies-library/nowpayments
pkg:composer/serenity_technologies/nowpayments
Requires
- php: ^8.2
- ext-hash: *
- ext-json: *
- guzzlehttp/guzzle: ^7.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
README
A comprehensive Laravel package for integrating with the NOWPayments cryptocurrency payment processing API.
Features
- Complete API Coverage: All 52 NOWPayments API endpoints supported
- Type-Safe DTOs: Request and Response DTOs with strict typing and numeric casting
- Status Enums: Type-safe payment, payout, conversion, and subscription statuses
- Query Builders: Fluent query builders for list endpoints
- Webhook System: IPN handler with HMAC-SHA512 verification, Laravel events, and controller trait
- Laravel Events: Auto-fired events for payment status changes, payouts, and conversions
- Laravel Service Provider: Easy integration with Laravel's DI container
- Facade Support: Convenient static access via
NowPaymentsfacade
Installation
1. Require the package via Composer
composer require serenity_technologies/nowpayments
2. Publish the configuration file
php artisan vendor:publish --provider="SerenityTechnologies\NowPayments\NowPaymentsServiceProvider" --tag="nowpayments-config"
3. Configure your environment variables
Add the following to your .env file:
NOWPAYMENTS_API_KEY=your_api_key_here
NOWPAYMENTS_IPN_SECRET=your_ipn_secret_here
NOWPAYMENTS_DASHBOARD_EMAIL=your_dashboard_email@example.com
NOWPAYMENTS_DASHBOARD_PASSWORD=your_password
NOWPAYMENTS_BASE_URL=https://api.nowpayments.io
NOWPAYMENTS_TIMEOUT=30
NOWPAYMENTS_FIXED_RATE=false
NOWPAYMENTS_FEE_PAID_BY_USER=false
NOWPAYMENTS_DEFAULT_PAYOUT_CURRENCY=usdttrc20
Usage
Basic Usage via Facade
use SerenityTechnologies\NowPayments\Facades\NowPayments;
// Check API status
$status = NowPayments::get('/v1/status');
// Or use the endpoint classes (recommended)
Using Endpoint Classes (Recommended)
use SerenityTechnologies\NowPayments\Endpoints\PaymentEndpoint;
use SerenityTechnologies\NowPayments\DTOs\Request\PaymentRequest;
public function createPayment(PaymentEndpoint $paymentEndpoint)
{
$request = new PaymentRequest(
price_amount: 100.00,
price_currency: 'usd',
pay_currency: 'btc',
order_id: 'ORDER-123',
order_description: 'Test payment'
);
$payment = $paymentEndpoint->createPayment($request);
return response()->json([
'payment_id' => $payment->payment_id,
'pay_address' => $payment->pay_address,
'pay_amount' => $payment->pay_amount,
]);
}
Available Endpoints
All endpoints are auto-resolved via Laravel's dependency injection:
Authentication & API Status
use SerenityTechnologies\NowPayments\Endpoints\AuthEndpoint;
$authEndpoint->getStatus(); // Returns ApiStatusResponse
$authEndpoint->authenticate($authRequest); // Returns AuthResponse
Currencies
use SerenityTechnologies\NowPayments\Endpoints\CurrencyEndpoint;
$currencyEndpoint->getAvailableCurrencies();
$currencyEndpoint->getFullCurrencies();
$currencyEndpoint->getMerchantCoins();
Payments
use SerenityTechnologies\NowPayments\Endpoints\PaymentEndpoint;
$paymentEndpoint->createPayment($request);
$paymentEndpoint->getPaymentStatus($paymentId);
$paymentEndpoint->getListPayments($queryBuilder);
$paymentEndpoint->getEstimate($estimateRequest);
$paymentEndpoint->getMinAmount($minAmountRequest);
Invoices
use SerenityTechnologies\NowPayments\Endpoints\InvoiceEndpoint;
$invoiceEndpoint->createInvoice($invoiceRequest);
$invoiceEndpoint->createInvoicePayment($invoicePaymentRequest);
Payouts
use SerenityTechnologies\NowPayments\Endpoints\PayoutEndpoint;
$payoutEndpoint->getBalance();
$payoutEndpoint->validateAddress($addressRequest);
$payoutEndpoint->createPayout($payoutRequest); // Requires auth
$payoutEndpoint->listPayouts($queryBuilder);
$payoutEndpoint->getPayoutStatus($payoutId);
$payoutEndpoint->verifyPayout($batchId, $verificationRequest);
$payoutEndpoint->cancelPayout($withdrawalId);
$payoutEndpoint->getMinWithdrawalAmount($coin);
$payoutEndpoint->getPayoutFeeEstimate();
Conversions
use SerenityTechnologies\NowPayments\Endpoints\ConversionEndpoint;
$conversionEndpoint->createConversion($conversionRequest);
$conversionEndpoint->listConversions($filters);
$conversionEndpoint->getConversionStatus($conversionId);
Sub-Partners (Customer Management)
use SerenityTechnologies\NowPayments\Endpoints\SubPartnerEndpoint;
$subPartnerEndpoint->createSubPartner($request);
$subPartnerEndpoint->getSubPartnerBalance($id);
$subPartnerEndpoint->listSubPartners($filters);
$subPartnerEndpoint->transferFunds($transferRequest);
$subPartnerEndpoint->getTransfer($id);
$subPartnerEndpoint->listTransfers($filters);
$subPartnerEndpoint->depositToSubPartner($depositRequest);
$subPartnerEndpoint->writeOffFromSubPartner($writeOffRequest);
$subPartnerEndpoint->createSubPartnerPayment($paymentRequest);
$subPartnerEndpoint->getSubPartnerPayments($filters);
Subscriptions (Recurring Payments)
use SerenityTechnologies\NowPayments\Endpoints\SubscriptionEndpoint;
$subscriptionEndpoint->createPlan($planRequest);
$subscriptionEndpoint->listPlans($filters);
$subscriptionEndpoint->getPlan($planId);
$subscriptionEndpoint->updatePlan($planId, $data);
$subscriptionEndpoint->createSubscription($subscriptionRequest);
$subscriptionEndpoint->listSubscriptions($filters);
$subscriptionEndpoint->getSubscription($subId);
$subscriptionEndpoint->deleteSubscription($subId);
Fiat Payouts
use SerenityTechnologies\NowPayments\Endpoints\FiatPayoutEndpoint;
$fiatPayoutEndpoint->getProviders();
$fiatPayoutEndpoint->getFiatCurrencies();
$fiatPayoutEndpoint->getCryptoCurrencies($provider, $currency);
$fiatPayoutEndpoint->getPaymentMethods($provider, $currency);
$fiatPayoutEndpoint->createAccount($accountRequest);
$fiatPayoutEndpoint->listAccounts($filters);
$fiatPayoutEndpoint->requestFiatPayout($payoutRequest);
$fiatPayoutEndpoint->listFiatPayouts($filters);
Query Builders
For list endpoints, use query builders for fluent pagination and filtering:
use SerenityTechnologies\NowPayments\QueryBuilders\PaymentListQueryBuilder;
$queryBuilder = new PaymentListQueryBuilder();
$queryBuilder->setLimit(50)
->setPage(0)
->setSortBy('created_at')
->setOrderBy('desc')
->setDateFrom('2024-01-01')
->setDateTo('2024-12-31');
$payments = $paymentEndpoint->getListPayments($queryBuilder->build());
Handling IPN Webhooks
Option 1: Using the Webhook Trait (Recommended)
use SerenityTechnologies\NowPayments\Support\HandlesIpnWebhooks;
use Illuminate\Routing\Controller;
class NowPaymentsWebhookController extends Controller
{
use HandlesIpnWebhooks;
}
Register the route in routes/api.php:
Route::post('nowpayments/webhook', NowPaymentsWebhookController::class);
The trait automatically:
- Verifies the IPN signature
- Fires Laravel events (
PaymentStatusChanged,PayoutCompleted,ConversionFinished) - Returns a success/error JSON response
Option 2: Manual Handler
use SerenityTechnologies\NowPayments\Handlers\IpnHandler;
use Illuminate\Http\Request;
public function handleWebhook(Request $request, IpnHandler $ipnHandler)
{
try {
$data = $ipnHandler->handleRequest($request);
// Process the webhook data
$paymentStatus = $data['payment_status'];
$paymentId = $data['payment_id'];
// Your business logic here
return response()->json(['status' => 'success']);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 403);
}
}
Listening to Webhook Events
use SerenityTechnologies\NowPayments\Events\PaymentStatusChanged;
use SerenityTechnologies\NowPayments\Events\PayoutCompleted;
use Illuminate\Support\Facades\Event;
Event::listen(PaymentStatusChanged::class, function (PaymentStatusChanged $event) {
Log::info("Payment {$event->paymentId} status: {$event->status}");
});
Event::listen(PayoutCompleted::class, function (PayoutCompleted $event) {
Log::info("Payout {$event->payoutId} completed with status: {$event->status}");
});
Manual IPN Signature Verification
use SerenityTechnologies\NowPayments\Handlers\IpnHandler;
$ipnHandler = new IpnHandler(config('nowpayments.ipn_secret'));
$isValid = $ipnHandler->verifySignature($postData, $signature);
// Check if this is a retry notification
$isRetry = $ipnHandler->isRetry($postData);
Status Enums
Use type-safe enums for status checking:
use SerenityTechnologies\NowPayments\Support\PaymentStatus;
use SerenityTechnologies\NowPayments\Support\PayoutStatus;
$status = PaymentStatus::from($paymentResponse->payment_status);
if ($status->isFinal()) {
// Payment is finished (finished, failed, refunded, or expired)
}
if ($status->isSuccessful()) {
// Payment completed successfully
}
if ($status->isPending()) {
// Payment is still in progress
}
Architecture
Directory Structure
src/
├── Client/
│ └── NowPaymentsClient.php # HTTP client wrapper
├── Config/
│ └── nowpayments.php # Package configuration
├── DTOs/
│ ├── Request/ # Request DTOs (20 files)
│ └── Response/ # Response DTOs (40 files)
├── Endpoints/ # API endpoint classes (9 files)
│ ├── AuthEndpoint.php
│ ├── CurrencyEndpoint.php
│ ├── PaymentEndpoint.php
│ ├── InvoiceEndpoint.php
│ ├── PayoutEndpoint.php
│ ├── ConversionEndpoint.php
│ ├── SubPartnerEndpoint.php
│ ├── SubscriptionEndpoint.php
│ └── FiatPayoutEndpoint.php
├── Events/
│ ├── NowPaymentsEvent.php # Base event class
│ ├── PaymentStatusChanged.php # Payment status change event
│ ├── PayoutCompleted.php # Payout completion event
│ └── ConversionFinished.php # Conversion finished event
├── Exceptions/
│ └── NowPaymentsException.php
├── Facades/
│ └── NowPayments.php # Laravel facade
├── Handlers/
│ └── IpnHandler.php # Webhook handler
├── QueryBuilders/
│ ├── PaymentListQueryBuilder.php
│ └── PayoutListQueryBuilder.php
├── Support/
│ ├── HandlesIpnWebhooks.php # Controller trait for webhooks
│ ├── PaymentStatus.php # Payment status enum
│ ├── PayoutStatus.php # Payout status enum
│ ├── ConversionStatus.php # Conversion status enum
│ └── SubscriptionStatus.php # Subscription status enum
└── NowPaymentsServiceProvider.php # Service provider
Key Components
- NowPaymentsClient: Base HTTP client that handles authentication, headers, error handling, and JWT token expiration
- Endpoint Classes: High-level API methods that use DTOs and return typed responses
- Request DTOs: Immutable request objects with validation (URL format, positive amounts, required fields)
- Response DTOs: Readonly response objects with
fromArray()factory methods and proper numeric casting - QueryBuilders: Fluent builders for list endpoint query parameters
- IpnHandler: Webhook signature verification using HMAC-SHA512 with retry detection
- HandlesIpnWebhooks: Laravel controller trait for easy webhook setup with auto-event firing
- Status Enums: Type-safe enums for payment, payout, conversion, and subscription statuses
- Laravel Events: Auto-fired events for webhook processing
API Endpoints Coverage
| Category | Endpoints | Status |
|---|---|---|
| Auth & API Status | 2 | ✅ |
| Currencies | 3 | ✅ |
| Payments | 6 | ✅ |
| Invoices | 2 | ✅ |
| Payouts | 9 | ✅ |
| Conversions | 3 | ✅ |
| Sub-Partners | 10 | ✅ |
| Subscriptions | 8 | ✅ |
| Fiat Payouts | 8 | ✅ |
| Total | 51 | ✅ |
Requirements
- PHP 8.2+
- Laravel 10.x, 11.x, or 12.x
- Guzzle HTTP Client 7.x
- JSON extension
- Hash extension
Development
Running Tests
composer test
Code Style
This package uses Laravel Pint for code style:
composer format
License
MIT License. See LICENSE for more information.
Support
For issues and feature requests, please create an issue in the repository.
Credits
Developed by Serenity Technologies for NOWPayments API integration.