npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zyntrialabs/zynpay-sdk

v1.1.10

Published

ZynPay SDK for Node.js/TypeScript - Accept USDC payments with automatic 3% platform fee

Downloads

54

Readme

ZynPay TypeScript/Node.js SDK

Base Mainnet Live! | Testnet also available for testing

Accept crypto payments in your app

Built for merchants and businesses who want to accept USDC payments. Your customers pay with their wallet—MetaMask, Coinbase Wallet, WalletConnect, or any web3 wallet. No complex integrations, no custody, no hassle.

Why businesses choose ZynPay

What your customers get:

  • ✅ Pay with their existing wallet (MetaMask, Coinbase Wallet, etc.)
  • ✅ See the exact amount before approving
  • ✅ Their private keys never leave their wallet
  • ✅ No sign-ups or extra accounts needed

What you get as a merchant:

  • ✅ Get paid in USDC directly to your wallet
  • ✅ Integrate in under 10 minutes
  • ✅ Zero backend infrastructure required
  • ✅ Support for multiple payment methods (wallet connect, payment links)
  • ✅ Works on Base Mainnet (live) and Base/Arc testnets

📦 Installation

npm install @zyntrialabs/zynpay-sdk

✅ Production Ready: Use Environment.MAINNET for Base Mainnet. Test with free tokens on Base Sepolia and Arc Testnet!

🎯 How Merchants Use ZynPay

Wallet Connect Payments

Perfect for e-commerce, SaaS platforms, marketplaces, subscriptions. Customers connect their wallet and pay directly.

import { ZynPayClient, Environment } from '@zyntrialabs/zynpay-sdk';
import { BrowserProvider } from 'ethers';

// Customer connects their wallet
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

// Initialize with your merchant wallet
const client = new ZynPayClient({
  merchantWallet: '0xYourBusinessWallet', // You receive payments here
  environment: Environment.MAINNET, // Use MAINNET for production, TESTNET for testing
  defaultChain: 'base',
});

// Create payment for any amount
const payment = client.createPayment(49.99); // $49.99 product price

// Customer approves payment in their wallet
const txHash = await client.pay(payment, signer);

console.log(`✅ Payment received! TX: ${txHash}`);
// USDC is now in your merchant wallet!

💡 What you can accept: Product purchases, subscriptions, service fees, donations, NFT minting fees, membership dues any USDC payment!

📚 Example Apps

Payment Link Example (examples/payment-link-app/)

Shows how to build a payment link page using the SDK:

cd examples/payment-link-app
npm install
npm run dev
# Open http://localhost:5173

What it demonstrates:

  • Creating payment requests with the SDK
  • MetaMask integration for customer payments
  • React + TypeScript implementation
  • Real-time balance checking
  • Step-by-step payment flow

Dashboard Example (examples/dashboard-app/)

Shows how to build a merchant dashboard using listPayments():

cd examples/dashboard-app
npm install
npm run dev
# Open http://localhost:5173

What it demonstrates:

  • Using listPayments() to fetch payment history
  • Displaying payment statistics
  • Building a payment history table
  • Filtering by network

These are reference implementations showing merchants how to build these features using the ZynPay SDK.

📚 Complete Integration Example

Here's a complete checkout flow for an e-commerce store:

import { ZynPayClient, Environment } from '@zyntrialabs/zynpay-sdk';
import { BrowserProvider } from 'ethers';

async function checkoutWithCrypto(productPrice: number) {
  // 1. Check if customer has a wallet
  if (!window.ethereum) {
    alert('Please install MetaMask or Coinbase Wallet to pay with crypto!');
    return;
  }

  // 2. Connect to customer's wallet
  const provider = new BrowserProvider(window.ethereum);
  await provider.send('eth_requestAccounts', []); // Customer approves connection
  const signer = await provider.getSigner();
  const customerAddress = await signer.getAddress();

  // 3. Initialize ZynPay with YOUR merchant wallet
  const client = new ZynPayClient({
    merchantWallet: '0x1234567890123456789012345678901234567890', // Your business wallet
    environment: Environment.MAINNET, // Use MAINNET for production
    defaultChain: 'base',
  });

  // 4. Create payment for the product
  const payment = client.createPayment(productPrice);

  // 5. Check if customer has enough USDC
  const balance = await client.getBalance(customerAddress);
  if (balance.usdc < payment.amount) {
    alert(
      `Insufficient USDC! You need ${payment.amount} but have ${balance.usdc}`
    );
    return;
  }

  // 6. Customer pays - they approve in their wallet
  try {
    const txHash = await client.pay(payment, signer);

    console.log('✅ Payment received!');
    console.log(`Amount: $${payment.amount} USDC`);
    console.log(`Transaction: ${txHash}`);

    // Payment is now in YOUR merchant wallet!
    // Update order status, send confirmation email, etc.

    return { success: true, txHash };
  } catch (error) {
    if (error.code === 'ACTION_REJECTED') {
      alert('Payment cancelled by customer');
    } else {
      console.error('Payment failed:', error);
    }
    return { success: false, error };
  }
}

// Use in your checkout button
document.getElementById('pay-with-crypto').addEventListener('click', () => {
  checkoutWithCrypto(49.99); // $49.99 product
});

🌐 Supported Networks

🚀 Mainnet (Production Ready)

  • Base Mainnet - chain: 'base' - Live and ready for production!
    • Router: 0x3309F63914954a1A35cc662E76a3805E86D37715 (X402RouterV2 with refunds)
    • Chain ID: 8453
    • RPC: https://mainnet.base.org
    • Explorer: https://basescan.org
    • Use real USDC and ETH for payments

🧪 Testnet (Free Tokens for Testing)

  • Base Sepolia - chain: 'base' - Recommended for testing

    • Router: 0x29F81b4870c3b6806a36d2c07db24fDFC6EcB5FF (3% fee, V2 with refunds)
    • Get free ETH & USDC: https://portal.cdp.coinbase.com/products/faucets
  • Arc Testnet - chain: 'arc' - USDC is the gas token

    • Router: 0x3309F63914954a1A35cc662E76a3805E86D37715
    • Get free USDC: https://faucet.circle.com

🔜 Coming Soon

  • 🔜 Arc Mainnet - chain: 'arc' - Will be available when Arc launches mainnet

📖 API Reference

ZynPayClient

Constructor

const client = new ZynPayClient({
  merchantWallet: '0x...', // Your wallet address
  environment: Environment.TESTNET, // or Environment.MAINNET
  defaultChain: 'base', // 'base', 'arc', 'ethereum'
  verbose: true, // Optional: enable logging
});

createPayment(amount: number, chain?: string): Payment

Create a new payment request.

const payment = client.createPayment(5.0, 'base');
pay(payment: Payment, signer: Signer, waitForConfirmation?: boolean): Promise<string>

Execute payment on blockchain using a wallet Signer.

// Get signer from wallet (MetaMask, WalletConnect, etc.)
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

// Execute payment
const txHash = await client.pay(payment, signer, true);
getBalance(wallet: string, chain?: string): Promise<Balance>

Check USDC and native token balance.

const balance = await client.getBalance('0x...');
console.log(`USDC: ${balance.usdc}, ETH: ${balance.native}`);
listPayments(merchantAddress?: string, options?: { network?: string; fromBlock?: string; toBlock?: string }): Promise<Payment[]>

Fetch all on-chain payments for a merchant. This queries the blockchain directly using getLogs to retrieve all PaymentSplit events.

// List all payments for the merchant wallet
const payments = await client.listPayments();

// List payments for a specific merchant address
const payments = await client.listPayments('0xMerchantAddress...');

// List payments with filters
const payments = await client.listPayments('0xMerchantAddress...', {
  network: 'base-sepolia',
  fromBlock: '34000000',
  toBlock: 'latest',
});

// Each payment includes:
// - paymentId, merchant, payer addresses
// - amountTotal, amountToMerchant, amountToPlatform
// - txHash, blockNumber, timestamp
// - metadata (if provided during payment creation)
// - status: 'paid'

💡 Tip: You can also view payments in the Merchant Dashboard by entering your wallet address!

estimateGas(amount: number, chain?: string): Promise<GasEstimate>

Estimate gas cost for payment transaction.

const gas = await client.estimateGas(10.0);
console.log(`Cost: $${gas.totalCostUsd}`);
getSupportedChains(): string[]

Get list of supported chains for current environment.

const chains = client.getSupportedChains();
console.log(chains); // ['base', 'arc']
getExplorerUrl(chain: string, txHashOrAddress?: string): string

Get block explorer URL for transaction or address.

const url = client.getExplorerUrl('base', txHash);
refundPayment(paymentId: string, refundAmount: number, signerOrPrivateKey: Signer | string, waitForConfirmation?: boolean): Promise<string>

Refund a payment (full or partial). Only the merchant who received the payment can initiate refunds.

Important Notes:

  • Platform fee (3%) is NOT automatically refunded
  • Merchant must have sufficient USDC balance to cover the refund amount
  • Refunds are sent from the merchant's wallet back to the original payer
// Browser (MetaMask) - Merchant refunds a payment
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner(); // Merchant's wallet

// Refund full amount
const paymentId = '0x...'; // From the original payment
const refundAmount = 49.99; // Amount to refund
const txHash = await client.refundPayment(paymentId, refundAmount, signer);

console.log(`✅ Refund processed! TX: ${txHash}`);
// Partial refund example
const originalAmount = 100.00;
const refundAmount = 25.00; // Refund 25% of the payment

const txHash = await client.refundPayment(paymentId, refundAmount, signer);
console.log(`Refunded $${refundAmount} of $${originalAmount}`);
// Server-side refund (using private key) - NOT for frontend!
// ⚠️ Never expose private keys in client-side code
const merchantPrivateKey = process.env.MERCHANT_PRIVATE_KEY!;
const txHash = await client.refundPayment(
  paymentId, 
  refundAmount, 
  merchantPrivateKey
);

Refund Flow:

  1. Merchant approves USDC spending for the router contract
  2. Router contract transfers USDC from merchant to original payer
  3. Refund is recorded on-chain (can be queried via listPayments())

🔧 Error Handling

import {
  InsufficientFundsError,
  TransactionFailedError,
  NetworkError,
} from '@zyntrialabs/zynpay-sdk';

try {
  // Get signer from wallet
  const provider = new BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();

  await client.pay(payment, signer);
} catch (error) {
  if (error.code === 'ACTION_REJECTED') {
    console.log('User cancelled the transaction');
  } else if (error instanceof InsufficientFundsError) {
    console.log(`Need ${error.required} USDC, have ${error.available}`);
  } else if (error instanceof TransactionFailedError) {
    console.log(`TX failed: ${error.txHash}`);
  } else if (error instanceof NetworkError) {
    console.log('Network issue:', error.message);
  }
}

💡 Testing

Get Testnet Tokens

  1. Base Sepolia ETH & USDC (for gas + payments)

    • https://portal.cdp.coinbase.com/products/faucets
    • Paste your wallet address
    • Claim both ETH and USDC
  2. Arc Testnet USDC (USDC is gas on Arc!)

    • https://faucet.circle.com
    • Select Arc Testnet
    • Claim USDC (used for both gas and payments)

Run Example

Browser (MetaMask):

  1. Open examples/metamask-payment.ts in your browser application
  2. Connect MetaMask wallet
  3. Switch to Base Sepolia testnet
  4. Make sure you have testnet USDC and ETH
  5. Execute payment - MetaMask will prompt you to approve

Node.js (Testing):

cd examples
npx tsx basic-payment.ts

🏗️ How Payments Work

Customer clicks "Pay with Crypto" on your site
                ↓
        Connects their wallet (MetaMask, etc.)
                ↓
        Views payment details and approves
                ↓
        Smart contract executes payment
                ↓
        USDC sent directly to your merchant wallet
                ↓
        You receive payment instantly - no waiting!

Why Merchants Love It

Direct to your wallet - Payments go straight to your business wallet. No intermediary custody, no withdrawal delays.

No chargebacks - Blockchain transactions are final. Once paid, it's yours.

Global reach - Accept payments from anyone with USDC, anywhere in the world.

Full transparency - Every transaction is on-chain and verifiable.

🔐 Security Best Practices

Wallet-Based Authentication

// ✅ BEST - Use wallet Signers (MetaMask, WalletConnect)
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner(); // User approves in wallet
await client.pay(payment, signer);

// Benefits:
// - Private keys never leave user's wallet
// - User sees exactly what they're signing
// - Works with hardware wallets (Ledger, Trezor)
// - No key management on your side

Environment Variables

// Store sensitive config in .env files
MERCHANT_WALLET=0x...

🔗 Links

  • Documentation: https://docs.zynpay.app
  • X: @zyntrialabs
  • npm: https://www.npmjs.com/package/@zyntrialabs/zynpay-sdk

Built with ❤️ for the web3 community