↓↓クリックして頂けると励みになります。
【22 | Stripe】 << 【ホーム】 >> 【24 | 配達依頼】
「core/templates/customer/payment_method.html」ファイルを編集します。
記述編集 【Desktop/crowdsource/core/templates/customer/payment_method.html】
{% extends 'customer/base.html' %}
{% load bootstrap4 %}
{% block head %}
<script src="https://js.stripe.com/v3/"></script>
<style>
.StripeElement {
height: 40px;
padding: 10px 12px;
width: 100%;
color: #32325d;
background-color: white;
/* border: 1px solid transparent; */
border: 1px solid #ced4da;
border-radius: 4px;
/* box-shadow: 0 1px 3px 0 #e6ebf1;
-webkit-transition: box-shadow 150ms ease;
transition: box-shadow 150ms ease; */
}
.StripeElement--focus {
border-color: #80bdff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, .25);
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}
</style>
{% endblock %}
{% block main %}
<b class="text-secondary">クレジットカード登録</b>
<div class="card bg-white mt-2 mb-5">
<div class="card-body">
{% if request.user.customer.stripe_payment_method_id %}
<div id="change-card" class="input-group">
<input type="text" class="form-control" disabled
value="**** **** **** {{ request.user.customer.stripe_card_last4 }}">
<div class="input-group-append">
<form method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-danger">カード登録削除</button>
</form>
</div>
</div>
{% else %}
<form id="setup-form" data-secret="{{ client_secret }}">
<div id="card-element"></div>
<button id="card-button" class="btn btn-danger mt-3" type="button">
カード登録
</button>
</form>
{% endif %}
</div>
</div>
<script>
var stripe = Stripe("{{ STRIPE_API_PUBLIC_KEY }}");
var elements = stripe.elements();
var cardElement = elements.create('card');
cardElement.mount('#card-element');
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var clientSecret = "{{ client_secret }}";
cardButton.addEventListener('click', function (ev) {
stripe.confirmCardSetup(
clientSecret,
{
payment_method: {
card: cardElement,
},
}
).then(function (result) {
if (result.error) {
// Display error.message in your UI.
toast(result.error.message, 'error');
} else {
toast("クレジットカードが登録されました。", 'success');
window.location.reload();
// The setup has succeeded. Display a success message.
}
});
});
</script>
{% endblock %}
「core/customer/views.py」ファイルを編集します。
記述編集 【Desktop/crowdsource/core/customer/views.py】
import firebase_admin from firebase_admin import credentials, auth import stripe from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.urls import reverse from core.customer import forms from django.contrib import messages from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth import update_session_auth_hash from django.conf import settings cred = credentials.Certificate(settings.FIREBASE_ADMIN_CREDENTIAL) firebase_admin.initialize_app(cred) stripe.api_key = settings.STRIPE_API_SECRET_KEY @login_required() def home(request): return redirect(reverse('customer:profile')) @login_required(login_url="/sign-in/?next=/customer/") def profile_page(request): user_form = forms.BasicUserForm(instance=request.user) customer_form = forms.BasicCustomerForm(instance=request.user.customer) password_form = PasswordChangeForm(request.user) if request.method == "POST": if request.POST.get('action') == 'update_profile': user_form = forms.BasicUserForm(request.POST, instance=request.user) customer_form = forms.BasicCustomerForm(request.POST, request.FILES, instance=request.user.customer) if user_form.is_valid() and customer_form.is_valid(): user_form.save() customer_form.save() messages.success(request, 'プロフィールが更新されました。') return redirect(reverse('customer:profile')) elif request.POST.get('action') == 'update_password': password_form = PasswordChangeForm(request.user, request.POST) if password_form.is_valid(): user = password_form.save() update_session_auth_hash(request, user) messages.success(request, 'パスワードが更新されました。') return redirect(reverse('customer:profile')) elif request.POST.get('action') == 'update_phone': # Get Firebase user data firebase_user = auth.verify_id_token(request.POST.get('id_token')) request.user.customer.phone_number = firebase_user['phone_number'] request.user.customer.save() messages.success(request, '電話番号が更新されました。') return redirect(reverse('customer:profile')) return render(request, 'customer/profile.html', { "user_form": user_form, "customer_form": customer_form, "password_form": password_form, }) @login_required(login_url="/sign-in/?next=/customer/") def payment_method_page(request): current_customer = request.user.customer # Save stripe customer infor if not current_customer.stripe_customer_id: customer = stripe.Customer.create() current_customer.stripe_customer_id = customer['id'] current_customer.save() # Get Stripe payment method stripe_payment_methods = stripe.PaymentMethod.list( customer = current_customer.stripe_customer_id, type = "card", ) print(stripe_payment_methods) if stripe_payment_methods and len(stripe_payment_methods.data) > 0: payment_method = stripe_payment_methods.data[0] current_customer.stripe_payment_method_id = payment_method.id current_customer.stripe_card_last4 = payment_method.card.last4 current_customer.save() else: current_customer.stripe_payment_method_id = "" current_customer.stripe_card_last4 = "" current_customer.save() intent = stripe.SetupIntent.create( customer = current_customer.stripe_customer_id ) return render(request, 'customer/payment_method.html', { "client_secret": intent.client_secret, "STRIPE_API_PUBLIC_KEY": settings.STRIPE_API_PUBLIC_KEY, })
これでクレジットカード登録ができるようになりました。
テストカード「4242 4242 4242 4242」を登録して試します。
http://127.0.0.1:8000/customer/payment_method/
StripeIDとカードの下4桁が登録されているのがわかります。

Stripeにも顧客情報が登録されました。

カード削除ボタンを実装していきます。
「core/templates/customer/payment_method.html」ファイルを編集します。
記述編集 【Desktop/crowdsource/core/templates/customer/payment_method.html】
{% extends 'customer/base.html' %}
{% load bootstrap4 %}
{% block head %}
<script src="https://js.stripe.com/v3/"></script>
<style>
.StripeElement {
height: 40px;
padding: 10px 12px;
width: 100%;
color: #32325d;
background-color: white;
/* border: 1px solid transparent; */
border: 1px solid #ced4da;
border-radius: 4px;
/* box-shadow: 0 1px 3px 0 #e6ebf1;
-webkit-transition: box-shadow 150ms ease;
transition: box-shadow 150ms ease; */
}
.StripeElement--focus {
border-color: #80bdff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, .25);
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}
</style>
{% endblock %}
{% block main %}
{% if not request.user.customer.stripe_payment_method_id %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
仕事を登録するにはクレジットカードを追加する必要があります。
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
<b class="text-secondary">クレジットカード登録</b>
<div class="card bg-white mt-2 mb-5">
<div class="card-body">
{% if request.user.customer.stripe_payment_method_id %}
<div id="change-card" class="input-group">
<input type="text" class="form-control" disabled
value="**** **** **** {{ request.user.customer.stripe_card_last4 }}">
<div class="input-group-append">
<form method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-danger">削除</button>
</form>
</div>
</div>
{% else %}
<form id="setup-form" data-secret="{{ client_secret }}">
<div id="card-element"></div>
<button id="card-button" class="btn btn-info mt-3" type="button">
クレジットカード登録
</button>
</form>
{% endif %}
</div>
</div>
{% if not request.user.customer.stripe_payment_method_id %}
<script>
var stripe = Stripe("{{ STRIPE_API_PUBLIC_KEY }}");
var elements = stripe.elements();
var cardElement = elements.create('card');
cardElement.mount('#card-element');
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
var clientSecret = "{{ client_secret }}";
cardButton.addEventListener('click', function (ev) {
stripe.confirmCardSetup(
clientSecret,
{
payment_method: {
card: cardElement,
},
}
).then(function (result) {
if (result.error) {
// Display error.message in your UI.
toast(result.error.message, 'error');
} else {
toast("クレジットカードが登録されました。", 'success');
window.location.reload();
// The setup has succeeded. Display a success message.
}
});
});
</script>
{% endif %}
{% endblock %}
「core/customer/views.py」ファイルを編集します。
記述編集 【Desktop/crowdsource/core/customer/views.py】
import firebase_admin from firebase_admin import credentials, auth import stripe from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.urls import reverse from core.customer import forms from django.contrib import messages from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth import update_session_auth_hash from django.conf import settings cred = credentials.Certificate(settings.FIREBASE_ADMIN_CREDENTIAL) firebase_admin.initialize_app(cred) stripe.api_key = settings.STRIPE_API_SECRET_KEY @login_required() def home(request): return redirect(reverse('customer:profile')) @login_required(login_url="/sign-in/?next=/customer/") def profile_page(request): user_form = forms.BasicUserForm(instance=request.user) customer_form = forms.BasicCustomerForm(instance=request.user.customer) password_form = PasswordChangeForm(request.user) if request.method == "POST": if request.POST.get('action') == 'update_profile': user_form = forms.BasicUserForm(request.POST, instance=request.user) customer_form = forms.BasicCustomerForm(request.POST, request.FILES, instance=request.user.customer) if user_form.is_valid() and customer_form.is_valid(): user_form.save() customer_form.save() messages.success(request, 'プロフィールが更新されました。') return redirect(reverse('customer:profile')) elif request.POST.get('action') == 'update_password': password_form = PasswordChangeForm(request.user, request.POST) if password_form.is_valid(): user = password_form.save() update_session_auth_hash(request, user) messages.success(request, 'パスワードが更新されました。') return redirect(reverse('customer:profile')) elif request.POST.get('action') == 'update_phone': # Get Firebase user data firebase_user = auth.verify_id_token(request.POST.get('id_token')) request.user.customer.phone_number = firebase_user['phone_number'] request.user.customer.save() messages.success(request, '電話番号が更新されました。') return redirect(reverse('customer:profile')) return render(request, 'customer/profile.html', { "user_form": user_form, "customer_form": customer_form, "password_form": password_form, }) @login_required(login_url="/sign-in/?next=/customer/") def payment_method_page(request): current_customer = request.user.customer # Remove existing card if request.method == "POST": stripe.PaymentMethod.detach(current_customer.stripe_payment_method_id) current_customer.stripe_payment_method_id = "" current_customer.stripe_card_last4 = "" current_customer.save() return redirect(reverse('customer:payment_method')) # Save stripe customer infor if not current_customer.stripe_customer_id: customer = stripe.Customer.create() current_customer.stripe_customer_id = customer['id'] current_customer.save() # Get Stripe payment method stripe_payment_methods = stripe.PaymentMethod.list( customer = current_customer.stripe_customer_id, type = "card", ) print(stripe_payment_methods) if stripe_payment_methods and len(stripe_payment_methods.data) > 0: payment_method = stripe_payment_methods.data[0] current_customer.stripe_payment_method_id = payment_method.id current_customer.stripe_card_last4 = payment_method.card.last4 current_customer.save() else: current_customer.stripe_payment_method_id = "" current_customer.stripe_card_last4 = "" current_customer.save() if not current_customer.stripe_payment_method_id: intent = stripe.SetupIntent.create( customer = current_customer.stripe_customer_id ) return render(request, 'customer/payment_method.html', { "client_secret": intent.client_secret, "STRIPE_API_PUBLIC_KEY": settings.STRIPE_API_PUBLIC_KEY, }) else: return render(request, 'customer/payment_method.html')
ブラウザを確認します。
http://127.0.0.1:8000/customer/payment_method/
削除機能が実装されました。

↓↓クリックして頂けると励みになります。
【22 | Stripe】 << 【ホーム】 >> 【24 | 配達依頼】