README.md

This page is generated directly from the repository README.

KHQR SDK Demo

Interactive demo application showcasing the KHQR SDK for Cambodia’s Bakong QR payment system.

KHQR Demo

🎯 Features

  • QR Code Generator: Create static and dynamic KHQR codes with customizable payment details
  • Bakong API Tester: Test real Bakong API endpoints with manual input
  • QR Verification: Decode and validate KHQR strings with CRC integrity checks
  • Type-Safe: Full TypeScript support throughout the application
  • Modern SSR: Built with Astro, React islands, and TailwindCSS

πŸš€ Quick Start

Prerequisites

  • Node.js >= 20
  • pnpm (recommended) or npm

Installation

# Install dependencies
pnpm install

Development

# Start development server
pnpm dev

Then open http://localhost:4321 in your browser.

Production

# Build for production
pnpm build

# Preview production build locally
pnpm preview

# Deploy to Vercel
pnpm deploy

πŸ“ Project Structure

example/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”‚   β”œβ”€β”€ qr/
β”‚   β”‚   β”‚   β”‚   └── generate.json.ts       # QR generation endpoint
β”‚   β”‚   β”‚   └── bakong/
β”‚   β”‚   β”‚       β”œβ”€β”€ check-account.json.ts  # Bakong API proxy
β”‚   β”‚   β”‚       β”œβ”€β”€ check-tx-md5.json.ts   # Transaction check proxy
β”‚   β”‚   β”‚       β”œβ”€β”€ check-tx-short-hash.json.ts
β”‚   β”‚   β”‚       └── renew-token.json.ts
β”‚   β”‚   β”œβ”€β”€ index.astro                    # Homepage
β”‚   β”‚   β”œβ”€β”€ generator.astro                # QR Generator page
β”‚   β”‚   └── api-tester.astro               # API Tester page
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ QRGeneratorClient.tsx          # QR Generator React island
β”‚   β”‚   β”œβ”€β”€ BakongAPITesterClient.tsx      # API Tester React island
β”‚   β”‚   └── ToasterProvider.tsx            # Toast notifications
β”‚   β”œβ”€β”€ layouts/
β”‚   β”‚   └── Layout.astro                   # Base layout
β”‚   β”œβ”€β”€ styles/
β”‚   β”‚   └── global.css                     # Global styles
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   └── api.ts                         # API client functions
β”‚   └── types/
β”‚       └── index.ts                       # TypeScript types
β”œβ”€β”€ public/                                 # Static assets
β”œβ”€β”€ astro.config.mjs                        # Astro configuration
β”œβ”€β”€ vercel.json                             # Vercel deployment config
└── package.json

πŸ”Œ API Endpoints

QR Operations

POST /api/qr/generate
  Body: { bakongAccountID, merchantName, merchantCity, currency, amount?, ... }
  Response: { qr: string, md5: string }

Bakong API (Proxy Endpoints)

POST /api/bakong/renew-token
  Body: { email, token? }
  Response: APIResponse

POST /api/bakong/check-account
  Body: { bakongAccountID, token? }
  Response: APIResponse

POST /api/bakong/check-tx-md5
  Body: { md5, token? }
  Response: APIResponse

POST /api/bakong/check-tx-short-hash
  Body: { shortHashRequest: { hash, amount, currency }, token? }
  Response: APIResponse

πŸ“¦ Tech Stack

Framework

  • Astro 5 - SSR framework with React islands architecture
  • React 18 - Interactive UI components (islands)
  • TypeScript - Type safety

Styling

  • TailwindCSS - Utility-first CSS
  • Lucide React - Icons

Libraries

  • @manethpak/khqr-sdk - KHQR generation, decoding, and validation
  • QRCode - QR code image generation
  • Sonner - Toast notifications

Deployment

  • Vercel - Serverless deployment with edge functions

🌐 Deployment

Deploy to Vercel

The easiest way to deploy this demo:

Deploy with Vercel

Or manually:

# Install Vercel CLI (if not already installed)
npm i -g vercel

# Deploy
cd example
vercel

Environment Variables

For real Bakong API integration (optional):

# Copy example env file
cp .env.example .env

# Edit .env and add your token
BAKONG_API_TOKEN=your_jwt_token_here

Architecture

This demo uses Astro’s islands architecture for optimal performance:

  • Static pages: Generated at build time (homepage)
  • SSR pages: Server-rendered on demand (generator, api-tester)
  • React islands: Interactive components hydrated on the client
  • API routes: Serverless functions that proxy to Bakong API or handle QR generation

Why Astro?

  • Better performance: Ships minimal JavaScript (only islands are interactive)
  • Simpler deployment: Single unified codebase with built-in SSR
  • Vercel-optimized: First-class Vercel adapter support
  • Developer experience: File-based routing, automatic TypeScript support

API Proxy Pattern

The API endpoints follow a simple proxy pattern:

  1. User provides input through React component
  2. Component calls /api/* endpoint
  3. API endpoint uses KHQR SDK server-side
  4. Response sent back to client

This approach:

  • βœ… Keeps SDK logic server-side (Node.js crypto module compatibility)
  • βœ… Allows users to test with their own API tokens
  • βœ… No database or state management needed
  • βœ… Perfect for demo/testing purposes

πŸ§ͺ Development Notes

No Backend State

The demo is designed for manual testing:

  • No database or persistence layer
  • API endpoints are stateless proxies
  • Users provide all input directly through forms
  • Perfect for learning and testing the KHQR SDK

Adding Custom Endpoints

Create a new file in src/pages/api/:

// src/pages/api/custom.json.ts
import type { APIRoute } from 'astro'

export const POST: APIRoute = async ({ request }) => {
  const body = await request.json()

  // Your logic here

  return new Response(JSON.stringify({ success: true }), {
    status: 200,
    headers: { 'Content-Type': 'application/json' },
  })
}

πŸ“š Learn More

🀝 Contributing

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

πŸ“ License

ISC Β© Manethpak


Made with ❀️ for the Cambodian fintech community