This article is written according to version 1 (freshly made) of webpay-python. After that, we made a major version upgrade.
Most of the content can be used as it is, but some method names have been changed. For the latest information, refer to Python API documentation on the official WebPay website.
In addition, the repository on github has stopped updating in line with the major version upgrade. For library information, see Library Document.
The WebPay Advent Calendar has also entered the second half of the game. We are working hard to encourage the number of stocks of everyone who is gradually increasing.
Today is the series "Introducing WebPay with a little code".
So far, Ruby and PHP versions have appeared. It is the Python version that comes with it. What's more, I tried using Google App Engine as the environment to run it.
Nowadays, many PaaS are crowded in the world, and there are many convenient programming environments, so I think some people have forgotten about GAE, but GAE is a long-established PaaS. Please remember GAE once in a while.
webpay-python
WebPay's official Python library (webpay-python) has been released!
** Celebration ** Release
Now, let's use this Python library to introduce WebPay on GAE at explosive speed.
webpay meets GAE
Let's start programming right away. A major feature of GAE is that the SDK for local development is provided, and the GAE environment can be reproduced locally. However, while the environment is preset, the libraries and versions provided by GAE are limited, so you cannot freely load and use the libraries. Major versions are supported if it is a basic framework, but of course the payment gateway library etc. are not built in.
Today's programmers think that the world of reinventing the wheel and not being able to use the library freely is an intolerable world. I can't stand it either.
Therefore, I will explain the points when using an external library with GAE, so please refer to it.
This time, we will use webapp2
built into GAE and webpay-python
as an external library.
If you have a Merverics Mac at hand,
Download GoogleAppEngineLauncher-1.8.8.dmg
from GAE SDK and apply the opened file (GoogleAppEngineLauncher.app). Just place it in a folder and you're good to go. When you start GoogleAppEngineLauncher.app, it will install the python script for GAE's local development environment in / usr / local / bin
.
Prepare a suitable directory for your project. Prepare app.yaml and appengine_config.py there. I think it has the following directory structure.
webpay-sample
├── app.yaml
└── appengine_config.py
The contents of app.yaml
app.yaml
application: webpay-sample
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.app
Let's set python27
to runtime
like this. GAE is also moving into the 2.7 era. For application, specify the application_id created in GAE's Dashboard. If you want to try it locally, you don't need to create an application on the GAE dashboard. Threadsafe parameters may not be familiar to those who used GAE in the past, but since python27 became available, they have been explicitly specified. (I will not explain in detail because it deviates from the main subject, but if you set threadsafe: true
, you will not be able to return data to the client using standard output with print etc.)
Next is ʻappengine_config.py`.
appengine_config.py
import os
import sys
ROOTPATH = os.path.dirname(__file__)
LIBPATH = os.path.join(ROOTPATH, 'lib')
sys.path.append(LIBPATH)
appengine_config.py is a special file used for settings that are commonly used in the project and library path settings. This time we will save the external library under lib
, so add the lib
directory to the library path.
Finally, create the main program part. This time, I specified script: main.app
in ʻapp.yaml, so let's create it with the file name
main.py. In addition, prepare two files, ʻindex.html
and succeeded.html
, as templates to be read by main.py
.
webpay-sample
├── app.yaml
├── lib
├── main.py
├── index.html
├── succeeded.html
└── appengine_config.py
Let's take a look at each file.
main.py
# -*- coding: utf-8 -*-
import os
import webapp2
from google.appengine.ext.webapp import template
from webpay import WebPay
SECRET_KEY = 'test_secret_eHn4TTgsGguBcW764a2KA8Yd'
PUBLIC_KEY = 'test_public_19DdUs78k2lV8PO8ZCaYX3JT'
class MainPage(webapp2.RequestHandler):
def get(self):
template_values = {
'public_key': PUBLIC_KEY
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
def post(self):
amount = self.request.POST.get('amount')
token = self.request.POST.get('webpay-token')
webpay = WebPay(SECRET_KEY)
try:
# webpay-Access to WebPay using python library
charge = webpay.charges.create(
amount=amount,
currency="jpy",
card=token
)
template_values = {
'charge': charge
}
path = os.path.join(os.path.dirname(__file__), 'succeeded.html')
self.response.out.write(template.render(path, template_values))
except webpay.errors.CardError, e:
#If the card is rejected
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("CardException")
self.response.out.write("Status is: %d" % e.status)
self.response.out.write("Type is: %s" % e.type)
self.response.out.write("Code is: %s" % e.code)
self.response.out.write("Param is: %s" % e.param)
self.response.out.write("Message is: %s" % e)
except webpay.errors.InvalidRequestError, e:
#When the parameter specified in the request is invalid
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("InvalidRequestException")
except webpay.errors.AuthenticationError, e:
#If authentication fails
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("AuthenticationException")
pass
except webpay.errors.ApiConnectionError, e:
#When a connection error to the API occurs
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("APIConnectionException")
pass
except webpay.errors.WebpayError, e:
#If an error occurs on the WebPay server
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("APIException")
pass
except Exception, e:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write("Unexpected exception")
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
main.py is a webapp2
app that implements the get
and post
methods in the MainPage
class.
In the first get
method, create the template path withpath = os.path.join (os.path.dirname (__ file__),'index.html')
andself.response.out. I'm rendering html with write (template.render (path, template_values))
. Assign the public_key
used in CheckoutHelper as a template variable.
charge = webpay.charges.create(
amount=amount,
currency="jpy",
card=token
)
The second post
method uses thewebpay.charges.create ()
shown above to do the billing process. Since the token created by CheckoutHelper is sent from the client, a code like token = self.request.POST.get ('webpay-token')
Gets the value POSTed in.
Finally, let's check the contents of the ʻindex.htmland
succeeded.html templates. In ʻindex.html
, with the advent calendar of Ruby and PHP Similarly, we are using a Javascript library called Checkout Helper that displays a dialog for entering the card number.
index.html
<html>
<head>
<meta charset="utf-8">
<title>WebPay Google App Engine Python sample</title>
</head>
<body>
<h1>WebPay Google App Engine Python sample</h1>
<form action="/" method="post">
<input type="number" name="amount" value="300" />I will pay the yen.<br />
<!--Sending your credit card information to your server creates an obligation to handle your credit card information properly.
By using JavaScript to generate a webpay token, you don't have to deal with credit card information directly.
webpay-An input with the name token is automatically added.-->
<script src="https://checkout.webpay.jp/v1/" class="webpay-button"
data-text="Enter your card information and pay"
data-key="{{ public_key }}"></script>
</form>
</body>
</html>
succeeded.html
is a simple template that just displays the results.
succeeded.html
<html>
<head>
<meta charset="utf-8">
<title>WebPay PHP sample</title>
</head>
<body>
<h1>Thank you for your payment</h1>
<ul>
<li>The amount of money for payment: {{charge.amount}}</li>
<li>Card name: {{charge.card.name}}</li>
<li>card number: ****-****-****-{{charge.card.last4}}</li>
</ul>
</body>
</html>
This is the end of programming.
Now, let's finally install the library.
The python library is generally managed by pip or easy_install. But that's the case in a normal Python environment, not in a GAE environment. This time, let's put webpay-python
and its dependent libraries in the lib
directory created first.
First, git clone
the library. (You can have the library at hand in another way, such as zip or egg.)
mkdir tmp && cd tmp
git clone [email protected]:webpay/webpay-python.git
git clone https://github.com/kennethreitz/requests.git
Build the library when the clone is complete. After building, move the built files to the lib
directory as shown below.
cd webpay-python
python setup.py build
cd ../requests
python setup.py build
cd ../../
mv tmp/webpay-python/build/lib/webpay lib/
mv tmp/requests/build/lib/requests lib/
In the end, I think the directory structure is as follows.
webpay-sample
├── app.yaml
├── lib
├── webpay
└── requests
├── tmp
├── main.py
├── index.html
├── succeeded.html
└── appengine_config.py
Let's run it in a local development environment. Execute the following command in the webpay-sample
directory.
dev_appserver.py .
Let's access http: // localhost: 8080 /.
how is it? Was it displayed?
If it looks good, deploy it to Google App Engine.
appcfg.py update .
Once deployed
https://webpay-sample.appspot.com/
I think you can see a page like this. Compared to the articles on ruby and php, the amount is a little larger, but you can experience that you can introduce WebPay using the official library even with GAE, which is a typical PaaS that is easy and anyone can use. Isn't it?
You were able to run WebPay even with the nostalgic GAE that started the cloud era.
Recommended Posts