Nellika SCB Payment Integration - Hardened C Module (Commercial License Required)
Project description
nell-scb-lib
Python C extension for SCB (Siam Commercial Bank) payment integration with PromptPay QR code generation.
⚠️ IMPORTANT LICENSING INFORMATION
This software is subject to commercial licensing terms and usage fees.
- This library requires a valid commercial license for production use
- Usage telemetry data is collected and transmitted to Nellika Consulting Services Ltd.
- By installing and using this library, you agree to the collection and transmission of usage telemetry
- For licensing inquiries and pricing information, please contact: sales@nellika.co.th
Copyright © 2024 Nellika Consulting Services Ltd. All rights reserved.
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
pip install nell-scb-lib
Supported Platforms:
- Linux x86_64 (manylinux_2_31+)
- macOS ARM64 (Apple Silicon M1/M2/M3/M4)
- Python 3.9 through 3.14
Telemetry & Privacy
This library collects the following telemetry data:
- License key usage and validation events
- API operation counts (QR creation, token refresh, payment checks)
- Error rates and types
- Library version and platform information
- No sensitive data (API keys, secrets, transaction details, or customer information) is collected
Telemetry helps us:
- Monitor license compliance
- Improve library stability and performance
- Provide better support to our customers
By using this library, you consent to this data collection.
For questions about data collection or to request data deletion, contact: privacy@nellika.co.th
Quick Start
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:
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_for_invoice(invoice_id, company_id, config_id, reference, amount, bank_account_id)
Smart Intent Caching - Create SCB QR code for invoices with automatic caching. Returns cached QR if intent already exists (prevents duplicate API calls).
Parameters:
invoice_id(int): Invoice ID fromaccount.movecompany_id(int): Company IDconfig_id(int): SCB API configuration IDreference(str): Payment reference (e.g. "I202500096")amount(float): Payment amount in THBbank_account_id(str): Bank account ID fromres.partner.bank
Returns: dict - Intent data with QR
{
"intent_id": 35,
"reference": "I202500096",
"amount": 11.77,
"qr_payload": "00020101021230...",
"qr_image_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
"transaction_id": "202512047YrL0GYH1tAUC0t",
"status": "pending",
"channel": "invoice"
}
Example:
import nell_scb_lib
result = nell_scb_lib.create_qr_for_invoice(
invoice_id=118,
company_id=1,
config_id=1,
reference="I202500096",
amount=11.77,
bank_account_id="1"
)
print(f"Intent: {result['intent_id']}, QR: {result['qr_payload'][:50]}...")
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 fromres.partner.bankamount(float): Payment amount in THBref1(str): Reference 1, max 20 charactersref2(str): Reference 2, max 12 charactersref3(str, optional): Reference 3, defaults to "SCB"
Returns: dict - SCB API response
{
"status": {"code": 1000, "description": "Success"},
"data": {
"qrRawData": "00020101021230...",
"qrImage": "iVBORw0KGgoAAAANSUhEUgAA...",
"transactionId": "..."
}
}
Example:
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 keyaccess_token(str): Valid OAuth tokenqr_create_url(str): SCB QR endpoint URLbiller_id(str): PromptPay biller IDamount(float): Payment amount in THBref1(str): Reference 1, max 20 charactersref2(str): Reference 2, max 12 charactersref3(str, optional): Reference 3, defaults to "SCB"
Returns: dict - SCB API response
Example:
# Step 1: Get access token using config ID
token_resp = nell_scb_lib.refresh_token(config_id=1)
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(config_id)
Refresh SCB OAuth access token using config ID. Automatically fetches API credentials from database and determines token URL based on environment.
Parameters:
config_id(int): SCB API configuration ID fromscb_api_configtable
Returns: dict - Token response
{
"status": {"code": 1000, "description": "Success"},
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 1800,
"tokenType": "Bearer"
}
}
Example:
result = nell_scb_lib.refresh_token(config_id=1)
if result['status']['code'] == 1000:
token = result['data']['accessToken']
payment_inquiry(config_id, transaction_ref=None, biller_id=None, reference1=None, reference2=None, amount=None, transaction_date=None)
Check SCB payment status via payment inquiry API. Supports both Tag 31 (transaction ID) and Tag 30 (reference) inquiry modes.
Parameters:
config_id(int): SCB API configuration IDtransaction_ref(str, optional): Transaction reference for Tag 31 inquirybiller_id(str, optional): PromptPay biller ID for Tag 30 inquiryreference1(str, optional): Reference 1 for Tag 30 inquiryreference2(str, optional): Reference 2 for Tag 30 inquiryamount(str, optional): Payment amount for Tag 30 inquirytransaction_date(str, optional): Transaction date (YYYY-MM-DD)
Returns: dict - Payment inquiry response
{
"status": {"code": 1000, "description": "Success"},
"data": {
"paymentStatus": "PAID",
"transactionId": "202512143idG583rgs8s5ps",
"amount": "100.00",
"billPaymentRef1": "P00001"
}
}
Example:
# Tag 31 inquiry (by transaction ID)
result = nell_scb_lib.payment_inquiry(
config_id=1,
transaction_ref="202512143idG583rgs8s5ps"
)
# Tag 30 inquiry (by reference)
result = nell_scb_lib.payment_inquiry(
config_id=1,
biller_id="010555555555555",
reference1="P00001",
amount="100.00"
)
Low-Level API (Legacy)
create_qr(config_id, amount, reference, channel="ecomm")
Deprecated - Use create_qr_by_bank_account() or create_qr_for_invoice() instead.
Create QR code using config ID from database.
Parameters:
config_id(str): SCB API configuration IDamount(float): Payment amountreference(str): Payment referencechannel(str, optional): Payment channel ("pos", "ecomm", "invoice")
Returns: str - JSON string (not dict)
check_payment(reference)
Deprecated - Use payment_inquiry() instead for better control and error handling.
Check SCB payment status by reference.
Parameters:
reference(str): Payment reference to check
Returns: str - JSON string (not dict)
version()
Get module version string.
Returns: str - Version (e.g., "1.6.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 (v1.2.0+)
All functions return dicts with status and data keys. Check status.code to determine success/failure.
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 - use the data
qr_image = result['data']['qrImage']
transaction_id = result['data']['transactionId']
print(f"QR created: {transaction_id}")
else:
# Error - check the code and description
error_code = result['status']['code']
error_msg = result['status']['description']
print(f"Error {error_code}: {error_msg}")
# Handle specific errors
if error_code == 5114:
print("Incorrect biller ID - check your bank account configuration")
elif error_code in [9001, 9002]:
print("Database connection issue - check environment variables")
elif error_code == 9003:
print("SCB configuration not found for this bank account")
Response Status Codes
Success Codes (1xxx)
1000: Success
SCB API Errors (5xxx)
These are errors returned directly from SCB's API:
5114: Incorrect biller ID - verify PromptPay biller ID in database- Other 5xxx codes: See SCB API documentation
System Errors (9xxx)
Database Errors (90xx):
9001: Database environment variables not configured9002: Failed to connect to database9003: No SCB configuration found for bank account9004: Invalid SCB API configuration (missing required fields)
Network Errors (91xx):
9101: Network error connecting to SCB token endpoint9102: Network error connecting to SCB QR endpoint9103: HTTP error from SCB API (see description for details)
Authentication Errors (93xx):
9301: Failed to refresh SCB access token9302: Token refresh failed with HTTP error
Always check the status code:
if result['status']['code'] == 1000:
# Process successful response
qr_data = result['data']
else:
# Handle error - log or display to user
error_code = result['status']['code']
error_msg = result['status']['description']
# Example: Raise user-friendly error in Odoo
if error_code in [5114, 9003, 9004]:
# Configuration error - show to admin
raise UserError(f"SCB Configuration Error: {error_msg}")
else:
# System error - log it
_logger.error(f"SCB API error {error_code}: {error_msg}")
Best Practices
-
Use High-Level API:
- Invoices: Use
create_qr_for_invoice()for automatic caching - POS/Ecommerce: Use
create_qr_by_bank_account() - Avoid legacy
create_qr()andcheck_payment()
- Invoices: Use
-
Validate References: Keep ref1 ≤ 20 chars, ref2 ≤ 12 chars
-
Check Status Codes: Always verify
status.code == 1000before using data -
Payment Status: Use
payment_inquiry()for checking payment status:- Better error handling
- Supports both Tag 30 and Tag 31 inquiry
- Automatic token refresh and retry on 401
-
Handle Errors: Check status codes and handle errors gracefully
-
Environment Setup: Configure PostgreSQL environment variables before use
Features
- ✅ Native C implementation for high performance
- ✅ Smart Intent Caching for invoices (prevents duplicate QR codes)
- ✅ Automatic OAuth token management with retry on 401
- ✅ Database-driven configuration (PostgreSQL)
- ✅ PromptPay QR code generation
- ✅ Payment inquiry API (Tag 30 and Tag 31)
- ✅ Thread-safe operations
- ✅ Secure API communication (libcurl + OpenSSL)
- ✅ Built-in license management
- ✅ Usage telemetry for compliance and support
Changelog
See CHANGELOG.md for detailed version history.
Latest Releases
v1.6.0 (2024-12-24)
- 🔴 BREAKING:
refresh_token()signature changed to useconfig_idinstead of raw credentials - Enhanced security: API URLs and credentials now hidden from Python code
- Consistency: All C library functions use same pattern (IDs, not credentials)
- Simplified usage:
refresh_token(config_id=1)instead of passing api_key, api_secret, token_url - Migration: Old code using 3 parameters needs update to pass single config_id
v1.3.0 (2024-12-03)
- 🆕 Payment Inquiry API: New
payment_inquiry()function for checking payment status - Support for both Tag 30 and Tag 31 inquiry modes
- Automatic token caching and refresh for payment inquiry
- URL computation centralized in C library based on environment
v1.2.4 (2024-12-02)
- ⚡ PERFORMANCE: Automatic token caching in database
- Reduces token refresh API calls by ~95% (~30/day instead of ~100+/day)
- Token management now completely abstracted in C library
- Faster QR generation (no auth overhead when token is cached)
v1.2.3 (2024-12-02)
- 🔴 CRITICAL FIX: Corrected SCB config selection when multiple configs exist
- Fixed "Incorrect biller Id" errors (SCB 5114)
- Added detailed logging for Bank ID, Config ID, Biller ID
Support & Contact
- Sales & Licensing: sales@nellika.co.th
- Technical Support: support@nellika.co.th
- Privacy Inquiries: privacy@nellika.co.th
- Website: https://nellika.co.th
Legal
Copyright © 2024 Nellika Consulting Services Ltd. All rights reserved.
This software is proprietary and confidential. Unauthorized copying, distribution, or use of this software, via any medium, is strictly prohibited without prior written permission from Nellika Consulting Services Ltd.
For licensing terms and conditions, please contact sales@nellika.co.th
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nell_scb_lib-1.6.1-cp314-cp314-macosx_14_0_arm64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp314-cp314-macosx_14_0_arm64.whl
- Upload date:
- Size: 4.5 MB
- Tags: CPython 3.14, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e8801d45f54f32d9e6016f0e05f34d24796ce305591f5a3fe83b8b7ca187da3
|
|
| MD5 |
36eb45e4b495429c7b6745806ed8e38b
|
|
| BLAKE2b-256 |
a5db45e7180611b025cba846acd8dabaf1a4ebce8c8baee378563668867a6648
|
File details
Details for the file nell_scb_lib-1.6.1-cp313-cp313-macosx_14_0_arm64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp313-cp313-macosx_14_0_arm64.whl
- Upload date:
- Size: 4.5 MB
- Tags: CPython 3.13, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5e19758ad2aab1c3bd9440e733c0eca509d400543ce2952c886d6a5492e4056
|
|
| MD5 |
2e698b18aec3f46633d6c1d411755ae2
|
|
| BLAKE2b-256 |
cac2f38fca9c2096205a34bc203532697d4c397ed4dfe3b3cb0fa0e853400405
|
File details
Details for the file nell_scb_lib-1.6.1-cp312-cp312-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp312-cp312-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 7.3 MB
- Tags: CPython 3.12, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58c8f056488779a43dc9a7de5e07b1ef8ed7d4386b953d0d67e1ee068eb60386
|
|
| MD5 |
438d4c145f6de0501238f368fbc3d149
|
|
| BLAKE2b-256 |
7ebcbb6de2c32d695d73e552ffc0b14145d154d7407f0504ed700515edc8bbdd
|
File details
Details for the file nell_scb_lib-1.6.1-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 7.0 MB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
008abb03268877c0c9ef1e75d06ffe92123ead6e6e15c97eb6d64ffc631ffdf5
|
|
| MD5 |
0aeece979e56f2a7e366718f7632f1c1
|
|
| BLAKE2b-256 |
b9f9a69f9fa131e2e27542e2093021b867d98867bf4c3e67dbee164a2b755a27
|
File details
Details for the file nell_scb_lib-1.6.1-cp312-cp312-macosx_14_0_arm64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp312-cp312-macosx_14_0_arm64.whl
- Upload date:
- Size: 4.5 MB
- Tags: CPython 3.12, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
efacddd372c296d09d28cbd847fa7c1adffd40323bcddd3cb140c836c9968602
|
|
| MD5 |
2cbc60fc12acf3ba16c62bcd3ce5ea81
|
|
| BLAKE2b-256 |
8c1196c59765cb428baa461de25413dbb4b9af1062d5a6a1750471596d9fd576
|
File details
Details for the file nell_scb_lib-1.6.1-cp311-cp311-macosx_14_0_arm64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp311-cp311-macosx_14_0_arm64.whl
- Upload date:
- Size: 4.5 MB
- Tags: CPython 3.11, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4c10b04f9cb2b32331db9b788f8d12a4374ab7f3fd26afacc5947d158f8f0d6
|
|
| MD5 |
6500a88c8209ace15e07bfdaba7abd85
|
|
| BLAKE2b-256 |
439de65ef24802e66994fff87c0dba190e3b85e5647fdb729df7378d8767fb3c
|
File details
Details for the file nell_scb_lib-1.6.1-cp310-cp310-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp310-cp310-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 7.0 MB
- Tags: CPython 3.10, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91a6a930fa89ebbca790b6fee240d5435889c9663abb5af0edc98c776c307ad7
|
|
| MD5 |
59be7cf5c1e8d71fee4cf81cc729103c
|
|
| BLAKE2b-256 |
e94921ef9ed2d9608408639d19be132dc86fdc15b0c4eef2bcb09abe150dccf6
|
File details
Details for the file nell_scb_lib-1.6.1-cp310-cp310-macosx_14_0_arm64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp310-cp310-macosx_14_0_arm64.whl
- Upload date:
- Size: 4.5 MB
- Tags: CPython 3.10, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d76ceff13e9301c6bcb37fe4da4e48e5a93eb849382c89bd059b93d9491bdaa
|
|
| MD5 |
bb6f4eafaaae0abf2b031d2357812975
|
|
| BLAKE2b-256 |
beb5184944455628bd6d7a291a3e02ab684a6981a189fc0694f02236f5edff3c
|
File details
Details for the file nell_scb_lib-1.6.1-cp39-cp39-macosx_14_0_arm64.whl.
File metadata
- Download URL: nell_scb_lib-1.6.1-cp39-cp39-macosx_14_0_arm64.whl
- Upload date:
- Size: 4.5 MB
- Tags: CPython 3.9, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a8db2dd9726b3c87b1954a30bca4e4151b687bcd09b35aea53ff894d7e4bf37
|
|
| MD5 |
5c61d4f86e8b5a7e1069ca608d4785ff
|
|
| BLAKE2b-256 |
33de5c4aae4b4bc276001b7e4d795c7f9e8d00d7bfcdedcdc6e100b6bec4b364
|