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

betabotz-paygate

v1.0.1

Published

Official Node.js SDK for Betabotz Paygate - Payment Gateway API

Readme

Betabotz Paygate SDK

Official Node.js SDK for Betabotz Payment Gateway API.

npm version License: MIT

Features

  • 🚀 Easy to use
  • 💳 Support for multiple payment methods (QRIS, Dana, GoPay, OVO, ShopeePay)
  • 🔒 Secure API key authentication
  • 📦 TypeScript support
  • ⚡ Promise-based API
  • 🔄 Automatic retries and error handling

Installation

npm install betabotz-paygate

or with yarn:

yarn add betabotz-paygate

Quick Start

const BetabotzPaygate = require('betabotz-paygate');

// Initialize client
const paygate = new BetabotzPaygate({
  apiKey: 'YOUR_PAYMENT_METHOD_APIKEY',
});

// Create a transaction
async function createPayment() {
  try {
    const transaction = await paygate.createTransaction({
      amount: 10000,
      notes: 'Order #123',
      callback_url: 'https://yourdomain.com/webhook',
      return_url: 'https://yourdomain.com/thankyou',
      metadata: {
        orderId: '123',
        productName: 'Premium Package',
      },
    });

    console.log('Payment URL:', transaction.data.paymentUrl);
    console.log('Transaction ID:', transaction.data.transactionId);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

createPayment();

Configuration

Constructor Options

const paygate = new BetabotzPaygate({
  apiKey: 'YOUR_PAYMENT_METHOD_APIKEY', // Required
  baseURL: 'https://web.btzpay.my.id',  // Optional (default value)
  timeout: 30000,                        // Optional (default: 30000ms)
});

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | apiKey | string | Yes | Your payment method API key from dashboard | | baseURL | string | No | Base URL for API (default: https://web.btzpay.my.id) | | timeout | number | No | Request timeout in milliseconds (default: 30000) |

API Methods Documentation

1. createTransaction(params)

Create a new QRIS or e-wallet transaction.

Basic Example

const transaction = await paygate.createTransaction({
  amount: 10000,
  notes: 'Payment for Order #123',
});

Complete Example with All Parameters

const transaction = await paygate.createTransaction({
  // Required
  amount: 10000,
  
  // Payment Config (Optional)
  fee: 15,
  paymentMethod: 'qrisgopay',
  timeout: 900000,
  
  // URLs (Optional)
  callback_url: 'https://yourdomain.com/webhook',
  return_url: 'https://yourdomain.com/thankyou',
  
  // Info (Optional)
  notes: 'Order #123',
  
  // Customer (Optional)
  customerInfo: {
    name: 'John Doe',
    email: '[email protected]',
    phone: '081234567890',
  },
  
  // Metadata (Optional)
  metadata: {
    orderId: '123',
    productName: 'Premium Package',
  },
});

Response

{
  success: true,
  data: {
    transactionId: 'TRX17685466153087427',
    paymentUrl: 'https://web.btzpay.my.id/transaction/TRX...',
    accessKey: 'ae160236...',
    amount: 10000,
    totalAmount: 10574,
    status: 'pending',
    // ... more fields
  }
}

2. getTransaction(transactionId, accessKey)

Get transaction details.

Example

const details = await paygate.getTransaction(
  'TRX17685466153087427',
  'ae160236cc2f6012f8a2e273ac9dd955'
);

console.log(details.data.status); // pending, sukses, gagal, expired, cancel

3. cancelTransaction(transactionId, reason)

Cancel a pending transaction.

Example

const result = await paygate.cancelTransaction(
  'TRX17685466153087427',
  'User cancelled order'
);

console.log(result.data.status); // cancel

4. sendCallback(params)

Send payment callback from listener app. appVersionCode required!

Dana Example

const result = await paygate.sendCallback({
  action: 'update',
  app: 'com.dana.id',
  notification: 'Kamu menerima Rp10.000 dari John Doe',
  amount: 10000,
  appVersionCode: 123,
});

GoPay Example

await paygate.sendCallback({
  action: 'update',
  app: 'com.gojek.app',
  notification: 'Pembayaran Rp50.000 berhasil',
  amount: 50000,
  appVersionCode: 123,    
});

5. getPaymentUrl(transactionId, accessKey)

Generate payment URL.

Example

const url = paygate.getPaymentUrl(
  'TRX17685466153087427',
  'ae160236cc2f6012f8a2e273ac9dd955'
);
// https://web.btzpay.my.id/transaction/TRX...?key=...

Payment Methods

Supported payment methods:

  • qrisdana - QRIS Dana
  • qrisgopay - QRIS GoPay
  • qrisorkut - QRIS Orkut
  • qrisshopeepay - QRIS ShopeePay

Webhook/Callback

When a transaction status changes, Betabotz Paygate will send a POST request to your callback_url.

Callback Payload Example

{
  pay_id: 'TRX17685536101913729',
  unique_code: '123',
  status: 'sukses', // pending, sukses, gagal, expired, cancel
  raw: {
    success: true,
    message: 'Payment confirmed successfully',
    data: {
      transactionId: 'TRX17685536101913729',
      amount: 10000,
      status: 'sukses',
      paidAt: '2026-01-16T08:53:59.148Z',
      expiredAt: '2026-01-16T08:58:30.261Z',
      orderId: '123',
      productName: 'Premium Package',
      reason: 'macroDroid_notification',
      notes: 'Order #123',
      return_url: 'https://yourdomain.com/thankyou'
    }
  }
}

Handling Webhook (Express.js Example)

const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook', (req, res) => {
  const { pay_id, status, raw } = req.body;

  console.log('Payment received:', pay_id, status);
  
  // Process the payment based on status
  if (status === 'sukses') {
    // Update your database, fulfill order, etc.
    console.log('Order completed:', raw.data.orderId);
  }

  // IMPORTANT: Respond with success
  res.json({ success: true });
});

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

Transaction Status

| Status | Description | |--------|-------------| | pending | Transaction is waiting for payment | | sukses | Payment successfully received | | gagal | Payment failed | | expired | Transaction expired (timeout reached) | | cancel | Transaction cancelled by user or merchant |

Rate Limits

| Endpoint | Limit | Window | |----------|-------|--------| | Create/Cancel | 10 requests | 1 seconds | | Callback | 100 requests | 15 seconds | | Get Transaction | 60 requests | 1 seconds |

Error Handling

The SDK throws errors that you should catch and handle:

try {
  const transaction = await paygate.createTransaction({
    amount: 10000,
  });
} catch (error) {
  console.error('Error code:', error.status);
  console.error('Error message:', error.message);
  console.error('Error data:', error.data);
}

Common Error Responses

Validation Error (400)

{
  success: false,
  message: 'Validation error',
  errors: [
    {
      field: 'amount',
      message: 'Amount must be a number'
    }
  ]
}

Rate Limit Error (429)

{
  success: false,
  message: 'Too many requests. Please try again in 1 minute.'
}

Not Found (404)

{
  success: false,
  message: 'Transaction not found'
}

TypeScript Support

This package includes TypeScript definitions:

import BetabotzPaygate, { CreateTransactionParams, TransactionData } from 'betabotz-paygate';

const paygate = new BetabotzPaygate({
  apiKey: 'YOUR_API_KEY',
});

const params: CreateTransactionParams = {
  amount: 10000,
  notes: 'Order #123',
};

const transaction = await paygate.createTransaction(params);
const data: TransactionData = transaction.data;

Complete Example

const BetabotzPaygate = require('betabotz-paygate');
const express = require('express');

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

const paygate = new BetabotzPaygate({
  apiKey: 'YOUR_API_KEY',
});

// Create payment endpoint
app.post('/create-payment', async (req, res) => {
  try {
    const { amount, orderId, productName } = req.body;

    const transaction = await paygate.createTransaction({
      amount: amount,
      notes: `Order ${orderId}`,
      callback_url: 'https://yourdomain.com/webhook',
      return_url: 'https://yourdomain.com/thankyou',
      metadata: {
        orderId: orderId,
        productName: productName,
      },
    });

    res.json({
      success: true,
      paymentUrl: transaction.data.paymentUrl,
      transactionId: transaction.data.transactionId,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
});

// Webhook endpoint
app.post('/webhook', async (req, res) => {
  const { pay_id, status, raw } = req.body;

  if (status === 'sukses') {
    console.log('✅ Payment successful:', pay_id);
    // Update database, send confirmation email, etc.
  } else if (status === 'expired') {
    console.log('⏱️ Payment expired:', pay_id);
  } else if (status === 'cancel') {
    console.log('❌ Payment cancelled:', pay_id);
  }

  res.json({ success: true });
});

// Check transaction status
app.get('/check-payment/:transactionId', async (req, res) => {
  try {
    const { transactionId } = req.params;
    const { accessKey } = req.query;

    const details = await paygate.getTransaction(transactionId, accessKey);

    res.json({
      success: true,
      status: details.data.status,
      amount: details.data.amount,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: error.message,
    });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Support

  • Documentation: https://web.btzpay.my.id/documentation
  • Issues: https://github.com/ERLANRAHMAT/betabotz-paygate/issues
  • Email: [email protected]

License

MIT License - see LICENSE file for details

Notes

  • All amounts are in Indonesian Rupiah (IDR)
  • Minimum transaction amount is Rp 1
  • Timeout is specified in milliseconds (60000ms = 1 minute)
  • Always secure your API key and never commit it to version control
  • Use environment variables to store sensitive data

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Testing

The SDK includes a comprehensive test suite to verify all functionality.

Running Tests

# Run all tests
npm test

# Run transaction tests only
npm run test:transaction
# or
npm run test:tx

# Run callback tests only
npm run test:callback
# or
npm run test:cb

# Run specific test file
node test/callback.test.js
node test/transaction.test.js

Test Coverage

Transaction Tests (11 tests):

  • Create simple transaction
  • Create detailed transaction
  • Get transaction details
  • Cancel transaction
  • All payment methods
  • Minimum/maximum amounts
  • Custom timeout
  • Error handling
  • Complete lifecycle

Callback Tests (9 tests):

  • Callback for Dana, GoPay, OVO, ShopeePay
  • Callback with unique code
  • Error handling
  • Complete flow (create + callback + verify)
  • Multiple callbacks (batch)

Writing Custom Tests

const BetabotzPaygate = require('betabotz-paygate');

const paygate = new BetabotzPaygate({
  apiKey: 'YOUR_API_KEY',
});

async function myCustomTest() {
  try {
    const tx = await paygate.createTransaction({
      amount: 50000,
    });
    console.log('✅ Test passed:', tx.data.transactionId);
  } catch (error) {
    console.error('❌ Test failed:', error.message);
  }
}

myCustomTest();

For more details, see test/README.md.