SDK Documentation

@profullstack/coinpay - Node.js SDK & CLI for cryptocurrency payments

Installation

Install the CoinPay SDK using your preferred package manager:

Using pnpm (recommended)

pnpm add @profullstack/coinpay

Using npm

npm install @profullstack/coinpay

Global CLI Installation

# Install globally for CLI access
pnpm add -g @profullstack/coinpay

# Or with npm
npm install -g @profullstack/coinpay

Requirements: Node.js 20+ with ESM support

Quick Start

How CoinPay Works

  1. Your server calls the CoinPay API to create a payment request
  2. CoinPay generates a unique payment address and QR code
  3. Your customer sends cryptocurrency to that address
  4. CoinPay monitors the blockchain and notifies you via webhook
  5. Funds are automatically forwarded to your wallet (minus fees)

SDK Usage

Basic SDK Example

import { CoinPayClient, Blockchain } from '@profullstack/coinpay';

// Initialize with your API key (get it from your dashboard)
const coinpay = new CoinPayClient({
  apiKey: 'cp_live_your_api_key_here',
});

// Create a payment when customer checks out
const result = await coinpay.createPayment({
  businessId: 'your-business-id',  // From your dashboard
  amount: 100,                      // Amount in fiat currency
  currency: 'USD',                  // Fiat currency (default: USD)
  blockchain: Blockchain.BTC,       // Cryptocurrency to accept
  description: 'Order #12345',      // Shown to customer
  metadata: {                       // Your custom data
    orderId: '12345',
    customerEmail: 'customer@example.com'
  }
});

// Display to customer
console.log('Send payment to:', result.payment.payment_address);
console.log('Amount:', result.payment.crypto_amount, result.payment.blockchain);
console.log('QR Code:', result.payment.qr_code);

cURL Example

Direct API Call

curl -X POST https://coinpayportal.com/api/payments/create \
  -H "Authorization: Bearer cp_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "your-business-id",
    "amount": 100,
    "blockchain": "BTC",
    "description": "Order #12345",
    "metadata": {"orderId": "12345"}
  }'

CLI Usage

CLI Quick Start

# Configure your API key (one-time setup)
coinpay config set-key cp_live_your_api_key

# Create a Bitcoin payment
coinpay payment create --business-id biz_123 --amount 100 --blockchain BTC

# Create an Ethereum payment with description
coinpay payment create --business-id biz_123 --amount 50 --blockchain ETH --description "Order #12345"

# Create a USDC payment on Polygon
coinpay payment create --business-id biz_123 --amount 25 --blockchain USDC_MATIC

# Get payment details
coinpay payment get pay_abc123

# List payments
coinpay payment list --business-id biz_123

# Get exchange rates
coinpay rates get BTC

SDK Client Configuration

Initialize the CoinPayClient with your API key from your business dashboard:

Client Initialization

import { CoinPayClient } from '@profullstack/coinpay';

const client = new CoinPayClient({
  // Required: Your API key (starts with cp_live_)
  apiKey: 'cp_live_your_api_key_here',
  
  // Optional: Custom API URL (defaults to https://coinpayportal.com/api)
  baseUrl: 'https://coinpayportal.com/api',
  
  // Optional: Request timeout in milliseconds (default: 30000)
  timeout: 30000,
});

Environment Variables

VariableDescription
COINPAY_API_KEYAPI key (overrides config file)
COINPAY_BASE_URLCustom API URL

Payments API

Primary Use Case: Call this API from your backend when a customer wants to pay with cryptocurrency. Display the returned payment address and QR code to your customer.

Create Payment

Create a new payment

const result = await client.createPayment({
  businessId: 'your-business-id',  // Required: From your dashboard
  amount: 100,                      // Required: Amount in fiat
  currency: 'USD',                  // Optional: Fiat currency (default: USD)
  blockchain: 'BTC',                // Required: BTC, ETH, SOL, MATIC, BCH, USDC_ETH, USDC_MATIC, USDC_SOL
  description: 'Order #12345',      // Optional: Shown to customer
  metadata: {                       // Optional: Your custom data
    orderId: '12345',
    customerEmail: 'customer@example.com'
  }
});

// Response structure
console.log(result);
// {
//   success: true,
//   payment: {
//     id: 'pay_abc123',
//     payment_address: 'bc1q...',
//     crypto_amount: '0.00234567',
//     blockchain: 'BTC',
//     status: 'pending',
//     expires_at: '2024-01-01T13:00:00Z',
//     qr_code: 'data:image/png;base64,...'
//   },
//   usage: { current: 45, limit: 100, remaining: 55 }
// }

Check Payment Status

There are two ways to know when a payment is complete:

Option 1: Polling (Simple)

Poll for payment status

// Check status once
const result = await client.getPayment('pay_abc123');
console.log(result.payment.status); // 'pending', 'confirmed', 'forwarded', etc.

// Or wait for payment to complete (polls automatically)
const payment = await client.waitForPayment('pay_abc123', {
  interval: 5000,      // Check every 5 seconds
  timeout: 600000,     // Give up after 10 minutes
  onStatusChange: (status, payment) => {
    console.log(`Status changed to: ${status}`);
  }
});

if (payment.payment.status === 'confirmed' || payment.payment.status === 'forwarded') {
  console.log('Payment successful!');
} else {
  console.log('Payment failed or expired');
}

Option 2: Webhooks (Recommended)

Configure a webhook URL in your business settings to receive real-time notifications. See the Webhook Verification section below.

List Payments

List payments with filters

const payments = await client.listPayments({
  businessId: 'biz_123',
  status: 'completed', // optional filter
  limit: 20,           // optional, default 50
  offset: 0,           // optional, for pagination
});

console.log(`Found ${payments.length} payments`);

Get Payment QR Code

The QR code endpoint returns binary PNG image data that can be used directly in HTML.

QR code usage

// Get QR code URL for use in HTML <img> tags
const qrUrl = client.getPaymentQRUrl('pay_abc123');
// Returns: "https://coinpayportal.com/api/payments/pay_abc123/qr"

// Use directly in HTML:
// <img src={qrUrl} alt="Payment QR Code" />

// Or fetch as binary data (for server-side processing)
const imageData = await client.getPaymentQR('pay_abc123');

// Save to file (Node.js)
import fs from 'fs';
fs.writeFileSync('payment-qr.png', Buffer.from(imageData));

HTML usage

<!-- Use QR endpoint directly as image source -->
<img src="https://coinpayportal.com/api/payments/pay_abc123/qr" alt="Payment QR Code" />

Businesses API

Create Business

Create a new business

const business = await client.createBusiness({
  name: 'My Store',
  webhookUrl: 'https://your-site.com/webhook',
  walletAddresses: {
    BTC: 'bc1q...',
    ETH: '0x...',
    SOL: '...',
  },
});

console.log(`Business ID: ${business.id}`);
console.log(`API Key: ${business.apiKey}`);

Get Business

Retrieve business details

const business = await client.getBusiness('biz_123');

console.log(business.name);
console.log(business.walletAddresses);

List Businesses

List all businesses

const businesses = await client.listBusinesses();

businesses.forEach(biz => {
  console.log(`${biz.name}: ${biz.id}`);
});

Update Business

Update business settings

const updated = await client.updateBusiness('biz_123', {
  name: 'Updated Store Name',
  webhookUrl: 'https://new-webhook-url.com/webhook',
});

Exchange Rates

Get Single Rate

Get exchange rate for one cryptocurrency

const rate = await client.getExchangeRate('BTC', 'USD');

console.log(`1 BTC = $${rate.price} USD`);
console.log(`Last updated: ${rate.timestamp}`);

Get Multiple Rates

Get rates for multiple cryptocurrencies

const rates = await client.getExchangeRates(['BTC', 'ETH', 'SOL'], 'USD');

rates.forEach(rate => {
  console.log(`${rate.symbol}: $${rate.price}`);
});

Supported Blockchains

Bitcoin
BTC
Bitcoin Cash
BCH
Ethereum
ETH
Polygon
MATIC
Solana
SOL
USDC (Ethereum)
USDC_ETH
USDC (Polygon)
USDC_MATIC
USDC (Solana)
USDC_SOL

Webhook Verification

Verify webhook signatures to ensure requests are from CoinPay:

Manual Verification

Verify webhook signature

import { verifyWebhookSignature } from '@profullstack/coinpay';

// In your webhook handler
const isValid = verifyWebhookSignature({
  payload: rawBody,  // Raw request body as string
  signature: req.headers['x-coinpay-signature'],
  secret: 'your-webhook-secret',
});

if (!isValid) {
  return res.status(401).json({ error: 'Invalid signature' });
}

// Process the webhook...

Express Middleware

Use the webhook handler middleware

import express from 'express';
import { createWebhookHandler } from '@profullstack/coinpay';

const app = express();

// Use raw body parser for webhook route
app.post('/webhook', 
  express.raw({ type: 'application/json' }),
  createWebhookHandler({
    secret: 'your-webhook-secret',
    onEvent: async (event) => {
      console.log('Received event:', event.type);
      
      switch (event.type) {
        case 'payment.completed':
          // Handle completed payment
          await fulfillOrder(event.payment_id);
          break;
        case 'payment.expired':
          // Handle expired payment
          await cancelOrder(event.payment_id);
          break;
        case 'payment.failed':
          // Handle failed payment
          await notifyCustomer(event.payment_id);
          break;
      }
    },
    onError: (error) => {
      console.error('Webhook error:', error);
    },
  })
);

Webhook Events

payment.createdPayment was created
payment.pendingPayment is pending confirmation
payment.confirmingPayment is being confirmed on blockchain
payment.completedPayment completed successfully
payment.expiredPayment expired without completion
payment.failedPayment failed
payment.refundedPayment was refunded

Webhook Logs

Get webhook delivery logs

// Get recent webhook logs for a business
const logs = await client.getWebhookLogs('biz_123', 50);

logs.forEach(log => {
  console.log(`${log.event}: ${log.status} (${log.statusCode})`);
});

// Test webhook endpoint
const result = await client.testWebhook('biz_123', 'payment.completed');
console.log(`Test delivery: ${result.success ? 'OK' : 'Failed'}`);

CLI Commands

The CoinPay CLI provides command-line access to all API features:

Configuration

Configure CLI

# Set your API key
coinpay config set-key sk_live_xxxxx

# Set custom API URL (optional)
coinpay config set-url https://custom-api.example.com

# Show current configuration
coinpay config show

Payment Commands

Payment operations

# Create a Bitcoin payment
coinpay payment create \
  --business-id biz_123 \
  --amount 100 \
  --blockchain BTC \
  --description "Order #12345"

# Create a USDC payment on Polygon
coinpay payment create \
  --business-id biz_123 \
  --amount 50 \
  --blockchain USDC_MATIC

# Get payment details
coinpay payment get pay_abc123

# List payments
coinpay payment list --business-id biz_123 --status completed --limit 20

# Generate QR code
coinpay payment qr pay_abc123 --format png > payment-qr.png

Business Commands

Business operations

# Create a business
coinpay business create --name "My Store" --webhook-url https://example.com/webhook

# Get business details
coinpay business get biz_123

# List all businesses
coinpay business list

# Update business
coinpay business update biz_123 --name "New Name" --webhook-url https://new-url.com/webhook

Exchange Rate Commands

Rate operations

# Get rate for single cryptocurrency
coinpay rates get BTC --fiat USD

# List all supported rates
coinpay rates list --fiat EUR

Webhook Commands

Webhook operations

# View webhook logs
coinpay webhook logs biz_123 --limit 50

# Test webhook endpoint
coinpay webhook test biz_123 --event payment.completed

Error Handling

Handle errors gracefully in your integration:

Error handling example

import { CoinPayClient } from '@profullstack/coinpay';

const client = new CoinPayClient({ apiKey: 'cp_live_your_api_key' });

try {
  const result = await client.createPayment({
    businessId: 'your-business-id',
    amount: 100,
    blockchain: 'BTC',
  });
  
  console.log('Payment created:', result.payment.id);
  console.log('Address:', result.payment.payment_address);
} catch (error) {
  if (error.status === 401) {
    console.error('Invalid API key');
  } else if (error.status === 400) {
    console.error('Invalid request:', error.response?.error);
  } else if (error.status === 429) {
    // Transaction limit exceeded or rate limit
    console.error('Limit exceeded:', error.response?.error);
    console.error('Usage:', error.response?.usage);
  } else {
    console.error('Unexpected error:', error.message);
  }
}

Error Codes

400
Bad Request
Invalid parameters or missing required fields
401
Unauthorized
Invalid or missing API key
403
Forbidden
Access denied to resource
404
Not Found
Resource not found
429
Too Many Requests
Rate limit exceeded
500
Server Error
Internal server error

TypeScript Support

The SDK is written in JavaScript (ESM) but includes JSDoc type annotations for IDE support:

Type hints in VS Code

import { CoinPayClient, Blockchain, PaymentStatus } from '@profullstack/coinpay';

// Use Blockchain constants for type safety
const result = await client.createPayment({
  businessId: 'biz_123',
  amount: 100,
  blockchain: Blockchain.BTC,  // 'BTC' | 'BCH' | 'ETH' | 'MATIC' | 'SOL' | 'USDC_ETH' | 'USDC_MATIC' | 'USDC_SOL'
});

// result.payment.status: 'pending' | 'detected' | 'confirmed' | 'forwarding' | 'forwarded' | 'expired' | 'failed'
// result.payment.payment_address: string
// result.payment.crypto_amount: string