EX-決済API と Ruby 🍣 時々 Rails

EX-Omise JapanのLead Developerです。

決済APIでカードの有効期限切れの対応ってどうするの?

PryとOmiseのRubyライブラリを使って、有効期限が切れるカードを持っているCustomerを検索する方法を書いておきます。

# pryを実行
pry

# omiseライブラリを読込
require "omise"

# APIキーを設定
Omise.api_key = "秘密鍵(シークレットキー)"

# 試しにdescriptionを更新するCustomerを取得
customer_id = "cust_test_xxxxx"
customer = Omise::Customer.retrieve(customer_id)

# デフォルトカードの有効期限を取得
expiration_month = customer.default_card.expiration_month
expiration_year = customer.default_card.expiration_year
expiration = "#{expiration_month}/#{expiration_year}"

# customerのdescriptionへデフォルトカードの有効期限を入れる
customer.update({description: expiration})

# 3/2019のデフォルトカードを持っているCustomerを検索
search_result = Omise::Search.execute(scope: "customer", query: expiration)
search_result.data.each do |customer|
  # ここで有効期限が切れそうなcustomerへ何かをする処理をいれる。
end

Customerへカードを紐づけるChargeをしている人には重宝するかもしれません。 Customerは Omise::Customer.list で一覧を取得することもできるので、これを使っていっきにdescriptionをアップデートしてもいいかもです。

オンライン決済 Omise で円決済の実装

Omiseが昨年の2016年06月14日(火)から日本向けに円決済を提供していることを皆さんはご存知でしょうか? 日本の法人・個人向けに日本円での決済ができるのです。

細かいこと抜きで、ゲストアカウントでささっと円決済をOmise Rubyライブラリで試す方法をまとめてみます。

ゲストアカウントでサインアップ!

テストアカウントを作る手間を省くため、ゲストサインアップを利用します。

Omiseの登録ぺージ へ移動し、 ゲストとしてサインアップする のテキストリンクをクリック。 f:id:akinrt:20170307152345p:plain

アカウント作成のページへ移動した後に、日本を選択し、契約内容に同意にチェックをつけてアカウント作成ボタンをクリックします。 f:id:akinrt:20170307152355p:plain

その後 テストキー を取得します! 公開鍵(パブリックキー)と秘密鍵(シークレットキー)があるので、これを後ほど利用します! f:id:akinrt:20170307152404p:plain

PryでChargeをしてみよう

ruby2.3.1以降とpryがインストールされている状態をイメージして話をしていきます。 Omise Ruby の公式ライブラリを使ってChargeをしていきます。 gemで配布しているので、下記のようにインストールします。

gem install omise

それでは、 pry をターミナルで実行してrubyを書いていきましょう!

APIキーの設定(公開鍵・秘密鍵)

ここでは、先ほどの テストキー から秘密鍵と公開鍵を使っていきます。 下記の、秘密鍵と公開鍵はご自身のキーを入れてください。

Omise.api_key = "秘密鍵"
Omise.vault_key = "公開鍵"

Omise.vault_key は、Tokenを作成する時に利用します。 クレジットカードデータを扱うので、本番利用時には使用しないようにしましょう。(※Omise.jsでトークンを作るようにしましょう。)

Tokenを作成

ここではVISAカードのテストカード番号である 4242424242424242 を利用してテストのトークンを作成します。

token = Omise::Token.create(card: {
  name: "TARO OMISE",
  number: "4242424242424242",
  expiration_month: 3,
  expiration_year: 2019,
  city: "Tokyo",
  postal_code: "1510051",
  security_code: 123
})

これにより、Charge を行うためのTokenが取得できました。 次に3種類あるChargeの方法を一つずつ見ていきます。

1. TokenだけをつかったCharge

さきほど作った token のidを参照させてChargeを行うには下記になります。 わずかこれだけで課金ができてしまっています。

charge = Omise::Charge.create({
  amount: 100000,
  currency: "jpy",
  card: token.id
})

しかし、トークンは一度だけ使えるといった性質があるため、このコードを再利用するとエラーが返ってきます。 次に同じカードを再利用する方法を見ていきましょう。

2. CustomerにCard(Token)を保存してCharges

Customerオブジェクトにはカード(Token)を複数持たせることができます。 最初に登録したカードをデフォルトカードとして所有する性質があります。 さきほどのTokenは再利用できなくなってしまっているので、再度新しいTokenを発行します。

token = Omise::Token.create(card: {
  name: "TARO OMISE",
  number: "4242424242424242",
  expiration_month: 3,
  expiration_year: 2019,
  city: "Tokyo",
  postal_code: "1510051",
  security_code: 123
})

customer = Omise::Customer.create({
  email: "taro.omise@omise.co",
  description: "taro omiseさんに関するメモなどを書ける場所",
  card: token.id
})

こうすうることで、Customerオブジェクトへカード(Token)を紐づけることができ、Customerオブジェクトを使ったChargeができるようになります。 この場合のChargeは下記のように行います。

charge = Omise::Charge.create({
  amount: 100000,
  currency: "jpy",
  customer: customer.id
})

こうすることで Customerに紐づけたカードを使って、再利用可能なChargeができるようになりました。

3. Customerの所有するカードを明示的に指定してCharge

Customerには複数カードを持たせることができますが、2枚目以降のカードを使うようにするには、Card IDを指定して利用します。 ここでは、先ほどの customer へ Mastercardのテストクレジットカード 5555555555554444 を追加してMastercard(2枚目のクレジットカード)でChargeをやってみましょう!

token = Omise::Token.create(card: {
  name: "TARO OMISE",
  number: "5555555555554444",
  expiration_month: 3,
  expiration_year: 2019,
  city: "Tokyo",
  postal_code: "1510051",
  security_code: 123
})

# Mastercardを先ほどのcustomerへ登録
customer.update(card: token.id)

# cardsの中身はarrayにhashでCardオブジェクトが入っています、2個目のCard IDを取得
mastercard_id = customer.cards.data[1]["id"]

charge = Omise::Charge.create({
  amount: 100000,
  currency: "jpy",
  customer: customer.id,
  card: mastercard_id
})

こんな感じでOmiseのChargeができます。 やってみるとすごく簡単だと思いますので、ぜひゲストアカウントからさくっと動かして見てください。

動作検証用のテストカードはこちらにたくさんあります。 正常動作とCharge時に各種エラー(failure code)がレスポンスに含まれるカードが整っています。

テストカードのGem omise_test_cards を作りました

これを使えばテストカードをウェブサイトから探さなくても簡単に利用できるようになります!

akinrt.hatenablog.com

Omise 商用へ移行した時にお伝えしたいこと(トークンとオーソリ)

商用へ移行され、実際に課金をテストされることがあるかと思います。
ここでは、商用へ移行された時に私たちが伝えきれていない?(と個人的には思います)情報を説明したいと思います。

1. 商用モードでのトークン作成って何をしているの?

カードの有効性チェックを行います。
そのため、日本の加盟店では、トークンを作成する時にカードが実際に使えるかを確認するため下記のことを行います。

クレジットカードの場合

  • トークンを作成開始
  • 送信したカードで100円の与信を行い100円の枠を抑える
  • 100円の与信が成功すれば、100円の与信枠を解放し、そのタイミングでの有効性を確認できたとして使えると判断する
  • 100円の与信が成功しなければ、トークン作成がエラーになる

デビットカードの場合

  • トークンを作成開始
  • 送信したカードで100円を本売上する
  • 100円の本売上が成功すれば、100円の返金をし、そのタイミングでの有効性を確認できたとして使えると判断する
  • 100円の本売上が成功しなければ、トークン作成がエラーになる

クレジットカードとデビットカードで言葉が若干違いますが、100円で課金できるかを確認して、そのタイミングでのカードの有効性を確認しています。

ですので、ほんの少しの間だけ100円の与信枠を確保と解放する時間がカードに発生します。
決済の裏事情ですね。。。。

※有効性チェックをオーソリともいいます。

※デビットカードの場合、明細書に100円の出金と返金が履歴に残るようです。
引き落としのギモン|Visaデビット|ジャパンネット銀行

2. そのタイミングでのカードの有効性って?

つまり、カードを使おうとした時に、カードがまだ使える状態かということです。

次の例の場合、課金(Charge)作成の時に失敗することがあります。

  1. 与信枠が残り2000円のカードで、カードを情報をフォームへ入力中
  2. カードフォームへ入力中に、どこかで登録している定期課金で2000円の与信が行われた
  3. カード情報を入力終わり、トークン作成
  4. トークン作成エラー(2. のタイミングで与信枠が足りなく(0円)なっているため)

3. 課金(Charge)作成時のエラーについて

課金(Charge)作成時のエラーについては、現時点では下記のエラーを返しています。
こちらは、日本でもタイでもインドネシアでも、英語が共通語としてChargeオブジェクトの failure_message に入ってきます。
日本語で対応されたい場合は、failure_code の文字列を参照していただき、switch文などでご利用に最適化した日本語に訳したテキストをアプリでご利用されると良いかと思います。

failure_code failure_message いつ発生するか
insufficient_fund “insufficient funds in the account or the card has reached the credit limit” 与信限度枠を超えた時
stolen_or_lost_card “card is stolen or lost” 盗難カード、または紛失カードの場合
failed_processing “failed processing” トランザクション処理のプロセスが失敗した場合
payment_rejected “payment rejected” 何らかの理由により、課金が拒否された場合
invalid_security_code “the security code is invalid” セキュリティコードが無効の場合
failed_fraud_check “failed fraud check” カードが不正だと判定した場合に発生
invalid_account_number “the account number is invalid” 利用できないカード番号の場合

4. 番外編 トークン作成時のステータスコードとレスポンス(Token/Errorオブジェクト)

TokenをOmise.jsで作成する時のつまづきポイントをメモしておきます。

ステータスコートとTokenオブジェクト

Tokenオブジェクトがレスポンスで返ってくる場合、ステータスコードは200が返ってきます。 このレスポンスには注意点がひとつあり、Tokenオブジェクトの中のCardオブジェクトの security_code_check が true になっているかも確認してください。 security_code_check が false の場合、そのTokenを使って課金(Charge)をしても invalid_security_code で課金は失敗します。

ステータスコードとErrorオブジェクト

Errorオブジェクトがレスポンスで返ってくる場合、ステータスコードはエラーの値が返ります。