flutter_bakong_payway 1.0.4
flutter_bakong_payway: ^1.0.4 copied to clipboard
A Flutter plugin for generating Bakong KHQR payment codes. Supports Android, iOS, and Web. KHQR is Cambodia's centralized QR payment system.
Flutter Bakong Payway #
A Flutter plugin for generating Bakong KHQR payment codes. Supports Android, iOS, and Web platforms.
KHQR is Cambodia's centralized QR code payment system - Scan. Pay. Done.
☕ Support & Donate #
If you find this package helpful, consider supporting the development!
KUN VENG ANN
Scan with any Bakong-supported banking app
Features #
- ✅ Generate Individual KHQR codes (personal accounts)
- ✅ Generate Merchant KHQR codes (business accounts)
- ✅ Support for USD and KHR currencies
- ✅ Cross-platform: Android, iOS, and Web
- ✅ Easy-to-use API with type-safe models
- ✅ Auto-configuration (minimal setup required)
Installation #
Add this to your pubspec.yaml:
dependencies:
flutter_bakong_payway: ^1.0.0
Then run:
flutter pub get
Platform Setup #
Android #
No additional setup required. The plugin automatically includes the BakongKHQR SDK.
iOS #
No additional setup required. The plugin embeds the BakongKHQR SDK via CocoaPods.
Web #
Web requires 2 JavaScript files in your web/ folder:
Step 1: Download the SDK
Download the BakongKHQR SDK:
# Download from GitHub releases
curl -L -o web/khqr-sdk.min.js "https://github.com/nicholasblexrud/bakong-khqr/releases/download/bakong-khqr-1.0.6/khqr-1.0.6.min.js"
Or manually download from: https://github.com/nicholasblexrud/bakong-khqr/releases
Save it to your web/ folder as khqr-sdk.min.js
Step 2: Create the Wrapper File
Create a new file web/khqr_wrapper.js with this content:
// khqr_wrapper.js - Wrapper for BakongKHQR JavaScript SDK
(function () {
"use strict";
function checkKHQR() {
if (typeof BakongKHQR === "undefined") {
throw new Error("BakongKHQR SDK not loaded. Include khqr script first.");
}
}
window.flutterBakongKHQR = {
generateIndividual: function (info) {
return new Promise(function (resolve, reject) {
try {
checkKHQR();
var sdk = BakongKHQR;
var khqr = new sdk.BakongKHQR();
var khqrData = sdk.khqrData;
var currencyStr = (info.currency || "USD").toUpperCase();
var currency =
currencyStr === "KHR"
? khqrData.currency.khr
: khqrData.currency.usd;
var optionalData = {
currency: currency,
amount: info.amount || 0,
billNumber: info.billNumber || "",
mobileNumber: info.mobileNumber || "",
storeLabel: info.storeLabel || "",
terminalLabel: info.terminalLabel || "",
purposeOfTransaction: info.purposeOfTransaction || "",
merchantCategoryCode: info.merchantCategoryCode || "5999",
};
if (info.expirationTimestamp) {
optionalData.expirationTimestamp = info.expirationTimestamp;
} else if (info.amount && info.amount > 0) {
optionalData.expirationTimestamp = Date.now() + 5 * 60 * 1000;
}
var individualInfo = new sdk.IndividualInfo(
info.bakongAccountId || info.accountId || "",
info.merchantName || "",
info.merchantCity || "Phnom Penh",
optionalData
);
var response = khqr.generateIndividual(individualInfo);
if (response && response.data) {
resolve({
qr: response.data.qr || "",
md5: response.data.md5 || "",
});
} else {
reject(new Error("Failed to generate KHQR"));
}
} catch (e) {
reject(e);
}
});
},
generateMerchant: function (info) {
return new Promise(function (resolve, reject) {
try {
checkKHQR();
var sdk = BakongKHQR;
var khqr = new sdk.BakongKHQR();
var khqrData = sdk.khqrData;
var currencyStr = (info.currency || "USD").toUpperCase();
var currency =
currencyStr === "KHR"
? khqrData.currency.khr
: khqrData.currency.usd;
var optionalData = {
currency: currency,
amount: info.amount || 0,
billNumber: info.billNumber || "",
mobileNumber: info.mobileNumber || "",
storeLabel: info.storeLabel || "",
terminalLabel: info.terminalLabel || "",
purposeOfTransaction: info.purposeOfTransaction || "",
merchantCategoryCode: info.merchantCategoryCode || "5999",
};
if (info.expirationTimestamp) {
optionalData.expirationTimestamp = info.expirationTimestamp;
} else if (info.amount && info.amount > 0) {
optionalData.expirationTimestamp = Date.now() + 5 * 60 * 1000;
}
var merchantInfo = new sdk.MerchantInfo(
info.bakongAccountId || info.accountId || "",
info.merchantName || "",
info.merchantCity || "Phnom Penh",
info.merchantId || "",
info.acquiringBank || "",
optionalData
);
var response = khqr.generateMerchant(merchantInfo);
if (response && response.data) {
resolve({
qr: response.data.qr || "",
md5: response.data.md5 || "",
});
} else {
reject(new Error("Failed to generate KHQR"));
}
} catch (e) {
reject(e);
}
});
},
};
console.log("flutterBakongKHQR wrapper loaded");
})();
Step 3: Update index.html
Add these scripts to your web/index.html before the Flutter bootstrap script:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Your App</title>
<!-- BakongKHQR SDK - Add BEFORE flutter.js -->
<script src="khqr-sdk.min.js"></script>
<!-- KHQR Wrapper - Add BEFORE flutter.js -->
<script src="khqr_wrapper.js"></script>
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>
Your web/ folder structure:
web/
├── index.html (modified)
├── khqr-sdk.min.js (downloaded - ~55KB)
├── khqr_wrapper.js (created above)
├── manifest.json
└── icons/
Important: The scripts must be loaded before Flutter initializes.
Usage #
Import the package #
import 'package:flutter_bakong_payway/flutter_bakong_payway.dart';
Generate Individual KHQR #
final bakong = FlutterBakongPayway();
final info = IndividualInfo(
accountId: 'your_account@bank',
merchantName: 'John Doe',
currency: KHQRCurrency.usd,
amount: 10.00,
);
final result = await bakong.generateIndividualQR(info);
print('QR Data: ${result?.qr}');
print('MD5: ${result?.md5}');
Generate Merchant KHQR #
final bakong = FlutterBakongPayway();
final info = MerchantInfo(
accountId: 'merchant@bank',
merchantId: 'M001',
merchantName: 'ABC Store',
acquiringBank: 'ABA Bank',
currency: KHQRCurrency.khr,
amount: 50000.0,
merchantCity: 'Phnom Penh',
);
final result = await bakong.generateMerchantQR(info);
print('QR Data: ${result?.qr}');
print('MD5: ${result?.md5}');
Currency Options #
// US Dollar
currency: KHQRCurrency.usd
// Khmer Riel
currency: KHQRCurrency.khr
Display QR Code #
Use any QR code package like qr_flutter:
import 'package:qr_flutter/qr_flutter.dart';
QrImageView(
data: result?.qr ?? '',
version: QrVersions.auto,
size: 250,
)
API Reference #
IndividualInfo #
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId |
String | ✅ | Bakong account ID (e.g., "user@bank") |
merchantName |
String | ✅ | Account holder name |
currency |
KHQRCurrency | ✅ | USD or KHR |
amount |
double | ✅ | Payment amount |
merchantCity |
String | ❌ | City (default: "Phnom Penh") |
billNumber |
String | ❌ | Invoice/bill number |
mobileNumber |
String | ❌ | Contact phone number |
storeLabel |
String | ❌ | Store name |
terminalLabel |
String | ❌ | Terminal identifier |
expirationTimestamp |
int | ❌ | Expiration time (auto-set if amount > 0) |
MerchantInfo #
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId |
String | ✅ | Bakong account ID |
merchantId |
String | ✅ | Merchant ID |
merchantName |
String | ✅ | Business name |
acquiringBank |
String | ✅ | Bank name |
currency |
KHQRCurrency | ✅ | USD or KHR |
amount |
double | ✅ | Payment amount |
merchantCity |
String | ❌ | City (default: "Phnom Penh") |
billNumber |
String | ❌ | Invoice/bill number |
mobileNumber |
String | ❌ | Contact phone number |
storeLabel |
String | ❌ | Store name |
terminalLabel |
String | ❌ | Terminal identifier |
expirationTimestamp |
int | ❌ | Expiration time (auto-set if amount > 0) |
KHQRData (Response) #
| Field | Type | Description |
|---|---|---|
qr |
String | The KHQR string to encode as QR code |
md5 |
String | MD5 hash of the QR data |
Example #
See the example folder for a complete demo app.
cd example
flutter run
Notes #
- When
amount > 0, an expiration timestamp is automatically set to 5 minutes from now if not provided. - The plugin handles all platform-specific configurations internally.
- For Web, ensure the SDK scripts are loaded before Flutter initializes.
License #
MIT License - see LICENSE for details.
Credits #
- BakongKHQR SDK by National Bank of Cambodia
- bakong-khqr npm package for Web support