polybrainz_now_payments
A type-safe Dart API wrapper for NOWPayments cryptocurrency payment gateway
Features • Installation • Quick Start • API Reference • Error Handling
✨ Features
💳 PaymentsCreate and track cryptocurrency payments with real-time status updates 🧾 InvoicesGenerate hosted payment pages with QR codes 💸 PayoutsSend crypto to multiple recipients (mass payouts) 🔔 IPN WebhooksValidate payment notifications with HMAC-SHA512 |
🛡️ Type-SafeEnums for statuses, currencies, and all API responses 🚫 No Magic StringsAll constants defined as strongly-typed enums 🧪 TestableMockable HTTP client via dependency injection 🏖️ Sandbox SupportTest in sandbox before going live |
📦 Installation
Add to your pubspec.yaml:
dependencies:
polybrainz_now_payments: ^1.0.0
Then run:
dart pub get
🚀 Quick Start
import 'package:polybrainz_now_payments/polybrainz_now_payments.dart';
void main() async {
final client = NowPaymentsClient(
config: NowPaymentsConfig(
apiKey: 'YOUR_API_KEY',
environment: NowPaymentsEnvironment.sandbox, // or .production
),
);
try {
// Check API status
final status = await client.getStatus();
print('API Status: ${status.message}');
// Create a payment
final payment = await client.createPayment(
CreatePaymentRequest(
priceAmount: 100.0,
priceCurrency: FiatCurrency.usd,
payCurrency: 'btc',
orderId: 'ORDER-123',
ipnCallbackUrl: 'https://yoursite.com/webhook',
),
);
print('Pay ${payment.payAmount} BTC to ${payment.payAddress}');
} finally {
client.dispose();
}
}
📖 API Reference
⚙️ Configuration
final client = NowPaymentsClient(
config: NowPaymentsConfig(
apiKey: 'YOUR_API_KEY',
environment: NowPaymentsEnvironment.production,
timeout: Duration(seconds: 30),
logger: print, // Optional debug logging
),
);
💳 Payments
Create a Payment
final payment = await client.createPayment(
CreatePaymentRequest(
priceAmount: 50.0,
priceCurrency: FiatCurrency.usd,
payCurrency: 'eth',
orderId: 'ORDER-456',
orderDescription: 'Premium subscription',
),
);
Check Payment Status
final status = await client.getPaymentStatus(payment.paymentId);
print('Status: ${status.paymentStatus}'); // PaymentStatus.waiting, .finished, etc.
// Helper methods
if (status.isComplete) print('Payment received!');
if (status.isPending) print('Waiting for payment...');
if (status.isFailed) print('Payment failed or expired');
List Payments
final payments = await client.getPayments(
ListPaymentsRequest(
limit: 10,
page: 0,
orderBy: SortOrder.desc,
),
);
for (final p in payments.data) {
print('${p.paymentId}: ${p.paymentStatus}');
}
🧾 Invoices
Create an Invoice
final invoice = await client.createInvoice(
CreateInvoiceRequest(
priceAmount: 25.0,
priceCurrency: FiatCurrency.eur,
orderId: 'INV-789',
successUrl: 'https://yoursite.com/success',
cancelUrl: 'https://yoursite.com/cancel',
),
);
print('Invoice URL: ${invoice.invoiceUrl}');
💱 Currencies & Estimates
Get Available Currencies
final currencies = await client.getCurrencies();
print('Available: ${currencies.join(", ")}');
// Get your enabled currencies
final enabled = await client.getSelectedCurrencies();
Get Minimum Payment Amount
final min = await client.getMinimumPaymentAmount(
currencyFrom: 'btc',
currencyTo: 'usd',
);
print('Minimum: ${min.minAmount} BTC');
Get Price Estimate
final estimate = await client.getEstimatePrice(
amount: 100,
currencyFrom: 'usd',
currencyTo: 'btc',
);
print('100 USD = ${estimate.estimatedAmount} BTC');
🔔 IPN Webhook Validation
Validate & Handle Webhooks
import 'dart:convert';
void handleWebhook(Map<String, String> headers, String body) {
final validator = IpnValidator('YOUR_IPN_SECRET_KEY');
final signature = headers['x-nowpayments-sig']!;
final payload = jsonDecode(body) as Map<String, dynamic>;
final payment = validator.parseIpnPayload(
signature: signature,
payload: payload,
);
if (payment == null) {
print('Invalid signature!');
return;
}
switch (payment.paymentStatus) {
case PaymentStatus.finished:
print('Payment complete!');
break;
case PaymentStatus.failed:
case PaymentStatus.expired:
print('Payment failed');
break;
default:
print('Status: ${payment.paymentStatus}');
}
}
💸 Payouts
⚠️ Note: Payouts require custody account and JWT authentication
Create a Payout
// Authenticate first
await client.authenticate(
email: '[email protected]',
password: 'your_password',
);
// Check balance
final balance = await client.getBalance();
print('BTC balance: ${balance.getBalance("btc")}');
// Create payout
final payout = await client.createPayout(
CreatePayoutRequest(
address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
currency: 'btc',
amount: 0.001,
),
);
// Verify with 2FA
await client.verifyPayout(
VerifyPayoutRequest(
payoutId: payout.id,
verificationCode: '123456',
),
);
📊 Payment Statuses
| Status | Icon | Description |
|---|---|---|
waiting |
⏳ | Waiting for customer to send funds |
confirming |
🔄 | Transaction detected, awaiting confirmations |
confirmed |
✅ | Confirmed on blockchain |
sending |
📤 | Sending funds to merchant |
partiallyPaid |
⚠️ | Customer sent less than required |
finished |
✨ | Payment complete |
failed |
❌ | Payment failed |
refunded |
↩️ | Payment refunded |
expired |
⏰ | Payment expired |
🛡️ Error Handling
try {
await client.createPayment(...);
} on AuthenticationException catch (e) {
// Invalid API key
print('Auth error: ${e.message}');
} on BadRequestException catch (e) {
// Invalid parameters
print('Bad request: ${e.message}');
} on NotFoundException catch (e) {
// Resource not found
print('Not found: ${e.message}');
} on RateLimitException catch (e) {
// Too many requests
print('Rate limited, retry after: ${e.retryAfter}');
} on NowPaymentsException catch (e) {
// Generic API error
print('API error (${e.statusCode}): ${e.message}');
}
Exception Hierarchy
NowPaymentsException (base)
├── AuthenticationException (401)
├── BadRequestException (400)
├── NotFoundException (404)
├── RateLimitException (429)
└── ServerException (5xx)
🧪 Testing
Use dependency injection to mock the HTTP client:
import 'package:http/http.dart' as http;
import 'package:mocktail/mocktail.dart';
class MockHttpClient extends Mock implements http.Client {}
void main() {
final mockClient = MockHttpClient();
final client = NowPaymentsClient(
config: NowPaymentsConfig(apiKey: 'test'),
httpClient: mockClient,
);
// Set up mock responses...
}
📋 Requirements
| Requirement | Version |
|---|---|
| Dart SDK | ^3.0.0 |
| Flutter | Compatible ✅ |
You'll also need a NOWPayments account with an API key from nowpayments.io
🔗 Links
📚 API Docs • 🔑 Dashboard • 🐛 Report Issues
📄 License
MIT License
Copyright (c) 2026 Polybrainz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
Made with ❤️ by Polybrainz
Libraries
- polybrainz_now_payments
- A Dart API wrapper for NOWPayments cryptocurrency payment gateway.