ピティナ開発者ブログ

全日本ピアノ指導者協会のIT担当者が気まぐれにつづる技術系中心のブログです


クレジットカード決済にOmiseを導入してみている最中で、良さそうな点・いまいちな点

前置き

2017年の1月も半ばですね、Hiroyuki Noguchiです。
Webpay終了事件への対応に追われている方々が、結構出てきている頃なんじゃないかなーと思いますがいかがでしょうか。

当協会では、あれこれ検討した結果、Omiseさんを移行の第一候補として進めることにいたしました。

www.omise.co

導入の決め手

導入の決め手はいくつかありますが、

  • バックグラウンドがしっかりしていそう(Webpayのようなクローズはなさそう)
  • Recursions API (定期課金) の実装予定がある
  • 日本向けに ******(本決まり未定とのことで一応伏せ字) の実装予定がある
  • 日本向けにJCBの実装もできる
  • リンク型決済の実装がある
  • 営業担当者さんのご対応

このへんが、やはり大きいところでした。

APIの充実度などはやはりStripeに惹かれるところもありましたが、JCB対応できないというのが、当協会としてはかなり厳しい判定要因になりました。

リンク型決済とは

さて、導入理由の4番目、

  • リンク型決済の実装がある

と書きました、これについて。

そもそもリンク型決済って何ぞや、という話については簡潔に。
特定のURLを、メールなりチャットなりで、支払して欲しい相手に送信する。……と、それだけで、クレジットカード決済できる。

例えば以下のような感じになります(テストショップのURLになります)

test - Omise Link

PayPalなんかでよくあるアレですね。
決済を申込フォームと切り離し、疎結合にできるので、素敵です。

ただ、これで決済完了に至っても、「決済完了メール」が飛ぶような実装にはなっていないんですね。
このあたりがPayPalと違って貧弱で、悲しいところです。
なので、自分で作らないといけない。悲しい(強調)

OmiseのWebhook

自分で作る。面倒です。
OmiseのWebhookがPOSTで渡してくれるJSONデータを受け取るクチを用意しなくてはなりません。面倒です(強調)

なるべくサーバレスでやりたいと考えているので、ひとまず、GoogleAppsScriptで受け取るようにしてみます。
ただ、ドキュメントを読んでみても、情報が少なくて何が返ってくるんだかよく分からないのですね。

www.omise.co

  • 返ってくるのはJSON
  • POSTでくる?

このドキュメントだけでは分かりませんので、やってみて自分で確かめろ、ってことですかね……

www.omise.co

そもそもOmiseのドキュメントは、

Version 2015-11-17

のまま止まっているように見えます。
が、サポートさんに問合せてみたところ、最新にupdateされている、とのご回答でした。
いやそれなら、日付も最新にしておいて欲しいのですが……これについては、横道に逸れるので、末尾に補足を書いておきます。

さて、日本語版のローカライズができていないだけなんじゃないか、という淡い期待を持って、URLから言語指定はずしてみました。

www.omise.co

すると、POSTで返ってくるということは分かりました。日本語ページで何で「POST」の記述をはずしたし。
何はともあれ、何が返ってくるのか、まずは試してみましょう。

で、実装した最低限のコードとしては以下のようになります。

function doPost(e) {
  var jsonString = e.postData.getDataAsString();
  var jsonData   = JSON.parse(jsonString);
  
  var ss    = SpreadsheetApp.openById('hogehogehogehogehogehoge');
  var sheet = ss.getSheetByName('hoge');
  
  sheet.appendRow([jsonString]);
}

doPost() 関数を書くことで、トリガーは特に設定せずに、POSTで渡ってきたデータを受け取ることができるようになります。
以下、GoogleAppsScript の doPost() のドキュメントなのですが、まあ、あまり親切ではないですね……

Web Apps  |  Apps Script  |  Google Developers

あと、GoogleAppsScriptで動作させる上で、知っておかないとハマるよなあ……というポイントを押さえた記事を引用しておきます。

アプリの実行権限を得る

qiita.com

4.スクリプトを変更したら必ずバージョンを更新する!

qiita.com

あとは、Omiseのダッシュボードで、WebhookからエンドポイントのURLを登録しましょう。
登録すべきURLは、GooeleAppsScriptで発行されたURLになります。
URLの発行の仕方は、上記同記事、以下参照にて。

1.まずスクリプトエディタ画面の公開>ウェブアプリケーションとして導入をクリック
2.アプリケーションの実行ユーザは「自分」、アクセスできるユーザーを「全員(匿名ユーザーを含む)」にする。これで公開URLゲットです。

qiita.com

JSONが返ってきた

さて、これらが済んだ上で、テストで決済をおこなってみたところ、指定したスプレッドシート内のシートの指定行に、以下の内容が返ってきました。

"{
  ""object"": ""event"",
  ""id"": ""evnt_test_hogehogehogehogehoge"",
  ""livemode"": false,
  ""location"": ""/events/evnt_test_hogehogehogehogehoge"",
  ""key"": ""charge.create"",
  ""created"": ""2017-01-19T07:19:08Z"",
  ""data"": {
    ""object"": ""charge"",
    ""id"": ""chrg_test_hogehogehogehogehoge"",
    ""livemode"": false,
    ""location"": ""/charges/chrg_test_hogehogehogehogehoge"",
    ""amount"": 1000,
    ""currency"": ""jpy"",
    ""description"": ""test\n\ntest"",
    ""status"": ""successful"",
    ""capture"": true,
    ""authorized"": true,
    ""reversed"": false,
    ""captured"": true,
    ""transaction"": ""trxn_test_hogehogehogehogehoge"",
    ""source_of_fund"": ""card"",
    ""refunded"": 0,
    ""refunds"": {
      ""object"": ""list"",
      ""from"": ""1970-01-01T00:00:00+00:00"",
      ""to"": ""2017-01-19T07:19:08+00:00"",
      ""offset"": 0,
      ""limit"": 20,
      ""total"": 0,
      ""order"": null,
      ""location"": ""/charges/chrg_test_hogehogehogehogehoge/refunds"",
      ""data"": [

      ]
    },
    ""return_uri"": ""https://link.omise.co/hogehoge/complete"",
    ""offsite"": null,
    ""reference"": ""paym_test_hogehogehogehogehoge"",
    ""authorize_uri"": ""http://api.omise.co/payments/paym_test_hogehogehogehogehoge/authorize"",
    ""failure_code"": null,
    ""failure_message"": null,
    ""card"": {
      ""object"": ""card"",
      ""id"": ""card_test_hogehogehogehogehoge"",
      ""livemode"": false,
      ""country"": ""us"",
      ""city"": null,
      ""postal_code"": null,
      ""financing"": """",
      ""bank"": """",
      ""last_digits"": ""4242"",
      ""brand"": ""Visa"",
      ""expiration_month"": 11,
      ""expiration_year"": 2020,
      ""fingerprint"": ""hogehogehogehogehogehogehogehogehogehoge"",
      ""name"": ""test"",
      ""security_code_check"": true,
      ""created"": ""2017-01-19T07:19:06Z""
    },
    ""customer"": null,
    ""ip"": ""192.168.1.1"",
    ""dispute"": null,
    ""created"": ""2017-01-19T07:19:07Z""
  }
}
"

JSON形式でした。
後はこれをお料理すれば……

……あれ?

そういや個人情報どこにもないじゃん

ええ、そうなんです、Omiseのリンク型決済って、PayPalみたいに、名前もメールアドレスも何も入力させられないんですよね。
なので、個人情報の収集のしようがない、だからJSONにそんなデータが入っているはずもない。
メールを送れない、どころか、支払者の個人特定が困難。

ん? じゃあ、「複数使用可能なリンク型決済」って、使い道あるの……?

使い道ないです。現状、落とし穴です。

クレジットカード名義(アルファベット)しか取得できないので……特に日本じゃきつすぎる(同姓同名とか……)

まあ、人間が目視確認すれば、誰が何について入金したか、っていうのを、ある程度はつきあわせて照合できる、のかも、しれ、ま、せん、が、が、が……

もっとも、リンク型決済の作成を「一回限りの支払」という設定にして、「このリンクURLを送信したのはこの人」というように一対一対応しておけば、個人特定はできます。
が、その場合、リンク型決済URLが大量増殖していくので、ちょっと管理がつらみ。
リンク型決済は、数少なく抑えておいた方が、運用が楽でいいと思います。その方がDRYです。

リンク型決済は今のところ使わない方がよいです

……という結論になりますね。
このあたり、何とかしてくださいよ、という要望は、Omiseさんにはお伝えしていますが、今のところ、有効回答はいただけていません。
何とかして欲しいです(切実)

何らか有効なご回答いただけたら本記事も更新予定ではおります。
きっといただけるんじゃないかなーという期待はあります。

Webpay事件でクレジットカード決済の移行先を検討中の方々、Omiseをこれから導入しようと考えている方々に、少しでも参考になればと共有させていただきます。

補足:実はドキュメントは最新じゃないし、Githubソースコードも最新じゃないですよ、という落とし穴

もうちょっとだけ続くんじゃよ。

サポートさんからは、最新です、と言われていたドキュメントですが、どう見ても最新じゃなさそうです。

www.omise.co

こちらCard.jsのドキュメントページで、どういうものかというと、

Card.jsを使って[今すぐ支払う(Pay Now)]ボタンをフォームに設置できます。このボタンにより、ユーザーがクレジットカード情報を入力することのできるポップアップウィンドウが起動します。

ということで、必要不可欠な機能ですね。
なのに、まずいきなり文中に、

currency: ‘jpy’ は、現在未対応です。

と出ています。
が、そんな馬鹿な、ですよね、日本で展開しているのに日本円に対応していないわけがない……

www.omise.co

「Currency と Amount」ページを見ると、jpyについての記載もあります(当然)

Card.js のドキュメントに戻ってきて、読み進めてみると、サンプルコードがあります。
そのまま引用させていただきます。

<html>
...
<body>
<form name="checkoutForm" method="POST" action="checkout">
    <input type="hidden" name="description" value="商品合計 10,025円" />
    <script type="text/javascript" src="https://cdn.omise.co/card.js"
      data-key="YOUR_PUBLIC_KEY"
      data-image="PATH_TO_LOGO_IMAGE"
      data-frame-label="Merchant site name"
      data-button-label="Pay now"
      data-submit-label="Submit"
      data-location="yes"
      data-amount="10025"
      data-currency="jpy"
      >
    </script>
    <!--the script will render <input type="hidden" name="omiseToken"> for you automatically-->
</form>
</body>
</html>

……ん? サンプルコード中に、思いっきり、

data-currency="jpy"

ってあるじゃないですか。じゃあ、これでいけるじゃないですかー、と思うじゃないですか。
で、やってみると、

f:id:ptna_it:20170119190052p:plain

……THB! THBじゃないか!!

まあ、そうですよね、

currency: ‘jpy’ は、現在未対応です。

って言ってましたものね、ここに嘘偽りは無いんですね……

あれ、じゃあ、Omiseって日本で使えないんじゃない!?
そんな馬鹿な話は無いと思って、色々試してみました、当協会のHiroto Otakeと一緒に。
そうしましたらですね、

<script type="text/javascript" src="https://cdn.omise.co/card.js"

 ↓

<script type="text/javascript" src="https://cdn.omise.co/omise.js"

こう書き換えると、なんと!

f:id:ptna_it:20170119190042p:plain

いける。ちゃんとjpyで表示されている。っていうか、デザインが全然違う、イケてる感じになってる。
……え、何、この裏技? こんなのドキュメントに書いてない。
そりゃ、頭に、

Card.jsはOmise.js上で構築されており

と書かれてはいるけれど、まさか、 Card.js は廃止?で、 Omise.js が完全に代替できてしまうなんて、そんな馬鹿な。

Github 行って、中身を見てみることにしました。

github.com

……あれ?
CDNにあがっているソースコードと違うんじゃね??

https://cdn.omise.co/omise.js ※minifyされてます

違いますね、ええ、どう見ても……
このあたりで、ちょっと疲れてきて思考が止まってきました。

Github上では、最終コミット日が

16 Nov 2015

となっているので、ドキュメントの日付とは符号します。
が、CDN上のファイルだとjpyに対応しているので、おそらく、CDNのファイルはGithubと連携されずに更新されているのだと思います。
うん……うん? ……うん。

こんなこと書いてくると、「Omise導入つらい」という結論になりそうなものですが、とはいえ、誤りは正してもらえそうな雰囲気は今のところ感じられてはおりますし(当然ではあるんですが、当然が通用しないような企業もあるのでしてね……)将来性は感じられるので、もう少しOmiseで突っ込んでみようとは思っています。

Omiseさん、がんばってください。

追記(2017/02/05)

中の人がはてなブログを開始されたようで、早速、Webhookの記事をあげられていましたので、共有します。

akinrt.hatenablog.com

(著: Hiroyuki Noguchi)
この記事は現在0人が閲覧中