@zyntrialabs/zynpay-sdk
v1.1.10
Published
ZynPay SDK for Node.js/TypeScript - Accept USDC payments with automatic 3% platform fee
Downloads
54
Maintainers
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.MAINNETfor 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:5173What 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:5173What 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
- Router:
🧪 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
- Router:
✅ Arc Testnet -
chain: 'arc'- USDC is the gas token- Router:
0x3309F63914954a1A35cc662E76a3805E86D37715 - Get free USDC: https://faucet.circle.com
- Router:
🔜 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:
- Merchant approves USDC spending for the router contract
- Router contract transfers USDC from merchant to original payer
- 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
Base Sepolia ETH & USDC (for gas + payments)
- https://portal.cdp.coinbase.com/products/faucets
- Paste your wallet address
- Claim both ETH and USDC
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):
- Open
examples/metamask-payment.tsin your browser application - Connect MetaMask wallet
- Switch to Base Sepolia testnet
- Make sure you have testnet USDC and ETH
- 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 sideEnvironment 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
