【Stripe】顧客登録してクレジットカードを保存する方法【Django】

アイキャッチ画像
  • Stripeを用いた、顧客登録とクレジットカード保存の方法とは?
  • StripeのCustomer API・Setup Intent APIの使い方とは?

本記事ではこのような疑問を解決します。


Webアプリ開発の中でStripeを利用しているのであれば、
顧客登録をしてから、その顧客のクレジットカードを保存するという一連の処理を実装したいものです。

顧客のクレジットカードを保存できれば、
次回の支払いからは一からカード情報を入力せずに保存したカードを使用してもらうというUXを実現できます。


そこで今回はStripeを用いた、顧客登録とクレジットカード保存の方法を解説していきます。

なお、本記事ではWebフレームワークにDjangoを使用します。
(※他の言語・FWでも書き方が異なるだけで実装方法は基本的に同じです。)

顧客登録とクレジットカード保存の流れ

今回は、
「あるWebサイトにおいて会員登録を済ませたログインユーザーがクレジットカードを登録する」
という流れで話を進めていきます。

①ユーザー側:クレジットカード登録フォームにアクセスする


①開発者側:
・バックエンド(views.py)
→Customerオブジェクトを生成する

→SetupIntentオブジェクトを生成する
→SetupIntentオブジェクトに紐づいたclient secretをテンプレートへ渡す

・フロントエンド(stripe.js)
→SetupIntentオブジェクトに紐づいたclient_secretを取得する
→Stripeインスタンスを作成する
→クレジットカード入力フォームで使用するElementsを設定し、取得したclient secretを渡す
→Payment Elementを作成し、既存のDOM要素を、生成したDOM要素に置き換える

②ユーザー側:クレジットカード情報を入力し、支払い確定ボタンを押す


②開発者側:
・バックエンド(views.py)
→任意でクレジットカード情報をDBに保存する

・フロントエンド(stripe.js)
→confirmSetupでクレジットカード登録処理を完了させる

③ユーザー側:クレジットカード登録完了画面が表示される


③開発者側:
・バックエンド(views.py)
→クレジットカード登録完了ページ等を表示する

顧客登録とクレジットカード保存の実装手順

ここでは以下のDjangoプロジェクトを前提とし、顧客登録とクレジットカード保存に関係するファイルのみを操作します。

 sampleproject
 ├── sampleapp
 │   ├── __init__.py
 │   ├── admin.py
 │   ├── apps.py
 │   ├── migrations
 │   │   └── (中身省略)
 │   ├── models.py
 │   ├── tests.py
 │   └── views.py
 ├── sampleproject
 │   ├── __init__.py
 │   ├── __pycache__
 │   │   └── (中身省略)
 │   ├── asgi.py
 │   ├── settings.py
 │   ├── urls.py
 │   └── wsgi.py
 ├── templates
 │   ├── create_card.html
 │   └── thanks.html
 ├── static
 │   ├── js
 │    ├── stripe.js
 └── manage.py 

バックエンド(Django)側の設定

DjangoでのStripe初期設定をする(settings.py)

#Stripeのダッシュボードからシークレットキーとパブリックキーをコピペする
STRIPE_API_KEY = 'Stripeのシークレットキー'
STRIPE_PUBLISHABLE_KEY = 'Stripeのパブリックキー'

URLを設定する(urls.py)

#①クレジットカード入力フォームのページと②送信完了後に表示するページのURLを設定する
urlpatterns = [
    path('create_card/', views.create_card, name="create_card"),
    path('thanks/', views.thanks, name="thanks"),
]

クレジットカード入力フォームを返す処理を記述する(views.py)

まずはCustomer APIを使用して顧客データを作成します。

具体的にいうと、Customerオブジェクトの生成です。


次にSetup Intent APIを使用して、作成した顧客データの中にクレジットカード情報を格納する準備をします。

ここでは、SetupIntentオブジェクトを生成し、クレジットカード入力フォームを画面に表示するための処理を行います。

from django.conf import settings
import stripe

def create_card(request):
    user = request.user
    stripe.api_key = settings.STRIPE_API_KEY

    # Customerオブジェクト生成(引数は任意→今回はnameを指定)
    stripe_customer = stripe.Customer.create(
        name=user.username,
        )

    # SetupIntentオブジェクト生成
    setup_intent = stripe.SetupIntent.create(
        customer=stripe_customer.id,# 生成したCustomerのIDを指定
        payment_method_types=["card"],# 支払い方法→今回はクレジットカード("card")
        )

    # 作成したSetupIntentからclient_secretを取得する→テンプレートへ渡す
    context = {
        "client_secret": setup_intent.client_secret,
    }
    template_name = 'create_card.html'
    return render(request, template_name, context)

クレジットカード情報が送信された後の処理を記述する(views.py)

#単純に、クレジットカード登録完了ページを表示する処理
def thanks(request):
    template_name = "thanks.html"
    return render(request, template_name)

フロントエンド(HTML・JavaScript)側の設定

クレジットカード入力フォームのページを作成する(create_card.html)

<!DOCTYPE html>
{% load static %}
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <script src="https://js.stripe.com/v3/"></script>    
    </head>
    <body>
        <!-- inputタグでclient_secretを渡す→JavaScriptで値(value)を取得する -->
        <input type="hidden" id="client_secret" value="{{ client_secret }}">

        <!--フォームが読み込まれたら、Payment Elementのインスタンスを作成して、それをコンテナーのDOMノードにマウントする-->
        <form id="payment-form">
            <div id="payment-element">
            <!-- クレジットカード入力フォームが挿入される部分 -->
            </div>
            <div id="error-message">
            <!-- エラーが起こった場合のメッセージ -->
            </div>
            <button id="submit">登録する</button>
        </form>
        
        <script src="{% static 'js/stripe.js' %}"></script>
    </body>

クレジットカード保存後に表示するページのファイルを作成する(thanks.html)

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <p>クレジットカード登録完了</p>
    </body>

Stripe処理を行うJavaScriptファイルを作成する(stripe.js)

// JavaScriptを使用して、client secretを取得する
const client_secret = document.getElementById('client_secret').value;

// JavaScriptを使用して、Stripeのインスタンスを作成する
const stripe = Stripe('Stripeのパブリックキー');

// クレジットカード入力フォームで使用するElementsを設定し、上で取得したclient secretを渡す
const elements = stripe.elements({
    clientSecret:client_secret,
    appearance:{
        theme: 'stripe',
    },
});

// Payment Elementを作成し、既存のDOM要素から生成したDOM要素に置き換える
const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');

// id=payment-formの要素を取得する
const form = document.getElementById('payment-form');

// クレジットカード情報が送信された時の処理を記述する
form.addEventListener('submit', async (event) => {
    event.preventDefault();

    // confirmSetupを呼び出して支払い処理を完了させる
    const {error} = await stripe.confirmSetup({
        elements,
        confirmParams: {
            return_url: '支払い完了後に呼び出すURL(ここでは/thanks)',
            }
           });

    if (error) {
        const messageContainer = document.querySelector('#error-message');
        messageContainer.textContent = error.message;
    } else {
        // none
    }
});

まとめ

以上がStripeを用いた、顧客登録とクレジットカード保存の方法になります。

簡単に流れをおさらいすると、
Customer APIを使って顧客情報を作成し、Setup Intent APIで入力フォーム生成、カード情報取得を経て登録完了というプロセスです。

本記事が、少しでもStripeを用いらWebアプリ開発の手助けになれれば幸いです。


なお、今回の続きとして、こちらの記事では顧客の支払処理に保存したクレジットカードを使う方法を解説していますのでご参考にしてみてください。

関連記事

Stripeを用いて、顧客の支払処理に保存したクレジットカードを使う方法とは?StripeのCustomer API・Payment Intent APIの使い方とは? 本記事ではこのような疑問を解決します。前回こちらの記事でStr[…]

アイキャッチ画像

実務1年未満でもOK!フリーランスエンジニアの案件獲得方法はこちら!

必読

フリーランスエンジニアが案件獲得方法とは?自ら営業せずに案件を獲得するには?実務経験1年未満でも大丈夫なの? 本記事ではこのような疑問を解決します。これからフリーランスエンジニアとして独立したい方は、兎にも角にも案件の獲得が急務です[…]

アイキャッチ画像