NOWPayments

polybrainz_now_payments

A type-safe Dart API wrapper for NOWPayments cryptocurrency payment gateway

pub package License: MIT Dart SDK Flutter Compatible

FeaturesInstallationQuick StartAPI ReferenceError Handling


✨ Features

💳 Payments

Create and track cryptocurrency payments with real-time status updates

🧾 Invoices

Generate hosted payment pages with QR codes

💸 Payouts

Send crypto to multiple recipients (mass payouts)

🔔 IPN Webhooks

Validate payment notifications with HMAC-SHA512

🛡️ Type-Safe

Enums for statuses, currencies, and all API responses

🚫 No Magic Strings

All constants defined as strongly-typed enums

🧪 Testable

Mockable HTTP client via dependency injection

🏖️ Sandbox Support

Test 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


📚 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.