【※ガチガチの初心者です。】
オーダー内容に応じて、決済内容が変わるようにしました。

参考にしているページ

「Stripe決済の最新事情〜Django と Stripe と 私〜」
http://akiyoko.hatenablog.jp/entry/2016/12/25/085750

Stripe公式ドキュメント
https://stripe.com/docs

Add a new payment gateway to Oscar
https://groups.google.com/forum/#!topic/django-oscar/Cr8sBI0GBu0

Stripeを選んだ理由

シンプルにこの3つ。他のでもよくない?ってなるかもしれないですが、半ばノリで決めました。笑
1.決済にページ遷移が無い
2.固定費用が無い
3.導入が楽(苦戦しましたが。。。)らしい

という感じです。Paypalとかも結構楽に入れられるみたいです。

導入

「Stripe決済の最新事情」に載っている事をそのまま進めました。割愛多いです。

①Stripeに会員登録して、APIを取得する。

https://stripe.com/jp

②settings.pyに追記する。

settings.py
STRIPE_LIVE_PUBLIC_KEY = os.environ.get("STRIPE_LIVE_PUBLIC_KEY", "<your publishable key>")
STRIPE_LIVE_SECRET_KEY = os.environ.get("STRIPE_LIVE_SECRET_KEY", "<your secret key>")
STRIPE_TEST_PUBLIC_KEY = os.environ.get("STRIPE_TEST_PUBLIC_KEY", "<your publishable test key>")
STRIPE_TEST_SECRET_KEY = os.environ.get("STRIPE_TEST_SECRET_KEY", "<your secret test key>")
STRIPE_LIVE_MODE = False
STRIPE_CURRENCY = "JPY"

③テンプレートにcheckout.jsを入れる。

project_dir/templates/checkout/payment_details.html
{% extends "oscar/checkout/payment_details.html" %}
{% load currency_filters %}
{% load i18n %}

{% block payment_details_content %}
        <form action="{% url 'checkout:preview' %}" class="form-stacked" method="POST">
          <script
              src="https://checkout.stripe.com/checkout.js"
              class="stripe-button"
              data-key="{{ stripe_publishable_key }}"
              data-amount="{{ order_total_incl_tax }}"
              data-name="{{ shop_name }}"
              data-description="{{ basket.num_items }} items ({{ order_total.incl_tax|currency }})"
              data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
              data-locale="auto"
              data-currency="jpy">
          </script>
        </form>
{% endblock %}

④views.pyを編集する

project_dir/oscar_fork/checkout/views.py
from oscar.apps.checkout.views import PaymentDetailsView as CorePaymentDetailsView

import logging

from django.conf import settings
from oscar.core.loading import get_model
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from oscar_fork.checkout.facade import Facade
from . import PAYMENT_METHOD_STRIPE, PAYMENT_EVENT_PURCHASE, STRIPE_EMAIL, STRIPE_TOKEN
from oscar_fork.checkout.forms import StripeTokenForm

logger = logging.getLogger(__name__)

SourceType = get_model('payment', 'SourceType')
Source = get_model('payment', 'Source')


class PaymentDetailsView(CorePaymentDetailsView):

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(PaymentDetailsView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        ctx = super(PaymentDetailsView, self).get_context_data(**kwargs)

        if self.preview:
            ctx['stripe_token_form'] = StripeTokenForm(self.request.POST)
            ctx['order_total_incl_tax'] = (
               ctx['order_total'].incl_tax
            ).to_integral_value()
        else:
            ctx['order_total_incl_tax'] = (
               ctx['order_total'].incl_tax
            ).to_integral_value()
            ctx['stripe_publishable_key'] = settings.STRIPE_TEST_PUBLIC_KEY
        return ctx

    def handle_payment(self, order_number, total, **kwargs):
        stripe_ref = Facade().charge(
            order_number,
            total,
            card=self.request.POST[STRIPE_TOKEN],
            description=self.payment_description(order_number, total, **kwargs),
            metadata=self.payment_metadata(order_number, total, **kwargs))

        source_type, __ = SourceType.objects.get_or_create(name=PAYMENT_METHOD_STRIPE)
        source = Source(
            source_type=source_type,
            currency=settings.STRIPE_CURRENCY,
            amount=total.incl_tax,
            )

        self.add_payment_source(source)
        self.add_payment_event(PAYMENT_EVENT_PURCHASE, total.incl_tax)

    def payment_description(self, order_number, total, **kwargs):
        return self.request.POST[STRIPE_EMAIL]

    def payment_metadata(self, order_number, total, **kwargs):
        return {'order_number': order_number}

__init__.pyを編集する

project_dir/oscar_fork/checkout/__init__.py
default_app_config = 'oscar_fork.checkout.config.CheckoutConfig'

PAYMENT_EVENT_PURCHASE = 'Purchase'
PAYMENT_METHOD_STRIPE = 'Stripe'
STRIPE_EMAIL = 'stripeEmail'
STRIPE_TOKEN = 'stripeToken'

⑥stipe決済用のファイルfacade.pyを作る

project_dir/oscar_fork/checkout/facade.py
from django.conf import settings
from oscar.apps.payment.exceptions import UnableToTakePayment, InvalidGatewayRequestError

import stripe


class Facade(object):
    def __init__(self):
        stripe.api_key = settings.STRIPE_API_KEY

    @staticmethod
    def get_friendly_decline_message(error):
        return 'The transaction was declined by your bank - please check your bankcard details and try again'

    @staticmethod
    def get_friendly_error_message(error):
        return 'An error occurred when communicating with the payment gateway.'

    def charge(self, order_number, total, card, currency=settings.STRIPE_CURRENCY, description=None, metadata=None, **kwargs):

        try:
            return stripe.Charge.create(
                amount=(total.incl_tax).to_integral_value(),
                currency=currency,
                card=card,
                description=description,
                metadata=(metadata or {'order_number': order_number}),
                **kwargs).id

        except stripe.error.CardError as e:
            raise UnableToTakePayment(self.get_friendly_decline_message(e))
        except stripe.error.StripeError as e:
            raise InvalidGatewayRequestError(self.get_friendly_error_message(e))

forms.pyを作成する

project_dir/oscar_fork/checkout/forms.py
from django import forms


class StripeTokenForm(forms.Form):
    stripeEmail = forms.EmailField(widget=forms.HiddenInput())
    stripeToken = forms.CharField(widget=forms.HiddenInput())

これで、オーダー内容に応じた決済がStripeで出来るようになります!

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.