Python Ver. To introduce WebPay with a little code.

Update notice

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.

Install the SDK

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.

Use WebPay from Python

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.htmlandsucceeded.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?

in conclusion

You were able to run WebPay even with the nostalgic GAE that started the cloud era.

Recommended Posts

Python Ver. To introduce WebPay with a little code.
Try to create a python environment with Visual Studio Code & WSL
I was addicted to creating a Python venv environment with VS Code
Steps to create a Python virtual environment with VS Code on Windows
How to read a CSV file with Python 2/3
Send a message to LINE with Python (LINE Notify)
Try to draw a life curve with python
I want to make a game with Python
Try to make a "cryptanalysis" cipher with Python
Decide to assign a laboratory with Python (fiction)
Steps to create a Twitter bot with python
Try to make a dihedral group with Python
I want to write to a file with Python
A layman wants to get started with Python
Build a python execution environment with VS Code
Rewrite Python2 code to Python3 (2to3)
Try to solve the traveling salesman problem with a genetic algorithm (Python code)
A note I was addicted to when running Python with Visual Studio Code
How to convert / restore a string with [] in python
A memo connected to HiveServer2 of EMR with python
[Python] How to draw a line graph with Matplotlib
Try to make a command standby tool with python
Get financial data with python (then a little tinkering)
I tried to draw a route map with Python
I want to work with a robot in python.
From buying a computer to running a program with python
How to make a Python package using VS Code
I tried to automatically generate a password with Python3
[Python] A memo to write CSV vertically with Pandas
A program to write Lattice Hinge with Rhinoceros with Python
A note on speeding up Python code with Numba
Write code to Unit Test a Python web app
[Python] How to create a 2D histogram with Matplotlib
How to create a kubernetes pod from python code
I want to run a quantum computer with Python
[Python] How to draw a scatter plot with Matplotlib
[Python] Road to a snake charmer (5) Play with Matplotlib
Run the output code with tkinter, saying "A, pretending to be B" in python
Get country code with python
Python with VS Code (Windows 10)
Connect to BigQuery with Python
A road to intermediate Python
Connect to Wikipedia with Python
Post to slack with Python 3
Debug Python with VS Code
Make a fortune with Python
Switch python to 2.7 with alternatives
Write to csv with Python
Create a directory with python
A little stuck with chainer
Convert python 3.x code to python 2.x
Document Python code with Doxygen
Set up a Python development environment with Visual Studio Code
How to convert an array to a dictionary with Python [Application]
Create a Mastodon bot with a function to automatically reply with Python
I made a package to filter time series with python
I wrote a program quickly to study DI with Python ①
A collection of competitive pro techniques to solve with Python
Probably the easiest way to create a pdf with Python3
Experiment to make a self-catering PDF for Kindle with Python
[python] A note when trying to use numpy with Cython