OrderKuota API Reference

Yoru AKioYoru AKio
7 min read

orderkuota


OrderKuota Node.js API Wrapper

A fully type-safe Node.js wrapper for OrderKuota API with complete TypeScript support.

Features

  • Full TypeScript Support - Complete type definitions for all methods and responses
  • Type-Safe Configuration - Required fields validation at compile time
  • Custom Error Handling - Specific error types with detailed information
  • Modern Promise-based API - Full async/await support
  • QRIS QR Code Generation - Generate payment QR codes with custom styling
  • Base64 Image Support - Direct base64 output for web applications
  • Comprehensive Documentation - JSDoc comments for all methods

Note

⚠ Beta Notice: This package is currently in beta testing. Some transaction checking methods may not work as expected, as not all features have been fully tested. Please report any issues you encounter.

Installation

npm install orderkuota

# or using bun

bun add orderkuota

Quick Start

JavaScript Usage

const OrderKuota = require('orderkuota');

const client = new OrderKuota({
  username: 'your-username',
  password: 'your-password',
  userid: 'your-userid',
  apikey: 'your-apikey',
  pin: 'your-pin'
});

const balance = await client.checkBalance();
console.log(balance.balance);

TypeScript Usage

import OrderKuota, { 
  OrderKuotaConfig, 
  BalanceResponse,
  QrisHistoryResponse 
} from 'orderkuota';

const config: OrderKuotaConfig = {
  username: 'your-username',
  password: 'your-password', 
  userid: 'your-userid',
  apikey: 'your-apikey',
  pin: 'your-pin'
};

const client = new OrderKuota(config);

// Full type safety
const balance: BalanceResponse = await client.checkBalance();
const qrisHistory: QrisHistoryResponse = await client.fetchQrisHistory();

Configuration

All configuration fields are required except baseQrString which is needed only for QRIS generation:

FieldTypeRequiredDescription
usernamestringYesYour account username
passwordstringYesYour account password
useridstringYesUser ID or Merchant Code from OkeConnect
apikeystringYesAPI Key from OkeConnect
pinstringYesYour account PIN
baseQrStringstringNoBase QRIS string for QR code generation (required only for QRIS features)

API Methods

checkBalance(): Promise<BalanceResponse>

Check your account balance.

Note: Manage your IP whitelist in account settings

try {
  const balance = await client.checkBalance();
  console.log(`Current balance: ${balance.balance}`);
  console.log(`Status: ${balance.status}`);
  console.log(`Message: ${balance.message}`);
} catch (error) {
  console.error('Balance check failed:', error.message);
}

fetchQrisHistory(): Promise<QrisHistoryResponse>

Fetch QRIS (Quick Response Code Indonesian Standard) transaction history.

try {
  const history = await client.fetchQrisHistory();
  if (history.data) {
    history.data.forEach(transaction => {
      console.log(`Transaction: ${transaction.id} - ${transaction.amount}`);
      if (transaction.qris_data?.merchant_name) {
        console.log(`Merchant: ${transaction.qris_data.merchant_name}`);
      }
    });
  }
} catch (error) {
  console.error('Failed to fetch QRIS history:', error.message);
}

fetchVirtualAccountHistory(): Promise<VirtualAccountHistoryResponse>

Fetch Virtual Account transaction history.

try {
  const history = await client.fetchVirtualAccountHistory();
  if (history.data) {
    history.data.forEach(transaction => {
      console.log(`VA Transaction: ${transaction.id} - ${transaction.amount}`);
      if (transaction.va_number) {
        console.log(`VA Number: ${transaction.va_number}`);
      }
    });
  }
} catch (error) {
  console.error('Failed to fetch VA history:', error.message);
}

fetchRetailHistory(): Promise<RetailHistoryResponse>

Fetch retail (Alfamart & Indomart) transaction history.

try {
  const history = await client.fetchRetailHistory();
  if (history.data) {
    history.data.forEach(transaction => {
      console.log(`Retail Transaction: ${transaction.id} - ${transaction.amount}`);
      if (transaction.product_code) {
        console.log(`Product: ${transaction.product_code}`);
      }
    });
  }
} catch (error) {
  console.error('Failed to fetch retail history:', error.message);
}

getConfig(): Omit<OrderKuotaConfig, 'password' | 'pin' | 'apikey'>

Get current configuration without sensitive data.

const config = client.getConfig();
console.log(`Username: ${config.username}, User ID: ${config.userid}`);

isConfigValid(): boolean

Validate if the current configuration is complete.

if (client.isConfigValid()) {
  console.log('Configuration is valid');
} else {
  console.log('Missing required configuration');
}

Error Handling

The wrapper provides detailed error information through the OrderKuotaError class:

import { OrderKuotaError } from 'orderkuota';

try {
  const balance = await client.checkBalance();
} catch (error) {
  if (error instanceof OrderKuotaError) {
    console.error(`Error [${error.code}]: ${error.message}`);
    if (error.status) {
      console.error(`HTTP Status: ${error.status}`);
    }
  } else {
    console.error('Unexpected error:', error);
  }
}

Error Codes

CodeDescription
MISSING_CONFIGRequired configuration fields are missing
BALANCE_CHECK_FAILEDBalance check API returned an error
QRIS_FETCH_FAILEDQRIS history fetch failed
VA_FETCH_FAILEDVirtual Account history fetch failed
RETAIL_FETCH_FAILEDRetail history fetch failed
QRIS_GENERATION_FAILEDQRIS string generation failed
INVALID_AMOUNTPayment amount is invalid
INVALID_QRIS_FORMATBase QRIS string format is invalid
MISSING_BASE_QR_STRINGBase QR string is required for QRIS generation
CRC_CALCULATION_FAILEDCRC16 checksum calculation failed
INVALID_QRIS_STRINGQRIS string is empty or invalid
QR_GENERATION_FAILEDQR code image generation failed
NETWORK_ERRORNetwork connection error
UNKNOWN_ERRORUnexpected error occurred

TypeScript Interfaces

All response types are fully typed:

interface BalanceResponse {
  status: boolean;
  message: string;
  balance: number;
}

interface QrisTransaction {
  id: string;
  amount: number;
  date: string;
  status: string;
  description?: string;
  qris_data?: {
    merchant_name?: string;
    terminal_id?: string;
  };
}

interface QrisHistoryResponse {
  status: boolean;
  message: string;
  data?: QrisTransaction[];
  error?: string;
}

Registration

To register for an account, contact an admin from Telegram.

Contributing

If you want to contribute to this project, simply submit a pull request. For any bugs, suggestions, or fixes, please open an issue on the GitHub repository.

Contact

If you encounter a bug, error, or want to request a feature, you can contact the package maintainer directly:

License

This project is licensed under the MIT License - see the LICENSE file for details.

QRIS Payment QR Code Generation

OrderKuota supports generating QRIS (Quick Response Code Indonesian Standard) strings and QR code images for Indonesian digital payments.

Configuration for QRIS Generation

To use QRIS generation features, you need to provide a baseQrString in your configuration:

const client = new OrderKuota({
  username: 'your-username',
  password: 'your-password',
  userid: 'your-userid',
  apikey: 'your-apikey',
  pin: 'your-pin',
  baseQrString: 'your-base-qris-string' // Required for QRIS generation
});

// Check if QRIS generation is available
if (client.isQrisGenerationAvailable()) {
  console.log('QRIS generation is available!');
} else {
  console.log('baseQrString not configured');
}

generateQrisString(amount: number): Promise<string>

Generate a QRIS string with the specified payment amount.

try {
  const amount = 50000; // 50,000 IDR
  const qrisString = await client.generateQrisString(amount);
  console.log('Generated QRIS:', qrisString);

  // Use this string with any QR code library
  // const qrCode = await QR.toDataURL(qrisString);
} catch (error) {
  console.error('QRIS generation failed:', error.message);
}

generateQrisImage(qrisString: string, options?): Promise<string>

Generate a QR code image from a QRIS string and return it as base64.

try {
  const qrisString = await client.generateQrisString(75000);

  const qrImageBase64 = await client.generateQrisImage(qrisString, {
    width: 512,        // QR code width in pixels (default: 512)
    margin: 4,         // Margin around the QR code (default: 4)
    color: {
      dark: '#000000', // Dark color for QR modules (default: '#000000')
      light: '#FFFFFF' // Light color for background (default: '#FFFFFF')
    }
  });

  console.log('QR Image Base64:', qrImageBase64);

  // Use in HTML
  const imgSrc = `data:image/png;base64,${qrImageBase64}`;

  // Or save to file
  const fs = require('fs');
  fs.writeFileSync('payment-qr.png', qrImageBase64, 'base64');

} catch (error) {
  console.error('QR image generation failed:', error.message);
}

generateQrisQrCode(amount: number, options?): Promise<string>

Generate a complete QRIS QR code image with the specified amount in one step.

try {
  // Generate QR code directly from amount
  const qrCodeBase64 = await client.generateQrisQrCode(100000, {
    width: 256,
    margin: 6,
    color: {
      dark: '#1a1a1a',
      light: '#f5f5f5'
    }
  });

  console.log('QR Code generated successfully!');

  // Display in web application
  document.getElementById('qr-image').src = `data:image/png;base64,${qrCodeBase64}`;

} catch (error) {
  console.error('QR code generation failed:', error.message);
}

Complete QRIS Example

import OrderKuota from 'orderkuota';
import fs from 'fs';

const client = new OrderKuota({
  username: 'your-username',
  password: 'your-password',
  userid: 'your-userid',
  apikey: 'your-apikey',
  pin: 'your-pin',
  baseQrString: 'your-base-qris-string-here'
});

async function createPaymentQrCode() {
  try {
    if (!client.isQrisGenerationAvailable()) {
      throw new Error('QRIS generation not available');
    }

    const amount = 150000; // 150,000 IDR

    // Method 1: Two-step process (more control)
    const qrisString = await client.generateQrisString(amount);
    const qrImage = await client.generateQrisImage(qrisString);

    // Method 2: One-step process (simpler)
    const qrCodeDirect = await client.generateQrisQrCode(amount, {
      width: 300,
      color: { dark: '#2c5530', light: '#ffffff' }
    });

    // Save QR codes
    fs.writeFileSync('payment-step1.png', qrImage, 'base64');
    fs.writeFileSync('payment-direct.png', qrCodeDirect, 'base64');

    console.log(`✅ QR codes generated for payment of Rp ${amount.toLocaleString()}`);

  } catch (error) {
    console.error('❌ Error:', error.message);
  }
}

createPaymentQrCode();

isQrisGenerationAvailable(): boolean

Check if QRIS generation is available (baseQrString is configured and valid).

if (client.isQrisGenerationAvailable()) {
  // Generate QRIS codes
} else {
  console.log('Please configure baseQrString for QRIS generation');
}
0
Subscribe to my newsletter

Read articles from Yoru AKio directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yoru AKio
Yoru AKio