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

crystalpayio-sdk

v1.0.1

Published

TypeScript SDK for CrystalPay.io payment system — invoices, payoffs, swaps, transfers, and more

Readme

crystalpayio-sdk

Типизированный TypeScript/Node.js SDK для CrystalPay.io — платёжной системы с поддержкой криптовалют и карт.

Покрывает весь API v3: инвойсы, выводы, обмены, переводы, балансы, методы, курсы валют, историю и callback.


Установка

npm install crystalpayio-sdk
# или
bun add crystalpayio-sdk
# или
yarn add crystalpayio-sdk
# или
pnpm add crystalpayio-sdk

Быстрый старт

import { CrystalPayClient } from 'crystalpayio-sdk';

const client = new CrystalPayClient({
  login: 'your_login',
  secret: 'your_secret',
  salt: 'your_salt',
});

// Создать инвойс
const invoice = await client.invoice.create({
  amount: 500,
  type: 'purchase',
  lifetime: 30,
  description: 'Оплата заказа #42',
});

console.log(invoice.url); // ссылка на страницу оплаты

Конфигурация

| Параметр | Тип | Обязателен | Описание | |---|---|---|---| | login | string | Да | Логин кассы (auth_login) | | secret | string | Да | Секретный ключ (auth_secret) | | salt | string | Да | Соль для генерации подписей операций | | baseUrl | string | Нет | Базовый URL API. По умолчанию https://api.crystalpay.io/v3/ |

Где взять ключи: зарегистрируйтесь в @CrystalPAY_bot и создайте кассу.


Модули

client.me — Информация о кассе

const info = await client.me.info();
// { id, name, status_level, created_at }

client.balance — Балансы

// Все методы (hideEmpty — скрыть нулевые)
const { items } = await client.balance.list(true);

// Один метод
const btc = await client.balance.get('BITCOIN');
console.log(btc.amount, btc.currency); // "0.0012" "BTC"

client.method — Методы оплаты

// Полный список с комиссиями и лимитами
const { items } = await client.method.list();

// Компактный список
const { items: compact } = await client.method.list({ compact: true });

// Один метод
const method = await client.method.get('USDTTRC');
console.log(method.out.limits.min, method.out.limits.max);

// Изменить настройки (включение / доп. комиссия)
await client.method.edit({
  method: 'USDTTRC',
  enabled: true,
  extra_commission_percent: 2,
});

client.invoice — Инвойсы (входящие платежи)

Создание

// Фиксированный платёж (покупатель платит точную сумму)
const invoice = await client.invoice.create({
  amount: 500,
  type: 'purchase',
  lifetime: 30,              // минут
  currency: 'RUB',          // по умолчанию RUB
  subtract_from: 'amount',  // 'amount' | 'balance'
  required_method: 'USDTTRC', // предустановить метод (опционально)
  description: 'Заказ #42',
  extra: 'order_42',        // вернётся в callback
  redirect_url: 'https://yourshop.com/success',
  callback_url: 'https://yourshop.com/webhooks/crystalpay',
});

console.log(invoice.id);
console.log(invoice.url);

// Пополнение баланса (покупатель может заплатить любую сумму, инвойс пересчитается)
// amount задаёт начальную сумму — должна быть > 0
const topup = await client.invoice.create({
  amount: 100,
  type: 'topup',
  lifetime: 60,
  callback_url: 'https://yourshop.com/webhooks/crystalpay',
});

Проверка статуса

const info = await client.invoice.info('123456789_abcdefghij');

console.log(info.state);           // 'created' | 'notpayed' | 'payed' | ...
console.log(info.balance_amount);  // сколько будет зачислено на баланс
console.log(info.remaining_amount); // сколько ещё нужно оплатить

Возможные статусы: created, notpayed, processing, wrongamount, failed, payed✓, unavailable


client.payoff — Выводы средств

Подписи SHA1 вычисляются автоматически из salt.

// 1. Создать заявку
const payoff = await client.payoff.create({
  method: 'USDTTRC',
  wallet: 'TYourWalletAddress',
  amount: 50,
  subtract_from: 'balance', // комиссия поверх суммы
  callback_url: 'https://yoursite.com/webhooks/crystalpay',
  extra: 'withdrawal_99',
});

console.log(payoff.id);
console.log(payoff.receive_amount);   // получит адресат
console.log(payoff.deduction_amount); // спишется с баланса

// 2. Подтвердить
const result = await client.payoff.submit(payoff.id);
console.log(result.state); // 'processing'

// 3. Статус
const info = await client.payoff.info(payoff.id);
console.log(info.state);   // 'payed' | 'failed' | 'canceled'
console.log(info.message); // TX-хэш при успехе

// Отменить (если ещё не обработан)
await client.payoff.cancel(payoff.id);

Возможные статусы: created, processing, failed✓, payed✓, canceled


client.swap — Обмен между счетами

Подписи SHA1 вычисляются автоматически из salt.

// Список пар обмена
const { items } = await client.swap.pairList({
  page: 1,
  items: 20,
  source: 'CARDRUBP2P', // фильтр (опционально)
  target: 'USDTTRC',
});

// Конкретная пара
const pair = await client.swap.pairGet(1);
console.log(pair.price); // курс

// Создать заявку
const swap = await client.swap.create({
  pair_id: 1,
  amount: 1000,
  amount_type: 'source', // 'source' — сколько отдаём, 'target' — сколько получаем
});

console.log(swap.source.amount, swap.source.currency); // отдаём
console.log(swap.target.amount, swap.target.currency); // получаем

// Подтвердить
const result = await client.swap.submit(swap.id);

// Отменить / статус
await client.swap.cancel(swap.id);
const info = await client.swap.info(swap.id);

Возможные статусы: created, processing, failed✓, success✓, canceled


client.transfer — Переводы между кассами

Подписи SHA1 вычисляются автоматически из salt.

// Создать перевод
const transfer = await client.transfer.create({
  method: 'USDTTRC',
  amount: 25,
  receiver: 'partner_login',
  description: 'Партнёрская выплата',
});

// Подтвердить
await client.transfer.submit(transfer.id);

// Статус / отмена
const info = await client.transfer.info(transfer.id);
await client.transfer.cancel(transfer.id);

client.ticker — Курсы валют

// Список поддерживаемых тикеров
const { tickers } = await client.ticker.list();
// ['BTC', 'ETH', 'USDT', 'TON', 'RUB', ...]

// Курсы к базовой валюте (по умолчанию RUB)
const rates = await client.ticker.get({
  tickers: ['BTC', 'ETH', 'USDT', 'TON'],
  base_currency: 'RUB',
});

for (const [ticker, { price }] of Object.entries(rates.currencies)) {
  console.log(`1 ${ticker} = ${price.toLocaleString()} RUB`);
}

client.report — История и статистика

// История инвойсов за 7 дней
const { items, has_next_page } = await client.report.invoiceHistory({
  page: 1,
  items: 50,
  period: 7,
});

// Статистика за 30 дней
const summary = await client.report.invoiceSummary({ period: 30 });
console.log(summary.payed_count, summary.conversion_percent + '%');

// Аналогично для выводов, обменов и переводов:
await client.report.payoffHistory({ page: 1, items: 20, period: 30 });
await client.report.payoffSummary({ period: 30 });
await client.report.swapHistory({ page: 1, items: 20, period: 30 });
await client.report.transferHistory({ page: 1, items: 20, period: 30 });

client.callback — Callback-уведомления

// Список попыток доставки callback для инвойса
const { items } = await client.callback.invoiceList('123456789_abcdefghij');
for (const cb of items) {
  console.log(cb.state, cb.attempts, cb.last_response);
}

// Принудительно переотправить
await client.callback.invoiceResend('123456789_abcdefghij');

// То же для выводов
await client.callback.payoffList('123456789_dpWminAiaqwTcBOJVlFk');
await client.callback.payoffResend('123456789_dpWminAiaqwTcBOJVlFk');

Обработка ошибок

import { CrystalPayClient, CrystalPayError, CrystalPayNetworkError } from 'crystalpayio-sdk';

try {
  await client.invoice.create({ ... });
} catch (err) {
  if (err instanceof CrystalPayError) {
    // Ошибка от API (неверные параметры, недостаточно прав и т.д.)
    console.error(err.errors); // string[]
  } else if (err instanceof CrystalPayNetworkError) {
    // Сетевая ошибка (нет соединения, таймаут)
    console.error(err.message, err.cause);
  } else {
    throw err;
  }
}

Верификация callback-уведомлений

CrystalPay отправляет POST-запрос на callback_url после завершения операции. Проверяйте подпись перед обработкой:

import { verifyCallbackSignature } from 'crystalpayio-sdk';
import type { InvoiceCallbackPayload } from 'crystalpayio-sdk';

// В вашем HTTP-обработчике (Express, Fastify, Hono и т.д.)
app.post('/webhooks/crystalpay', (req, res) => {
  const body = req.body as InvoiceCallbackPayload;

  // Проверяем SHA1({id}:{salt})
  if (!verifyCallbackSignature(body.id, 'your_salt', body.signature)) {
    return res.status(403).send('Invalid signature');
  }

  if (body.state === 'payed') {
    console.log('Оплачен инвойс:', body.id);
    console.log('extra (ваш ID заказа):', body.extra);
    console.log('Зачислено:', body.balance_amount, body.amount_currency);
    // ... начислить баланс, обновить заказ
  }

  res.status(200).send('OK');
});

IP-адреса CrystalPay для белого списка:

193.141.53.171  193.141.53.176
191.101.112.123 191.101.112.154
185.168.250.38  163.198.213.130

Подписи операций

SDK автоматически генерирует подписи при создании и подтверждении secure-операций. Соль (salt) задаётся один раз в конфиге клиента.

| Операция | Формат | |---|---| | Создание вывода | SHA1({amount}:{method}:{wallet}:{salt}) | | Подтверждение / отмена вывода | SHA1({id}:{salt}) | | Создание обмена | SHA1({amount}:{pair_id}:{salt}) | | Подтверждение / отмена обмена | SHA1({id}:{salt}) | | Создание перевода | SHA1({amount}:{method}:{receiver}:{salt}) | | Подтверждение / отмена перевода | SHA1({id}:{salt}) |

Если нужна ручная генерация:

import { sha1, signPayoffCreate, signById } from 'crystalpayio-sdk';

const sig = signPayoffCreate(50, 'USDTTRC', 'TYourWallet', 'your_salt');
const submitSig = signById('123456789_dpWminAiaqwTcBOJVlFk', 'your_salt');

Лимиты API

| Лимит | Значение | |---|---| | Запросов в секунду | 5 | | Запросов за 10 секунд | 50 |

При превышении API возвращает 429 Too Many Requests.