node-rdcw-slipverify
v3.0.0
Published
RDCW Slip Verify SDK for Node.js - Verify Thai bank transfer slips via QR code scanning
Maintainers
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-slipverifyQuick 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 IDconfig.secret(string, required): Your SlipVerify client secretconfig.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 stringoptions(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 inquiryoptions(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:
- Validity: The slip must be marked as valid by the API
- Cache Status: The slip must not have been used before (not cached)
- Age: The slip must not be older than 1 day
- Account Number: Matches the expected account (if provided)
- Bank Code: Matches the expected bank (if provided)
- 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 invalidEXPIRED_SLIP: The slip is older than 1 dayQR_CODE_ERROR: Failed to read or parse QR codeAPI_ERROR: API request failedVALIDATION_ERROR: Validation checks failed
Development
Setup
# Install dependencies
npm install
# Build the package
npm run build
# Run in development mode
npm run devScripts
npm run build- Build the packagenpm run dev- Run the package in development modenpm run clean- Remove build artifactsnpm run prepare- Prepare the package for publishing
License
ISC
