Help us understand the problem. What is going on with this article?

WebPayはStripeと何が互換しているのか

More than 5 years have passed since last update.

本記事の内容は2013年12月のものです

WebPayはこの後、2014年6月にStripeとの互換性を維持しないという決定を下しました。
本記事のようにStripeが公開しているライブラリを用いての実装はサポートしないこととなります。

その一方で、どの言語でもよりWebPayが使いやすいように、ライブラリの作成、更新に力をいれています。
詳細は次のブログ記事をご覧ください。 非互換なライブラリのアップデートを行いました - WebPay Engineering Blog

ライブラリについてご意見、ご要望がある場合はライブラリ用のフォーラムより御気軽にお問い合わせください。

Stripe製ライブラリについて

WebPayは登場時、Stripeとの互換性を謳い

require "stripe"
Stripe.api_key  = "test_secret_7u7fWx6xObdffBLbr8eJL11L"
Stripe.api_base = "https://api.webpay.jp"
Stripe::Charge.create(
   :amount=>400,
   :currency=>"jpy",
   :card=>
    {:number=>"4242-4242-4242-4242",
     :exp_month=>"11",
     :exp_year=>"2014",
     :cvc=>"123",
     :name=>"KEI KUBO"},
   :description=>"アイテムの購入"
)

のようなコードでWebPayを利用した決済が可能であることを紹介することが多々ありました。

この例は今でも利用可能で、同様にPHP, Python向けのStripeのライブラリでの利用方法を掲載しています。

ただし、こちらのドキュメントを閲覧する分には問題ないのですが、逆にStripeの方のドキュメントを見ながら実装していくとWebPayでは利用出来ない機能が多々あり、困らされることがあるでしょう。

今回はWebPayとStripeの互換について触れていきます。

単純なオブジェクトだけの互換

では、どの部分が互換なのか。これを簡単に答えるとするならば
Charge、Customer、Tokenのオブジェクトに関してほぼ互換と私はよく話します。

WebPayは正式リリースである今年の6月までに大きな仕様の変更がこの1年間に2度ほどありました。
ひとつ目は

  • 初回にベータとしてリリースしたものから当時のStripeとほぼ完全互換にフルスクラッチで作り直した時

で、Charge, Customer, Token, Subscriptionまわり(Subscription, Plan, Invoice)がいくつかの機能がStripeと互換しているものから
2013/1頃のStripeのドキュメントにあるほぼ全ての動作と互換したものに変わりました。初期のリリース時には無かった、InvoiceItem, Coupon, Discountといったオブジェクト群からSubscriptionの挙動までほぼ同様に動く要になっていました。

ふたつ目は

  • 正式リリース前に定期購読周辺を全て外した時

で、今のような限定されたオブジェクトでの互換に変更しました。
(ref: 定期課金周りの仕様変更について : ウェブ決済ブログ

定期購読を惜しむ声も頂いており、これは大きな決断となりました。
というのも、StripeのSubscriptionまわりの仕様が、ドキュメントからでは判断し切れないほど複雑で、それを私たちが上手にユーザに届ける自信が無かったこと、互換性を追い過ぎてシンプルな形を見失っていたことからでした。

ここでその深くに触れはしませんが定期購読は

  • トライアル期間を設けられる
  • プランの乗り換えができる
    • 同じ周期(月、年など)なら日割り計算される
  • 解約しても期間末まで使えるかどうかを選択できる
  • クーポンが利用出来る
    • 割引、値引を選べる
    • 有効期限や利用回数を設定出来る
  • 定期購読の請求にadditionalな請求を付加できる
  • ...etc

といった、とてもリッチな機能揃いだったのですが、APIドキュメントからそれを全て察することはほとんどのユーザが出来ないのではないかと思われるほどでした。

さて、互換している部分の話に戻って実際にそれぞれのgemでそれぞれのサービスを叩いてみましょう。

StripeのgemでWebPayを使う

概ねは

に書かれている通りなのですが

  • Stripe::Charge
    • .create / .retrieve / #refund / #capture / .all
  • Stripe::Customer
    • .create / .retrieve / #delete / .all
  • Stripe::Token
    • .create / .retrieve
  • Stripe::Event
    • .retrieve / .all
  • Stripe::Account
    • .retrieve

が、ほぼそのまま利用が出来ます。

WebPayのgemでStripeを使う

逆の方法については、なかなか書かれることがありませんでしたのでここで実際に触っていきましょう。

課金を行うなら

require 'webpay'
WebPay.api_base = "https://api.stripe.com/"
WebPay.api_key = "sk_test_6Uz1kR2biJfcy8BjNVqm5PJ5"
WebPay::Charge.create(
  :amount => 400,
  :currency => "usd",
  :description => "Charge through Stripe with webpay gem",
  :card=>
    {:number=>"4242-4242-4242-4242",
     :exp_month=>"11",
     :exp_year=>"2014",
     :cvc=>"123",
     :name=>"KEI KUBO"}
)

としてみましょう。(APIキーはStripeのものを入れます)

=> #<WebPay::Charge:0x007f974b114290
 @attributes=
  {"id"=>"ch_34w180wsExSITd",
   "object"=>"charge",
   "created"=>1386426843,
   "livemode"=>false,
   "paid"=>true,
   "amount"=>400,
   "currency"=>"usd",
   "refunded"=>false,
   "card"=>
    #<WebPay::Card:0x007f974b115a78
     @attributes=
      {"id"=>"card_34w1nCKowm1sv1",
       "object"=>"card",
       "last4"=>"4242",
       "type"=>"Visa",
       "exp_month"=>11,
       "exp_year"=>2014,
       "fingerprint"=>"UuOVvNwpeLsLaOr5",
       "customer"=>nil,
       "country"=>"US",
       "name"=>"KEI KUBO",
       "address_line1"=>nil,
       "address_line2"=>nil,
       "address_city"=>nil,
       "address_state"=>nil,
       "address_zip"=>nil,
       "address_country"=>nil,
       "cvc_check"=>"pass",
       "address_line1_check"=>nil,
       "address_zip_check"=>nil}>,
   "captured"=>true,
   "balance_transaction"=>"txn_34w1CywUmzBMKv",
   "failure_message"=>nil,
   "failure_code"=>nil,
   "amount_refunded"=>0,
   "customer"=>nil,
   "invoice"=>nil,
   "description"=>"Charge through Stripe with webpay gem",
   "dispute"=>nil,
   "metadata"=>{},
   "fee"=>42,
   "fee_details"=>
    [{"amount"=>42,
      "currency"=>"usd",
      "type"=>"stripe_fee",
      "description"=>"Stripe processing fees",
      "application"=>nil}]}>

返って来ました。このままこのChargeのID(ch_34w180wsExSITd)で情報を取り出してみます。

WebPay::Charge.retrieve("ch_34w180wsExSITd")
=> #<WebPay::Charge:0x007f974b9643a0
 @attributes=
  {"id"=>"ch_34w180wsExSITd",
   "object"=>"charge",
   "created"=>1386426843,
   "livemode"=>false,
   "paid"=>true,
   "amount"=>400,
   "currency"=>"usd",
   "refunded"=>false,
   "card"=>
    #<WebPay::Card:0x007f974b9643c8
     @attributes=
      {"id"=>"card_34w1nCKowm1sv1",
       "object"=>"card",
       "last4"=>"4242",
       "type"=>"Visa",
       "exp_month"=>11,
       "exp_year"=>2014,
       "fingerprint"=>"UuOVvNwpeLsLaOr5",
       "customer"=>nil,
       "country"=>"US",
       "name"=>"KEI KUBO",
       "address_line1"=>nil,
       "address_line2"=>nil,
       "address_city"=>nil,
       "address_state"=>nil,
       "address_zip"=>nil,
       "address_country"=>nil,
       "cvc_check"=>"pass",
       "address_line1_check"=>nil,
       "address_zip_check"=>nil}>,
   "captured"=>true,
   "balance_transaction"=>"txn_34w1CywUmzBMKv",
   "failure_message"=>nil,
   "failure_code"=>nil,
   "amount_refunded"=>0,
   "customer"=>nil,
   "invoice"=>nil,
   "description"=>"Charge through Stripe with webpay gem",
   "dispute"=>nil,
   "metadata"=>{},
   "fee"=>42,
   "fee_details"=>
    [{"amount"=>42,
      "currency"=>"usd",
      "type"=>"stripe_fee",
      "description"=>"Stripe processing fees",
      "application"=>nil}]}>

これでWebPayのgemでStripeのAPIを利用出来ていることがわかります。逆の場合も同様に

  • WebPay::Charge
    • .create / .retrieve / #refund / #capture / .all
  • WebPay::Customer
    • .create / .retrieve / #delete / .all
  • WebPay::Token
    • .create / .retrieve
  • WebPay::Event
    • .retrieve / .all
  • WebPay::Account
    • .retrieve

を利用できます。

互換したら何が良いのだろう

どちらのgemでもお互いのサービスの特定の機能が使えることがわかりましたが、これの何が良いのだと思われるでしょう。

それはStripeが日本以外、円以外の通貨への展開を行っており、WebPayが日本、円への展開を行っていることが特にキーとなります。
これの表わすところは、互換している箇所においては、接続先を切り替える(通貨を切り替える)だけで米国展開->日本展開、日本展開->世界展開が可能になるという点です。

require "webpay"
+ WebPay.api_base = "https://api.stripe.com/"
+ WebPay.api_key = "[Stripeのキー]"
- WebPay.api_key = "test_secret_7u7fWx6xObdffBLbr8eJL11L"
WebPay::Charge.create(
    :amount=>400,
+   :currency=>"usd",
-    :currency=>"jpy",
   :card=>
    {:number=>"4242-4242-4242-4242",
     :exp_month=>"11",
     :exp_year=>"2014",
     :cvc=>"123",
     :name=>"KEI KUBO"},
   :description=>"アイテムの購入"
)

というdiffだけで世界に出られるというのは素敵ではないでしょうか。
もちろん国を越えることで価格をはじめ、色んな差異を鑑みないとならない話ではありますが、第一歩をこれだけで踏めるというのはシンプルでしょう。
(WebPayがドル対応すれば良いのではという話もごもっともですね)

また、決済サービスの登場の度に色んな仕様が現れることに最初は抵抗感があったというのが正直なところです。
「とても良くなる」という話でなければ無為に世の中にクレジットカード決済のための仕様を増やすことを避けたかったのです。

加えて、Stripeのために既に世に生まれている多くの資産にあやかれるというのも絶大です。

WebPay独自のインタフェース

クレジットカード決済をシンプルにする方角であれば、互換しないということを選ぶという判断上、独自のインタフェースが追加されていくことでしょう。
逆にStripeも日々進化しており、WebPay側にキャッチアップ出来ていない機能も多々現れてきています。もしStripeのあれみたいなの欲しいのだけどというお話があれば是非声をかけて貰えると嬉しいです。

今はまだまだユーティリティレベルのものでテスト環境のデータの全削除
くらいしかありませんが、ここから表向きにも少しずつ情報を出して行けるのではないかと思います。ちなみにこの機能はWebPayのテスト環境も含めたインテグレーションテストを行う場合のセットアップ時に実行すると便利です。

もちろん定期購読についても取り消したままのつもりではありません、シンプルな形に落とせた定期購読の機能もいずれリリース出来るようしていければと思います。

それでは本日はここまで。良い日曜日をお過ごしください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away