Metadata-Version: 2.4
Name: nell-scb-lib
Version: 1.0.3
Summary: Nellika SCB Payment Integration - Hardened C Module
Author: Danny G.
Author-email: "Danny G." <danny.g@nellika.co.th>
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: requires-python

# nell-scb-lib

Python C extension for SCB (Siam Commercial Bank) payment integration with PromptPay QR code generation.

## Overview

`nell-scb-lib` is a high-performance C extension module providing SCB payment integration for Python applications. It handles OAuth token management, QR code generation, and payment status checking through SCB's official API.

## Installation

```bash
pip install nell-scb-lib
```

**Supported Platforms:**
- Linux x86_64 (manylinux)
- macOS ARM64 (Apple Silicon M1/M2/M3)
- Python 3.8+

## Quick Start

```python
import nell_scb_lib

# Create QR payment (database-driven, recommended)
result = nell_scb_lib.create_qr_by_bank_account(
    bank_account_id=1,
    amount=250.75,
    ref1="P00001",      # Invoice number (max 20 chars)
    ref2="CUST001",     # Customer code (max 12 chars)
    ref3="SCB"          # Optional reference
)

if result['status']['code'] == 1000:
    qr_image = result['data']['qrImage']  # Base64 PNG
    qr_raw = result['data']['qrRawData']  # PromptPay string
    print(f"QR created: {result['data']['transactionId']}")
```

## Environment Variables

Required for database-driven methods:

```bash
export PGDATABASE=your_database
export PGHOST=localhost
export PGPORT=5432
export PGUSER=odoo
export PGPASSWORD=your_password  # optional
```

## API Reference

### High-Level API (Recommended)

#### `create_qr_by_bank_account(bank_account_id, amount, ref1, ref2, ref3="SCB")`

Create SCB QR payment code using bank account ID. Automatically fetches configuration from database and manages token refresh.

**Parameters:**
- `bank_account_id` (str/int): Bank account ID from `res.partner.bank`
- `amount` (float): Payment amount in THB
- `ref1` (str): Reference 1, max 20 characters
- `ref2` (str): Reference 2, max 12 characters  
- `ref3` (str, optional): Reference 3, defaults to "SCB"

**Returns:** `dict` - SCB API response
```python
{
    "status": {"code": 1000, "description": "Success"},
    "data": {
        "qrRawData": "00020101021230...",
        "qrImage": "iVBORw0KGgoAAAANSUhEUgAA...",
        "transactionId": "..."
    }
}
```

**Example:**
```python
result = nell_scb_lib.create_qr_by_bank_account(
    bank_account_id=1,
    amount=250.75,
    ref1="P00001",
    ref2="CUST001"
)
```

---

### Mid-Level API

#### `create_qr_full(api_key, access_token, qr_create_url, biller_id, amount, ref1, ref2, ref3="SCB")`

Create SCB QR code with explicit parameters (requires manual token management).

**Parameters:**
- `api_key` (str): SCB API key
- `access_token` (str): Valid OAuth token
- `qr_create_url` (str): SCB QR endpoint URL
- `biller_id` (str): PromptPay biller ID
- `amount` (float): Payment amount in THB
- `ref1` (str): Reference 1, max 20 characters
- `ref2` (str): Reference 2, max 12 characters
- `ref3` (str, optional): Reference 3, defaults to "SCB"

**Returns:** `dict` - SCB API response

**Example:**
```python
# Step 1: Get access token
token_resp = nell_scb_lib.refresh_token(api_key, api_secret, token_url)
access_token = token_resp['data']['accessToken']

# Step 2: Create QR
result = nell_scb_lib.create_qr_full(
    api_key="your_api_key",
    access_token=access_token,
    qr_create_url="https://api.scb/...",
    biller_id="894547854396914",
    amount=100.50,
    ref1="P00001",
    ref2="TEST"
)
```

---

#### `refresh_token(api_key, api_secret, token_url)`

Refresh SCB OAuth access token.

**Parameters:**
- `api_key` (str): SCB API key
- `api_secret` (str): SCB API secret
- `token_url` (str): Token endpoint URL

**Returns:** `dict` - Token response
```python
{
    "status": {"code": 1000, "description": "Success"},
    "data": {
        "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
        "expiresIn": 1800,
        "tokenType": "Bearer"
    }
}
```

---

### Low-Level API

#### `create_qr(config_id, amount, reference, channel="ecomm")`

Create QR code using config ID from database (legacy method).

**Parameters:**
- `config_id` (str): SCB API configuration ID
- `amount` (float): Payment amount
- `reference` (str): Payment reference
- `channel` (str, optional): Payment channel, defaults to "ecomm"

**Returns:** `dict` - SCB API response

---

#### `check_payment(reference)`

Check SCB payment status by reference.

**Parameters:**
- `reference` (str): Payment reference to check

**Returns:** `dict` - Payment status
```python
{
    "status": {"code": 1000, "description": "Success"},
    "data": {
        "paymentStatus": "SUCCESS",
        "transactionId": "...",
        "amount": 100.50
    }
}
```

---

#### `version()`

Get module version string.

**Returns:** `str` - Version (e.g., "1.0.1")

---

## Database Schema Requirements

For database-driven methods, these tables are required:

**`res_partner_bank`:**
- Column: `scb_biller_id` (VARCHAR) - PromptPay biller ID

**`scb_api_config`:**
- Columns: `api_key`, `api_secret`, `environment`, `token_url`, `qr_create_url`, `payment_inquiry_url`
- Must have active configuration record

## Error Handling

All functions raise `RuntimeError` for failures:

```python
try:
    result = nell_scb_lib.create_qr_by_bank_account(
        bank_account_id=1,
        amount=250.75,
        ref1="P00001",
        ref2="CUST001"
    )
    
    if result['status']['code'] == 1000:
        # Success
        qr_data = result['data']
    else:
        # API error
        print(f"Error: {result['status']['description']}")
        
except RuntimeError as e:
    # System error
    print(f"Failed: {e}")
```

## Response Status Codes

- `1000`: Success
- `1001`: Invalid request
- `1002`: Authentication failed
- `1003`: Insufficient balance
- `1004`: Transaction not found
- `1005`: System error

**Always check the status code:**
```python
if result['status']['code'] == 1000:
    # Process successful response
    pass
else:
    # Handle error
    error_msg = result['status']['description']
```

## Best Practices

1. **Use High-Level API**: Prefer `create_qr_by_bank_account()` for automatic configuration management
2. **Validate References**: Keep ref1 ≤ 20 chars, ref2 ≤ 12 chars
3. **Check Status Codes**: Always verify `status.code == 1000` before using data
4. **Handle Errors**: Wrap API calls in try-except blocks
5. **Environment Setup**: Configure PostgreSQL environment variables before use

## Features

- ✅ Native C implementation for high performance
- ✅ Automatic OAuth token management
- ✅ Database-driven configuration
- ✅ PromptPay QR code generation
- ✅ Payment status checking
- ✅ Thread-safe operations
- ✅ Secure API communication (libcurl)

## License

Proprietary - Nellika Consulting Services
