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

@transaksikita/node

v1.0.1

Published

Official Node.js SDK for TransaksiKita Payment Gateway — Create QRIS payments, check status, cancel, and list transactions with zero dependencies.

Readme


Features

  • Zero Dependencies — Hanya menggunakan built-in Node.js http/https
  • TypeScript Support — Full type definitions included
  • Auto Retry — Exponential backoff untuk network errors dan server errors
  • Error Handling — Custom error class dengan helper methods
  • Callback Verification — Verifikasi callback payload langsung dari SDK
  • Payment Polling — Built-in waitForPayment() untuk polling status
  • Idempotency — Cegah duplikasi pembayaran dengan idempotency key
  • Sandbox & Production — Mode otomatis dari prefix API key

Table of Contents

Installation

npm install @transaksikita/node
yarn add @transaksikita/node
pnpm add @transaksikita/node

Requirements: Node.js >= 14.0.0

Quick Start

const { TransaksiKita } = require('@transaksikita/node');

// 1. Inisialisasi SDK
const tk = new TransaksiKita({
  projectId: 'YOUR_PROJECT_ID',
  publicKey: 'tk_sandbox_xxxxxxxxxxxx',
  secretKey: 'sk_sandbox_xxxxxxxxxxxx',
});

// 2. Buat pembayaran
const payment = await tk.createPayment({
  amount: 50000,
  customerName: 'Budi Santoso',
  description: 'Pembelian Paket Premium',
  referenceId: 'ORDER-001',
  expiredMinutes: 60,
});

// 3. Redirect customer ke checkout
console.log(payment.checkoutFullUrl);
// → https://transaksikita.com/pay/PAY-xxxxx

// 4. Cek status pembayaran
const status = await tk.checkStatus(payment.paymentId);
console.log(status.status); // 'pending' | 'paid' | 'expired' | 'cancelled'

Configuration

const tk = new TransaksiKita({
  // WAJIB
  projectId: 'PROJECT_ID',        // Project ID dari dashboard
  publicKey: 'tk_sandbox_xxx',    // Public Key dari dashboard
  secretKey: 'sk_sandbox_xxx',    // Secret Key dari dashboard

  // OPSIONAL
  baseUrl: 'https://transaksikita.com',  // Default base URL
  timeout: 30000,                          // Request timeout dalam ms (default: 30000)
  maxRetries: 2,                           // Auto-retry untuk network/server error (0-3)
});

| Param | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | projectId | string | ✅ | — | Project ID dari dashboard TransaksiKita | | publicKey | string | ✅ | — | Public Key (prefix tk_sandbox_ atau tk_production_) | | secretKey | string | ✅ | — | Secret Key (prefix sk_sandbox_ atau sk_production_) | | baseUrl | string | ❌ | https://transaksikita.com | Base URL API | | timeout | number | ❌ | 30000 | Request timeout dalam milliseconds | | maxRetries | number | ❌ | 0 | Jumlah retry (0-3), dengan exponential backoff |

Mode Otomatis: SDK otomatis mendeteksi mode (sandbox/production) dari prefix API key Anda. Tidak perlu konfigurasi manual.

API Reference

ping()

Test koneksi API dan verifikasi credentials.

const info = await tk.ping();

Returns: PingData

| Field | Type | Description | |-------|------|-------------| | projectId | string | Project ID | | projectName | string | Nama project | | mode | string | 'sandbox' atau 'production' | | timestamp | string | Waktu server (ISO 8601) |

Example:

const info = await tk.ping();
console.log(info.projectName); // "Toko Saya"
console.log(info.mode);        // "sandbox"

createPayment(params)

Buat pembayaran baru. Customer akan diarahkan ke halaman checkout TransaksiKita.

const payment = await tk.createPayment({
  amount: 100000,
  customerName: 'Budi Santoso',
  description: 'Order #12345',
  referenceId: 'ORD-12345',
  expiredMinutes: 60,
  paymentMethod: 'QRIS',
  idempotencyKey: 'ORD-12345',
  sandbox: false,
});

Parameters:

| Param | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | amount | number | ✅ | — | Nominal pembayaran dalam Rupiah (min. 500) | | customerName | string | ❌ | — | Nama customer | | description | string | ❌ | — | Deskripsi pembayaran | | referenceId | string | ❌ | — | ID referensi unik dari sistem Anda | | expiredMinutes | number | ❌ | 60 | Waktu expired: 5 - 1440 menit (24 jam) | | paymentMethod | string | ❌ | — | 'QRIS' atau kosong (customer pilih di checkout) | | idempotencyKey | string | ❌ | — | Mencegah duplikasi pembayaran | | sandbox | boolean | ❌ | false | Force sandbox mode |

Returns: PaymentData

| Field | Type | Description | |-------|------|-------------| | paymentId | string | ID pembayaran unik | | projectId | string | Project ID | | mode | string | 'sandbox' atau 'production' | | status | string | Status: 'pending' | | amount | number | Nominal asli | | feeAmount | number | Biaya QRIS | | totalAmount | number | Total yang harus dibayar (amount + fee + unique code) | | expiredMinutes | number | Waktu expired dalam menit | | referenceId | string\|null | ID referensi Anda | | createdAt | string | Waktu dibuat (ISO 8601) | | expiresAt | number | Timestamp expired (ms) | | checkoutUrl | string | Path checkout (relative) | | checkoutFullUrl | string | Full URL checkout — redirect customer ke sini | | qrisPayload | string\|null | QRIS payload untuk generate QR code sendiri |


checkStatus(paymentId)

Cek status pembayaran secara real-time.

const status = await tk.checkStatus('PAY-xxxxx');

Returns: PaymentStatusData

| Field | Type | Description | |-------|------|-------------| | paymentId | string | ID pembayaran | | status | string | 'pending' | 'paid' | 'expired' | 'cancelled' | | amount | number | Nominal asli | | feeAmount | number | Biaya QRIS | | totalAmount | number | Total amount | | paidAmount | number | Jumlah yang dibayar (jika sudah paid) | | paidAt | string\|null | Waktu pembayaran (ISO 8601) | | remainingMs | number | Sisa waktu dalam milliseconds | | customerName | string | Nama customer | | description | string | Deskripsi | | referenceId | string\|null | ID referensi Anda | | checkoutFullUrl | string | Full checkout URL | | qrisPayload | string\|null | QRIS payload (hanya jika pending) |

Example:

const status = await tk.checkStatus('PAY-xxxxx');

switch (status.status) {
  case 'paid':
    console.log('✅ Pembayaran berhasil!');
    console.log('Dibayar pada:', status.paidAt);
    console.log('Jumlah:', TransaksiKita.formatRupiah(status.paidAmount));
    break;
  case 'pending':
    console.log('⏳ Menunggu pembayaran...');
    console.log('Sisa waktu:', Math.floor(status.remainingMs / 60000), 'menit');
    break;
  case 'expired':
    console.log('⏰ Pembayaran expired');
    break;
  case 'cancelled':
    console.log('❌ Pembayaran dibatalkan');
    break;
}

cancelPayment(paymentId)

Batalkan pembayaran. Hanya bisa untuk status pending.

const result = await tk.cancelPayment('PAY-xxxxx');
console.log(result.status);      // 'cancelled'
console.log(result.cancelledAt); // '2026-04-24T12:00:00.000Z'

Returns: CancelPaymentData

| Field | Type | Description | |-------|------|-------------| | paymentId | string | ID pembayaran | | status | string | 'cancelled' | | cancelledAt | string | Waktu pembatalan (ISO 8601) | | amount | number | Nominal asli | | totalAmount | number | Total amount | | referenceId | string\|null | ID referensi |


listPayments(params?)

Daftar semua pembayaran dengan pagination dan filter.

const { data, pagination } = await tk.listPayments({
  page: 1,
  limit: 20,
  status: 'paid',
});

Parameters:

| Param | Type | Default | Description | |-------|------|---------|-------------| | page | number | 1 | Halaman | | limit | number | 20 | Jumlah per halaman (1-100) | | status | string | — | Filter: 'pending', 'paid', 'expired', 'cancelled' |

Returns: { data: PaymentListItem[], pagination: Pagination }

const { data, pagination } = await tk.listPayments({ limit: 5, status: 'paid' });

console.log(`Total: ${pagination.total} payments`);
console.log(`Halaman: ${pagination.page}/${pagination.totalPages}`);

data.forEach((p) => {
  console.log(`${p.paymentId} | ${TransaksiKita.formatRupiah(p.amount)} | ${p.status}`);
});

verifyCallback(payload)

Verifikasi callback payload dengan re-check ke API TransaksiKita. Selalu gunakan ini di callback endpoint!

const isValid = await tk.verifyCallback(req.body);

Returns: booleantrue jika payment ID, status, dan amount cocok.


waitForPayment(paymentId, intervalMs?, maxAttempts?)

Polling status sampai berubah dari pending. Berguna untuk CLI tools atau background jobs.

// Polling setiap 5 detik, max 60x (5 menit)
const result = await tk.waitForPayment('PAY-xxxxx', 5000, 60);

| Param | Type | Default | Description | |-------|------|---------|-------------| | paymentId | string | — | ID pembayaran | | intervalMs | number | 5000 | Interval polling dalam ms | | maxAttempts | number | 60 | Jumlah maksimum polling |


Static Helpers

// Format angka ke Rupiah
TransaksiKita.formatRupiah(50000);  // "Rp 50.000"
TransaksiKita.formatRupiah(1500000); // "Rp 1.500.000"

// Cek apakah payment masih bisa dibayar
const status = await tk.checkStatus('PAY-xxx');
TransaksiKita.isPaymentActive(status); // true/false

Error Handling

SDK menggunakan custom TransaksiKitaError class dengan helper methods:

const { TransaksiKita, TransaksiKitaError } = require('@transaksikita/node');

try {
  await tk.createPayment({ amount: 100 });
} catch (err) {
  if (err instanceof TransaksiKitaError) {
    console.log(err.message);    // Pesan error
    console.log(err.statusCode); // HTTP status code (0 = network/timeout)
    console.log(err.detail);     // Detail tambahan dari API
    console.log(err.response);   // Raw API response

    // Helper methods
    err.isAuthError();       // 401/403 — API key salah
    err.isValidationError(); // 400 — Parameter tidak valid
    err.isNotFound();        // 404 — Payment tidak ditemukan
    err.isRateLimited();     // 429 — Terlalu banyak request
    err.isConflict();        // 409 — Idempotency conflict
    err.isRetryable();       // Network error, timeout, atau 5xx
  }
}

Error codes:

| Code | Penyebab | Solusi | |------|----------|--------| | 400 | Parameter tidak valid | Cek amount (min 500), expiredMinutes (5-1440) | | 401 | API key tidak valid | Cek publicKey dan secretKey | | 403 | Project ditolak/tidak punya akses | Hubungi admin | | 404 | Payment/project tidak ditemukan | Cek paymentId atau projectId | | 409 | Idempotency conflict | Request sedang diproses, tunggu | | 429 | Rate limit | Maksimum 60 req/menit, tunggu 1 menit | | 0 | Network error / timeout | Cek koneksi, gunakan maxRetries |

Auto Retry

const tk = new TransaksiKita({
  // ...credentials
  maxRetries: 3,  // Retry 3x untuk network/server error
  timeout: 15000, // 15 detik per request
});
// Retry delay: 1s → 2s → 4s (exponential backoff)
// TIDAK retry untuk: 400, 401, 403, 404, 409

Examples

Express.js Integration

const express = require('express');
const { TransaksiKita, TransaksiKitaError } = require('@transaksikita/node');

const app = express();
app.use(express.json());

const tk = new TransaksiKita({
  projectId: process.env.TK_PROJECT_ID,
  publicKey: process.env.TK_PUBLIC_KEY,
  secretKey: process.env.TK_SECRET_KEY,
});

// Buat pembayaran
app.post('/checkout', async (req, res) => {
  try {
    const payment = await tk.createPayment({
      amount: req.body.amount,
      customerName: req.body.name,
      description: `Order dari ${req.body.name}`,
      referenceId: `ORD-${Date.now()}`,
      expiredMinutes: 60,
    });

    res.json({
      checkoutUrl: payment.checkoutFullUrl,
      paymentId: payment.paymentId,
    });
  } catch (err) {
    if (err instanceof TransaksiKitaError) {
      return res.status(err.statusCode || 500).json({ error: err.message });
    }
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.listen(3000);

📁 Lihat contoh lengkap: examples/express.js

Callback Handler

// Endpoint untuk menerima callback dari TransaksiKita
app.post('/callback/transaksikita', async (req, res) => {
  // PENTING: Selalu verifikasi callback!
  const isValid = await tk.verifyCallback(req.body);
  if (!isValid) {
    return res.status(400).json({ error: 'Invalid callback' });
  }

  const { paymentId, status, referenceId, amount } = req.body;

  if (status === 'paid') {
    // Update order di database Anda
    await db.orders.update(
      { status: 'paid', paidAt: new Date() },
      { where: { orderId: referenceId } }
    );
    // Kirim email konfirmasi
    await sendEmail(customer.email, 'Pembayaran Berhasil!');
  }

  // WAJIB: respond 200
  res.json({ received: true });
});

Polling Payment

// Menunggu pembayaran selesai (untuk CLI/background job)
const payment = await tk.createPayment({ amount: 50000 });
console.log('Scan QR:', payment.checkoutFullUrl);

// Polling setiap 3 detik, max 100x
const result = await tk.waitForPayment(payment.paymentId, 3000, 100);

if (result.status === 'paid') {
  console.log('Pembayaran berhasil!');
}

📁 Lihat contoh lengkap: examples/polling.js

Idempotency

Cegah pembayaran duplikat menggunakan idempotency key:

const orderId = 'ORDER-12345';

// Request pertama — buat pembayaran baru
const pay1 = await tk.createPayment({
  amount: 50000,
  idempotencyKey: orderId,
});

// Request kedua dengan key sama — TIDAK membuat pembayaran baru
// Mengembalikan data pembayaran yang sama
const pay2 = await tk.createPayment({
  amount: 50000,
  idempotencyKey: orderId,
});

console.log(pay1.paymentId === pay2.paymentId); // true

📁 Lihat contoh lengkap: examples/error-handling.js

TypeScript

import TransaksiKita, {
  TransaksiKitaError,
  CreatePaymentParams,
  PaymentData,
  PaymentStatusData,
} from '@transaksikita/node';

const tk = new TransaksiKita({
  projectId: process.env.TK_PROJECT_ID!,
  publicKey: process.env.TK_PUBLIC_KEY!,
  secretKey: process.env.TK_SECRET_KEY!,
});

const params: CreatePaymentParams = {
  amount: 100000,
  customerName: 'Budi',
};

const payment: PaymentData = await tk.createPayment(params);
const status: PaymentStatusData = await tk.checkStatus(payment.paymentId);

📁 Lihat contoh lengkap: examples/typescript.ts

Headers & Authentication

SDK otomatis mengirim headers berikut ke API TransaksiKita:

| Header | Value | Description | |--------|-------|-------------| | Authorization | Bearer {secretKey} | Secret Key sebagai Bearer token | | X-Public-Key | {publicKey} | Public Key | | X-Project-Id | {projectId} | Project ID | | Content-Type | application/json | JSON body | | User-Agent | TransaksiKita-Node/1.0.0 | SDK identifier | | X-Idempotency-Key | {key} | (opsional) Idempotency key | | X-Sandbox | 1 | (opsional) Force sandbox mode |

Environment Variables

Rekomendasi: simpan credentials di environment variables, jangan hardcode di source code.

# .env
TK_PROJECT_ID=your-project-id-here
TK_PUBLIC_KEY=tk_production_xxxxxxxxxxxx
TK_SECRET_KEY=sk_production_xxxxxxxxxxxx
const tk = new TransaksiKita({
  projectId: process.env.TK_PROJECT_ID,
  publicKey: process.env.TK_PUBLIC_KEY,
  secretKey: process.env.TK_SECRET_KEY,
});

FAQ

Q: Apakah SDK ini perlu dependency tambahan? A: Tidak. SDK ini zero dependencies — hanya menggunakan built-in Node.js http dan https.

Q: Bagaimana cara mendapatkan API key? A: Daftar di transaksikita.com, buat project, dan API key akan digenerate otomatis.

Q: Apa bedanya sandbox dan production? A: Sandbox untuk testing (pembayaran simulasi), production untuk transaksi nyata. Mode otomatis dari prefix API key (tk_sandbox_ vs tk_production_).

Q: Berapa rate limit API? A: Maksimum 60 request per menit per IP. SDK akan throw TransaksiKitaError dengan statusCode: 429 jika melebihi limit.

Q: Apakah callback aman? A: Selalu gunakan tk.verifyCallback() untuk memverifikasi callback. Method ini akan re-check ke API TransaksiKita untuk memastikan data valid.

Q: Pembayaran bisa expired? A: Ya. Set expiredMinutes saat createPayment() (5-1440 menit). Setelah expired, payment otomatis berubah status.

Support

License

MIT © PT Azvera Technology Indonesia