The official Python SDK for secure digital payments, EDAHABIA / CIB transactions, utility bill payments, and telecom recharges in Algeria.
pip install sofizpay-sdk-pythonimport asyncio
from sofizpay import SofizPayClient
async def main():
# Production mode (default)
client = SofizPayClient()
# Or Sandbox mode for testing:
# client = SofizPayClient(is_sandbox=True)
# Send direct wallet payment (DZT)
result = await client.send_payment(
source_secret='YOUR_SECRET_KEY',
destination_public_key='RECIPIENT_PUBLIC_KEY',
amount='100',
memo='Payment description'
)
print('Payment sent!' if result.get('successful') else result.get('error'))
asyncio.run(main())- 💳 CIB & EDAHABIA Gateway - Accept bank card and postal card payments with full 3D Secure, Webhooks, and Sandbox testing.
- 🔍 CIB Transaction Status Check - Real-time verification of CIB/EDAHABIA payment status.
- ⚡ Send Secure Payments - Instant DZT wallet digital transactions on Stellar network.
- 💰 Account Balance - Real-time balance checking for DZT.
- 📜 Transaction History & Search - Complete transaction history and memo/hash searching.
- 📡 Real-time Streaming - Live transaction monitoring with customizable intervals.
- 🛍️ Products Catalog - Browse available products, gaming vouchers, and telecom packages.
- 🧾 Utility Bill Payments - Pay Sonelgaz, ADE (water), and Algérie Télécom bills programmatically.
- 📱 Mobile & Internet Top-ups - Flexy (Mobilis, Djezzy, Ooredoo) and IDOOM (ADSL / 4G LTE).
- 🎮 Gaming Credits - Instant top-ups for PUBG UC, Free Fire Diamonds, and more.
- 🔐 Digital Signature Verification - Verify cryptographic RSA SHA-256 signatures from SofizPay callbacks.
- 🌐 Multi-platform - Fully asynchronous with async/await support across Linux, Windows, macOS.
| Method | Description | Example |
|---|---|---|
make_cib_transaction(data) |
Create CIB / EDAHABIA payment link | await client.make_cib_transaction({...}) |
make_sandbox_cib_transaction(data) |
Create Sandbox CIB payment link | await client.make_sandbox_cib_transaction({...}) |
check_cib_transaction(data) |
Check CIB transaction status | await client.check_cib_transaction('order_id') |
check_cib_status(cib_id) |
Production CIB status check | await client.check_cib_status('2517039448') |
check_sandbox_cib_status(cib_id) |
Sandbox CIB status check | await client.check_sandbox_cib_status('40a11881...') |
send_payment(secret, dest, amount, memo) |
Send DZT Stellar payment | await client.send_payment(...) |
get_balance(public_key) |
Get DZT account balance | await client.get_balance('GXXX...') |
get_transactions(public_key, limit) |
Get transaction history | await client.get_transactions('GXXX...', 50) |
search_transactions_by_memo(pk, memo, limit) |
Search transactions by memo | await client.search_transactions_by_memo('GXXX...', 'Order #1') |
get_transaction_by_hash(hash) |
Find transaction by hash | await client.get_transaction_by_hash('abc123...') |
setup_transaction_stream(pk, cb, from_now) |
Stream live transactions | await client.setup_transaction_stream('GXXX...', cb) |
stop_transaction_stream(stream_id) |
Stop live stream | client.stop_transaction_stream(stream_id) |
get_products(encrypted_sk, search) |
Browse products catalog | await client.get_products('SXXX', search='PUBG') |
get_operation_history(encrypted_sk, limit) |
View service operations history | await client.get_operation_history('SXXX') |
get_operation_details(id, encrypted_sk) |
Operation status tracking | await client.get_operation_details('UUID', 'SXXX') |
pay_ade_bill(data) |
Pay ADE water bill | await client.pay_ade_bill({...}) |
pay_sonelgaz_bill(data) |
Pay Sonelgaz electricity/gas | await client.pay_sonelgaz_bill({...}) |
pay_algerie_telecom_bill(data) |
Pay Algérie Télécom bill | await client.pay_algerie_telecom_bill({...}) |
recharge_phone(data) |
Flexy mobile credit | await client.recharge_phone({...}) |
recharge_internet(data) |
IDOOM ADSL / 4G recharge | await client.recharge_internet({...}) |
recharge_game(data) |
PUBG / Free Fire recharge | await client.recharge_game({...}) |
verify_signature(data) |
Verify RSA SHA-256 webhook | SofizPayClient.verify_signature({...}) |
Generate a secure payment URL to accept CIB or EDAHABIA payments with 3D Secure support, webhook callbacks, and sandbox testing.
import asyncio
from sofizpay import SofizPayClient
async def create_payment():
client = SofizPayClient()
response = await client.make_cib_transaction({
'account': 'GDNS27ISCGOIJFXC6CM4O5SVHVJPSWR42QEBWUFF24N5VVHGW73ZSJNQ', # Your Sofizpay receiving account
'amount': 1500, # Amount in DZD
'full_name': 'Ahmed Ben Ali', # Customer name
'phone': '+213555123456', # Customer phone
'email': 'ahmed.benali@example.com', # Customer email
'return_url': 'https://mystore.com/payment-callback', # Redirect URL after checkout
'webhook_url': 'https://mystore.com/api/cib-webhook', # Real-time async webhook URL
'invoice_id': 'INV-2026-001', # Optional invoice ID
'language': 'ar', # 'ar' | 'en' | 'fr'
'memo': 'Order #12345', # Payment note (max 28 bytes)
'redirect': 'yes', # 'yes' | 'no'
'keep_return_url': 'True', # Include signed callback params
'is_sandbox': False # Set True for Sandbox testing
})
if response.get('success'):
print('Payment URL:', response.get('payment_url'))
print('Transaction ID:', response.get('transaction_id'))
print('CIB Transaction ID:', response.get('cib_transaction_id'))
# Redirect customer to response['payment_url']
else:
print('Failed to initiate payment:', response.get('error'))
asyncio.run(create_payment())# Creates a CIB transaction directly in the Sandbox environment
sandbox_res = await client.make_sandbox_cib_transaction({
'account': 'GDNS27ISCGOIJFXC6CM4O5SVHVJPSWR42QEBWUFF24N5VVHGW73ZSJNQ',
'amount': 150.0,
'full_name': 'Sandbox Tester',
'phone': '0661000000',
'email': 'sandbox@sofizpay.com',
'memo': 'Python Sandbox Test'
})
print('Sandbox Payment URL:', sandbox_res.get('payment_url'))Verify the payment status of an order after the customer completes payment on the SATIM payment page.
# Query by order number / CIB transaction ID
check = await client.check_cib_transaction({
'order_number': '2517039448',
'is_sandbox': False # Set True if checking a sandbox transaction
})
if check.get('success') and check.get('status') == 'paid':
print(f"Order {check.get('order_number')} was successfully paid! Amount: {check.get('amount')} DZD")
else:
print('Payment status:', check.get('status'), check.get('error_message'))# Check status in Production
prod_status = await client.check_cib_status('2517039448')
# Check status in Sandbox
sandbox_status = await client.check_sandbox_cib_status('40a11881d8764fe9a371')For maximum security, store the cib_transaction_id in your database server-side and verify status before fulfilling orders:
# 1. Server initiates transaction
result = await client.make_cib_transaction({
'account': 'YOUR_PUBLIC_KEY',
'amount': 5000,
'full_name': 'Customer Name',
'phone': '0555000000',
'email': 'customer@example.com',
'memo': 'Order #9921'
})
if result.get('success'):
cib_id = result.get('cib_transaction_id')
# Save cib_id to database linked to order #9921
# db.orders.update_one({'id': 9921}, {'$set': {'cib_id': cib_id}})
payment_url = result.get('payment_url')
# 2. When customer returns or webhook triggers, verify server-side:
status = await client.check_cib_status(cib_id)
if status.get('success') and status.get('status') == 'paid':
# Mark order as PAID in database and dispatch goods
passRetrieve available products and services with their prices in DZT, with optional search filtering.
# Get all available products
catalog = await client.get_products('YOUR_SECRET_KEY')
print(f"Available products count: {catalog.get('count')}")
for product in catalog.get('products', []):
print(f"{product.get('name')}: {product.get('price')} DZT")
# Search for specific products (e.g., PUBG, Free Fire, Mobilis)
search_result = await client.get_products({
'encrypted_sk': 'YOUR_SECRET_KEY',
'search': 'PUBG'
})
print('Found products:', search_result.get('products'))Pay Algerian utility bills directly via the Python SDK:
ade_payment = await client.pay_ade_bill({
'encrypted_sk': 'YOUR_SECRET_KEY',
'amount': 2500,
'bill': '0123456789' # Bill reference number
})
if ade_payment.get('success'):
print('ADE Bill Paid! Operation ID:', ade_payment.get('operation_id'))sonelgaz_payment = await client.pay_sonelgaz_bill({
'encrypted_sk': 'YOUR_SECRET_KEY',
'amount': 3500,
'customerId': 'CUST-100234', # Customer ID
'ebb': 'EBB-987654', # EBB Number
'bill': 'BILL-456789' # Bill Number
})
if sonelgaz_payment.get('success'):
print('Sonelgaz Bill Paid! Operation ID:', sonelgaz_payment.get('operation_id'))telecom_payment = await client.pay_algerie_telecom_bill({
'encrypted_sk': 'YOUR_SECRET_KEY',
'amount': 2000,
'phone': '021234567', # Landline or subscription number
'bill': 'BILL-00129'
})flexy = await client.recharge_phone({
'encrypted_sk': 'YOUR_SECRET_KEY',
'phone': '0661234567',
'operator': 'djezzy', # 'mobilis' | 'djezzy' | 'ooredoo'
'amount': 500,
'offer': 'prepaid'
})internet = await client.recharge_internet({
'encrypted_sk': 'YOUR_SECRET_KEY',
'phone': '0458230823', # 10 digits for 4G, 9 digits for ADSL
'operator': 'idoom',
'amount': 1000,
'offer': 'IDOOM 4G 1000' # e.g. 'IDOOM 4G 1000' or 'IDOOM ADSL 2000'
})game = await client.recharge_game({
'encrypted_sk': 'YOUR_SECRET_KEY',
'operator': 'pubg', # 'pubg' | 'freefire'
'playerId': '5123456789', # Player in-game ID
'amount': 1200,
'offer': '60' # '60' | '325' | '660' for PUBG, '110' | '210' for Free Fire
})# Get details of a specific operation
details = await client.get_operation_details({
'operation_id': '550e8400-e29b-41d4-a716-446655440000',
'encrypted_sk': 'YOUR_SECRET_KEY'
})
# Get operation history
history = await client.get_operation_history('YOUR_SECRET_KEY', limit=10, offset=0)
print('Recent Operations:', history.get('data'))Verify webhook callbacks signed with RSA SHA-256:
from fastapi import FastAPI, Request, HTTPException
from sofizpay import SofizPayClient
app = FastAPI()
@app.post("/api/cib-webhook")
async def cib_webhook(request: Request):
payload = await request.json()
message = payload.get("message")
signature = payload.get("signature_url_safe")
is_valid = SofizPayClient.verify_signature({
"message": message,
"signature_url_safe": signature
})
if not is_valid:
raise HTTPException(status_code=400, detail="Invalid signature")
# Process authentic payment confirmation
return {"status": "success", "received": True}# Get DZT balance
balance = await client.get_balance('GDNS27ISCGOIJFXC6CM4O5SVHVJPSWR42QEBWUFF24N5VVHGW73ZSJNQ')
print('Balance:', balance)
# Search transactions by memo
search_res = await client.search_transactions_by_memo(
'GDNS27ISCGOIJFXC6CM4O5SVHVJPSWR42QEBWUFF24N5VVHGW73ZSJNQ',
'Order #12345',
limit=50
)
print('Search Results:', search_res.get('transactions'))
# Real-time transaction streaming
def handle_tx(tx):
print('Live Payment Received:', tx.get('amount'), tx.get('memo'), tx.get('from'))
stream_id = await client.setup_transaction_stream(
'GDNS27ISCGOIJFXC6CM4O5SVHVJPSWR42QEBWUFF24N5VVHGW73ZSJNQ',
handle_tx,
from_now=True,
check_interval=30
)
# Later, stop stream:
client.stop_transaction_stream(stream_id)SofizPay provides a mock testing environment to test CIB / EDAHABIA payments without real cards:
Set is_sandbox=True in SofizPayClient(is_sandbox=True) or pass 'is_sandbox': True to make_cib_transaction / check_cib_transaction.
| Card Number | Expiry | CVV | Expected Result |
|---|---|---|---|
6280581001234567 |
12/28 |
123 |
Approved |
6280581009876543 |
12/29 |
456 |
Approved |
6280581005555555 |
06/28 |
999 |
Declined by issuer |
6280581004444444 |
09/28 |
444 |
Insufficient funds |
6280581003333333 |
03/21 |
333 |
Expired card |
6280581002222222 |
11/28 |
222 |
Timeout |
Sandbox OTP: Use
123456for any test transaction.
- Protect Secret Keys: Never hardcode secret keys in frontend or public code. Always use environment variables (
os.environ.get('SOFIZPAY_SECRET_KEY')). - Verify Webhooks: Always use
SofizPayClient.verify_signature()to validate incoming webhook payloads before updating database records. - Check Status Server-side: When a customer returns to your
return_url, verify the transaction usingcheck_cib_transaction()from your server before granting access or fulfilling orders.
MIT © SofizPay Team
Built with ❤️ for Algerian Fintech | docs.sofizpay.com
