CrypaxDocs

@crypax/node

Node.js 서버 사이드 SDK. 결제 생성, 웹훅 검증, 온체인 확인.


설치

$ npm install @crypax/node

설정

비밀 키로 클라이언트를 초기화합니다. 비밀 키는 절대 클라이언트 코드에 노출하지 마세요.

crypax.ts
import { Crypax } from '@crypax/node';

const crypax = new Crypax('sk_live_your_secret_key', {
  apiUrl: 'https://api.crypax.io',  // optional, defaults to production
});

체인 상수

SDK에서 사전 정의된 체인 상수를 제공하므로 체인 ID를 외울 필요가 없습니다. 결제 생성 시 이 상수를 사용하세요.

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]

지원 체인

상수이름체인 ID심볼테스트넷
PLUMISE_MAINNETPlumise Mainnet41956PLMNo
PLUMISE_TESTNETPlumise Testnet419561PLMYes

결제 (Payments)

payments.create(params)

새 결제를 생성합니다. 프론트엔드로 전달할 clientSecret이 포함된 Payment 객체를 반환합니다.

import { PLUMISE_MAINNET } from '@crypax/node';

const payment = await crypax.payments.create({
  amount: '1.0',                                  // Amount as string
  recipientAddress: '0xYourAddress',              // Recipient wallet
  chainId: PLUMISE_MAINNET.chainId,               // 41956
  currency: 'native',                             // 'native' | token address
  orderId: 'order_123',                           // Your internal order ID
  description: 'Premium Plan',                   // Human-readable description
  metadata: { userId: 'user_456' },               // Arbitrary key-value pairs
  expiresInMinutes: 30,                           // Expiry (default: 60)
});

console.log(payment.id);           // Payment UUID
console.log(payment.clientSecret); // 'cs_live_...' — send to frontend
CreatePaymentParams
파라미터타입필수설명
amountstring필수소수점 문자열로 표현한 결제 금액 (예: '1.0')
recipientAddressstring필수결제를 받을 지갑 주소
chainIdnumber필수체인 상수 사용: PLUMISE_MAINNET.chainId (41956), PLUMISE_TESTNET.chainId (419561)
currencystring선택PLM은 'native', ERC20은 토큰 컨트랙트 주소
orderIdstring선택내부 주문 식별자
descriptionstring선택사람이 읽을 수 있는 설명
metadataRecord<string, unknown>선택결제에 첨부할 임의 키-값 데이터
expiresInMinutesnumber선택결제 만료까지의 분 수 (기본값: 60)

payments.retrieve(id)

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?)

상태, 날짜 범위, 페이지네이션 필터로 결제 목록을 조회합니다.

const { data, total } = await crypax.payments.list({
  limit: 20,
  offset: 0,
  status: 'confirmed',  // optional filter
});

data.forEach(payment => {
  console.log(payment.id, payment.amount, payment.status);
});

웹훅

webhooks.constructEvent(payload, signature, secret)

들어오는 웹훅 요청을 파싱하고 검증합니다. 원시 요청 바디(Buffer), 시그니처 헤더, 웹훅 시크릿을 전달하세요. 시그니처가 유효하지 않으면 예외를 던집니다.

webhook.ts
import { Crypax } from '@crypax/node';
import express from 'express';

const app = express();
const crypax = new Crypax('sk_live_your_secret_key');

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_your_webhook_secret'
    );

    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;
    }

    res.json({ received: true });
  } catch (err) {
    res.status(400).json({ error: 'Invalid signature' });
  }
});

webhooks.verifySignature(payload, signature, secret)

이벤트 파싱 없이 HMAC-SHA256 시그니처를 검증합니다. 유효하면 true를 반환합니다.

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(paymentId)

온체인에서 네이티브 PLM 결제를 검증합니다. txHash와 blockNumber가 포함된 결제 결과를 반환합니다.

const result = await crypax.verification.verifyPayment('payment-uuid');
console.log(result.status);      // 'confirmed'
console.log(result.txHash);      // '0x...'
console.log(result.blockNumber); // 12345678

verification.verifyERC20Payment(paymentId)

온체인에서 ERC20 토큰 결제를 검증합니다. 토큰 주소와 전송된 금액을 반환합니다.

const result = await crypax.verification.verifyERC20Payment('payment-uuid');
console.log(result.tokenAddress); // ERC20 contract address
console.log(result.amount);       // Transferred amount

타입 정의

// Payment object
interface Payment {
  id: string;
  clientSecret: string;
  amount: string;
  recipientAddress: string;
  senderAddress?: string;
  chainId: number;
  currency: string;
  orderId?: string;
  description?: string;
  metadata?: Record<string, unknown>;
  status: 'created' | 'processing' | 'confirmed' | 'expired' | 'failed';
  txHash?: string;
  blockNumber?: number;
  expiresAt: string;
  confirmedAt?: string;
  createdAt: string;
}

// Webhook event
interface WebhookEvent {
  id: string;
  type: 'payment.created' | 'payment.confirmed' | 'payment.expired' | 'payment.failed';
  data: Payment;
  createdAt: string;
}
Node.js SDK | Crypax