Langsung ke konten utama

GitHub Repository

Selesaikan boilerplate FastAPI + Dodo Payments

Ikhtisar

Boilerplate FastAPI menyediakan titik awal yang siap produksi untuk mengintegrasikan Dodo Payments dengan backend Python Anda. Template ini mencakup penanganan sesi checkout, verifikasi webhook, integrasi portal pelanggan, dan pola API async untuk membantu Anda mulai menerima pembayaran dengan cepat.
Boilerplate ini menggunakan FastAPI dengan pola async/await, Pydantic untuk validasi, dan dodopayments Python SDK untuk integrasi API yang mulus.

Fitur

  • Pengaturan Cepat - Mulai dalam waktu kurang dari 5 menit
  • Dukungan Async - Dibangun dengan pola async/await asli FastAPI
  • Sesi Checkout - Alur checkout yang sudah dikonfigurasi menggunakan Python SDK
  • Penanganan Webhook - Titik akhir webhook yang aman dengan verifikasi tanda tangan
  • Portal Pelanggan - Pembuatan sesi portal pelanggan yang mudah
  • Keamanan Tipe - Validasi Pydantic penuh dan petunjuk tipe
  • Konfigurasi Lingkungan - Pengaturan variabel lingkungan siap pakai

Prasyarat

Sebelum Anda mulai, pastikan Anda memiliki:
  • Python 3.9+ (disarankan: Python 3.11+)
  • pip atau uv untuk manajemen paket
  • Akun Dodo Payments (untuk mengakses API dan Kunci Webhook dari dasbor)

Memulai dengan Cepat

1

Clone the Repository

git clone https://github.com/dodopayments/fastapi-boilerplate.git
cd fastapi-boilerplate
2

Create Virtual Environment

Siapkan lingkungan Python terisolasi:
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
Atau menggunakan uv untuk manajemen ketergantungan yang lebih cepat:
uv venv
source .venv/bin/activate
3

Install Dependencies

pip install -r requirements.txt
Atau dengan uv:
uv pip install -r requirements.txt
4

Get API Credentials

Daftar di Dodo Payments dan dapatkan kredensial Anda dari dasbor:
Pastikan Anda dalam Mode Uji saat mengembangkan!
5

Configure Environment Variables

Buat file .env di direktori root:
cp .env.example .env
Perbarui nilai dengan kredensial Dodo Payments Anda:
.env
DODO_PAYMENTS_API_KEY=your_api_key_here
DODO_PAYMENTS_WEBHOOK_KEY=your_webhook_signing_key_here
DODO_PAYMENTS_ENVIRONMENT=test_mode
Jangan pernah meng-commit file .env ke kontrol versi. File tersebut sudah termasuk di .gitignore.
6

Run the Development Server

uvicorn main:app --reload
Buka http://localhost:8000/docs untuk melihat dokumentasi API interaktif!
Anda harus melihat UI Swagger FastAPI dengan semua endpoint yang tersedia siap untuk diuji.

Struktur Proyek

fastapi-boilerplate/
├── main.py                 # FastAPI application entry point
├── routers/
│   ├── checkout.py         # Checkout session endpoints
│   ├── webhook.py          # Webhook handler endpoint
│   └── customer_portal.py  # Customer portal endpoints
├── config.py               # Environment configuration
├── requirements.txt        # Python dependencies
├── .env.example            # Environment template
└── README.md

Endpoint API

Boilerplate ini mencakup endpoint yang sudah dikonfigurasi sebagai berikut:
EndpointMetodeDeskripsi
/checkoutPOSTCreate a new checkout session
/webhookPOSTHandle Dodo Payments webhooks
/customer-portalPOSTGenerate customer portal URL

Contoh Kode

Membuat Sesi Checkout

from fastapi import APIRouter, HTTPException
from dodopayments import AsyncDodoPayments
from pydantic import BaseModel
from config import settings

router = APIRouter()
dodo = AsyncDodoPayments(
    bearer_token=settings.DODO_PAYMENTS_API_KEY,
    environment=settings.DODO_PAYMENTS_ENVIRONMENT
)

class CheckoutRequest(BaseModel):
    product_id: str
    quantity: int = 1
    customer_email: str | None = None
    customer_name: str | None = None

@router.post("/checkout")
async def create_checkout(request: CheckoutRequest):
    try:
        session = await dodo.checkout_sessions.create(
            product_cart=[{
                "product_id": request.product_id,
                "quantity": request.quantity
            }],
            customer={
                "email": request.customer_email,
                "name": request.customer_name
            } if request.customer_email else None,
            return_url="http://localhost:8000/success"
        )
        return {"checkout_url": session.url, "session_id": session.session_id}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))

Menangani Webhook

from fastapi import APIRouter, Request, HTTPException
import hmac
import hashlib
from config import settings

router = APIRouter()

def verify_webhook_signature(payload: bytes, signature: str) -> bool:
    expected = hmac.new(
        settings.DODO_PAYMENTS_WEBHOOK_KEY.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

@router.post("/webhook")
async def handle_webhook(request: Request):
    payload = await request.body()
    signature = request.headers.get("webhook-signature", "")
    
    if not verify_webhook_signature(payload, signature):
        raise HTTPException(status_code=401, detail="Invalid signature")
    
    event = await request.json()
    event_type = event.get("type")
    
    match event_type:
        case "payment.succeeded":
            # Handle successful payment
            payment_id = event["data"]["payment_id"]
            print(f"Payment succeeded: {payment_id}")
            
        case "subscription.active":
            # Handle subscription activation
            subscription_id = event["data"]["subscription_id"]
            print(f"Subscription activated: {subscription_id}")
            
        case "refund.succeeded":
            # Handle refund
            refund_id = event["data"]["refund_id"]
            print(f"Refund processed: {refund_id}")
    
    return {"status": "received"}

Integrasi Portal Pelanggan

from fastapi import APIRouter, HTTPException
from dodopayments import AsyncDodoPayments
from pydantic import BaseModel
from config import settings

router = APIRouter()
dodo = AsyncDodoPayments(
    bearer_token=settings.DODO_PAYMENTS_API_KEY,
    environment=settings.DODO_PAYMENTS_ENVIRONMENT
)

class PortalRequest(BaseModel):
    customer_id: str

@router.post("/customer-portal")
async def create_portal_session(request: PortalRequest):
    try:
        session = await dodo.customers.create_customer_portal(
            customer_id=request.customer_id
        )
        return {"portal_url": session.url}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))

Peristiwa Webhook

Boilerplate ini menunjukkan penanganan peristiwa webhook umum:
AcaraDeskripsi
payment.succeededPembayaran berhasil diselesaikan
payment.failedUpaya pembayaran gagal
subscription.activeLangganan sekarang aktif
subscription.cancelledLangganan dibatalkan
refund.succeededPengembalian dana berhasil diproses
Tambahkan logika bisnis Anda di dalam penangan webhook untuk:
  • Memperbarui izin pengguna di database Anda
  • Mengirim email konfirmasi
  • Menyediakan akses ke produk digital
  • Melacak analitik dan metrik

Menguji Webhook Secara Lokal

Untuk pengembangan lokal, gunakan alat seperti ngrok untuk mengekspos server lokal Anda:
ngrok http 8000
Perbarui URL webhook di Dasbor Dodo Payments Anda:
https://your-ngrok-url.ngrok.io/webhook

Penyebaran

Docker

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Bangun dan jalankan:
docker build -t fastapi-dodo .
docker run -p 8000:8000 --env-file .env fastapi-dodo

Pertimbangan Produksi

Sebelum melakukan deploy ke produksi:
  • Switch DODO_PAYMENTS_ENVIRONMENT ke live_mode
  • Gunakan kunci API produksi dari dasbor
  • Perbarui URL webhook ke domain produksi Anda
  • Aktifkan HTTPS untuk semua endpoint

Pemecahan Masalah

Pastikan lingkungan virtual Anda diaktifkan dan dependensi telah diinstal:
source venv/bin/activate
pip install -r requirements.txt
Penyebab umum:
  • ID produk tidak valid - verifikasi bahwa itu ada di dasbor Dodo Anda
  • Kunci API atau pengaturan lingkungan yang salah di .env
  • Periksa log FastAPI untuk pesan kesalahan yang lebih rinci
Untuk pengujian lokal, gunakan ngrok untuk mengekspos server Anda:
ngrok http 8000
Perbarui URL webhook di dasbor Dodo Anda ke URL ngrok. Pastikan untuk memperbarui file .env Anda dengan kunci verifikasi webhook yang benar.
  • Pastikan DODO_PAYMENTS_WEBHOOK_KEY sudah diatur dengan benar di .env Anda
  • Verifikasi bahwa Anda menggunakan tubuh permintaan mentah untuk verifikasi tanda tangan
  • Periksa bahwa Anda membaca header webhook-signature dengan benar

Pelajari Lebih Lanjut

Dukungan

Butuh bantuan dengan boilerplate?