在使用Django创建的Web应用中添加订阅功能

在网页应用中,支付功能被列为一个所需功能。
这次我们尝试使用Stripe来实现。

想要实现的目标

    Djangoにサブスクリプション機能を追加する

前提

    Djangoチュートリアルが完了していること

工作环境

    • OS

CentOS7

webサーバー

Nginx

言語

Python

フレームワーク

Django

请参考下方网站

    • Django Stripe Subscriptions

 

    Create subscriptions with Checkout

步骤

    1. 项目创建和应用程序创建

 

    1. 安装stripe

 

    1. 添加客户模型

 

    1. 创建订阅计划

 

    1. 创建结帐会话

 

    进行付款

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. 应用程序安装

将刚刚创建的计费应用程序添加到已安装的应用程序中。

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创建订阅计划。
创建计划的方法有两种。
• 命令行界面(CLI)
• 官方网站

请使用链接https://dashboard.stripe.com/test/products/create访问一个简单创建计划的官方网站,并创建您喜欢的计划。

完成之后,请记下API ID,以免忘记。
稍后会需要这个信息。

创建结帐会话。

接下来,我们将创建付款界面。
您可以从以下链接获取所需的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

将款项支付

我会启动服务器。

python manage.py runserver

当您访问此链接时,将会显示一个只有按钮的界面。
当您点击按钮时,将会跳转至Stripe提供的支付界面。

接下来需要输入用于测试的信用卡号码:4242 4242 4242 4242

然后页面会显示“成功”,并且跳转到那个页面。
这样订阅就完成了。

如果有任何问题或错误,请在评论中提出。

请参考以下网站

    • Django Stripe Subscriptions

 

    Create subscriptions with Checkout