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 🙏

© 2025 – Pkg Stats / Ryan Hefner

node-rdcw-slipverify

v3.0.0

Published

RDCW Slip Verify SDK for Node.js - Verify Thai bank transfer slips via QR code scanning

Readme

node-rdcw-slipverify

An unofficial SDK for RDCW Slip Verify with a clean factory function API combining functional and OOP paradigms.

Installation

npm install node-rdcw-slipverify

Quick Start

import { createRdcwVerify } from "node-rdcw-slipverify";

const rdcw = createRdcwVerify({
  clientId: "your-client-id",
  secret: "your-client-secret",
});

// Verify a slip from payload
const result = await rdcw.inquiryPayload(
  "0038000600000101030060217Bf870bf26685f55526203TH9104CF62"
);

if (result.error) {
  console.log("Error:", result.error.message);
} else {
  console.log("Success:", result.data);
}

Locale Support

The SDK supports multiple locales for error messages. By default, it uses English (en), but you can configure it to use Thai (th) or provide custom messages.

Using Thai Locale

import { createRdcwVerify } from "node-rdcw-slipverify";

const rdcw = createRdcwVerify({
  clientId: "your-client-id",
  secret: "your-client-secret",
  locale: "th", // Use Thai locale
});

// All error messages will now be in Thai
const result = await rdcw.inquiryPayload(invalidPayload);

if (result.error) {
  console.log(result.error.message); // "สลิปไม่ถูกต้อง" instead of "Invalid slip"
}

Custom Messages

You can also provide custom messages to override the default locale messages:

const rdcw = createRdcwVerify({
  clientId: "your-client-id",
  secret: "your-client-secret",
  locale: "en",
  customMessages: {
    validation: {
      invalidSlip: "The slip you provided is not valid",
      slipExpired: "This slip is too old to be processed",
    },
    qr: {
      notFound: "We couldn't find a QR code in your image",
    },
  },
});

Available Locales

  • en - English (default)
  • th - Thai (ภาษาไทย)

Usage

1. Basic Inquiry (No Validation)

import { createRdcwVerify } from "node-rdcw-slipverify";

const rdcw = createRdcwVerify({
  clientId: "your-client-id",
  secret: "your-client-secret",
});

// Verify from payload
const result = await rdcw.inquiryPayload(payload);

// Verify from image
const imageResult = await rdcw.inquiryImage(imageBuffer);

if (result.data) {
  console.log("Transaction details:", result.data);
}

2. Inquiry with Auto-Validation

const result = await rdcw.inquiryPayload(payload, {
  expectedAccount: "1234567890",
  expectedBank: "014",
  expectedAmount: "100.00", // Optional
});

if (result.error) {
  console.log("Validation failed:", result.error.message);
  // Handle specific error types
  switch (result.error.type) {
    case "INVALID_SLIP":
      // Handle invalid slip
      break;
    case "EXPIRED_SLIP":
      // Handle expired slip
      break;
    case "VALIDATION_ERROR":
      // Handle validation errors
      break;
    case "API_ERROR":
      // Handle API errors
      break;
    case "QR_CODE_ERROR":
      // Handle QR code errors
      break;
  }
} else {
  console.log("Validation successful!", result.data);
}

3. Using Callbacks

const result = await rdcw.inquiryImage(imageBuffer, {
  expectedAccount: "1234567890",
  expectedBank: "014",
  onSuccess: (data) => {
    console.log("✅ Verification successful!");
    console.log("Amount:", data.data.amount);
    console.log("From:", data.data.sender.displayName);
  },
  onError: (error) => {
    console.log("❌ API Error:", error.message);
  },
  onValidationError: (error) => {
    console.log("⚠️ Validation failed:", error.message);
  },
});

// Result is still returned for further processing
if (result.data) {
  // Save to database, etc.
}

4. Manual Validation

// First, verify the slip
const verifyResult = await rdcw.inquiryPayload(payload);

if (verifyResult.data) {
  // Then, validate manually
  const validateResult = rdcw.validate(verifyResult.data, {
    expectedAccount: "1234567890",
    expectedBank: "014",
    expectedAmount: "100.00",
    onSuccess: (data) => console.log("Validation passed!"),
    onValidationError: (error) =>
      console.log("Validation failed:", error.message),
  });

  if (validateResult.data) {
    console.log("All checks passed!");
  }
}

5. Reading QR Code from Image

import fs from "fs";

// From file buffer
const imageBuffer = fs.readFileSync("path/to/qr-code-image.png");
const result = await rdcw.inquiryImage(imageBuffer, {
  expectedAccount: "1234567890",
  expectedBank: "014",
});

// From base64 string
const base64Image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...";
const result2 = await rdcw.inquiryImage(base64Image);

API Reference

Factory Function

createRdcwVerify(config)

Creates a new RDCW Verify instance.

Parameters:

  • config.clientId (string, required): Your SlipVerify client ID
  • config.secret (string, required): Your SlipVerify client secret
  • config.baseUrl (string, optional): Custom API base URL (default: "https://suba.rdcw.co.th")
  • config.locale (Locale, optional): Locale for error messages - "en" or "th" (default: "en")
  • config.customMessages (Partial, optional): Custom message overrides

Returns: RdcwVerify instance

Instance Methods

inquiryPayload(payload, options?)

Verifies a slip using its payload string.

Parameters:

  • payload (string): The QR code payload string
  • options (ValidationOptions, optional): Validation options

Returns: Promise<Result<VerifySlipResult, SlipError>>

inquiryImage(imageData, options?)

Reads a QR code from an image and verifies the slip.

Parameters:

  • imageData (ArrayBuffer | Buffer | string): Image data (buffer or base64 string)
  • options (ValidationOptions, optional): Validation options

Returns: Promise<Result<VerifySlipResult, SlipError>>

validate(result, options)

Manually validates a verification result.

Parameters:

  • result (VerifySlipResult): The result from inquiry
  • options (ValidationOptions): Validation options

Returns: Result<VerifySlipResult, SlipError>

Types

Locale

type Locale = "en" | "th";

LocaleMessages

interface LocaleMessages {
  qr: {
    invalidDimensions: string;
    notFound: string;
    readFailed: string;
  };
  api: {
    invalidResponse: string;
    requestFailed: string;
    unexpectedError: string;
  };
  validation: {
    invalidSlip: string;
    slipAlreadyUsed: string;
    slipExpired: string;
    invalidAccount: string;
    invalidBank: string;
    invalidQRFormat: string;
    amountMismatch: string;
  };
}

Result<T, E>

type Result<T, E> = Success<T> | Failure<E>;

interface Success<T> {
  data: T;
  error?: never;
}

interface Failure<E> {
  data?: never;
  error: E;
}

ValidationOptions

interface ValidationOptions {
  expectedAccount?: string;
  expectedBank?: string;
  expectedAmount?: string;
  onSuccess?: (data: VerifySlipResult) => void;
  onError?: (error: SlipError) => void;
  onValidationError?: (error: SlipError) => void;
}

SlipError

interface SlipError {
  type: ErrorType;
  message: string;
}

type ErrorType =
  | "INVALID_SLIP"
  | "EXPIRED_SLIP"
  | "QR_CODE_ERROR"
  | "API_ERROR"
  | "VALIDATION_ERROR";

VerifySlipResult

interface VerifySlipResult {
  discriminator: string;
  valid: boolean;
  data: Data;
  quota: Quota;
  subscription: Subscription;
  isCached: boolean;
}

interface Data {
  language: string;
  transRef: string;
  sendingBank: string;
  receivingBank: string;
  transDate: string;
  transTime: string;
  sender: Receiver;
  receiver: Receiver;
  amount: string;
  paidLocalAmount: string;
  paidLocalCurrency: string;
  countryCode: string;
  transFeeAmount: string;
  ref1: string;
  ref2: string;
  ref3: string;
  toMerchantId: string;
}

Validation Rules

The SDK validates slips based on the following criteria:

  1. Validity: The slip must be marked as valid by the API
  2. Cache Status: The slip must not have been used before (not cached)
  3. Age: The slip must not be older than 1 day
  4. Account Number: Matches the expected account (if provided)
  5. Bank Code: Matches the expected bank (if provided)
  6. Amount: Matches the expected amount (if provided)

Error Handling

All methods return a Result type that contains either data or error:

const result = await rdcw.inquiryPayload(payload);

if (result.error) {
  // Handle error
  console.error(result.error.type, result.error.message);
} else {
  // Process data
  console.log(result.data);
}

Error Types

  • INVALID_SLIP: The slip is invalid
  • EXPIRED_SLIP: The slip is older than 1 day
  • QR_CODE_ERROR: Failed to read or parse QR code
  • API_ERROR: API request failed
  • VALIDATION_ERROR: Validation checks failed

Development

Setup

# Install dependencies
npm install

# Build the package
npm run build

# Run in development mode
npm run dev

Scripts

  • npm run build - Build the package
  • npm run dev - Run the package in development mode
  • npm run clean - Remove build artifacts
  • npm run prepare - Prepare the package for publishing

License

ISC