少しのコードでWebPayを導入する


## はじめに

[WebPay Advent Calendar 2013](http://qiita.com/advent-calendar/2013/webpay) は、日頃あれ書きたいねこれ書きたいねと言いながら丁寧に整形するのが億劫になって優先度を下げがちな、WebPayの細かかったり、具体的だったりする情報を「まず外に出す」を実践しようということで@sowawa と私の思いつきでオーガナイズされました。
**減らそうお問い合わせ対応**。

もちろん、ユーザのみなさまのご参加も歓迎しているのですが、プレゼンスに弱気な私たちは、25日全てが埋まらなかった（現在お二人ですしね）場合に毎日WebPayやそれにまつわる決済のTipsを紹介していく決意をしております。下手したら毎日publishに迫られる現状を直視しても足の震えを抑えなければなりません。師と名乗るのは憚られますが、まさに師走です。

## 更新のおしらせ

本記事はWebPay gemのバージョン2系に即して記述しています。
その後、メジャーバージョンアップを行いました。

ほとんどの内容はそのまま利用できますが、メソッド名などが一部変更になっています。
最新の情報は[WebPay公式サイトのRuby APIドキュメント](https://webpay.jp/docs/api/ruby)を参照してください。

## 決済のコードを出来るだけ少なく

ウェブサービスのコードの中で決済に関わる部分に対する開発者の不安を拭うことはとても難しいです。ソフトウェアとして動くというのは勿論、ビジネス上の条件との整合性や
決済に限った話ではないですが、お金を払うお客さんという登場人物が増えるだけで「何か問題があったら...」と膨らむ緊張感は小さくありません。

テストを書くとかプライシングの責任者とのコミュニケーションを密にとか大事なことはいくらでもあるのですが、その中でも「決済にまつわるコードを少なくする」というのもあっても良いかもしれません。シンプルで短いコードで無為なミスや変な勘違いの種を出来る限り排除出来るのではないでしょうか。

[WebPay](https://webpay.jp/)では、APIの仕様をはじめ各言語向けのライブラリを公開しているため、それを利用すれば簡単な記述ですぐに決済を行う処理を記述できそうです。

## Sinatraアプリ で WebPay を使う

今回は、トップページにあるボタンを押したらすぐに商品の購入が行えるような[Gumroad](https://gumroad.com/)のようなウェブアプリケーションをRuby向けのウェブアプリケーションフレームワーク、[Sinatra](http://www.sinatrarb.com/)を使って作ってみます。

利用するGemは次の通りです。私はhamlがとても好きです。

```ruby
gem 'sinatra'
gem 'haml'
gem 'webpay'
```

### 実装

- '/'で購入情報を入力して、'/purhcase'にpost
- '/purchase'でWebPayを利用した課金処理と結果出力

を実現するSinatraアプリケーションをざっと書くとこんな感じでしょうか。

```ruby
require 'bundler'
Bundler.require

WebPay.api_key = 'test_secret_eHn4TTgsGguBcW764a2KA8Yd'
WEBPAY_PUBLIC_KEY = 'test_public_19DdUs78k2lV8PO8ZCaYX3JT'
WEBDB_PRESS_PRICE = 1554

set :haml, format: :html5

get '/' do
  haml :index
end

post '/purchase' do
  begin
    @charge = WebPay::Charge.create(currency: 'jpy', amount: WEBDB_PRESS_PRICE, card: params['webpay-token'])
    haml :purchased
  rescue => e
    redirect to('/')
  end
end
```

WebPayでの課金の発生方法（on Ruby）については[こちら](https://webpay.jp/docs/api/ruby#charge_create)をご参照ください。

これに加えてカード情報を入力して送信するためのviewである`haml :index`で、[CheckoutHelper](https://webpay.jp/docs/checkout)を利用します。

CheckoutHelperは数行のHTMLを記述しておくだけで

- クレジットカード番号、有効期限のバリデート
- クレジットカードの有効性チェック
- クレジットカード情報の代替トークン化

をWebPayと直接通信をユーザインタフェースを含め全て行ってくれる[WebPay.js](https://webpay.jp/docs/payments_with_token#client-side)のヘルパーです。使い方については[公式のドキュメント](https://webpay.jp/docs/checkout)に譲ります。

```haml
%form{ action: '/purchase', method: 'post' }
  %script{ src: 'https://checkout.webpay.jp/v1/', class: 'webpay-button', :'data-text' => 'WEB+DB PRESS vol.76 を購入する', :'data-submit-text' => '代金1554円をカードで支払う', :'data-key' => WEBPAY_PUBLIC_KEY }
```

これらのコードは https://github.com/hmsk/webpay-sinatra-sample でも公開しています。すぐにお手元でお試しの際は

```
$ git clone git@github.com:hmsk/webpay-sinatra-sample.git
$ cd webpay-sinatra-sample
$ bundle install
$ bundle exec ruby app.rb
```

の上で http://localhost:4567 をブラウザで開いてみてください。バックナンバーではありますが WEB+DB PRESS vol.76 の想像購入をお手元で楽しめます。ご自身のアカウントのテスト環境を利用したいということでしたら、`WebPay.api_key`、`WEBPAY_PUBLIC_KEY`を適宜書き換えてください。

このアプリケーションを[Herokuでも触れるように公開しておきました。](https://webpay-sinatra-sample.herokuapp.com/)是非お試しください。

ちなみに、お試しする際のカード情報として、
番号はこの世に実在しても良さそうなもの（[Luhnのチェックサム](http://ja.wikipedia.org/wiki/Luhn%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0)が通る）、未来にあたる有効期限、任意の数字3,4桁が揃っていれば、WebPayのテスト環境上で利用可能ですので、あなたの本物のカードの情報や[テスト用のカード情報](https://webpay.jp/docs/mock_cards)を入力すると良いでしょう。

ここまで10分もかかっていませんし、正味30行そこそこといったところでしょうか。それなりに短いコードで決済のロジックを含めてGumloadっぽいウェブアプリケーションになりました。

`haml :purchased`にあたるviewもそうですが、あとはよしなに見映えや補助的なページ、例外ハンドリング等を加えていけばすぐに何かを売る事が出来そうです。

さて今日はここまで。明日の@sowawa にバトンタッチです。
私もいずれまたお会いしますでしょう。