Widget SDK

CRYPTOMENTS Widget SDK는 파트너 웹사이트에 암호화폐 결제 UI를 쉽게 통합할 수 있는 JavaScript 라이브러리입니다. 입금, 출금, Axim Pay, 결제 링크 등 모든 기능을 iframe 또는 팝업으로 제공합니다.

문서 버전: 2.0 최종 수정: 2026년 3월 30일 CDN: https://widget.cryptoments.cc/src/v2/widget.cryptoments.sdk.js

1 개요

CryptoPaymentsWidget은 파트너 웹사이트에 암호화폐 결제 UI를 쉽게 통합할 수 있는 JavaScript SDK입니다.

💰 입금

USDT, USDC를 여러 블록체인에서 입금 받기

📤 출금

사용자 지갑으로 직접 출금하기

💳 Axim Pay

Axim 지갑으로 신속하게 결제

🔗 결제 링크

동적 결제 링크 생성 및 추적

⏰ 입금 예약

정기적인 입금 일정 관리

🌐 멀티체인

Ethereum, BSC, Polygon, TRON 지원

ℹ️
SDK 정보
CDN URL: https://widget.cryptoments.cc/src/v2/widget.cryptoments.sdk.js
지원 브라우저: Chrome, Safari, Firefox, Edge (최신 2 버전)

표시 모드

위젯은 두 가지 모드로 표시할 수 있습니다:

  • Modal: 현재 페이지 위에 오버레이 모달로 표시 (권장)
  • Window: 새 탭 또는 팝업 창에서 열기

2 빠른 시작

3단계로 위젯을 통합할 수 있습니다.

Step 1: SDK 로드

<script src="https://widget.cryptoments.cc/src/v2/widget.cryptoments.sdk.js"></script>

Step 2: 초기화

JavaScript
const widget = new CryptoPaymentsWidget({
  apiKey: 'YOUR_API_KEY',
  partnerId: 'YOUR_PARTNER_ID',
  userId: 'user_001',
  mode: 'modal',
  theme: 'light',
  language: 'ko',
  onReady: () => console.log('Widget ready'),
  onError: (error) => console.error('Widget error:', error)
});

Step 3: 위젯 열기

JavaScript
// 입금 화면 열기
widget.open('deposit');

// 또는 버튼에 이벤트 핸들러 추가
document.getElementById('deposit-btn').addEventListener('click', () => {
  widget.open('deposit');
});
완료! 이제 사용자가 위젯을 통해 암호화폐를 입금할 수 있습니다.

3 설치 & 인증

클라이언트 측과 서버 측 설정 방법입니다.

클라이언트 측 (Client-Side)

SDK는 글로벌 window.CryptoPaymentsWidget 객체를 제공합니다. 추가 설치 단계는 필요하지 않습니다.

서버 측 (Server-Side) — 위젯 토큰 생성

보안을 위해 서버에서 위젯 인증 토큰을 생성하고 클라이언트에 전달해야 합니다.

Node.js 예제

JavaScript
const crypto = require('crypto');

const SECRET_KEY = 'your_partner_secret_key';
const API_KEY = 'your_api_key';

// 위젯 토큰 생성 엔드포인트
app.post('/api/widget-token', (req, res) => {
  const timestamp = Date.now().toString();
  const partnerId = req.body.partnerId;
  const partnerUserId = req.body.partnerUserId;
  const permissions = req.body.permissions || ['deposit'];

  const body = JSON.stringify({
    partnerId,
    partnerUserId,
    permissions,
    timestamp
  });

  const signature = crypto.createHmac('sha256', SECRET_KEY)
    .update(timestamp + 'POST' + '/widgets/auth/token' + body)
    .digest('hex');

  // 실제로는 CRYPTOMENTS API 호출
  const token = Buffer.from(body).toString('base64') + '.' + signature;

  res.json({ token, expiresIn: 3600 });
});

Java/Spring 예제

Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

@RestController
@RequestMapping("/api")
public class WidgetController {

    @PostMapping("/widget-token")
    public ResponseEntity<?> generateWidgetToken(@RequestBody WidgetTokenRequest req) {
        String secretKey = "your_partner_secret_key";
        String timestamp = String.valueOf(System.currentTimeMillis());

        String body = "{\"partnerId\":\"" + req.getPartnerId() +
                     "\",\"partnerUserId\":\"" + req.getPartnerUserId() +
                     "\",\"permissions\":" + req.getPermissions() + "}";

        String message = timestamp + "POST" + "/widgets/auth/token" + body;
        String signature = hmacSha256(message, secretKey);

        String token = Base64.getEncoder().encodeToString(body.getBytes())
                      + "." + signature;

        return ResponseEntity.ok(Map.of(
            "token", token,
            "expiresIn", 3600
        ));
    }

    private String hmacSha256(String message, String secret) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
            return Base64.getEncoder().encodeToString(mac.doFinal(message.getBytes()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

클라이언트에서 토큰 사용

JavaScript
// 서버에서 토큰 받기
const response = await fetch('/api/widget-token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    partnerId: 'partner_123',
    partnerUserId: 'user_001',
    permissions: ['deposit', 'withdrawal']
  })
});

const { token } = await response.json();

// 위젯 초기화 (토큰 포함)
const widget = new CryptoPaymentsWidget({
  apiKey: 'pk_live_xxx',
  token: token,
  userId: 'user_001',
  mode: 'modal'
});

4 구성 옵션

위젯 생성자에 전달할 수 있는 모든 옵션입니다.

옵션 타입 필수 기본값 설명
apiKey string - 파트너 API 키
partnerId string - 파트너 ID
userId string - 파트너의 사용자 ID
token string - - 위젯 인증 토큰
mode string - 'modal' 'modal' 또는 'window'
theme string - 'light' 'light' 또는 'dark'
language string - 'ko' 'ko', 'en', 'ja'
width number - 480 위젯 너비 (픽셀)
height number - 680 위젯 높이 (픽셀)
chains string[] - 모두 허용된 체인: ['BSC', 'POLYGON', 'ETHEREUM', 'TRON']
currencies string[] - 모두 허용된 토큰: ['USDT', 'USDC']
defaultChain string - - 기본 선택 체인
defaultCurrency string - - 기본 선택 토큰
aximPayEnabled boolean - false Axim Pay 기능 활성화
onReady function - - 초기화 완료 콜백
onError function - - 오류 발생 콜백

구성 예제

JavaScript
const widget = new CryptoPaymentsWidget({
  apiKey: 'pk_live_abc123',
  partnerId: 'partner_123',
  userId: 'user_001',
  token: 'eyJhbGc...',
  mode: 'modal',
  theme: 'dark',
  language: 'en',
  width: 500,
  height: 700,
  chains: ['BSC', 'POLYGON'],
  currencies: ['USDT'],
  defaultChain: 'BSC',
  defaultCurrency: 'USDT',
  aximPayEnabled: true,
  onReady: () => {
    console.log('Widget initialized successfully');
  },
  onError: (error) => {
    console.error('Widget error:', error.code, error.message);
  }
});

5 메서드

위젯 인스턴스에서 호출할 수 있는 메서드들입니다.

메서드 파라미터 반환값 설명
open(view?) string Promise<void> 위젯 열기. view: 'deposit', 'withdrawal', 'axim-pay', 'payment-link'
close() - void 위젯 닫기
destroy() - void 위젯 인스턴스 완전히 제거
getStatus() - string 현재 상태 ('ready', 'loading', 'open', 'closed', 'error')
setUser(userId) string void 사용자 ID 변경
setTheme(theme) string void 테마 변경 ('light' | 'dark')
setLanguage(lang) string void 언어 변경 ('ko' | 'en' | 'ja')
on(event, callback) string, function void 이벤트 리스너 등록
off(event, callback) string, function void 이벤트 리스너 해제

메서드 사용 예제

JavaScript
// 위젯 열기
widget.open('deposit').then(() => {
  console.log('Widget opened');
});

// 위젯 상태 확인
if (widget.getStatus() === 'ready') {
  widget.open('withdrawal');
}

// 사용자 변경
widget.setUser('user_002');

// 테마 변경
widget.setTheme('dark');

// 언어 변경
widget.setLanguage('en');

// 위젯 닫기
widget.close();

// 위젯 제거
widget.destroy();

6 이벤트

위젯에서 발생하는 이벤트들을 구독하고 처리할 수 있습니다.

이벤트 설명 데이터
ready 위젯 초기화 완료 -
open 위젯 열림 { view: string }
close 위젯 닫힘 { reason: 'user' | 'success' | 'error' }
error 오류 발생 { code: string, message: string }
deposit.created 입금 세션 생성 { sessionId, address, chain, currency }
deposit.pending 입금 감지 (미확정) { depositId, amount, txHash, chain }
deposit.confirmed 입금 확정 { depositId, amount, txHash, blockNumber, chain }
withdrawal.requested 출금 요청됨 { withdrawalId, amount, toAddress }
withdrawal.confirmed 출금 완료 { withdrawalId, txHash, confirmations }
withdrawal.failed 출금 실패 { withdrawalId, reason: string }
axim.connected Axim 지갑 연결 { aximUserId, walletAddress }
axim.payment.created Axim 결제 생성 { paymentId, amount, currency }
axim.payment.completed Axim 결제 완료 { paymentId, txHash }
payment-link.activated 결제 링크 활성화 { linkId, amount, currency }
payment-link.completed 결제 링크 완료 { linkId, depositId, txHash }

이벤트 처리 예제

JavaScript
// 입금 확정 이벤트
widget.on('deposit.confirmed', (data) => {
  console.log(`입금 확정: ${data.amount} ${data.currency}`);
  console.log(`TX Hash: ${data.txHash}`);

  // 서버에 입금 확인 알림
  fetch('/api/deposit-callback', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });
});

// 출금 실패 이벤트
widget.on('withdrawal.failed', (data) => {
  alert(`출금 실패: ${data.reason}`);
});

// 에러 이벤트
widget.on('error', (error) => {
  console.error(`[${error.code}] ${error.message}`);
  if (error.code === 'INVALID_TOKEN') {
    // 토큰 갱신 로직
    refreshWidgetToken();
  }
});

// 위젯 닫기 이벤트
widget.on('close', (data) => {
  if (data.reason === 'success') {
    console.log('거래가 성공적으로 완료되었습니다');
  }
});

7 화면별 가이드

각 화면의 기능과 주요 이벤트입니다.

입금 (Deposit)

사용자가 암호화폐를 입금할 수 있는 화면입니다.

widget.open('deposit');

주요 이벤트:

  • deposit.created: 입금 주소 생성
  • deposit.pending: TX 감지됨
  • deposit.confirmed: 입금 확정 (사용 가능)

출금 (Withdrawal)

사용자가 지갑으로 출금할 수 있는 화면입니다.

widget.open('withdrawal');

주요 이벤트:

  • withdrawal.requested: 출금 신청
  • withdrawal.confirmed: 출금 완료
  • withdrawal.failed: 출금 실패

Axim Pay

Axim 지갑을 통한 신속한 결제 화면입니다.

widget.open('axim-pay');

주요 이벤트:

  • axim.connected: 지갑 연결
  • axim.payment.created: 결제 생성
  • axim.payment.completed: 결제 완료

결제 링크 (Payment Link)

동적으로 생성된 결제 링크를 사용하여 결제하는 화면입니다.

widget.open('payment-link');

주요 이벤트:

  • payment-link.activated: 링크 활성화
  • payment-link.completed: 결제 완료

8 테마 & 커스터마이징

위젯의 외관을 커스터마이징할 수 있습니다.

기본 테마

위젯은 Light와 Dark 두 가지 테마를 제공합니다:

JavaScript
// Light 테마 (기본)
const widget = new CryptoPaymentsWidget({
  ...config,
  theme: 'light'
});

// Dark 테마
const widget = new CryptoPaymentsWidget({
  ...config,
  theme: 'dark'
});

// 런타임에 테마 변경
widget.setTheme('dark');

CSS 커스터마이징

위젯의 스타일을 CSS 변수로 커스터마이징할 수 있습니다:

CSS
:root {
  /* 컬러 스킴 */
  --cryptoments-primary: #2563eb;
  --cryptoments-primary-dark: #1d4ed8;
  --cryptoments-accent: #0ea5e9;
  --cryptoments-success: #10b981;
  --cryptoments-danger: #ef4444;

  /* 타이포그래피 */
  --cryptoments-font-family: 'Inter', sans-serif;
  --cryptoments-font-size-base: 14px;

  /* 디자인 */
  --cryptoments-border-radius: 12px;
  --cryptoments-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

커스텀 컨테이너

특정 DOM 엘리먼트를 위젯 컨테이너로 지정할 수 있습니다:

JavaScript
// HTML
<div id="widget-container"></div>

// JavaScript
const widget = new CryptoPaymentsWidget({
  ...config,
  container: '#widget-container', // 또는 DOM 엘리먼트
  mode: 'embedded' // 임베드 모드
});

9 에러 처리

위젯에서 발생할 수 있는 에러와 해결 방법입니다.

에러 코드

코드 설명 해결 방법
INVALID_API_KEY API 키가 유효하지 않음 API 키를 확인하세요
INVALID_TOKEN 토큰이 만료되었거나 유효하지 않음 새로운 토큰을 생성하세요
NETWORK_ERROR 네트워크 연결 실패 인터넷 연결을 확인하고 재시도하세요
TIMEOUT 요청 시간 초과 서버 상태를 확인하고 재시도하세요
BROWSER_NOT_SUPPORTED 브라우저가 지원되지 않음 최신 브라우저로 업데이트하세요
INSUFFICIENT_BALANCE 잔액 부족 충전 후 재시도하세요
DAILY_LIMIT_EXCEEDED 일일 한도 초과 내일 다시 시도하세요

에러 처리 패턴

JavaScript
const widget = new CryptoPaymentsWidget({
  ...config,
  onError: (error) => {
    switch (error.code) {
      case 'INVALID_TOKEN':
        // 토큰 갱신
        refreshWidgetToken().then(token => {
          widget.setToken(token);
          widget.open('deposit');
        });
        break;

      case 'NETWORK_ERROR':
        // 재시도 로직
        setTimeout(() => widget.open('deposit'), 3000);
        break;

      case 'INSUFFICIENT_BALANCE':
        // 사용자에게 알림
        alert('잔액이 부족합니다. 충전해주세요.');
        break;

      default:
        console.error(`${error.code}: ${error.message}`);
    }
  }
});

// 이벤트 기반 에러 처리
widget.on('error', (error) => {
  console.error('Widget error:', error);
  // UI에 에러 메시지 표시
  showErrorNotification(error.message);
});

네트워크 타임아웃 처리

JavaScript
const widget = new CryptoPaymentsWidget({
  ...config,
  timeout: 30000, // 30초
  retryCount: 3,
  retryDelay: 2000 // 2초
});

// 커스텀 재시도 로직
widget.on('error', async (error) => {
  if (error.code === 'TIMEOUT') {
    console.log('요청이 시간 초과되었습니다. 재시도합니다...');

    // 지수 백오프로 재시도
    for (let i = 0; i < 3; i++) {
      const delay = Math.pow(2, i) * 1000;
      await new Promise(r => setTimeout(r, delay));

      try {
        await widget.open('deposit');
        return; // 성공
      } catch (e) {
        console.log(`재시도 ${i + 1} 실패`);
      }
    }
  }
});

10 FAQ & 트러블슈팅

자주 묻는 질문과 문제 해결 가이드입니다.

위젯이 로드되지 않습니다

  1. SDK URL이 올바른지 확인하세요: https://widget.cryptoments.cc/src/v2/widget.cryptoments.sdk.js
  2. 브라우저 콘솔에서 에러 메시지를 확인하세요 (F12 키)
  3. API 키와 Partner ID가 올바른지 확인하세요
  4. CORS 설정을 확인하세요 (도메인이 화이트리스트에 있어야 함)
  5. CDN이 막혀있지 않은지 확인하세요 (방화벽/프록시)

이벤트가 발생하지 않습니다

  1. 위젯이 완전히 로드되었는지 확인하세요 (onReady 콜백)
  2. 이벤트 리스너를 올바르게 등록했는지 확인하세요
  3. 이벤트 이름의 대소문자를 확인하세요 (케이스 센서티브)
  4. 여러 개의 리스너를 등록할 경우 모두 작동하는지 확인하세요
  5. 콘솔을 열고 이벤트가 발생하는지 로깅해보세요

토큰이 만료되었습니다

토큰은 1시간 동안 유효합니다. 만료되면:

  1. 서버에서 새로운 토큰을 생성하세요
  2. 클라이언트에서 새 토큰으로 위젯을 재초기화하세요
JavaScript
// 토큰 갱신
const newToken = await fetch('/api/widget-token').then(r => r.json());

// 위젯 재초기화
widget.destroy();
const newWidget = new CryptoPaymentsWidget({
  ...config,
  token: newToken.token
});

CORS 에러가 발생합니다

CORS 에러는 도메인이 화이트리스트에 없을 때 발생합니다:

  1. 파트너 관리 콘솔에 로그인하세요
  2. Settings → Allowed Domains로 이동하세요
  3. 위젯을 사용할 도메인을 추가하세요 (예: https://example.com)
  4. 변경 사항이 적용될 때까지 5분 정도 기다리세요

입금이 감지되지 않습니다

  1. 입금 주소로 올바르게 송금했는지 확인하세요
  2. 올바른 네트워크(체인)에서 송금했는지 확인하세요
  3. 최소 입금액 이상인지 확인하세요
  4. 블록체인 확인을 기다리세요 (보통 1-5분)
  5. 파트너 대시보드에서 입금 기록을 확인하세요
  6. 웹훅이 제대로 설정되어 있는지 확인하세요

모바일에서 작동하지 않습니다

  1. 모바일 브라우저가 지원되는 버전인지 확인하세요
  2. viewport 메타 태그가 있는지 확인하세요: <meta name="viewport" content="width=device-width, initial-scale=1.0">
  3. window 모드 대신 modal 모드를 사용하세요 (더 안정적)
  4. HTTPS를 사용하고 있는지 확인하세요 (HTTP는 지원 안 함)
  5. 팝업 차단이 설정되어 있지 않은지 확인하세요
⚠️
추가 지원
더 이상의 도움이 필요하신가요? support@cryptoments.cc으로 연락하세요.