@crypax/node
Server-side SDK for Node.js. Create payments, manage customers, verify webhooks, and check on-chain confirmations.
Installation
$ npm install @crypax/nodeSetup
Initialize the client with your secret key. Never use secret keys in client-side code.
import { Crypax } from '@crypax/node';
const crypax = new Crypax('sk_live_...');Chains
Query supported chains and their tokens.
import { PLUMISE_MAINNET, PLUMISE_TESTNET, CHAINS, SUPPORTED_CHAIN_IDS } from '@crypax/node';
// Use chain constants instead of raw chain IDs
console.log(PLUMISE_MAINNET.chainId); // 41956
console.log(PLUMISE_TESTNET.chainId); // 419561
// Each constant includes full chain info
// { chainId, name, symbol, decimals, rpcUrl, explorerUrl, isTestnet }
// CHAINS object for iteration
Object.values(CHAINS).forEach(chain => {
console.log(chain.name, chain.chainId);
});
// SUPPORTED_CHAIN_IDS = [41956, 419561]sdkNode.chains.available
| sdkNode.chains.constantCol | sdkNode.chains.nameCol | sdkNode.chains.chainIdCol | sdkNode.chains.symbolCol | sdkNode.chains.testnetCol |
|---|---|---|---|---|
PLUMISE_MAINNET | Plumise Mainnet | 41956 | PLM | No |
PLUMISE_TESTNET | Plumise Testnet | 419561 | PLM | Yes |
Payments
payments.create(params)
Create a new payment. Returns a Payment object including a clientSecret to pass to the frontend.
const payment = await crypax.payments.create({
amount: '10.00',
chainId: 41956,
currency: 'native', // optional, defaults to 'native'
recipientAddress: '0x...', // optional, defaults to project wallet
description: 'Pro Plan',
metadata: { userId: 'user_456' },
qrMode: false, // set true to skip wallet selection
});
console.log(payment.id); // Payment UUID
console.log(payment.clientSecret); // 'cs_live_...' — send to frontend| Parameter | Type | Required | Description |
|---|---|---|---|
amount | string | Required | Payment amount as a decimal string (e.g. '10.00') |
chainId | number | Required | Chain ID (e.g. 41956 for Plumise Mainnet) |
currency? | string | Optional | 'native' for PLM, or an ERC20 token address |
recipientAddress? | string | Optional | Wallet address to receive the payment (optional — defaults to project wallet) |
description? | string | Optional | Human-readable description |
metadata? | Record<string, unknown> | Optional | Arbitrary key-value data attached to the payment |
qrMode? | boolean | Optional | Skip wallet selection and show QR code directly |
payments.retrieve(id)
Retrieve a payment by ID.
const payment = await crypax.payments.retrieve('payment-uuid');
console.log(payment.status); // 'created' | 'processing' | 'confirmed' | 'expired' | 'failed'
console.log(payment.txHash); // '0x...' (after confirmation)payments.list(params?)
List payments with optional filters for status and pagination.
const { data, total } = await crypax.payments.list({
status: 'confirmed', // optional filter
page: 1,
limit: 20,
});
data.forEach(payment => {
console.log(payment.id, payment.amount, payment.status);
});Customers
Create and manage customer records linked to wallet addresses.
// Create a customer
const customer = await crypax.customers.create({
walletAddress: '0x...',
email: 'user@example.com',
displayName: 'Alice',
metadata: { plan: 'pro' },
});
// Retrieve
const customer = await crypax.customers.retrieve('cust_...');
// List
const { data } = await crypax.customers.list({ page: 1, limit: 20 });
// Update
await crypax.customers.update('cust_...', { displayName: 'Bob' });
// Delete
await crypax.customers.delete('cust_...');Refunds
Initiate and track refunds for confirmed payments.
// Create a refund (full or partial)
const refund = await crypax.refunds.create({
paymentId: 'pay_...',
amount: '5.00', // optional — omit for full refund
reason: 'Customer request',
});
// Retrieve
const refund = await crypax.refunds.retrieve('refund_...');
// List
const { data } = await crypax.refunds.list({ paymentId: 'pay_...', page: 1, limit: 20 });Projects
Read and update your project configuration.
// Retrieve project settings
const project = await crypax.projects.retrieve();
// Update settings
await crypax.projects.update({
name: 'My Store',
brandingConfig: { primaryColor: '#8B5CF6' },
allowedOrigins: ['https:2
callbackUrl: 'https://my-store.com/api/crypax/callback',
});sdkNode.chainResource.title
sdkNode.chainResource.desc
// List supported chains
const chains = await crypax.chains.list();
// Get tokens for a specific chain
const tokens = await crypax.chains.getTokens(41956);
tokens.forEach(token => {
console.log(token.symbol, token.address, token.decimals);
});Webhooks
webhooks.constructEvent(rawBody, signature, secret)
Parse and verify an incoming webhook request. Pass the raw request body (Buffer or string), the X-Crypax-Signature header, and your webhook secret. Throws if the signature is invalid.
import { Crypax } from '@crypax/node';
import express from 'express';
const app = express();
const crypax = new Crypax('sk_live_...');
app.post('/webhooks/crypax', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-crypax-signature'] as string;
try {
const event = crypax.webhooks.constructEvent(
req.body,
signature,
'whsec_...',
);
switch (event.type) {
case 'payment.confirmed':
console.log('Confirmed:', event.data.id, event.data.txHash);
break;
case 'payment.expired':
console.log('Expired:', event.data.id);
break;
case 'payment.failed':
console.log('Failed:', event.data.id);
break;
case 'refund.completed':
console.log('Refund completed:', event.data.id);
break;
}
res.json({ received: true });
} catch (err) {
res.status(400).json({ error: 'Invalid signature' });
}
});webhooks.verifySignature(rawBody, signature, secret)
Verify the HMAC-SHA256 signature without parsing the event. Returns true if valid.
const isValid = crypax.webhooks.verifySignature(
rawBody, // Buffer or string
signature, // x-crypax-signature header value
webhookSecret // whsec_... from dashboard
);
if (!isValid) {
throw new Error('Invalid webhook signature');
}Verification
verification.verifyPayment(txHash, params)
Verify a native PLM payment on-chain by transaction hash.
const result = await crypax.verification.verifyPayment('0xabcdef...', {
to: '0xRecipientAddress',
amount: '10.00',
decimals: 18, // optional, defaults to 18
});
console.log(result.status); // 'confirmed'
console.log(result.txHash); // '0x...'
console.log(result.blockNumber); // 12345678verification.verifyERC20Payment(txHash, params)
Verify an ERC20 token payment on-chain by transaction hash.
const result = await crypax.verification.verifyERC20Payment('0xabcdef...', {
tokenAddress: '0xTokenContract',
to: '0xRecipientAddress',
amount: '100.00',
decimals: 6, // optional, e.g. USDC uses 6
});
console.log(result.tokenAddress); // ERC20 contract address
console.log(result.amount); // Transferred amountUtilities
Named utility exports from @crypax/node.
import {
isValidAddress,
addressEquals,
parseAmount,
formatAmount,
} from '@crypax/node';
isValidAddress('0x...'); // boolean
addressEquals('0xABC...', '0xabc...'); // true (case-insensitive)
parseAmount('10.00', 18); // BigInt wei value
formatAmount(1000000000000000000n, 18); // '1.0'Types
// Payment object
interface Payment {
id: string;
clientSecret: string;
amount: string;
chainId: number;
currency: string;
recipientAddress?: string;
senderAddress?: string;
description?: string;
metadata?: Record<string, unknown>;
qrMode?: boolean;
status: 'created' | 'processing' | 'confirmed' | 'expired' | 'failed' | 'refunded';
txHash?: string;
blockNumber?: number;
expiresAt: string;
confirmedAt?: string;
createdAt: string;
}
// Webhook event
interface WebhookEvent {
id: string;
type:
| 'payment.created' | 'payment.processing' | 'payment.confirmed'
| 'payment.failed' | 'payment.expired' | 'payment.refunded'
| 'refund.created' | 'refund.completed' | 'refund.failed'
| 'settlement.requested' | 'settlement.approved'
| 'settlement.completed' | 'settlement.failed'
| 'customer.created' | 'customer.updated';
data: Payment;
createdAt: string;
}