webアプリに欲しい機能として決済機能が挙げられます。
今回はstripeで実装してみました。
実現したいこと
- Djangoにサブスクリプション機能を追加する
前提条件
- Djangoチュートリアルが完了していること
作業環境
- OS
- CentOS7
- webサーバー
- Nginx
- 言語
- Python
- フレームワーク
- Django
参考サイト
手順
- プロジェクト作成&アプリ作成
- stripeインストール
- カスタマーモデル追加
- サブスクリプションプラン作成
- チェックアウトセッション作成
- 支払いを行う
1. プロジェクト作成&アプリ作成
まずは今回使うライブラリをインストールしていきます。
ライブラリの移動がしやすいようにrequirements.txtを作成します
touch requirements.txt
今回使うライブラリを記述します。
Django==3.1.4
stripe==2.56.0
ライブラリをインストールします。
pip install -r requirements.txt
プロジェクトを作成していきます。
django_stripeはプロジェクト名ですので、なんでもいいです。
同じにした方が後々分かりやすいと思います。
django-admin startproject django_stripe
アプリを追加します。
python manage.py startapp billing #請求って意味の英単語です
ここまでの作成で作業フォルダは以下のようになります。
.
├── billing
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── admin.cpython-39.pyc
│ │ └── models.cpython-39.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── django_stripe
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── settings.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── wsgi.cpython-39.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt
2. アプリインストール
インストールドアプリに先ほど作成したbillingアプリを追加します。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'billing', #追加
]
3. カスタマーモデル追加
stripeで使うモデルを作成します。
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.utils import timezone
class User(AbstractBaseUser):
email = models.EmailField('メールアドレス', unique=True)
password = models.CharField('パスワード',max_length=30)
first_name = models.CharField('性', max_length=30)
last_name = models.CharField('名', max_length=30)
address = models.CharField('住所', max_length=30, blank=True)
tel = models.CharField('電話番号', max_length=30, blank=True)
created = models.DateTimeField('入会日',default=timezone.now)
class StripeCustomer(models.Model):
user = models.OneToOneField(to=User, on_delete=models.CASCADE)
stripeCustomerId = models.CharField(max_length=255)
stripeSubscriptionId = models.CharField(max_length=255)
def __str__(self):
return self.user.username
4. サブスクリプションプラン作成
次はstripeでサブスクリプションのプランを作成していきます。
プランの作成方法は2種類あります。
・CLI
・公式サイト
今回は作成が簡単な公式サイトからプランを作成していきます。
以下のリンクからアクセスしてお好みのプランを作成してください。
https://dashboard.stripe.com/test/products/create
作成した後はAPI IDを忘れないようにメモしておきます。
後で必要になります。
5. チェックアウトセッション作成
次は支払い画面を作成していきます。
APIに必要なキーは以下から取得できます。
https://dashboard.stripe.com/test/apikeys
# STRIPE 追加
STRIPE_PUBLIC_KEY = '公開可能キー'
STRIPE_SECRET_KEY = 'シークレットキー'
STRIPE_PRICE_ID = 'API_ID price_xxxxなやつ'
from django.shortcuts import render
from django.conf import settings
from django.http.response import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from .models import User, StripeCustomer
from django.contrib.auth.decorators import login_required
import stripe
# 設定用の処理
@csrf_exempt
def stripe_config(request):
if request.method == 'GET':
stripe_config = {'publicKey': settings.STRIPE_PUBLIC_KEY}
return JsonResponse(stripe_config, safe=False)
# 支払い画面に遷移させるための処理
@csrf_exempt
def create_checkout_session(request):
if request.method == 'GET':
domain_url = 'http://localhost:8000/billing/'
stripe.api_key = settings.STRIPE_SECRET_KEY
try:
checkout_session = stripe.checkout.Session.create(
client_reference_id=request.user.id if request.user.is_authenticated else None,
success_url=domain_url + 'success?session_id={CHECKOUT_SESSION_ID}',
cancel_url=domain_url + 'cancel/',
payment_method_types=['card'],
mode='subscription',
line_items=[
{
'price': settings.STRIPE_PRICE_ID,
'quantity': 1,
}
]
)
return JsonResponse({'sessionId': checkout_session['id']})
except Exception as e:
return JsonResponse({'error': str(e)})
# 支払いに成功した後の画面
def success(request):
return render(request, 'billing/success.html')
# 支払いに失敗した後の画面
def cancel(request):
return render(request, 'billing/cancel.html')
この処理を呼び出すためのURLを作成します。
from django.urls import path
from accounts import views
from django.contrib import admin
from billing import views
urlpatterns = [
path('', views.index, name='index'),
path('config/', views.stripe_config),
path('create-checkout-session/', views.create_checkout_session),
path('success/', views.success),
path('cancel/', views.cancel),
]
テンプレートを作成します。
{% load static %}
<head>
<title>Checkout</title>
<script src="https://js.stripe.com/v3/"></script>
<script src="{% static 'billing/js/stripe.js' %}"></script>
</head>
<body>
<button id="checkout">Subscribe</button>
</body>
success
cancel
javascriptの処理を記述します。
console.log("Sanity check!");
// Get Stripe publishable key
fetch("/billing/config/")
.then((result) => { return result.json(); })
.then((data) => {
// Initialize Stripe.js
const stripe = Stripe(data.publicKey);
// Event handler
let submitBtn = document.querySelector("#checkout");
if (submitBtn !== null) {
submitBtn.addEventListener("click", () => {
// Get Checkout Session ID
fetch("/billing/create-checkout-session/")
.then((result) => { return result.json(); })
.then((data) => {
console.log(data);
// Redirect to Stripe Checkout
return stripe.redirectToCheckout({ sessionId: data.sessionId })
})
.then((res) => {
console.log(res);
});
});
}
});
最終的なファイル構成は以下の通りです。
.
├── billing
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── admin.cpython-39.pyc
│ │ ├── models.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── views.cpython-39.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-39.pyc
│ │ └── __init__.cpython-39.pyc
│ ├── models.py
│ ├── static
│ │ └── billing
│ │ └── js
│ │ └── stripe.js #追加
│ ├── templates
│ │ └── billing
│ │ ├── cancel.html #追加
│ │ ├── index.html #追加
│ │ └── success.html #追加
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── db.sqlite3
├── django_stripe
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-39.pyc
│ │ ├── settings.cpython-39.pyc
│ │ ├── urls.cpython-39.pyc
│ │ └── wsgi.cpython-39.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt
6. 支払いを行う
サーバーを起動させます
python manage.py runserver
(http://127.0.0.1:8000/billing)
アクセスするとボタンだけの画面になります。
ボタンをクリックするとstripeが用意してくれている支払い画面に遷移します。
後はテスト用のクレジットカード番号 4242 4242 4242 4242を入力します。
するとsuccessと表示されるページに遷移します。
これでサブスクリプションが完了になります。