Using with Django & DRF
This guide shows how to integrate the Univapay-Python SDK with a typical Django + DRF stack.
Install
pip install djangorestframework
pip install -e ".[dotenv]"
Settings
Set environment variables (or use python-dotenv
in manage.py
/wsgi.py
):
UNIVAPAY_JWT=...
UNIVAPAY_SECRET=...
UNIVAPAY_STORE_ID=...
UNIVAPAY_BASE_URL=https://api.univapay.com
Client dependency
# app/univapay_client.py
from univapay import UnivapayConfig, UnivapayClient
def get_client() -> UnivapayClient:
cfg = UnivapayConfig().validate()
return UnivapayClient(cfg, retries=1, backoff_factor=0.5)
DRF views
# app/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from univapay.resources import ChargesAPI, SubscriptionsAPI
from .univapay_client import get_client
@api_view(["POST"])
def create_charge(request):
token_id = request.data.get("tokenId")
amount = int(request.data.get("amount", 0))
currency = request.data.get("currency", "jpy")
if not token_id or amount <= 0:
return Response({"error": "tokenId and amount required"}, status=status.HTTP_400_BAD_REQUEST)
client = get_client()
try:
with client as c:
charges = ChargesAPI(c)
ch = charges.create_one_time(token_id=token_id, amount=amount, currency=currency)
return Response(ch.model_dump())
finally:
client.close()
@api_view(["POST"])
def create_subscription(request):
token_id = request.data.get("tokenId")
amount = int(request.data.get("amount", 0))
currency = request.data.get("currency", "jpy")
period = request.data.get("period")
if not token_id or amount <= 0 or not period:
return Response({"error": "tokenId, amount, period required"}, status=status.HTTP_400_BAD_REQUEST)
client = get_client()
try:
with client as c:
subs = SubscriptionsAPI(c)
s = subs.create(token_id=token_id, amount=amount, period=period, currency=currency)
return Response(s.model_dump())
finally:
client.close()
Webhook view
# app/webhooks.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from univapay.resources import parse_event, WebhookVerificationError
import os
WEBHOOK_SECRET = os.getenv("UNIVAPAY_WEBHOOK_SECRET")
@api_view(["POST"])
def univapay_webhook(request):
try:
ev = parse_event(body=request.body, headers=request.headers, secret=WEBHOOK_SECRET, tolerance_s=300)
# TODO: dispatch ev.type to handlers, update DB, etc.
return Response({"ok": True, "type": ev.type})
except WebhookVerificationError as e:
return Response({"ok": False, "error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
URLs
# app/urls.py
from django.urls import path
from . import views, webhooks
urlpatterns = [
path("api/charges", views.create_charge),
path("api/subscriptions", views.create_subscription),
path("webhook/univapay", webhooks.univapay_webhook),
]
With this setup, your DRF API can accept tokens from the Univapay widget and create charges/subscriptions server-side, and receive webhook notifications.