今回、「ゼロからはじめる Django で ECサイト構築」シリーズの第二回では、実際に、Django Oscar の Sandbox サイトを構築していくことにします。
ECサイト構築に必要な三要素
さて、ECサイトを構築するためには、
- 決済代行サービスのマーチャントアカウント
- ECパッケージ
- サーバ
の三つが必要最低限の要素として挙げられるでしょう。
まず一つ目の「決済代行サービスのマーチャントアカウント」は、PayPal や WebPay などの決済代行サービスのビジネスアカウント(売り手アカウント)を指します。Sandbox 環境においては、Sandbox(ややこしいですが、決済代行サービス側が用意してくれるテスト環境を指します)用のマーチャントアカウントを使用することで、実際に支払いをすることなく決済処理の流れをシミュレートすることができます。
今回の検証では、決済代行サービスとして PayPal を利用するのですが、Sandbox については次のように説明されています。
ペイパルでは、決済サービスの動作確認ができるテスト環境として、Sandboxを公開しています。
テスト用の「Buyer(買い手)」アカウントと、「Seller(売り手)」アカウントを作成し、サービスの導入から、決済の流れまで、詳細にシミュレーションすることができます。
Sandbox | ペイパルビジネスガイド - PayPal
二つ目の ECパッケージについては、前回の選定で最有力候補となった「Django Oscar」を使用します。なお、決済モジュールには「django-oscar-paypal」を使用することとします。
三つ目のサーバについては、今回の Sandbox サイトでは仮想環境(Vagrant 上の Ubuntu 仮想マシン)を利用します。
Sandbox サイトの構築手順
ここから実際に、Django Oscar の Sandbox サイトを構築していきます(2016/5/28 バージョン)。
構築する環境は以下となります。
- サーバ:Ubuntu 14.04TLS(on Vagrant)
- Python 2.7.6
- Django 1.9.6(現時点の最新バージョン)
- ECパッケージ:Django Oscar 1.2+(現時点の最新バージョン)
- 決済モジュール:django-oscar-paypal 0.9.7(現時点の最新バージョン)
以降、次のような手順で進めていきます。
私は通常、PyCharm Professional Edition の
- Vagrant 連携機能
- サーバとのソースコード同期機能
- リモートデバッグ機能
などの機能を利用するために、PyCharm を使っています。なので、いつもなら
- PyCharm の設定
- Pure Python Project を作成(空っぽのプロジェクトを作成)
- Vagrant連携
という流れで、PyCharm から Ubuntu サーバを立ち上げています。
<過去記事>
akiyoko.hatenablog.jp
手動でやるなら、以下のコマンドを実行します。
$ cd ~/PycharmProjects/oscar_sandbox/
$ vagrant init ubuntu/trusty64
仮想マシンに固定 IPアドレスを付けるために、Vagrantfile を書き換えます。
config.vm.network "private_network", ip: "192.168.33.105"
仮想マシンを起動します。
$ vagrant up
Vagrant サーバに ssh で乗り込みます。
$ ssh vagrant@192.168.33.105
$ sudo apt-get update
$ sudo apt-get -y install python-dev git tree
Ubuntu サーバに MySQL をインストールします。
$ sudo apt-get -y install mysql-server
(root/rootpass)
$ sudo apt-get -y install mysql-client libmysqlclient-dev python-mysqldb
$ mysql --version
mysql Ver 14.14 Distrib 5.5.49, for debian-linux-gnu (x86_64) using readline 6.3
$ sudo mysql_install_db
### 文字化け対策(セクションの最後に以下の設定を追加)
### http://blog.snowcait.info/2014/06/04/mariadb-utf8/
$ sudo vi /etc/mysql/my.cnf
---
[mysqld]
・
・
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem
# Character set settings
character-set-server = utf8
[mysqldump]
・
・
---
$ sudo service mysql restart
$ sudo mysql_secure_installation
Enter current password for root (enter for none):
Change the root password? [Y/n] n
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y
データベース、データベースユーザを作成します。
なお、データベース名は Djangoプロジェクト名と合わせて myproject とします。
データベース名 |
myproject |
データベースユーザ |
myprojectuser |
データベースユーザパスワード |
myprojectuserpass |
$ mysql -u root -p
mysql> create database myproject character set utf8;
mysql> create user myprojectuser@localhost identified by "myprojectuserpass";
mysql> grant all privileges on myproject.* to myprojectuser@localhost;
mysql> flush privileges;
mysql> exit
Python 2.7.9 以降であれば pip がバンドルされているのですが、Ubuntu 14.04LTS では Python 2.7.6 が標準なので、手動でインストールします。
「sudo apt-get -y install python-pip」でインストールすると pip のバージョンが古いので、get-pip.py で最新版を入れることにします。
$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo -H python get-pip.py
$ pip --version
pip 8.1.2 from /usr/local/lib/python2.7/dist-packages (python 2.7)
参考
### virtualenv, virtualenvwrapper をインストール
$ sudo -H pip install virtualenv virtualenvwrapper
### virtualenvwrapper の設定
$ cat << EOF >> ~/.bash_profile
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
EOF
$ cat << EOF >> ~/.bashrc
source /usr/local/bin/virtualenvwrapper.sh
export WORKON_HOME=~/.virtualenvs
EOF
$ source ~/.bashrc
Setting up the development environment — django-oscar 1.3 documentation
に従って、Oscar プロジェクトのインストールをします。
### Djangoプロジェクトの virtualenv 環境を設定して activate
$ mkvirtualenv myproject
### /opt/webapps 配下にプロジェクトの外箱を作成
$ sudo mkdir -p /opt/webapps/myproject
$ sudo chown -R `whoami`. /opt/webapps
### JPEG Support
### http://django-oscar.readthedocs.org/en/latest/internals/contributing/development-environment.html#jpeg-support
$ sudo apt-get -y install libjpeg-dev libfreetype6-dev zlib1g-dev
### make sandbox をした後であれば ↓ を実行して Pillow を再インストール
### pip install --no-cache-dir -I pillow
### http://qiita.com/tototoshi/items/7b74fe26eb7bf39be7b5
### MySQLライブラリのインストール
###($ pip install MySQL-python でも OK)
$ pip install mysqlclient
### Oscar プロジェクトを作成
$ cd /opt/webapps/myproject/
### 通常であれば、django-admin.py startproject . とするところを、今回は clone -> make sandbox として Sanbox サイトを作成
### http://django-oscar.readthedocs.org/en/latest/internals/getting_started.html
$ git clone https://github.com/django-oscar/django-oscar.git .
ここで、
###$ git checkout 1.2
として、最新の stable バージョン (1.2) に合わせようとしましたが、make sandbox 実行時に、
django.db.utils.OperationalError: (2013, 'Lost connection to MySQL server during query')
というエラーになってしまったので、master のままで試すことにしました(2016/5/28 時点)。
ちなみに、現時点の最新コミットは以下の通りです。
commit 156a4b814d540bb1c6216b757cfa4441b36f8077
Merge: e1a8ea7 de633f8
Author: Michael van Tellingen
Date: Wed Apr 13 09:03:37 2016 +0200
Merge pull request #2030 from crgwbr/fix_broken_py3_migrations
Fix makemigrations in Python 3
### MySQL用の設定変更
$ vi sites/sandbox/settings.py
<変更前>
---
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': location('db.sqlite'),
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
'ATOMIC_REQUESTS': True
}
}
---
↓
<変更後>
---
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'myprojectuserpass',
'HOST': 'localhost',
'PORT': '',
'ATOMIC_REQUESTS': True
}
}
---
### Sandbox プロジェクトを作成
### プロジェクトのディレクトリ構造は
### myproject/ (as <repository_root>)
### └─ sites/sandbox/ (as <django_project_root> also as <configuration_root>)
$ make sandbox
ちなみに、make sandbox の処理はこのようになっています。
Makefile(抜粋)
install:
pip install -e . -r requirements.txt
build_sandbox:
# Remove media
-rm -rf sites/sandbox/public/media/images
-rm -rf sites/sandbox/public/media/cache
-rm -rf sites/sandbox/public/static
-rm -f sites/sandbox/db.sqlite
# Create database
sites/sandbox/manage.py migrate
# Import some fixtures. Order is important as JSON fixtures include primary keys
sites/sandbox/manage.py loaddata sites/sandbox/fixtures/child_products.json
sites/sandbox/manage.py oscar_import_catalogue sites/sandbox/fixtures/*.csv
sites/sandbox/manage.py oscar_import_catalogue_images sites/sandbox/fixtures/images.tar.gz
sites/sandbox/manage.py oscar_populate_countries
sites/sandbox/manage.py loaddata sites/_fixtures/pages.json sites/_fixtures/auth.json sites/_fixtures/ranges.json sites/_fixtures/offers.json
sites/sandbox/manage.py loaddata sites/sandbox/fixtures/orders.json
sites/sandbox/manage.py clear_index --noinput
sites/sandbox/manage.py update_index catalogue
sandbox: install build_sandbox
Sandbox の作成が完了したら、作成状況を確認してみます。
$ pip list | grep Django
Django (1.9.6)
$ pip list | grep django-oscar
django-oscar (1.3.dev0, /opt/webapps/myproject/src)
$ pip freeze
alabaster==0.7.8
apipkg==1.4
Babel==2.3.4
beautifulsoup4==4.4.1
coverage==3.7.1
coveralls==0.4.4
decorator==4.0.9
Django==1.9.6
django-debug-toolbar==1.4
django-extensions==1.6.1
django-extra-views==0.6.4
django-haystack==2.4.1
-e git+https://github.com/django-oscar/django-oscar.git@156a4b814d540bb1c6216b757cfa4441b36f8077#egg=django_oscar
django-tables2==1.0.7
django-treebeard==4.0.1
django-webtest==1.7.8
django-widget-tweaks==1.4.1
docopt==0.6.2
docutils==0.12
execnet==1.4.1
factory-boy==2.6.1
fake-factory==0.5.7
flake8==2.5.1
flake8-blind-except==0.1.0
flake8-debugger==1.4.0
funcsigs==1.0.2
ipaddress==1.0.16
ipdb==0.8.1
ipython==4.0.1
ipython-genutils==0.1.0
isort==4.2.2
Jinja2==2.8
MarkupSafe==0.23
mccabe==0.3.1
mock==1.3.0
mysqlclient==1.3.7
nose==1.3.7
pathlib2==2.1.0
pbr==1.10.0
pep8==1.7.0
pexpect==4.1.0
phonenumbers==7.4.1
pickleshare==0.7.2
Pillow==2.7.0
pockets==0.3
ptyprocess==0.5.1
purl==1.3
py==1.4.31
pycountry==1.8
pyflakes==1.0.0
Pygments==2.1.3
pyprof2calltree==1.3.2
pysolr==3.2.0
pytest==2.8.5
pytest-cache==1.0
pytest-cov==2.2.0
pytest-django==2.9.1
pytest-xdist==1.13.1
python-dateutil==2.5.3
pytz==2016.4
PyYAML==3.11
requests==2.7.0
simplegeneric==0.8.1
six==1.10.0
snowballstemmer==1.2.1
sorl-thumbnail==12.4a1
spec==0.11.1
Sphinx==1.3.3
sphinx-rtd-theme==0.1.9
sphinxcontrib-napoleon==0.4.3
sqlparse==0.1.19
tox==1.8.1
traitlets==4.2.1
Unidecode==0.4.19
uWSGI==2.0.12
virtualenv==15.0.1
waitress==0.9.0
WebOb==1.6.1
WebTest==2.0.17
Werkzeug==0.9.6
whitenoise==2.0.6
Whoosh==2.6.0
$ find . -name "*.pyc" -exec rm -rf {} \;
$ tree -a /opt/webapps/myproject/ -I ".git|docs|tests" -L 3
/opt/webapps/myproject/
├── AUTHORS
├── CHANGELOG.rst
├── CONTRIBUTING.rst
├── .coveragerc
├── Dockerfile
├── .dockerignore
├── .gitignore
├── gulpfile.js
│ ├── index.js
│ └── tasks
│ ├── default.js
│ ├── less.js
│ └── watch.js
├── LICENSE
├── lint.sh
├── .mailmap
├── Makefile
├── MANIFEST.in
├── package.json
├── README.rst
├── requirements_migrations.txt
├── requirements.txt
├── runtests.py
├── sandbox.yml
├── setup.cfg
├── setup.py
├── sites
│ ├── _fixtures
│ │ ├── auth.json
│ │ ├── comms.json
│ │ ├── offers.json
│ │ ├── order-events.json
│ │ ├── pages.json
│ │ ├── promotions.json
│ │ ├── range-products.csv
│ │ └── ranges.json
│ ├── README.rst
│ └── sandbox
│ ├── apps
│ ├── deploy
│ ├── fixtures
│ ├── __init__.py
│ ├── logs
│ ├── manage.py
│ ├── public
│ ├── README.rst
│ ├── settings_mysql.py
│ ├── settings_postgres.py
│ ├── settings.py
│ ├── settings_sphinx.py
│ ├── static
│ ├── templates
│ ├── test_migrations.sh
│ ├── update_latest.sh
│ ├── urls.py
│ ├── whoosh_index
│ └── wsgi.py
├── src
│ ├── django_oscar.egg-info
│ │ ├── dependency_links.txt
│ │ ├── PKG-INFO
│ │ ├── requires.txt
│ │ ├── SOURCES.txt
│ │ └── top_level.txt
│ └── oscar
│ ├── app.py
│ ├── apps
│ ├── core
│ ├── defaults.py
│ ├── forms
│ ├── __init__.py
│ ├── locale
│ ├── management
│ ├── models
│ ├── profiling
│ ├── static
│ ├── templates
│ ├── templatetags
│ ├── test
│ └── views
├── tox.ini
├── transifex.sh
├── .travis.yml
└── .tx
└── config
29 directories, 56 files
ここで一旦、データベースをバックアップしておきます。
### http://weblabo.oscasierra.net/mysql-mysqldump-01/
### ちなみに、リストアするときは mysql -u root -p myproject < ~/myproject_init.dump
$ mysqldump --single-transaction -u root -p myproject > ~/myproject_init.dump
$ python sites/sandbox/manage.py runserver 0.0.0.0:8000
でサーバを起動して、
http://192.168.33.105:8000/
にブラウザからアクセスします。
ログインユーザ
username: superuser
email: superuser@example.com
password: testing
username: staff
email: staff@example.com
password: testing
疎通ができたら、Runserver を一旦停止します。
ちなみにここまでの設定では、決済モジュールの設定をしていないので、決済処理を完了することができなくなっています。
(住所や電話番号などのダミー情報は、US Address Generator - Fake Address, Random Address Generator で生成したものを入力しました。)
このように、決済モジュール(payment gateway libraries)を設定してね、って怒られます。
以下、PyCharm を使う場合のメモです。PyCharm を使ってない方はすっ飛ばしてください。
- PyCharm の設定
- デプロイ先サーバ設定
- ソースコードの同期
- ローカル側でソースコードを Git管理
- Project Interpreter の設定
- Run/Debug設定(以下に詳細を記載)
Project ペインの manage.py ファイルで右クリック > [Create "manage"] を選択します。
Name |
manage |
Script |
sites/sandbox/manage.py |
Script parameters |
runserver 0.0.0.0:8000 |
Environment variables |
PYTHONUNBUFFERED=1(デフォルトのまま) |
Python interpreter |
Project Default (Remote Python 2.7.6 Vagrant VM at ~/PycharmProjects/oscar_sandbox (/home/vagrant/.virtualenvs/myproject/bin/python)) |
Working directory |
/opt/webapps/myproject |
Path mappings - Local path |
/Users/akiyoko/PycharmProjects/oscar_sandbox |
Path mappings - Remote path |
/opt/webapps/myproject |
ここで、「Add content roots to PYTHONPATH」と「Add source roots to PYTHONPATH」のチェックを外します。
要するに、Script のパスに気をつけてね、ってことです。
各種設定を確認
Sandbox サイトの settings.py を確認すると、以下のドキュメントに書かれている、既存サイトに追加する場合に追加する必要のある設定が全て追加されています。
http://django-oscar.readthedocs.org/en/latest/internals/getting_started.html
sites/sandbox/settings.py(抜粋)
・
・
SITE_ID = 1
・
・
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.request",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
'oscar.apps.search.context_processors.search_form',
'oscar.apps.promotions.context_processors.promotions',
'oscar.apps.checkout.context_processors.checkout',
'oscar.core.context_processors.metadata',
'oscar.apps.customer.notifications.context_processors.notifications',
)
MIDDLEWARE_CLASSES = (
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'oscar.apps.basket.middleware.BasketMiddleware',
)
・
・
from oscar import OSCAR_MAIN_TEMPLATE_DIR
TEMPLATE_DIRS = (
location('templates'),
OSCAR_MAIN_TEMPLATE_DIR,
)
・
・
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'django.contrib.flatpages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'django_extensions',
'debug_toolbar',
'apps.gateway',
'widget_tweaks',
]
from oscar import get_core_apps
INSTALLED_APPS = INSTALLED_APPS + get_core_apps()
AUTHENTICATION_BACKENDS = (
'oscar.apps.customer.auth_backends.EmailBackend',
'django.contrib.auth.backends.ModelBackend',
)
・
・
INSTALLLED_APPS に
- django.contrib.sites
- django.contrib.flatpages
が追加されていて、MIDDLEWARE_CLASSES に
- oscar.apps.basket.middleware.BasketMiddleware
- django.contrib.flatpages.middleware.FlatpageFallbackMiddleware
が追加されていることが確認できます。
ちなみに、「TEMPLATE_CONTEXT_PROCESSORS」と「TEMPLATE_DIRS」を分けて記述している Sandbox の setteings.py の書き方は、Django 1.9 の書き方としては少し古いようですね。
Before Django 1.8 this setting was split between TEMPLATE_CONTEXT_PROCESSORS and TEMPLATE_DIRS.
http://django-oscar.readthedocs.org/en/latest/internals/getting_started.html
決済モジュールの導入手順
続けて、Django Oscar の Sandbox サイトに決済モジュールを組み込んでいきます。
決済代行サービスに「PayPal」を利用することを想定して、決済モジュールには「django-oscar-paypal」を選択することにします。
手順は以下の通りです。
参考
http://django-oscar-paypal.readthedocs.org/en/latest/
PayPal の決済モジュールを利用するには、「Test API Credentials」という PayPal の決済API を利用するための認証情報が必要となります。
「Test API Credentials」は、以下の 3セットのキー・バリューとなっています。
- PAYPAL_API_USERNAME
- PAYPAL_API_PASSWORD
- PAYPAL_API_SIGNATURE
Test API Credentials を取得する前に、まずは PayPal のアカウントを取得します。本番ではビジネスアカウントが必要ですが、Sandbox では個人アカウントでも大丈夫です。
PayPal アカウントを取得した後に、「PayPal Developer」ページからログインします。
https://developer.paypal.com/
Sandbox アカウントではなく、通常の PayPal アカウントでログインします。
「DASHBOARD」をクリックします。
「Accounts」を選択します。
Sandbox 用の「Buyer アカウント(マーチャントアカウント)」と「Seller アカウント(買い手アカウント)」がデフォルトで用意されている(はずな)ので、Type が「BUSINESS」となっている方の Buyer アカウントの「Profile」をクリックします。
「API Credentials」タブから Test API Credentials を確認することができます。
参考(PayPal 公式)
参考(Test API Credentials)
参考(ビジネスアカウント)
Ubuntu サーバ側で、django-oscar-paypal をインストールします。
$ workon myproject
$ pip install django-oscar-paypal
- django-localflavor==1.3
- django-oscar-paypal==0.9.7
が追加されました。
sites/sandbox/settings.py に「paypal」を加えます。
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'django.contrib.flatpages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'django_extensions',
'debug_toolbar',
'paypal',
'apps.gateway',
'widget_tweaks',
]
以下のコマンドを実行して、django-oscar-paypal 系のテーブルを作成します。
$ python sites/sandbox/manage.py migrate --run-syncdb
Operations to perform:
Synchronize unmigrated apps: reports_dashboard, messages, django_extensions, treebeard, gateway, communications_dashboard, reviews_dashboard, offers_dashboard, pages_dashboard, shipping_dashboard, haystack, promotions_dashboard, checkout, vouchers_dashboard, django_tables2, partners_dashboard, staticfiles, oscar, paypal, sitemaps, catalogue_dashboard, users_dashboard, search, debug_toolbar, widget_tweaks, dashboard, ranges_dashboard, orders_dashboard
Apply all migrations: customer, promotions, shipping, wishlists, offer, admin, sessions, thumbnail, contenttypes, auth, payment, reviews, analytics, catalogue, flatpages, sites, address, basket, partner, order, voucher
Synchronizing apps without migrations:
Creating tables...
Creating table paypal_expresstransaction
Creating table paypal_payflowtransaction
Running deferred SQL...
Running migrations:
No migrations to apply.
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
Django 1.9 の場合は、「run-syncdb」オプションを付けないとテーブルが作成されないので要注意です。(最後の警告は無視して OK。対応したいのであれば、makemigrations を実行すればよい。)
参考
http://stackoverflow.com/a/34635951
ここで、
- paypal_expresstransaction
- paypal_payflowtransaction
というテーブルが追加されました。
ここでもう一度、データベースをバックアップしておきます。
$ mysqldump --single-transaction -u root -p myproject > ~/myproject_migrate_paypal.dump
ここからは、
http://django-oscar-paypal.readthedocs.org/en/latest/express.html#getting-started
を参考にして進めていきます。
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/settings.py
を参考に、settings.py を修正します。
sites/sandbox/settings.py の最後の方に、以下の設定を追加します。
・
・
PAYPAL_SANDBOX_MODE = True
PAYPAL_CALLBACK_HTTPS = False
PAYPAL_API_VERSION = '119'
PAYPAL_API_USERNAME = ''
PAYPAL_API_PASSWORD = ''
PAYPAL_API_SIGNATURE = ''
from django.utils.translation import ugettext_lazy as _
OSCAR_DASHBOARD_NAVIGATION.append(
{
'label': _('PayPal'),
'icon': 'icon-globe',
'children': [
{
'label': _('Express transactions'),
'url_name': 'paypal-express-list',
},
]
})
try:
from settings_local import *
except ImportError:
pass
次に、sites/sandbox/settings_local.py に、「1. PayPal の Test API Credentials を取得」で取得したマーチャントアカウントの APIキーを設定します。
PAYPAL_API_USERNAME = 'xxxxxx-facilitator_api1.xxxxxx.xxx'
PAYPAL_API_PASSWORD = 'xxxxxxxxxxxxxxxx'
PAYPAL_API_SIGNATURE = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/urls.py
を参考に、sites/sandbox/urls.py を修正します。
<修正前>
・
・
from oscar.app import application
from oscar.views import handler500, handler404, handler403
・
・
urlpatterns += i18n_patterns('',
url(r'gateway/', include('apps.gateway.urls')),
url(r'', include(application.urls)),
)
・
・
↓
<修正後>
・
・
from oscar.app import application
from oscar.views import handler500, handler404, handler403
from paypal.express.dashboard.app import application as express_dashboard
・
・
urlpatterns += i18n_patterns('',
url(r'checkout/paypal/', include('paypal.express.urls')),
url(r'dashboard/paypal/express/', include(express_dashboard.urls)),
url(r'gateway/', include('apps.gateway.urls')),
url(r'', include(application.urls)),
)
・
・
Django Oscar の basket(ショッピングカート)機能、および checkout(チェックアウト)機能で使われている各種テンプレートファイルに対して、以下の修正を行います。
- Django 1.9 対応(django-oscar-paypal が Django 1.9 に対応していないため)
- 体裁修正(django-oscar-paypal が Django Oscar のスタイルに対応していないため)
ここで、settings.py の設定が以下のようになっており、Sandbox プロジェクトの仕組み上、「sites/sandbox/templates/」 -> 「src/oscar/templates/oscar/」の順にテンプレートファイルをルックアップし、それでも無ければ、INSTALLED_APPS でインストールしたアプリケーションのテンプレートファイルを参照するようになっています。
from oscar import OSCAR_MAIN_TEMPLATE_DIR
TEMPLATE_DIRS = (
location('templates'),
OSCAR_MAIN_TEMPLATE_DIR,
)
Sandbox プロジェクトでは、「src/oscar/templates/oscar/」配下に実ファイルを配置しているため、ライブラリが持っているテンプレートファイルによるオーバーライドが出来ないので注意が必要です。
1) ショッピングカート画面
django-oscar-paypal の Sandbox用に用意されているファイル
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/templates/basket/partials/basket_content.html
を sites/sandbox/templates/ 配下にコピーします。
$ cd /tmp/
$ git clone https://github.com/django-oscar/django-oscar-paypal.git
$ cd django-oscar-paypal/
$ git checkout 0.9.7
$ mkdir -p /opt/webapps/myproject/sites/sandbox/templates/basket/partials
$ cp -a sandbox/templates/basket/partials/basket_content.html /opt/webapps/myproject/sites/sandbox/templates/basket/partials/basket_content.html
2016/5/28 現時点の django-oscar-paypal のソースコードのままでは、以下のようにエラーが出てしまいます。
テンプレート内で、
{% load url from future %}
と書くと、Django 1.9 で動かした場合に、
'url' is not a valid tag or filter in tag library 'future'
というエラーが発生します。これは、Django1.9 以降では、future タグの url がなくなって、ビルトインのものを使うようになったからです。なので、Django1.9 以降では、url を load する必要は無く、
{% url 'checkout:preview' %}
とそのまま使えばよいです。
参考
https://www.bountysource.com/issues/29762758-django-1-9-compatibility-url-tag
要するに、django-oscar-paypal のテンプレートが Django 1.9 対応されていないのが原因なので、以下のように修正していきます。
sites/sandbox/templates/basket/partials/basket_content.html
<修正前>
{% extends 'oscar/basket/partials/basket_content.html' %}
{% load url from future %}
{% load i18n %}
{% block formactions %}
<div class="form-actions">
{% if anon_checkout_allowed or request.user.is_authenticated %}
{% if basket.total_excl_tax > 0 %}
<a href="{% url 'paypal-redirect' %}"><img src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;"></a>
{% endif %}
{% endif %}
<a href="{% url 'checkout:index' %}" class="pull-right btn btn-large btn-primary">{% trans "Proceed to checkout" %}</a>
</div>
{% endblock formactions %}
↓
<修正後>
{% extends 'oscar/basket/partials/basket_content.html' %}
{#{% load url from future %}#}
{% load i18n %}
{% block formactions %}
<div class="form-actions">
{% if anon_checkout_allowed or request.user.is_authenticated %}
{% if basket.total_excl_tax > 0 %}
<a href="{% url 'paypal-redirect' %}"><img src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;"></a>
{% endif %}
{% endif %}
<a href="{% url 'checkout:index' %}" class="pull-right btn btn-large btn-primary">{% trans "Proceed to checkout" %}</a>
</div>
{% endblock formactions %}
上記の対応後、ショッピングカート画面を確認すると、以下のように表示が少し崩れてしまっています。
こちらは、Django Oscar 側のテンプレートのスタイルの当て方が変わったのに、django-oscar-paypal の Sandbox 用のテンプレート側がまだ対応できていないことが原因のようです。
そこで、src/oscar/templates/oscar/basket/partials/basket_content.html を参考にして、以下のようにテンプレートファイルを修正します。
<再修正後>
{% extends 'oscar/basket/partials/basket_content.html' %}
{#{% load url from future %}#}
{% load i18n %}
{% block formactions %}
<div class="form-actions">
<div class="row">
<div class="col-sm-8">
{% if anon_checkout_allowed or request.user.is_authenticated %}
{% if basket.total_excl_tax > 0 %}
<a href="{% url 'paypal-redirect' %}"><img src="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif" align="left" style="margin-right:7px;"></a>
{% endif %}
{% endif %}
</div>
<div class="col-sm-4">
<a href="{% url 'checkout:index' %}" class="btn btn-lg btn-primary btn-block">{% trans "Proceed to checkout" %}</a>
</div>
</div>
</div>
{% endblock formactions %}
これで、きちんと表示されるようになりました。
2) チェックアウト画面
同じように、
https://github.com/django-oscar/django-oscar-paypal/blob/master/sandbox/templates/checkout/payment_details.html
を sites/sandbox/templates/ 配下にコピーします。
$ cd /tmp/django-oscar-paypal/
$ mkdir -p /opt/webapps/myproject/sites/sandbox/templates/checkout
$ cp -a sandbox/templates/checkout/payment_details.html /opt/webapps/myproject/sites/sandbox/templates/checkout/payment_details.html
こちらも、同様のエラーが出るので、
以下のように修正を加えます。
sites/sandbox/templates/checkout/payment_details.html
<修正前>
{% extends 'oscar/checkout/payment_details.html' %}
{% load url from future %}
{% load i18n %}
{% block payment_details %}
<div class="well">
<div class="sub-header">
<h3>{% trans "PayPal Express" %}</h3>
</div>
<p>{% trans "Click on the below icon to use Express Checkout but where the shipping address and method is already chosen on the merchant site." %}</p>
<div style="overflow:auto"><a href="{% url 'paypal-direct-payment' %}" title="{% trans "Pay with PayPal" %}"><img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" align="left" style="margin-right:7px;"></a> </div>
</div>
<div class="well">
<div class="sub-header">
<h3>{% trans "PayPal PayFlow Pro" %}</h3>
</div>
<form method="post" action="{% url 'checkout:preview' %}" class="form-stacked">
{% csrf_token %}
<h4>{% trans "Bankcard" %}</h4>
{% include "partials/form_fields.html" with form=bankcard_form %}
<h4>{% trans "Billing address" %}</h4>
{% include "partials/form_fields.html" with form=billing_address_form %}
<div class="form-actions">
<button type="submit" class="btn btn-large btn-primary">{% trans "Continue" %}</button>
</div>
</form>
</div>
{% endblock %}
↓
<修正後>
{% extends 'oscar/checkout/payment_details.html' %}
{#{% load url from future %}#}
{% load i18n %}
{% block payment_details %}
<div class="well">
<div class="sub-header">
<h3>{% trans "PayPal Express" %}</h3>
</div>
<p>{% trans "Click on the below icon to use Express Checkout but where the shipping address and method is already chosen on the merchant site." %}</p>
<div style="overflow:auto"><a href="{% url 'paypal-direct-payment' %}" title="{% trans "Pay with PayPal" %}"><img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" align="left" style="margin-right:7px;"></a> </div>
</div>
<div class="well">
<div class="sub-header">
<h3>{% trans "PayPal PayFlow Pro" %}</h3>
</div>
<form method="post" action="{% url 'checkout:preview' %}" class="form-stacked">
{% csrf_token %}
<h4>{% trans "Bankcard" %}</h4>
{% include "partials/form_fields.html" with form=bankcard_form %}
<h4>{% trans "Billing address" %}</h4>
{% include "partials/form_fields.html" with form=billing_address_form %}
<div class="form-actions">
<button type="submit" class="btn btn-large btn-primary">{% trans "Continue" %}</button>
</div>
</form>
</div>
{% endblock %}
ここでは詳しく触れませんが、日本では「PayPal PayFlow Pro」は使えないので、最終的なテンプレートファイルは以下のようにしておきます。
<再修正後>
{% extends 'oscar/checkout/payment_details.html' %}
{#{% load url from future %}#}
{% load i18n %}
{% block payment_details %}
<div class="well">
<div class="sub-header">
<h3>{% trans "PayPal Express" %}</h3>
</div>
<p>{% trans "Click on the below icon to use Express Checkout but where the shipping address and method is already chosen on the merchant site." %}</p>
<div style="overflow:auto"><a href="{% url 'paypal-direct-payment' %}" title="{% trans "Pay with PayPal" %}"><img src="https://www.paypal.com/en_US/i/logo/PayPal_mark_37x23.gif" align="left" style="margin-right:7px;"></a> </div>
</div>
{% endblock %}
3) PayPal からのリダイレクト画面
続いて、PayPal での処理処理が終わったときにリダイレクトされてくる画面のテンプレートファイルを修正します。これまで同様に、
の対応を行います。
$ cp -r /home/vagrant/.virtualenvs/myproject/lib/python2.7/site-packages/paypal/templates/* /opt/webapps/myproject/sites/sandbox/templates/
$ rm -rf /opt/webapps/myproject/sites/sandbox/templates/paypal/payflow
$ tree sites/sandbox/templates/paypal/
sites/sandbox/templates/paypal/
└── express
├── dashboard
│ ├── transaction_detail.html
│ └── transaction_list.html
└── preview.html
sites/sandbox/templates/paypal/express/preview.html
<修正前>
{% extends "checkout/preview.html" %}
{% load currency_filters %}
{% load i18n %}
{% load url from future %}
{% load thumbnail %}
{# Null out the actions as they can't be used here #}
{% block shipping_address_actions %}{% endblock %}
{% block shipping_method_actions %}{% endblock %}
{% block order_contents_actions %}{% endblock %}
{% block payment_method %}
<div class="span6">
<div class="sub-header">
<h2>{% trans "Payment" %}</h2>
</div>
<div class="well well-success">
<h4>{% trans "PayPal" %}</h4>
<p>
{% blocktrans with amt=paypal_amount|currency email=paypal_user_email %}
{{ amt }} will be deducted from your PayPal account, registered
to email: {{ email }}.
{% endblocktrans %}
</p>
</div>
</div>
{% endblock %}
・
・
↓
<修正後>
{% extends "checkout/preview.html" %}
{% load currency_filters %}
{% load i18n %}
{#{% load url from future %}#}
{% load thumbnail %}
{# Null out the actions as they can't be used here #}
{% block shipping_address_actions %}{% endblock %}
{% block shipping_method_actions %}{% endblock %}
{% block order_contents_actions %}{% endblock %}
{% block payment_method %}
<div class="col-sm-6">
<div class="sub-header">
<h2>{% trans "Payment" %}</h2>
</div>
<div class="well well-success">
<p>{% blocktrans with amount=order_total.incl_tax|currency %}<strong>{{ amount }}</strong> will be debited from your bankcard.{% endblocktrans %}</p>
<div class="alert-actions">
<a href="{% url 'checkout:payment-details' %}" class="btn">{% trans "Change payment details" %}</a>
</div>
</div>
</div>
{% endblock payment_method %}
・
・
4) ダッシュボード画面
Django Oscar のダッシュボード画面を使う場合は、以下の 2ファイルに Django 1.9 対応の修正を加える必要があります。
sites/sandbox/templates/paypal/express/dashboard/transaction_list.html
{% extends 'dashboard/layout.html' %}
{% load currency_filters %}
{% load i18n %}
{#{% load url from future %}#}
・
・
sites/sandbox/templates/paypal/express/dashboard/transaction_detail.html
{% extends 'dashboard/layout.html' %}
{% load currency_filters %}
{% load i18n %}
{#{% load url from future %}#}
・
・
以上で、Django Oscar の Sandbox サイトを構築するまでの作業は終了です。
GitHub にも修正内容をアップしたので、こちらも参照してください。
GitHub - akiyoko/oscar_sandbox