Python SDK
Official Python SDK for PayGate.
Python SDK
The official Python SDK for PayGate provides a convenient way to access the PayGate API from Python applications.
Requirements: Python 3.8 or later.
Installation
pip install paygate-pythonpoetry add paygate-pythonpipenv install paygate-pythonQuick Start
import paygate
client = paygate.Client('sk_test_...')
# Create a payment
payment = client.payments.create(
amount=5000,
currency='GHS',
payment_method='mobile_money',
provider='mtn',
phone='0241234567'
)
print(payment.id)Configuration
API Key
import os
import paygate
# Using environment variable (recommended)
client = paygate.Client(os.environ['PAYGATE_SECRET_KEY'])
# Or pass directly
client = paygate.Client('sk_test_...')Options
client = paygate.Client(
api_key='sk_test_...',
# API version (defaults to latest)
api_version='2024-01-01',
# Request timeout in seconds (default: 30)
timeout=60,
# Maximum retries for failed requests (default: 3)
max_retries=5,
# Custom base URL (for testing)
base_url='https://api.sandbox.paygate.com.gh'
)Payments
Create a Payment
payment = client.payments.create(
amount=5000,
currency='GHS',
payment_method='mobile_money',
provider='mtn',
phone='0241234567',
description='Order #1234',
metadata={
'order_id': '1234',
'customer_email': 'customer@example.com'
}
)Retrieve a Payment
payment = client.payments.retrieve('pay_abc123')List Payments
# Get a page of payments
payments = client.payments.list(limit=10, status='succeeded')
# Iterate through all payments
for payment in client.payments.list():
print(payment.id)Cancel a Payment
payment = client.payments.cancel('pay_abc123')Customers
Create a Customer
customer = client.customers.create(
email='customer@example.com',
name='John Doe',
phone='0241234567',
metadata={'user_id': '123'}
)Update a Customer
customer = client.customers.update('cus_abc123',
name='Jane Doe'
)List Customers
customers = client.customers.list(limit=10)Subscriptions
Create a Subscription
subscription = client.subscriptions.create(
customer='cus_abc123',
plan='plan_xyz789',
payment_method={
'type': 'mobile_money',
'phone': '0241234567',
'provider': 'mtn'
}
)Cancel a Subscription
# Cancel at period end
client.subscriptions.update('sub_abc123',
cancel_at_period_end=True
)
# Cancel immediately
client.subscriptions.cancel('sub_abc123')Webhooks
Verify Webhook Signature
from flask import Flask, request
import paygate
app = Flask(__name__)
endpoint_secret = 'whsec_...'
@app.route('/webhooks', methods=['POST'])
def webhook():
payload = request.data
signature = request.headers.get('X-PayGate-Signature')
try:
event = paygate.Webhook.construct_event(
payload, signature, endpoint_secret
)
except ValueError as e:
# Invalid payload
return 'Invalid payload', 400
except paygate.SignatureVerificationError as e:
# Invalid signature
return 'Invalid signature', 400
# Handle the event
if event['type'] == 'payment.succeeded':
payment = event['data']['object']
print(f"Payment {payment['id']} succeeded!")
elif event['type'] == 'payment.failed':
print('Payment failed')
return {'received': True}
if __name__ == '__main__':
app.run(port=3000)Django Example
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
import paygate
endpoint_secret = 'whsec_...'
@csrf_exempt
@require_POST
def webhook(request):
payload = request.body
signature = request.headers.get('X-PayGate-Signature')
try:
event = paygate.Webhook.construct_event(
payload, signature, endpoint_secret
)
except (ValueError, paygate.SignatureVerificationError):
return HttpResponse(status=400)
if event['type'] == 'payment.succeeded':
payment = event['data']['object']
# Handle successful payment
pass
return JsonResponse({'received': True})Error Handling
import paygate
from paygate.errors import (
PayGateError,
AuthenticationError,
InvalidRequestError,
PaymentError,
RateLimitError,
APIError
)
client = paygate.Client('sk_test_...')
try:
payment = client.payments.create(
amount=5000,
currency='GHS',
payment_method='mobile_money',
provider='mtn',
phone='0241234567'
)
except AuthenticationError as e:
print('Check your API key')
except InvalidRequestError as e:
print(f'Invalid parameter: {e.param}')
print(f'Message: {e.message}')
except PaymentError as e:
if e.code == 'insufficient_funds':
print('Please top up your account')
elif e.code == 'phone_unreachable':
print('Please check your phone')
else:
print(e.message)
except RateLimitError:
import time
time.sleep(60)
# Retry
except APIError as e:
print(f'PayGate server error: {e.message}')
except PayGateError as e:
print(f'Error: {e.message}')Error Types
| Type | Description |
|---|---|
AuthenticationError | Invalid API key |
InvalidRequestError | Invalid parameters |
PaymentError | Payment-specific error |
RateLimitError | Too many requests |
APIError | Server error |
Async Support
The SDK supports async/await with aiohttp:
import asyncio
import paygate
async def main():
client = paygate.AsyncClient('sk_test_...')
# Create a payment
payment = await client.payments.create(
amount=5000,
currency='GHS',
payment_method='mobile_money',
provider='mtn',
phone='0241234567'
)
print(payment.id)
# List payments
async for payment in client.payments.list():
print(payment.id)
asyncio.run(main())Idempotency
Use idempotency keys to safely retry requests:
payment = client.payments.create(
amount=5000,
currency='GHS',
payment_method='mobile_money',
provider='mtn',
phone='0241234567',
idempotency_key='order_1234_payment'
)Type Hints
The SDK includes full type hints for IDE support:
from paygate import Client
from paygate.types import Payment, Customer
client = Client('sk_test_...')
# Types are automatically inferred
payment: Payment = client.payments.create(
amount=5000,
currency='GHS',
payment_method='mobile_money',
provider='mtn',
phone='0241234567'
)
# IDE autocompletion works
print(payment.status) # 'pending' | 'processing' | 'succeeded' | 'failed'Pagination
Handle paginated results:
# Auto-pagination (recommended)
for payment in client.payments.list(status='succeeded'):
print(payment.id)
# Manual pagination
page = client.payments.list(limit=10)
while True:
for payment in page.data:
print(payment.id)
if not page.has_more:
break
page = client.payments.list(
limit=10,
starting_after=page.data[-1].id
)Invoices
Create an Invoice
invoice = client.invoices.create(
customer='cus_abc123',
items=[
{'description': 'Consulting Services', 'amount': 50000},
{'description': 'Development Work', 'amount': 150000}
],
due_date='2024-02-15',
metadata={'project': 'Website Redesign'}
)Send an Invoice
# Send invoice via email/SMS
client.invoices.send('inv_abc123')Pay an Invoice
# Mark invoice as paid
client.invoices.pay('inv_abc123',
payment_method={
'type': 'mobile_money',
'phone': '0241234567',
'provider': 'mtn'
}
)List Invoices
invoices = client.invoices.list(status='open', limit=10)
for invoice in invoices:
print(f"{invoice.id}: {invoice.amount_due / 100} {invoice.currency}")Coupons
Create a Coupon
# Percentage discount
coupon = client.coupons.create(
code='SAVE20',
type='percent',
percent_off=20,
duration='repeating',
duration_in_months=3,
max_redemptions=100
)
# Fixed amount discount
coupon = client.coupons.create(
code='FLAT50',
type='amount',
amount_off=5000, # 50 GHS in pesewas
currency='GHS',
duration='once'
)Validate a Coupon
try:
validation = client.coupons.validate('SAVE20')
if validation.valid:
print(f"Discount: {validation.percent_off}%")
except paygate.InvalidRequestError:
print("Coupon is invalid or expired")List Coupons
coupons = client.coupons.list(limit=10)
for coupon in coupons:
print(f"{coupon.code}: {coupon.times_redeemed}/{coupon.max_redemptions}")QR Codes
Create a Static QR Code
# Create a reusable payment QR code
qr_code = client.qr_codes.create(
type='static',
name='Store Counter QR',
description='Scan to pay at checkout'
)
print(f"QR Image URL: {qr_code.image_url}")Create a Dynamic QR Code
# Create a QR code for a specific payment
qr_code = client.qr_codes.create(
type='dynamic',
amount=5000,
currency='GHS',
description='Order #1234',
expires_in=3600 # 1 hour
)
print(f"QR Image URL: {qr_code.image_url}")Retrieve QR Code Status
qr_code = client.qr_codes.retrieve('qr_abc123')
print(f"Status: {qr_code.status}")
print(f"Times Used: {qr_code.times_used}")Reports
Generate a Report
report = client.reports.create(
type='payments_summary',
parameters={
'start_date': '2024-01-01',
'end_date': '2024-01-31',
'group_by': 'day'
},
format='csv'
)
print(f"Report ID: {report.id}")Retrieve Report Status
import time
report = client.reports.retrieve('report_abc123')
while report.status == 'pending':
time.sleep(5)
report = client.reports.retrieve('report_abc123')
if report.status == 'ready':
print(f"Download URL: {report.download_url}")Available Report Types
# Supported report types
report_types = [
'payments_summary',
'payouts_summary',
'settlements',
'disputes',
'customers',
'subscriptions',
'revenue'
]Events
List Events
# Get recent events
events = client.events.list(limit=20)
for event in events:
print(f"{event.type}: {event.id}")
# Filter by type
payment_events = client.events.list(
type='payment.succeeded',
limit=10
)Retrieve an Event
event = client.events.retrieve('evt_abc123')
print(f"Type: {event.type}")
print(f"Data: {event.data}")Event Types
Common event types include:
payment.createdpayment.succeededpayment.failedpayout.createdpayout.succeededcustomer.createdsubscription.createdsubscription.cancelledinvoice.createdinvoice.paiddispute.createddispute.closed
Settings
Settlement Schedule
# Get current settlement schedule
schedule = client.settings.get_settlement_schedule()
print(f"Frequency: {schedule.frequency}")
print(f"Day of week: {schedule.day_of_week}")
# Update settlement schedule
schedule = client.settings.update_settlement_schedule(
frequency='weekly',
day_of_week='friday'
)Transaction Limits
# Get current limits
limits = client.settings.get_transaction_limits()
print(f"Min: {limits.min_amount}")
print(f"Max: {limits.max_amount}")
print(f"Daily: {limits.daily_limit}")
# Update limits
limits = client.settings.update_transaction_limits(
min_amount=100, # 1 GHS
max_amount=10000000, # 100,000 GHS
daily_limit=50000000 # 500,000 GHS
)Two-Factor Authentication
Setup 2FA
# Generate 2FA secret and QR code
setup = client.auth.setup_2fa()
print(f"Secret: {setup.secret}")
print(f"QR Code URL: {setup.qr_code_url}")
# Display QR code to user for scanning with authenticator appEnable 2FA
# Verify and enable 2FA
result = client.auth.enable_2fa(
code='123456' # Code from authenticator app
)
if result.enabled:
print("2FA enabled successfully")
print(f"Backup codes: {result.backup_codes}")Verify 2FA Code
# Verify a 2FA code
result = client.auth.verify_2fa(code='123456')
if result.valid:
print("Code is valid")Disable 2FA
# Disable 2FA (requires current code)
client.auth.disable_2fa(code='123456')Regenerate Backup Codes
# Get new backup codes
result = client.auth.regenerate_backup_codes(code='123456')
print(f"New backup codes: {result.backup_codes}")