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

aba-payway

v0.2.2

Published

Type-safe TypeScript SDK for ABA PayWay — Cambodia's #1 payment gateway

Downloads

431

Readme

aba-payway

npm version CI License: MIT npm downloads Zero Dependencies

Type-safe TypeScript SDK for ABA PayWay — Cambodia's #1 payment gateway.

Unofficial community SDK. Not affiliated with ABA Bank.

Why aba-payway?

ABA PayWay's official SDK is a raw REST API with no official Node.js/TypeScript client. That means you're left dealing with manual HMAC hashing, snake_case field ordering, base64 encoding, and zero type safety. This SDK handles all of that for you.

| | aba-payway | Rolling your own | |---|---|---| | Type safety | Full TypeScript with strict types | None — guess the field names | | Hash computation | Automatic, correct field ordering | Manual HMAC-SHA512, easy to get wrong | | Base64 encoding | Automatic for items, URLs, payout | Do it yourself, hope you didn't miss one | | Dependencies | Zero — only Node.js built-ins | Probably axios + crypto-js + glue code | | API coverage | 15+ methods | Build each one from scratch | | Runtime support | Node.js, Bun, Deno, Cloudflare Workers | Whatever you tested |

Features

  • Zero runtime dependencies — uses Node.js built-in crypto and native fetch
  • Full TypeScript support with strict types and autocomplete
  • Dual ESM + CJS output — works everywhere
  • 15+ API methods — checkout, QR payments, refunds, pre-auth, payouts, and more
  • Runs anywhere — Node.js, Bun, Deno, Next.js, Express, Hono, Cloudflare Workers
  • Tested against ABA's sandbox — not just unit tests, real API integration tests

Installation

# bun
bun add aba-payway

# npm
npm install aba-payway

# pnpm
pnpm add aba-payway

Quick Start

import { PayWay } from 'aba-payway'

const payway = new PayWay({
  merchantId: 'your_merchant_id',
  apiKey: 'your_api_key',
})

// Generate checkout params (synchronous — no API call)
const params = payway.createTransaction({
  transactionId: 'order-001',
  amount: 10.00,
  items: 'Product A',
  returnUrl: 'https://yoursite.com/callback',
})

// Send `params` to your frontend, populate ABA's hidden form,
// and call AbaPayway.checkout() to open the payment dialog.
// See examples/ for more snippets and framework integrations.

API Reference

new PayWay(config)

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | merchantId | string | Yes | — | Your ABA PayWay merchant ID | | apiKey | string | Yes | — | Your ABA PayWay API key | | environment | 'sandbox' \| 'production' | No | 'sandbox' | Target environment | | baseUrl | string | No | — | Override the base URL directly (takes priority over environment) |

payway.createTransaction(options)

Generate checkout parameters for a payment. Synchronous — computes the HMAC hash and returns form params without making any API calls.

Returns CheckoutParams — snake_case form parameters to submit via ABA's checkout JS SDK.

| Parameter | Type | Required | Description | |---|---|---|---| | transactionId | string | Yes | Unique transaction ID (max 20 chars) | | amount | number | Yes | Purchase amount | | currency | 'USD' \| 'KHR' | No | Default: 'USD' | | paymentOption | PaymentOption | No | cards, abapay_khqr, abapay_khqr_deeplink, alipay, wechat, google_pay | | firstName | string | No | Buyer's first name | | lastName | string | No | Buyer's last name | | email | string | No | Buyer's email | | phone | string | No | Buyer's phone | | items | string \| ItemEntry[] | No | Item description — string or { name, quantity, price }[] | | returnUrl | string | No | Callback URL for payment completion | | cancelUrl | string | No | Redirect URL when user closes payment | | continueSuccessUrl | string | No | Redirect URL after success | | type | 'purchase' \| 'pre-auth' | No | Default: 'purchase' | | shipping | number | No | Shipping fee | | viewType | string | No | 'hosted_view' or 'popup' | | lifetime | number | No | Payment lifetime in minutes (3–43200) | | skipSuccessPage | number | No | 0 (don't skip) or 1 (skip) | | payout | string | No | Payout details (JSON string) | | returnDeeplink | string | No | Mobile app deeplink | | googlePayToken | string | No | Required if paymentOption is 'google_pay' |

items, returnUrl, returnDeeplink, and payout are automatically base64-encoded by the SDK.

payway.checkTransaction(transactionId)

Check the status of a transaction.

const result = await payway.checkTransaction('order-001')
console.log(result.status.code)          // '00' = success
console.log(result.data?.payment_status) // 'APPROVED' | 'DECLINED' | 'PENDING' | ...

payway.listTransactions(options?)

List transactions with optional filters. Max 3-day date range.

const list = await payway.listTransactions({
  fromDate: '2026-03-01 00:00:00',
  toDate: '2026-03-03 23:59:59',
  status: 'APPROVED',
  page: 1,
  pagination: 20,
})

| Parameter | Type | Description | |---|---|---| | fromDate | string | Start date: 'YYYY-MM-DD HH:mm:ss' | | toDate | string | End date: 'YYYY-MM-DD HH:mm:ss' | | fromAmount | number | Minimum amount filter | | toAmount | number | Maximum amount filter | | status | string | Comma-separated: APPROVED, DECLINED, PENDING, PRE-AUTH, CANCELLED, REFUNDED | | page | number | Page number (default: 1) | | pagination | number | Records per page (default: 40, max: 1000) |

payway.getTransactionDetails(transactionId)

Get detailed information about a transaction, including its operation history.

const details = await payway.getTransactionDetails('order-001')
console.log(details.data?.payment_status)            // 'APPROVED'
console.log(details.data?.transaction_operations)     // [{ status, amount, ... }]

payway.closeTransaction(transactionId)

Close (cancel) a pending transaction. The payment status becomes CANCELLED.

const result = await payway.closeTransaction('order-001')
console.log(result.status.code) // '00' = success

payway.getExchangeRate()

Fetch the latest exchange rates from ABA Bank for 12 currencies.

const rates = await payway.getExchangeRate()
console.log(rates.exchange_rates.eur) // { sell: '...', buy: '...' }

payway.generateQR(options)

Generate a dynamic QR code for payment via ABA KHQR, WeChat Pay, or Alipay.

const qr = await payway.generateQR({
  transactionId: 'qr-001',
  amount: 10.00,
  paymentOption: 'abapay_khqr',
  qrImageTemplate: 'template1',
  lifetime: 30,
})
console.log(qr.qrString)         // QR content string
console.log(qr.abapay_deeplink)  // ABA Mobile deep link

| Parameter | Type | Required | Description | |---|---|---|---| | transactionId | string | Yes | Unique transaction ID (max 20 chars) | | amount | number | Yes | Payment amount (min: 100 KHR or 0.01 USD) | | paymentOption | QRPaymentOption | Yes | abapay_khqr, wechat (USD only), alipay (USD only) | | qrImageTemplate | string | Yes | QR image template name | | currency | 'USD' \| 'KHR' | No | Default: 'USD' | | lifetime | number | No | Lifetime in minutes (3–43200) | | firstName | string | No | Payer's first name | | lastName | string | No | Payer's last name | | email | string | No | Payer's email | | phone | string | No | Payer's phone | | purchaseType | 'purchase' \| 'pre-auth' | No | Default: 'purchase' | | items | string | No | Item description (auto base64-encoded) | | callbackUrl | string | No | Payment callback URL (auto base64-encoded) | | returnDeeplink | string | No | Mobile deeplink (auto base64-encoded) | | payout | string | No | Payout JSON string (auto base64-encoded) |

payway.getTransactionsByRef(merchantRef)

Get transactions by merchant reference. Returns up to the last 50 transactions.

const txns = await payway.getTransactionsByRef('REF-001')
for (const txn of txns.data) {
  console.log(txn.transaction_id, txn.payment_status)
}

## Error Handling

```typescript
import { PayWay, PayWayAPIError, PayWayConfigError } from 'aba-payway'

| Error Class | When Thrown | |---|---| | PayWayConfigError | Missing or invalid constructor config | | PayWayAPIError | ABA API returns non-2xx response (has statusCode and responseBody properties) | | PayWayError | Base error class | | PayWayHashError | Hash generation failure |

Framework Examples

Next.js (App Router)

// app/api/pay/route.ts
import { PayWay } from 'aba-payway'

const payway = new PayWay({
  merchantId: process.env.PAYWAY_MERCHANT_ID!,
  apiKey: process.env.PAYWAY_API_KEY!,
  environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
})

export async function POST(request: Request) {
  const { orderId, amount } = await request.json()

  const params = payway.createTransaction({
    transactionId: orderId,
    amount,
    items: 'Order payment',
    returnUrl: `${process.env.NEXT_PUBLIC_URL}/api/pay/callback`,
  })

  return Response.json(params)
}

Express

import express from 'express'
import { PayWay } from 'aba-payway'

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

const payway = new PayWay({
  merchantId: process.env.PAYWAY_MERCHANT_ID!,
  apiKey: process.env.PAYWAY_API_KEY!,
})

app.post('/pay', (req, res) => {
  const params = payway.createTransaction({
    transactionId: req.body.orderId,
    amount: req.body.amount,
    items: 'Order payment',
    returnUrl: 'https://yoursite.com/callback',
  })
  res.json(params)
})

Sandbox Test Cards

| Card | Number | Expiry | CVV | Result | |---|---|---|---|---| | Mastercard | 5156 8399 3770 6777 | 01/30 | 993 | Approved | | Visa | 4286 0900 0000 0206 | 04/30 | 777 | Approved | | Mastercard | 5156 8302 7256 1029 | 04/30 | 777 | Declined | | Visa | 4156 8399 3770 6777 | 01/30 | 993 | Declined |

Documentation

For the full ABA PayWay API documentation, see aba-payway-docs.

Contributing

Found a bug or have a feature request? Open an issue — all feedback is welcome.

Pull requests are also welcome. Please make sure tests pass before submitting:

bun run test
bun run typecheck
bun run lint

License

MIT