今回は、BASEのオンライン決済システム「PAYJP」を用いた決済機能の実装手順を簡単に解説したいと思います。1行で実装できてしまうチェックアウト版ではなく、「gem ‘payjp’」を用いたカスタマイズ版のフォームを実装するので注意しましょう。
PAYJPの概要についてはこちらの記事を参考にしてください。

実装の概要
今回は下記のスライドを順に追って解説していく形になります。スライドだけで理解ができる方は読み飛ばしていただいて結構です。
PAYJPの大まかな実装の流れとしては、
- PAYJPにログイン
- PAYJPの導入
- フォーム実装
- JS実装
- 環境変数の設定
- コントローラー実装
となるので、この流れを頭に入れながら進めていきましょう。
実装の手順
以下のコードは記述例であるため、そのまま実装しても動かないので注意してください。
PAYJPにログイン
まずはPAYJPに会員登録&ログインをしなければなりません。こちらの記事にログインまでの流れも載せているので、これを参考に進めていきましょう。

PAYJPの導入
次はPAYJPが使えるよう、諸々の設定を行っていきます。やることとしてはgemの導入とapplication.html.hamlの編集です。
↓ Gemfile
gem 'payjp'
↓ ターミナル
$ bundle install
↓ application.html.haml
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%title PayApp
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application'
-# 以下の記述を追記
%script{src: "https://js.pay.jp/", type: "text/javascript"}
これでPAYJPを使う準備が整いました。
フォーム実装
続いてクレジットカードを登録するためのフォームを作成します。
↓ フォーム例
%form#charge-form{action: "/cards", method: "POST"}
%span.charge-errors
%h4 支払い
%label カード番号
%input.number{maxlength: "16", name: "number", placeholder: "カード番号", type: "text",id: "payment_card_no", value: 4242424242424242}/
%label CVC
%input.cvc{maxlength: "3", name: "cvc", placeholder: "CVC", type: "text",id: "payment_card_security_code", value: 123}/
%label 有効期限
%input.exp_month{maxlength: "2", name: "exp_month", placeholder: "月", type: "text",id: "payment_card_expire_mm", value: 12}/
%input.exp_year{maxlength: "4", name: "exp_year", placeholder: "年", type: "text",id: "payment_card_expire_yy", value: 2022}/
%button{type: "submit", id: "card-save"} 登録
JS実装
次にJSでトークンを作成し、PAYJP側にそのトークンを送ります。
↓ JS例
$(function() {
if (!$('#regist_card')[0]) return false;
Payjp.setPublicKey("テスト用の公開鍵");
$("#regist_card").on("click", function(e) {
e.preventDefault();
var card = {
number: $("#card_number_form").val(),
exp_month: $("#exp_month_form").val(),
exp_year: $("#exp_year_form").val(),
cvc: $("#cvc_form").val()
};
Payjp.createToken(card, function(status, response) {
if (status === 200) {
$("#card_number_form").removeAttr("name");
$("#exp_month_form").removeAttr("name");
$("#exp_year_form").removeAttr("name");
$("#cvc_form").removeAttr("name");
var token = response.id;
$("#card_token").append(`<input type="hidden" name="card_token" value=${token}>`)
$("#card_form").get(0).submit();
} else {
alert("カード情報が正しくありません。");
$("#regist_card").prop('disabled', false);
}
});
});
});
分解してそれぞれのコードを見ていきましょう。まずは、入力されたカード情報の値を取得し、変数cardに格納しています。
↓ 該当コード
var card = {
number: $("#card_number_form").val(),
exp_month: $("#exp_month_form").val(),
exp_year: $("#exp_year_form").val(),
cvc: $("#cvc_form").val()
};
それらの値をトークンを生成するメソッドを用いてトークンを発行し、PAYJP側に送っています。具体的にはresponse.idがトークンになります。
↓ 該当コード
Payjp.createToken(card, function(status, response) {
statusによってどのようなエラーが起きているかを確認することができます。statusが200であれば正常にPAYJPと通信できていることになります。
例), console.log(status)
↓ エラー内容一覧

その次に取得したトークンを変数tokenに格納し、.submit()メソッドを使ってコントローラー側に送信しています。
↓ 該当コード
var token = response.id;
$("#card_token").append(`<input type="hidden" name="card_token" value=${token}>`)
$("#card_form").get(0).submit();
ここまでがJSが行っている動作です。改めてまとめると、JSでは以下の3つの処理を行っていることになります。
- カード情報の取得
- 取得したカード情報を元にトークン作成
- トークンをコントローラーに送信
環境変数の設定
続いてテスト用の公開鍵と秘密鍵を環境変数として設定します。これらの設定が抜けていたり、値が異なったりしてしまうとエラーの原因になるので注意しながら進めていきましょう。
今回ではcredentials.yml.encにこれらの値を設定していきます。
credentials.yml.encについてはこちらの記事を参考にしてください。

↓ ターミナル
$ EDITOR="vi" bin/rails credentials:edit
↓ credentials.yml.enc
payjp:
public_key: 公開鍵をペースト ← 今回この値は使用しません
secret_key: 秘密鍵をペースト
コントローラー実装
コントローラーではトークンをPAYJP側に送信し、顧客IDを受け取ります。加えて、自身のデータベースにも保存するための記述を追加します。
↓ コントローラー例
class CardsController < ApplicationController
# 省略
def create
Payjp.api_key = Rails.application.credentials[:payjp][:secret_key]
customer = Payjp::Customer.create(
card: params[:card_token],
metadata: {user_id: current_user.id}
)
@card = Card.new(
card_id: customer.default_card,
customer_id: customer.id,
user_id: current_user.id
)
@card.save
end
# 省略
end
まずは先ほど設定した環境変数を読み込むことで、PAYJPと通信できるように設定しています。
↓ 該当コード
Payjp.api_key = Rails.application.credentials[:payjp][:secret_key]
次にPAYJPのメソッドを用いて顧客IDを生成・取得しています。
↓ 該当コード
customer = Payjp::Customer.create(
card: params[:card_token],
metadata: {user_id: current_user.id}
)
最後に自身のデータベースに顧客IDとカード情報、ユーザーIDを保存しています。
↓ 該当コード
@card = Card.new(
card_id: customer.default_card,
customer_id: customer.id,
user_id: current_user.id
)
@card.save
要点まとめ
- PAYJP実装の大まかな流れとしては、「PAYJPにログイン」→「PAYJPの導入」→「フォーム実装」→「JS実装」→「環境変数の設定」→「コントローラー実装」となる
- 「Payjp.createToken(card, function(status, response)」の記述でトークンを生成することができる
- 「Payjp::Customer.create(」の記述で顧客を生成・取得することができる
参考
PAYJP公式リファレンス:https://pay.jp/docs/api/#payjp-api
今回はBASEのオンライン決済システム「PAYJP」を用いた決済機能の実装手順を解説しました。シンプルなチェックアウト版ではなく、ぜひカスタマイズ版の実装に挑戦してみてください。