Metadata-Version: 2.4
Name: bakong-v2
Version: 1.1.1
Summary: A Python package for Bakong KHQR payment integration using the BakongV2 API. (Unofficial)
Home-page: https://bakong-v2.vercel.app
Author: Lim Visa
Author-email: limvisa168@gmail.com
License: MIT
Project-URL: Homepage, https://bakong-v2.vercel.app
Project-URL: Repository, https://github.com/limvisa168/bakong-v2
Keywords: bakong,khqr,payment,cambodia,nbc
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: image
Requires-Dist: pillow; extra == "image"
Requires-Dist: qrcode; extra == "image"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-python
Dynamic: summary

<p align="center">
  <img src="https://bakong.nbc.gov.kh/images/logo.svg" width="120" alt="Bakong Logo"/>
</p>

<h1 align="center">Bakong-V2</h1>

<p align="center">
  <strong>A Python package for Bakong KHQR payment integration</strong>
  <br/>
  <strong>កញ្ចប់ Python សម្រាប់ការរួមបញ្ចូលការទូទាត់តាមរយៈ Bakong KHQR</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/bakong-v2/"><img src="https://img.shields.io/pypi/v/bakong-v2" alt="PyPI"></a>
  <a href="https://pypi.org/project/bakong-v2/"><img src="https://img.shields.io/pypi/pyversions/bakong-v2" alt="Python Versions"></a>
  <a href="https://pypi.org/project/bakong-v2/"><img src="https://img.shields.io/pypi/l/bakong-v2" alt="License"></a>
</p>

---

## 📋 Table of Contents | តារាងមាតិកា

- [Features | មុខងារពិសេស](#-features--មុខងារពិសេស)
- [Installation | ការដំឡើង](#-installation--ការដំឡើង)
- [Quick Start | ការចាប់ផ្តើមរហ័ស](#-quick-start--ការចាប់ផ្តើមរហ័ស)
- [API Reference | ឯកសារយោង API](#-api-reference--ឯកសារយោង-api)
- [Advanced Usage | ការប្រើប្រាស់កម្រិតខ្ពស់](#-advanced-usage--ការប្រើប្រាស់កម្រិតខ្ពស់)
- [Error Handling | ការគ្រប់គ្រងកំហុស](#-error-handling--ការគ្រប់គ្រងកំហុស)
- [License | អាជ្ញាប័ណ្ណ](#-license--អាជ្ញាប័ណ្ណ)

---

## ✨ Features | មុខងារពិសេស

**English**

- Generate KHQR strings locally (no API call required for QR creation)
- Generate Bakong deep links for payment redirection
- Check payment status by MD5, transaction hash, short hash, reference codes
- Bulk check up to 50 payments in a single request
- Verify Bakong account information
- Generate QR code images (PNG, JPEG, WebP, Base64)
- No Cambodia IP required — all requests through BakongV2 relay
- Retry logic for API calls with configurable attempts

**ភាសាខ្មែរ**

- បង្កើត KHQR ដោយផ្ទាល់លើម៉ាស៊ីនអ្នក (មិនត្រូវការ API សម្រាប់បង្កើត QR)
- បង្កើតតំណភ្ជាប់ជ្រៅ Bakong សម្រាប់បញ្ជូនបន្តការទូទាត់
- ពិនិត្យស្ថានភាពការទូទាត់តាម MD5, លេខសម្ងាត់ប្រតិបត្តិការ, លេខសម្ងាត់ខ្លី, លេខយោង
- ពិនិត្យច្រើនក្នុងពេលតែមួយរហូតដល់ 50 ប្រតិបត្តិការ
- ផ្ទៀងផ្ទាត់ព័ត៌មានគណនី Bakong
- បង្កើតរូបភាព QR ជាទម្រង់ PNG, JPEG, WebP, Base64
- មិនត្រូវការ IP កម្ពុជា — សំណើទាំងអស់ឆ្លងកាត់ BakongV2 relay

---

## 📦 Installation | ការដំឡើង

**English**

Install the package via pip:

```bash
pip install bakong-v2
```

For QR image generation support (Pillow + qrcode):

```bash
pip install "bakong-v2[image]"
```

**Requirements:**
- Python 3.6+

**ភាសាខ្មែរ**

ដំឡើងកញ្ចប់តាមរយៈ pip:

```bash
pip install bakong-v2
```

សម្រាប់ការបង្កើតរូបភាព QR (Pillow + qrcode):

```bash
pip install "bakong-v2[image]"
```

**តម្រូវការ:**
- Python 3.6+

---

## 🚀 Quick Start | ការចាប់ផ្តើមរហ័ស

**English**

Get your token from [@KHQRNotificationBot](https://t.me/KHQRNotificationBot) on Telegram, then:

```python
from bakong_v2 import KHQR

# Initialize with your token
khqr = KHQR("your_token_here")

# Step 1: Generate a KHQR string
qr = khqr.create_qr(
    bank_account="your_name@aclb",      # Bakong account ID
    merchant_name="SK TOPUP",           # Business name
    merchant_city="Phnom Penh",         # Merchant city
    amount=0.50,                        # Transaction amount
    currency="USD",                     # USD or KHR
    store_label="Shop A",               # Optional: store identifier
    bill_number="INV-001",              # Optional: invoice number
    static=False,                       # False = dynamic QR (with expiry)
    expiration=1                        # QR valid for 1 day (dynamic only)
)

# Step 2: Generate MD5 hash of the QR string
md5 = khqr.generate_md5(qr)

# Step 3: Check payment status
status = khqr.check_payment(md5)
print(f"Payment status: {status}")  # "PAID" or "UNPAID"

# Step 4: Get full payment details
info = khqr.get_payment(md5)
print(f"Payment info: {info}")

# Step 5: Generate a deep link for payment
link = khqr.generate_deeplink(
    qr=qr,
    appDeepLinkCallback="https://your-site.com/callback",
    appName="MyApp",
)
print(f"Deep link: {link}")
```

**ភាសាខ្មែរ**

ទទួលបានថូខឹនពី [@KHQRNotificationBot](https://t.me/KHQRNotificationBot) តាមរយៈ Telegram:

```python
from bakong_v2 import KHQR

# ចាប់ផ្តើមជាមួយថូខឹនរបស់អ្នក
khqr = KHQR("your_token_here")

# ជំហានទី 1: បង្កើត KHQR string
qr = khqr.create_qr(
    bank_account="your_name@aclb",      # លេខគណនី Bakong
    merchant_name="SK TOPUP",           # ឈ្មោះអាជីវកម្ម
    merchant_city="Phnom Penh",         # ទីក្រុង
    amount=0.50,                        # ចំនួនទឹកប្រាក់
    currency="USD",                     # USD ឬ KHR
    store_label="Shop A",               # ស្លាកហាង (មិនចាំបាច់)
    bill_number="INV-001",              # លេខវិក្កយបត្រ (មិនចាំបាច់)
    static=False,                       # False = QR ប្រើតែម្តង (មានផុតកំណត់)
    expiration=1                        # QR អាចប្រើបាន 1 ថ្ងៃ
)

# ជំហានទី 2: បង្កើត MD5 hash ពី QR string
md5 = khqr.generate_md5(qr)

# ជំហានទី 3: ពិនិត្យស្ថានភាពការទូទាត់
status = khqr.check_payment(md5)
print(f"Payment status: {status}")  # "PAID" ឬ "UNPAID"

# ជំហានទី 4: ទទួលបានព័ត៌មានលម្អិតនៃការទូទាត់
info = khqr.get_payment(md5)
print(f"Payment info: {info}")

# ជំហានទី 5: បង្កើតតំណភ្ជាប់ជ្រៅសម្រាប់ការទូទាត់
link = khqr.generate_deeplink(
    qr=qr,
    appDeepLinkCallback="https://your-site.com/callback",
    appName="MyApp",
)
print(f"Deep link: {link}")
```

---

## 📚 API Reference | ឯកសារយោង API

### Constructor

```python
KHQR(token: str | None = None)
```

| Parameter | Type | Description | ការពិពណ៌នា |
|-----------|------|-------------|----------------|
| `token` | `str` | Token from @KHQRNotificationBot | ថូខឹនពី @KHQRNotificationBot |

---

### create_qr()

Generate a KHQR payment string locally.

```python
create_qr(
    bank_account: str,
    merchant_name: str,
    merchant_city: str,
    amount: float,
    currency: str,
    store_label: str | None = None,
    phone_number: str | None = None,
    bill_number: str | None = None,
    terminal_label: str | None = None,
    static: bool = False,
    expiration: int = 1,
    watch: bool = True
) -> str
```

| Parameter | Type | Required | Description | ការពិពណ៌នា |
|-----------|------|----------|-------------|----------------|
| `bank_account` | `str` | ✅ | Bakong account ID (e.g., `name@bank`) | លេខគណនី Bakong |
| `merchant_name` | `str` | ✅ | Business/merchant name | ឈ្មោះអាជីវកម្ម |
| `merchant_city` | `str` | ✅ | Merchant city | ទីក្រុង |
| `amount` | `float` | ✅ | Transaction amount (≤ 0 = static QR) | ចំនួនទឹកប្រាក់ |
| `currency` | `str` | ✅ | `"USD"` or `"KHR"` | រូបិយប័ណ្ណ |
| `store_label` | `str` | ❌ | Store identifier | ស្លាកហាង |
| `phone_number` | `str` | ❌ | Customer phone number | លេខទូរស័ព្ទអតិថិជន |
| `bill_number` | `str` | ❌ | Invoice/bill number | លេខវិក្កយបត្រ |
| `terminal_label` | `str` | ❌ | Terminal/POS identifier | ស្លាកស្ថានីយ |
| `static` | `bool` | ❌ | Static QR (no expiry, reusable) | QR ថេរ (គ្មានផុតកំណត់) |
| `expiration` | `int` | ❌ | Days until expiry (dynamic only) | ចំនួនថ្ងៃផុតកំណត់ |
| `watch` | `bool` | ❌ | Auto-check payment after creation | ពិនិត្យការទូទាត់ដោយស្វ័យប្រវត្តិ |

**Returns:** KHQR string | ខ្សែអក្សរ KHQR

---

### check_payment()

Check if a payment has been completed by MD5 hash.

```python
check_payment(md5: str) -> str
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `md5` | `str` | MD5 hash of the QR string |

**Returns:** `"PAID"` or `"UNPAID"` | `"PAID"` ឬ `"UNPAID"`

---

### get_payment()

Get full payment details by MD5 hash.

```python
get_payment(md5: str) -> dict | None
```

**Returns:** Payment data dictionary or `None` if unpaid.

---

### generate_deeplink()

Generate a Bakong deep link for payment redirection.

```python
generate_deeplink(
    qr: str,
    appDeepLinkCallback: str | None = None,
    appIconUrl: str = "https://bakong.nbc.gov.kh/images/logo.svg",
    appName: str = "MyAppName",
    callback: str | None = None   # Deprecated, use appDeepLinkCallback
) -> str | None
```

**Returns:** Short link or full link for payment redirection.

---

### check_account()

Verify a Bakong account exists and get its information.

```python
check_account(account_id: str) -> dict | None
```

| Parameter | Type | Description | ការពិពណ៌នា |
|-----------|------|-------------|----------------|
| `account_id` | `str` | Bakong account ID | លេខគណនី Bakong |

---

### Payment Check Methods | វិធីសាស្ត្រពិនិត្យការទូទាត់

| Method | Returns | Description | ការពិពណ៌នា |
|--------|---------|-------------|----------------|
| `check_payment_by_hash(hash)` | `"PAID"` / `"UNPAID"` | Check by transaction hash | ពិនិត្យតាមលេខសម្ងាត់ប្រតិបត្តិការ |
| `get_payment_by_hash(hash)` | `dict` / `None` | Get details by transaction hash | ទទួលព័ត៌មានតាមលេខសម្ងាត់ |
| `check_payment_by_short_hash(hash, amount, currency)` | `"PAID"` / `"UNPAID"` | Check by short hash + amount | ពិនិត្យតាមលេខសម្ងាត់ខ្លី |
| `get_payment_by_short_hash(hash, amount, currency)` | `dict` / `None` | Get details by short hash | ទទួលព័ត៌មានតាមលេខសម្ងាត់ខ្លី |
| `check_payment_by_instruction_ref(ref)` | `"PAID"` / `"UNPAID"` | Check by instruction ref | ពិនិត្យតាមលេខយោង |
| `check_payment_by_external_ref(ref)` | `"PAID"` / `"UNPAID"` | Check by external ref | ពិនិត្យតាមលេខយោងខាងក្រៅ |

---

### Bulk Check Methods | វិធីសាស្ត្រពិនិត្យច្រើនក្នុងពេលតែមួយ

```python
check_bulk_payments(md5_list: list[str]) -> list[str]
check_bulk_payments_by_hash(hash_list: list[str]) -> list[str]
```

- Maximum 50 items per request | អតិបរមា 50 ក្នុងមួយសំណើ
- Returns list of paid MD5s/hashes | ត្រឡប់បញ្ជី MD5/hash ដែលបានបង់ប្រាក់

---

### QR Image Generation | ការបង្កើតរូបភាព QR

```python
qr_image(
    qr: str,
    format: str = "png",
    output_path: str | None = None
) -> str | bytes
```

| Format | Output | ទម្រង់ |
|--------|--------|--------|
| `"png"` | File path to PNG | រូបភាព PNG |
| `"jpeg"` / `"jpg"` | File path to JPEG | រូបភាព JPEG |
| `"webp"` | File path to WebP | រូបភាព WebP |
| `"bytes"` | Raw bytes | ទិន្នន័យឆៅ |
| `"base64"` | Base64 string | ខ្សែអក្សរ Base64 |
| `"base64_uri"` | Data URI string | ខ្សែអក្សរ Data URI |

> **Note:** Requires `pip install "bakong-v2[image]"` | តម្រូវឱ្យដំឡើង `bakong-v2[image]`

---

## 🔧 Advanced Usage | ការប្រើប្រាស់កម្រិតខ្ពស់

### Static QR (No Amount)

For QR codes without a fixed amount (customer enters amount):

```python
qr = khqr.create_qr(
    bank_account="shop@aclb",
    merchant_name="My Shop",
    merchant_city="Phnom Penh",
    amount=0,           # ≤ 0 creates a static QR
    currency="USD",
    static=True,        # Force static mode
)
```

### Generate QR Image

```python
# Generate QR image
path = khqr.qr_image(qr, format="png", output_path="payment_qr.png")
print(f"QR saved to: {path}")

# Get base64 data URI
data_uri = khqr.qr_image(qr, format="base64_uri")
print(f'<img src="{data_uri}" />')
```

### Bulk Payment Checking

```python
md5_list = ["md5_1", "md5_2", "md5_3", ...]
paid = khqr.check_bulk_payments(md5_list)
print(f"Paid transactions: {paid}")
```

### Custom Deep Link

```python
link = khqr.generate_deeplink(
    qr=qr,
    appDeepLinkCallback="https://myapp.com/payment/confirm",
    appIconUrl="https://myapp.com/logo.png",
    appName="MyBusiness",
)
```

---

## ⚠️ Error Handling | ការគ្រប់គ្រងកំហុស

**English**

The package raises `ValueError` for various error conditions:

```python
from bakong_v2 import KHQR

khqr = KHQR()

# Missing token
try:
    khqr.check_payment("some_md5")
except ValueError as e:
    print(e)  # "Token is required. Get yours at https://t.me/KHQRNotificationBot"

# Invalid MD5
try:
    khqr = KHQR("your_token")
    status = khqr.check_payment("invalid_md5")
except ValueError as e:
    print(f"API Error: {e}")

# Network issues (auto-retries 2 times)
try:
    info = khqr.get_payment("some_md5")
except ValueError as e:
    print(f"Failed after retries: {e}")
```

**Common errors | កំហុសទូទៅ:**

| Error | Cause | មូលហេតុ |
|-------|-------|----------|
| `Token is required` | Missing token | ខ្វះថូខឹន |
| `API error (40x): ...` | Invalid parameters | ប៉ារ៉ាម៉ែត្រមិនត្រឹមត្រូវ |
| `API took too long` | Network timeout | បណ្តាញយឺត |
| `Failed to connect` | Network error | បញ្ហាបណ្តាញ |

---

## 📄 License | អាជ្ញាប័ណ្ណ

MIT © 2026 [Lim Visa](https://github.com/limvisa168)

---

<p align="center">
  <sub>
    Powered by <a href="https://bakong-v2.vercel.app">BakongV2 API</a> |
    ដំណើរការដោយ <a href="https://bakong-v2.vercel.app">BakongV2 API</a>
  </sub>
  <br/>
  <sub>
    Get your token: <a href="https://t.me/KHQRNotificationBot">@KHQRNotificationBot</a> |
    ទទួលបានថូខឹន៖ <a href="https://t.me/KHQRNotificationBot">@KHQRNotificationBot</a>
  </sub>
</p>
