orderkuota
Version:
OrderKuota API wrapper for Node.js
434 lines (333 loc) • 12 kB
Markdown
# 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
```bash
npm install orderkuota
# or using bun
bun add orderkuota
```
## Quick Start
### JavaScript Usage
```javascript
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
```typescript
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:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `username` | string | Yes | Your account username |
| `password` | string | Yes | Your account password |
| `userid` | string | Yes | User ID or Merchant Code from [OkeConnect](https://okeconnect.com/integrasi/payment_gateway) |
| `apikey` | string | Yes | API Key from [OkeConnect](https://okeconnect.com/integrasi/payment_gateway) |
| `pin` | string | Yes | Your account PIN |
| `baseQrString` | string | No | Base 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](https://okeconnect.com/integrasi/trx_ip)
```typescript
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.
```typescript
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.
```typescript
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.
```typescript
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.
```typescript
const config = client.getConfig();
console.log(`Username: ${config.username}, User ID: ${config.userid}`);
```
### `isConfigValid(): boolean`
Validate if the current configuration is complete.
```typescript
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:
```typescript
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
| Code | Description |
|------|-------------|
| `MISSING_CONFIG` | Required configuration fields are missing |
| `BALANCE_CHECK_FAILED` | Balance check API returned an error |
| `QRIS_FETCH_FAILED` | QRIS history fetch failed |
| `VA_FETCH_FAILED` | Virtual Account history fetch failed |
| `RETAIL_FETCH_FAILED` | Retail history fetch failed |
| `QRIS_GENERATION_FAILED` | QRIS string generation failed |
| `INVALID_AMOUNT` | Payment amount is invalid |
| `INVALID_QRIS_FORMAT` | Base QRIS string format is invalid |
| `MISSING_BASE_QR_STRING` | Base QR string is required for QRIS generation |
| `CRC_CALCULATION_FAILED` | CRC16 checksum calculation failed |
| `INVALID_QRIS_STRING` | QRIS string is empty or invalid |
| `QR_GENERATION_FAILED` | QR code image generation failed |
| `NETWORK_ERROR` | Network connection error |
| `UNKNOWN_ERROR` | Unexpected error occurred |
## TypeScript Interfaces
All response types are fully typed:
```typescript
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](https://t.me/orderkuota).
## 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:
- Telegram: [@Ethermite](https://t.me/ethermite)
- Group: [Vertion Group](https://t.me/vertion)
## License
This project is licensed under the MIT License - see the [LICENSE](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:
```typescript
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.
```typescript
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.
```typescript
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.
```typescript
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
```typescript
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).
```typescript
if (client.isQrisGenerationAvailable()) {
// Generate QRIS codes
} else {
console.log('Please configure baseQrString for QRIS generation');
}
```