Ruby
WebAPI
RubyOnRails
決済
square

クレジットカード番号を保有せずクレジットカード番号を保存するCard on Fileの使い方

More than 1 year has passed since last update.

Eコマースサイトなどでよくある「クレジットカード番号を保存する」チェックボックスですが、これをチェックしておくとクレジットカード番号がそのまま保存されそうで何となく避けてしまう人も多いでしょう。とは言え、毎回の決済時にカード番号を入力するのも面倒です。

そこでSquareで提供しているのがCard on Fileと呼ばれる機能です。これはカード番号を保有せず、サービス提供事業者がカード決済を繰り返し使えるようにする機能です。

今回はRuby on Railsで簡易的に実装したデモを元に紹介します。

認証について

カード情報を保存するので、認証はあった方が良いでしょう。今回はDeviseを使って簡単に実装してあります。

カード番号の保存

認証後、カード番号を保存できるようになります。

Screenshot_ 2017-11-23 14.40.03.png

クレジットカード番号の入力フォームです。Bootstrapベースになっています。ちなみにここで表示されているテキストボックスはすべてSquare側のiframe内で提供されており、Webサービス提供側からは触れないようになっています。ユーザからの見た目はWebサービス側そのままですし、デザインの自由度も高いのですがセキュリティ的に安全な仕組みになっています。

カード番号を入力してカード番号を保存するボタンを押すと、まずカード番号や有効期限、CVVといった情報がSquareのサーバに送られます。その結果、一時的に決済に使えるトークン(nonce)が発行されます。このトークンと決済金額を合わせて決済ができますが、これは一度しか使えません。

カード情報を永続化する

そこでこのトークンを映像化します。そのためにはまずSquareの顧客APIを使って、顧客を作ります。これはカード番号をまとめて管理するためのもので、メールアドレスや名前などだけで作れます。パスワードは不要です。

Rubyの場合は次のように実装します。

api = SquareConnect::CustomersApi.new

if current_user.square_customer_id.nil?
  customer = api.create_customer({
    email_address: current_user.email
  }).to_hash[:customer]
  current_user.update_attribute :square_customer_id, customer[:id]
end

次にこの情報とカードのトークン(nonce)とを結びつけてカードを作成します。

card = api.create_customer_card(
  current_user.square_customer_id, {
  card_nonce: card_nonce
}).to_hash[:card]

後はこの結果をもとに、IDをデータベースに保存します。

current_user.cards.create(
  nonce: card[:id],
  last4: params[:last_4],
  brand: params[:card_brand],
  exp_month: params[:exp_month],
  exp_year: params[:exp_year]
)

決済を行う

では決済を行う場合です。処理時には店舗ID(location_id)や処理ID(ユニークな文字列)が必要です。そして前述の顧客ID(current_user.square_customer_id)とカードIDを使って決済が行えます。

Screenshot_ 2017-11-24 9.14.15.png

idempotency_key = SecureRandom.uuid
card = current_user.cards.find(params[:checkout][:card])
amount = params[:checkout][:amount].to_i # 決済額

api = SquareConnect::TransactionsApi.new
transaction = api.charge(load_config['location_id'], {
  idempotency_key: idempotency_key,
  amount_money: {
    amount: amount, currency: 'JPY'
  },
  customer_id: current_user.square_customer_id,
  customer_card_id: card.nonce
}).to_hash[:transaction]

このIDの組み合わせであれば繰り返し決済処理が行えます。

Screenshot_ 2017-11-24 9.22.15.png


こちらのコードは goofmint/Square_Card_on_File_Demo: SquareのCard on Fileを使ったデモです。 にアップロードしてあります。実装時の参考にしてください。また、質問がある場合には Teratail にてお願いします!

Build with Square