Integrate Notch Pay into your Python applications
pip install notchpay
from notchpay import NotchPay
# Initialize with your API key
notchpay = NotchPay('YOUR_PUBLIC_KEY')
# For endpoints requiring advanced authentication
notchpay.set_grant_key('YOUR_PRIVATE_KEY')
try:
payment = notchpay.payments.create({
'amount': 5000,
'currency': 'XAF',
'customer': {
'email': 'customer@example.com',
'name': 'John Doe'
},
'reference': 'order_123',
'callback': 'https://example.com/callback',
'description': 'Payment for Order #123'
})
# Redirect to the payment page
print(f"Redirect to: {payment.authorization_url}")
except Exception as e:
print(f"Error: {str(e)}")
try:
reference = 'order_123'
payment = notchpay.payments.retrieve(reference)
if payment.transaction.status == 'complete':
# Payment is complete, fulfill the order
print('Payment complete!')
else:
# Payment is not complete
print(f"Payment status: {payment.transaction.status}")
except Exception as e:
print(f"Error: {str(e)}")
try:
payments = notchpay.payments.list({
'limit': 10,
'page': 1,
'status': 'complete'
})
for payment in payments.items:
print(f"{payment.reference}: {payment.amount} {payment.currency}")
except Exception as e:
print(f"Error: {str(e)}")
try:
# Set grant key for transfers
notchpay.set_grant_key('YOUR_PRIVATE_KEY')
transfer = notchpay.transfers.create({
'amount': 5000,
'currency': 'XAF',
'beneficiary': {
'name': 'John Doe',
'phone': '+237600000000'
},
'description': 'Salary payment',
'reference': 'transfer_123'
})
print(f"Transfer created: {transfer.transaction.id}")
except Exception as e:
print(f"Error: {str(e)}")
try:
# Set grant key for balance
notchpay.set_grant_key('YOUR_PRIVATE_KEY')
balance = notchpay.balance.retrieve()
print('Available balance:')
for currency, amount in balance.balance.available.items():
print(f"{currency}: {amount}")
except Exception as e:
print(f"Error: {str(e)}")
pip install notchpay
# settings.py
NOTCHPAY_API_KEY = 'YOUR_PUBLIC_KEY'
NOTCHPAY_GRANT_KEY = 'YOUR_PRIVATE_KEY'
NOTCHPAY_WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET'
# views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.conf import settings
import json
import hmac
import hashlib
from notchpay import NotchPay
# Initialize the SDK
notchpay = NotchPay(settings.NOTCHPAY_API_KEY)
def create_payment(request):
if request.method == 'POST':
try:
amount = int(request.POST.get('amount', 0))
email = request.POST.get('email', '')
name = request.POST.get('name', '')
if amount < 100 or not email:
return render(request, 'payment_form.html', {
'error': 'Invalid amount or email'
})
payment = notchpay.payments.create({
'amount': amount,
'currency': 'XAF',
'customer': {
'email': email,
'name': name
},
'reference': f"django_order_{int(time.time())}",
'callback': request.build_absolute_uri('/payment/callback/'),
'description': 'Payment from Django app'
})
# Redirect to the payment page
return redirect(payment.authorization_url)
except Exception as e:
return render(request, 'payment_form.html', {
'error': str(e)
})
return render(request, 'payment_form.html')
def payment_callback(request):
reference = request.GET.get('reference', '')
if not reference:
return render(request, 'payment_error.html', {
'error': 'No reference provided'
})
try:
payment = notchpay.payments.retrieve(reference)
if payment.transaction.status == 'complete':
# Payment is complete, fulfill the order
return render(request, 'payment_success.html', {
'payment': payment.transaction
})
else:
# Payment is not complete
return render(request, 'payment_failed.html', {
'payment': payment.transaction
})
except Exception as e:
return render(request, 'payment_error.html', {
'error': str(e)
})
def verify_webhook_signature(payload, signature, secret):
computed_signature = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed_signature, signature)
@csrf_exempt
@require_POST
def webhook_handler(request):
payload = request.body.decode('utf-8')
signature = request.headers.get('X-Notchpay-Signature', '')
if not verify_webhook_signature(payload, signature, settings.NOTCHPAY_WEBHOOK_SECRET):
return JsonResponse({'error': 'Invalid signature'}, status=401)
event = json.loads(payload)
# Process the event based on its type
event_type = event.get('type', '')
if event_type == 'payment.complete':
# Handle completed payment
payment = event.get('data', {})
# Update order status, send confirmation email, etc.
print(f"Payment {payment.get('reference')} completed")
elif event_type == 'payment.failed':
# Handle failed payment
payment = event.get('data', {})
# Update order status, notify customer, etc.
print(f"Payment {payment.get('reference')} failed")
# Handle other event types...
return JsonResponse({'status': 'success'})
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('payment/create/', views.create_payment, name='create_payment'),
path('payment/callback/', views.payment_callback, name='payment_callback'),
path('webhooks/notchpay/', views.webhook_handler, name='webhook_handler'),
]
<!-- payment_form.html -->
<!DOCTYPE html>
<html>
<head>
<title>Make a Payment</title>
</head>
<body>
<h1>Make a Payment</h1>
{% if error %}
<div class="error">
{{ error }}
</div>
{% endif %}
<form method="post">
{% csrf_token %}
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="amount">Amount (XAF):</label>
<input type="number" id="amount" name="amount" min="100" required>
</div>
<button type="submit">Pay Now</button>
</form>
</body>
</html>
<!-- payment_success.html -->
<!DOCTYPE html>
<html>
<head>
<title>Payment Successful</title>
</head>
<body>
<h1>Payment Successful!</h1>
<p>Thank you for your payment of {{ payment.amount }} {{ payment.currency }}</p>
<p>Reference: {{ payment.reference }}</p>
<a href="/">Return to Home</a>
</body>
</html>
<!-- payment_failed.html -->
<!DOCTYPE html>
<html>
<head>
<title>Payment Failed</title>
</head>
<body>
<h1>Payment Failed</h1>
<p>Status: {{ payment.status }}</p>
<p>Reference: {{ payment.reference }}</p>
<a href="/">Return to Home</a>
</body>
</html>
<!-- payment_error.html -->
<!DOCTYPE html>
<html>
<head>
<title>Payment Error</title>
</head>
<body>
<h1>Payment Error</h1>
<p>{{ error }}</p>
<a href="/">Return to Home</a>
</body>
</html>
pip install notchpay flask
from flask import Flask, request, render_template, redirect, url_for, jsonify
import time
import hmac
import hashlib
import json
from notchpay import NotchPay
app = Flask(__name__)
# Initialize the SDK
notchpay = NotchPay('YOUR_PUBLIC_KEY')
WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET'
@app.route('/')
def index():
return render_template('payment_form.html')
@app.route('/payment/create', methods=['POST'])
def create_payment():
try:
amount = int(request.form.get('amount', 0))
email = request.form.get('email', '')
name = request.form.get('name', '')
if amount < 100 or not email:
return render_template('payment_form.html', error='Invalid amount or email')
payment = notchpay.payments.create({
'amount': amount,
'currency': 'XAF',
'customer': {
'email': email,
'name': name
},
'reference': f"flask_order_{int(time.time())}",
'callback': url_for('payment_callback', _external=True),
'description': 'Payment from Flask app'
})
# Redirect to the payment page
return redirect(payment.authorization_url)
except Exception as e:
return render_template('payment_form.html', error=str(e))
@app.route('/payment/callback')
def payment_callback():
reference = request.args.get('reference', '')
if not reference:
return render_template('payment_error.html', error='No reference provided')
try:
payment = notchpay.payments.retrieve(reference)
if payment.transaction.status == 'complete':
# Payment is complete, fulfill the order
return render_template('payment_success.html', payment=payment.transaction)
else:
# Payment is not complete
return render_template('payment_failed.html', payment=payment.transaction)
except Exception as e:
return render_template('payment_error.html', error=str(e))
def verify_webhook_signature(payload, signature, secret):
computed_signature = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed_signature, signature)
@app.route('/webhooks/notchpay', methods=['POST'])
def webhook_handler():
payload = request.data.decode('utf-8')
signature = request.headers.get('X-Notchpay-Signature', '')
if not verify_webhook_signature(payload, signature, WEBHOOK_SECRET):
return jsonify({'error': 'Invalid signature'}), 401
event = json.loads(payload)
# Process the event based on its type
event_type = event.get('type', '')
if event_type == 'payment.complete':
# Handle completed payment
payment = event.get('data', {})
# Update order status, send confirmation email, etc.
app.logger.info(f"Payment {payment.get('reference')} completed")
elif event_type == 'payment.failed':
# Handle failed payment
payment = event.get('data', {})
# Update order status, notify customer, etc.
app.logger.info(f"Payment {payment.get('reference')} failed")
# Handle other event types...
return jsonify({'status': 'success'})
if __name__ == '__main__':
app.run(debug=True)
templates
folder:
<!-- templates/payment_form.html -->
<!DOCTYPE html>
<html>
<head>
<title>Make a Payment</title>
</head>
<body>
<h1>Make a Payment</h1>
{% if error %}
<div class="error">
{{ error }}
</div>
{% endif %}
<form action="{{ url_for('create_payment') }}" method="post">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="amount">Amount (XAF):</label>
<input type="number" id="amount" name="amount" min="100" required>
</div>
<button type="submit">Pay Now</button>
</form>
</body>
</html>
payment_success.html
, payment_failed.html
, and payment_error.html
as shown in the Django example.
pip install notchpay fastapi uvicorn
from fastapi import FastAPI, Request, Form, Header, HTTPException, Depends
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from typing import Optional
import time
import hmac
import hashlib
import json
from notchpay import NotchPay
app = FastAPI()
templates = Jinja2Templates(directory="templates")
app.mount("/static", StaticFiles(directory="static"), name="static")
# Initialize the SDK
notchpay = NotchPay('YOUR_PUBLIC_KEY')
WEBHOOK_SECRET = 'YOUR_WEBHOOK_SECRET'
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse("payment_form.html", {"request": request})
@app.post("/payment/create")
async def create_payment(
request: Request,
amount: int = Form(...),
email: str = Form(...),
name: str = Form(...)
):
try:
if amount < 100 or not email:
return templates.TemplateResponse(
"payment_form.html",
{"request": request, "error": "Invalid amount or email"}
)
payment = notchpay.payments.create({
'amount': amount,
'currency': 'XAF',
'customer': {
'email': email,
'name': name
},
'reference': f"fastapi_order_{int(time.time())}",
'callback': f"{request.url_for('payment_callback')}",
'description': 'Payment from FastAPI app'
})
# Redirect to the payment page
return RedirectResponse(payment.authorization_url, status_code=303)
except Exception as e:
return templates.TemplateResponse(
"payment_form.html",
{"request": request, "error": str(e)}
)
@app.get("/payment/callback", response_class=HTMLResponse)
async def payment_callback(request: Request, reference: Optional[str] = None):
if not reference:
return templates.TemplateResponse(
"payment_error.html",
{"request": request, "error": "No reference provided"}
)
try:
payment = notchpay.payments.retrieve(reference)
if payment.transaction.status == 'complete':
# Payment is complete, fulfill the order
return templates.TemplateResponse(
"payment_success.html",
{"request": request, "payment": payment.transaction}
)
else:
# Payment is not complete
return templates.TemplateResponse(
"payment_failed.html",
{"request": request, "payment": payment.transaction}
)
except Exception as e:
return templates.TemplateResponse(
"payment_error.html",
{"request": request, "error": str(e)}
)
def verify_webhook_signature(payload: bytes, signature: str, secret: str):
computed_signature = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed_signature, signature)
@app.post("/webhooks/notchpay")
async def webhook_handler(
request: Request,
x_notchpay_signature: Optional[str] = Header(None)
):
payload = await request.body()
if not x_notchpay_signature or not verify_webhook_signature(
payload, x_notchpay_signature, WEBHOOK_SECRET
):
raise HTTPException(status_code=401, detail="Invalid signature")
event = json.loads(payload)
# Process the event based on its type
event_type = event.get('type', '')
if event_type == 'payment.complete':
# Handle completed payment
payment = event.get('data', {})
# Update order status, send confirmation email, etc.
print(f"Payment {payment.get('reference')} completed")
elif event_type == 'payment.failed':
# Handle failed payment
payment = event.get('data', {})
# Update order status, notify customer, etc.
print(f"Payment {payment.get('reference')} failed")
# Handle other event types...
return {"status": "success"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
notchpay.payments.create(data)
- Create a paymentnotchpay.payments.retrieve(reference)
- Retrieve a paymentnotchpay.payments.list(params)
- List paymentsnotchpay.payments.cancel(reference)
- Cancel a paymentnotchpay.transfers.create(data)
- Create a transfernotchpay.transfers.retrieve(reference)
- Retrieve a transfernotchpay.transfers.list(params)
- List transfersnotchpay.transfers.cancel(reference)
- Cancel a transfernotchpay.transfers.create_bulk(data)
- Create a bulk transfernotchpay.customers.create(data)
- Create a customernotchpay.customers.retrieve(id)
- Retrieve a customernotchpay.customers.update(id, data)
- Update a customernotchpay.customers.list(params)
- List customersnotchpay.customers.delete(id)
- Delete a customernotchpay.beneficiaries.create(data)
- Create a beneficiarynotchpay.beneficiaries.retrieve(id)
- Retrieve a beneficiarynotchpay.beneficiaries.update(id, data)
- Update a beneficiarynotchpay.beneficiaries.list(params)
- List beneficiariesnotchpay.beneficiaries.delete(id)
- Delete a beneficiarynotchpay.balance.retrieve()
- Check balancenotchpay.balance.retrieve_currency(currency)
- Check balance for a specific currencynotchpay.balance.history(params)
- List balance historynotchpay.webhooks.create(data)
- Create a webhooknotchpay.webhooks.retrieve(id)
- Retrieve a webhooknotchpay.webhooks.update(id, data)
- Update a webhooknotchpay.webhooks.list(params)
- List webhooksnotchpay.webhooks.delete(id)
- Delete a webhookfrom notchpay.exceptions import (
NotchPayError, ValidationError, AuthenticationError, APIError
)
try:
payment = notchpay.payments.create({
# Payment data
})
except ValidationError as e:
# Handle validation errors
errors = e.errors
for field, messages in errors.items():
print(f"{field}: {', '.join(messages)}")
except AuthenticationError as e:
# Handle authentication errors
print(f"Authentication error: {str(e)}")
except APIError as e:
# Handle API errors
print(f"API error: {str(e)}")
print(f"Error code: {e.code}")
except NotchPayError as e:
# Handle other Notch Pay errors
print(f"Notch Pay error: {str(e)}")
except Exception as e:
# Handle other errors
print(f"Error: {str(e)}")
from notchpay import AsyncNotchPay
# Initialize the async SDK
notchpay = AsyncNotchPay('YOUR_PUBLIC_KEY')
async def create_payment_async():
try:
payment = await notchpay.payments.create({
'amount': 5000,
'currency': 'XAF',
'customer': {
'email': 'customer@example.com'
},
'reference': 'order_123'
})
return payment
except Exception as e:
print(f"Error: {str(e)}")
return None
Was this page helpful?