コムセント 技術情報

  1. TOP
  2. コムセント 技術情報
  3. 開発者がクレジットカード決済を組み込むための基礎知識

開発者がクレジットカード決済を組み込むための基礎知識

前書き

こんにちは、エンジニアのN. Goです。

日々色々な Web システムを構築している弊社ですが、中でも得意としているのがフルスクラッチで開発する EC システムです。
昨今は便利なサービスが続々リリースされ、簡単なネットショップであれば思い立ったその日から開けるような時代です。

ただし、そこそこ大規模・またはユニークなシステムを持ったサービスほど、汎用的に作られたシステムは嵌まらないもの。
例えば商品のサイズで価格を変動させたり、フローにサービス内で使用できるポイント購入を挟んだり、完全クローズドの会員専用 EC サイトだったり……

だからこそ 1 からビジネスに合った形のシステムを開発するニーズがあるわけですね。
そんな時にほぼ避けて通れないのが、クレジットカード決済の組み込みです。
それこそパッケージ化されているシステムを組み込んで済むのであれば、詳しいことを知らずとも難しいことはそのシステムに丸投げすれば事足ります。

ただし自由度の高いシステムを構築する場合は、どうしても開発者がクレジット決済の仕組みを理解して開発を進める必要があります。
今回はエンジニア目線でクレジットカード決済を組み込む際に知っておくべき前提についてお話しさせて頂きます。

そもそもなぜ決済代行会社と連携するのか?

決済代行会社との連携はビジネスサイドから見ても多くのメリットがあります。
開発者サイドでもしかり、細かく話せばそれこそ一冊の本になってしまいますが、究極的なメリットは以下の二点集約されると考えます。

  • カード会社ごとに専用のシステムを開発する必要がない。
  • 現実的に達成可能な開発コストでセキュリティが担保される。

ご存知の通り、クレジットカードには様々なブランドがあり、それぞれ発行している会社が違います。
発行している会社が違うということは、その数だけシステムの仕様は異なるということです。
主要カードブランドの数だけならまだしも、同じブランドでもカードの種類によって API の使い方が違うかもしれません。
エラーコードだって微妙に違うでしょう。
一度開発したとて、あるカードのシステム仕様が変わったら修正だけで相当な工数が掛かってしまいます。


反面、僕の経験上、決済代行会社を通してのクレジットカード決済組み込みは、単に「クレジットカード決済」ただ一種類を実装するだけです。
決済代行会社を通すことで、我々システム開発者はユーザーが使用するカードをほぼ気にする必要はないわけですね。
もちろんエラーコードも共通で返ってくるので、ちょっとした工数でユーザーに正しい情報を提供することができます。

EC システムは基本、クレジットカード番号に触れてはならない

現実的な工数で様々なクレジットカードに対応した決済システムが組み込めることが分かりました。
しかし、開発者がより意識すべきメリットは、クレジットカード情報のセキュリティについてのメリットです。

大原則として、システムはクレジットカードの各情報に一切触れるべきではありません。100% のセキュリティなんて存在しない世の中ですが、クレジットカード情報など漏らしたくない個人情報の筆頭です。
決済代行会社はクレジットカードについての情報保持・決済実行を行ってくれるので、わざわざ自身が管理しているサーバーに情報を持つ必要はありません。
ただ、恐ろしいことに Web サーバーの 99.9% ではなにかしら、管理者の知らないライブラリ・フレームワーク・パッケージやシステムが動いています。それら知らずのうちに動いているシステムの全てが信頼に足るものである保証はありません。つまり、真にクレジットカード情報を保持しないことを目指すのであれば、サーバーにクレジットカード情報を一切触れさせないという手段が唯一かつ最前の選択肢なのです。


具体的には以下が守れているかをチェックしながら開発を行いましょう。

  • サーバーにクレジットカード番号やセキュリティコード、有効期限や署名などをサーバーに送信していないか?
  • それら情報をサーバーに保存していないか?
  • 入力画面に余計なサードパーティシステムを組み込んでいないか?

普段は頭の片隅に置いておいていても、まだ工数に余裕のある段階で複数回、上記をチェックしてください。
意外と気を付けていないとフォームの中に情報が混じったりします。


さて、ところで、サーバーがクレジットカード情報を知らずに決済ってできるんでしょうか???

「リンク型決済」を採用する場合は、決済代行会社と情報がズレないように

もちろんできますし、代表的な決済代行会社であれば必ず手段を用意してくれています。
代表的なフローは二種類あり、それぞれ「リンク型決済」「トークン型決済」と呼ばれています。


リンク型決済は昔からあるタイプで、カード入力は決済代行会社のサイトで行うタイプの決済方法です。
あなたがネットショッピングをしていた際、決済直前で別のサイトに飛ばされてカード番号を入力した事はありませんか? あれがまさしくリンク型決済です。

メリットはカード入力画面も含めて決済代行会社に任せられるので、セキュリティの担保はもちろん、カード入力部分の開発コストもカットできる点です。
デメリットはユーザーにしてみるとサイトの雰囲気がいきなり変わってしまうのと、ページ遷移が増えるぶん時間が掛かるためストレスが溜まりやすい点があります。


しかし開発者にとって最も考慮しなくてはならないのは、決済代行会社側サイトで決済を完了させたユーザーが開発システム側のページに戻ってこない可能性についてです。
決済代行会社と連携する時のキモなのですが、ユーザーがお金を支払ったという事実は開発したシステムと決済代行会社で必ず同期しなくてはなりません。どちらか一方では決済されているのに、片方ではその記録が無いとなると決済状態の矛盾が生じるため、収益の問題が生じます。


リンク型決済を採用した際、決済は決済代行会社側のページ・システムで発生しますので、開発側サイトではその結果をどうにかして取得しなければなりません。
大抵のリンク型決済では最終的に自社サイトページへリダイレクトするように誘導してくれますが、リダイレクト前にブラウザを閉じてしまうユーザーだっています。


なので、大抵は決済代行会社側のサーバーがこちらのサーバーに HTTP リクエストで決済結果を送ってくれるが存在します。これは結果通知キックバックなどと呼ばれています。

このリクエストを受け取って、決済完了情報を保持するのが基本的な流れとなります。
この部分が意外と工数がかかることが多いので、もしリンク型決済を採用する場合は見積もりにしっかり入れておきましょう。

「トークン型決済」はサイト内で決済が完結する、ように見せられる

もう一方は最近主流になりつつあるトークン型決済です。
このフローを用いることでユーザー側からはサイト内で決済が完結しているように見えます。

より具体的には、同じカートフロ―中にクレジットカード情報入力フォームが設置できるのです。
ユーザーにとっては、いろいろな見た目のページにたらい回しにされず、統一されたデザインのカートフローで買い物が完了するのはメリットと言えるでしょう。


開発者目線から見ても、トークン型決済なら先述した決済代行会社側サーバーからの通知も不要なことが多いのは嬉しい点です。
反面ある意味気を付けなければならないのが、トークン型決済はリンク型決済より幾らか実装難易度が上がる点です。
なぜトークン型決済がやや実装し辛いのでしょう? その仕組みと一緒に説明しましょう。

トークン型決済はこのような順序で決済が行われる

説明に先んじて、フローを示します。

トークン型決済のフローとして以下を図解している。
1.    ユーザーが決済画面を EC システムサーバーへリクエストする。
2.    カード番号入力ページ HTML を出力する。同時にリンク、または埋め込まれる形で決済代行会社とやり取りするためのコードが書かれた JavaScript が提供される。
3.    ユーザーが入力したクレジットカード情報が JavaScript によって決済代行会社サーバーへ送信される。
4.    決済代行会社よりトークンが発行され、ユーザーのブラウザに返される。期限切れなど、明らかに情報が間違っているとこの時点でエラーが返されることもある。
5.    決済代行会社より取得したトークンを EC システムサーバーへ送信する。
6.    ユーザーより受け取ったトークンを決済代行会社へそのまま送信する。
7.    受け取ったトークンを照合し、正当なものであればクレジットカード会社のシステムへ与信チェックや売り上げ処理等を依頼する。
8.    依頼された処理が正当で問題がなければクレジットカードへの操作を実行し、結果を決済代行会社へ返す。
9.    結果が成功であれば決済代行会社内での処理も確定し、EC システムサーバーへ成功を返す。失敗であれば失敗情報を返す。
10. 決済代行会社からの応答を元に決済処理の結果をユーザーへ出力する。
  1. ユーザーが決済画面を EC システムサーバーへリクエストする。
  2. カード番号入力ページ HTML を出力する。同時にリンク、または埋め込まれる形で決済代行会社とやり取りするためのコードが書かれた JavaScript が提供される。
  3. ユーザーが入力したクレジットカード情報が JavaScript によって決済代行会社サーバーへ送信される。
  4. 決済代行会社よりトークンが発行され、ユーザーのブラウザに返される。期限切れなど、明らかに情報が間違っているとこの時点でエラーが返されることもある。
  5. 決済代行会社より取得したトークンを EC システムサーバーへ送信する。
  6. ユーザーより受け取ったトークンを決済代行会社へそのまま送信する。
  7. 受け取ったトークンを照合し、正当なものであればクレジットカード会社のシステムへ与信チェックや売り上げ処理などを依頼する。
  8. 依頼された処理が正当で問題がなければクレジットカードへの操作を実行し、結果を決済代行会社へ返す。
  9. 結果が成功であれば決済代行会社内での処理も確定し、EC システムサーバーへ成功を返す。失敗であれば失敗情報を返す。
  10. 決済代行会社からの応答を元に決済処理の結果をユーザーへ出力する。

見た目とは裏腹に複雑ですね。流れを追ってみましょう。


カード情報が入力され、ユーザーによって確定ボタンが押された際にカード情報はどこに飛んでいくでしょう?
普通に考えれば EC システムが動いているサーバーで読み込んで、受注データをデータベースに書き込むなりしたいですよね。


トークン型決は、ここでカード情報を決済代行会社のサーバーに送ります。
ただ、いわゆる HTML の form タグだとリンク型決済のように決済代行会社の URL へページ遷移してしまいます。
なので画面遷移をせずに決済代行会社サーバーと通信するため、JavaScript の非同期通信(Ajax)を用いて通信を行います。これがトークン型決済をやや難しくしているポイントの一つです。
大抵の決済代行会社が提供しているマニュアルではコード例などと共に詳細な説明が載っていますが、実装にはやはり最低限のフロントエンド知識が必須でしょう。


JavaScript によって決済代行会社へクレジットカード情報を投げると、今度は決済代行会社から長くて人には読めない乱数のように見える「トークン」が返ってきます。これが「トークン型決済」と呼ばれるゆえんです。
このトークンはそれ自身を見ただけでは何も解読できない、ただの文字列です。
トークンを受け取ったら今度はこれをEC システムが動いているサーバーへ送信します。
繰り返しになりますが、なんせこの時点このトークンはただの文字列です。なにをどう頑張ってもこのトークンからはクレジットカード情報は読み取れません。よってクレジットカード情報は EC サーバーに触れていません。


EC システムが動いているサーバーがブラウザからトークンを受け取ったら、次はこのトークンを「EC システムが動いているサーバー」が「決済代行会社側のサーバー」へ送信します。
慣れている人は問題ないですが、「サーバー」→「サーバー」の通信もトークン型決済をやや難しくしているポイントの一つです。


トークンがたらい回しにされていて混乱しますが、このタイミングで「EC システムが動いているサーバー」が「決済代行会社側のサーバー」に話しかけている内容を和訳するとこんな感じになります。


「ウチが提供しているサービスを利用したユーザー(=ブラウザ)がこんな領収書(=トークン)を貰ったって言っているけど、これは本物? 決済完了したことにしていい?」


決済代行会社側のサーバー」はこの問い合わせとトークンを受けて、そのトークンが正しく有効なものであれば決済代行者側の決済情報を保持した上でOK を返します。「EC システムが動いているサーバー」はこの OK を聞いた段階で自身のデータベースなりに受注情報を保持できるわけですね。
当然、トークンが偽物であれば「決済代行会社側のサーバー」は NO を返してきますし、偽物でなくてもセキュリティコードが間違っているだとか、与信枠が足りないようなエラーの場合も理由を返してきてくれます。

流れを再掲します。

  1. ユーザーが決済画面を EC システムサーバーへリクエストする。
  2. カード番号入力ページ HTML を出力する。同時にリンク、または埋め込まれる形で決済代行会社とやり取りするためのコードが書かれた JavaScript が提供される。
  3. ユーザーが入力したクレジットカード情報が JavaScript によって決済代行会社サーバーへ送信される。
  4. 決済代行会社よりトークンが発行され、ユーザーのブラウザに返される。期限切れなど、明らかに情報が間違っているとこの時点でエラーが返されることもある。
  5. 決済代行会社より取得したトークンを EC システムサーバーへ送信する。
  6. ユーザーより受け取ったトークンを決済代行会社へそのまま送信する。
  7. 受け取ったトークンを照合し、正当なものであればクレジットカード会社のシステムへ与信チェックや売り上げ処理などを依頼する。
  8. 依頼された処理が正当で問題がなければクレジットカードへの操作を実行し、結果を決済代行会社へ返す。
  9. 結果が成功であれば決済代行会社内での処理も確定し、EC システムサーバーへ成功を返す。失敗であれば失敗情報を返す。
  10. 決済代行会社からの応答を元に決済処理の結果をユーザーへ出力する。

改めて見てみるとリンク決済と違い、決済が確定するタイミングの前に決済フローがユーザー(=ブラウザ)から離れていることが分かりますね。
先述した「ユーザーがお金を支払ったという事実は開発したシステムと決済代行会社で必ず同期しなくてはならない」という前提がサーバー間の接続で満たされるので、データ矛盾を起こす可能性が低くなるわけです。

「決済番号」は必ず保持、そのほかの情報を保持するかはサービスとよく相談して

リンク型決済」「トークン型決済」でカード情報とサーバーが接触しないで決済が行えることが分かりました。
万事に言えることですが、システム開発で重要なのは「抱えなくてもいいものは持つな」です。


しかし、では EC システム自体は何も持たなければいいのか? というとそんなことはありません。
絶対に持ってはいけないクレジットカード情報とは対に、必ず保持しなければならないのが決済確定時に発行される「決済番号」です。


これは決済代行会社ごとに「決済コード」や「決済ID」「ユニークID」などと呼ばれるもので、大抵は決済ごとに重複しない文字列の形をとっています。
その後 API で決済操作をするのであれば間違いなく必須ですが、API を用いずとも決済管理会社とやり取りする際は大抵この決済番号で対象決済を指し示すことがほとんどです。
万が一システムのバグが発生して決済を取り消したい、価格を変更したいなどの依頼を決済代行会社にお願いする際はこの決済番号を提示しておけるようにしましょう。
場合によってはこの決済番号無しには依頼に答えてくれないかもしれません。


また、見落としがちなのですが、決済代行会社によってはこの決済番号は一種類でない場合もあります。
重要度の高いものは必ずマニュアルに明記されているハズですが、何を保持して何を保持しないべきなのか、判断に迷ったら早めに決済代行会社に問い合わせるべきでしょう。
僕の経験からして、マニュアルをさっと読んで分からなかった事は、その後いくら資料を熟読しても問い合わせないと分からなかったケースが多いです。


さらに開発するサービスの内容にもよるのですが、現実世界での対応準備としてどこまでの個人情報を保持しておくかは予め運営側・クライアントなどと決めておきましょう。
例えばクレジットカードの不正利用があった際、警察に提出する情報として決済時刻や総額・ IP アドレスなどは求められるケースもあります。
技術的に言えば、決済代行会社によっては特殊な操作(カード情報を決済代行会社に保持するなど)をする際に電話番号をパラメータとして必須としている代行会社も存在します。
サービス要件だけではなく、システムを動作させるのに必須な情報は早い段階で洗い出しておく必要があります。

即時売上にしない場合は「仮決済」の理解をしっかりと

カートフロー完了の時点で即請求が確定するタイプの決済を「即時売上」などと呼んだりしますが、より段階的な決済が要件になるかもしれません。


よくあるのは受注確定後に商品の製造が始まり、商品が完成して発送される際になって始めて請求が確定するサービスです。
このようなサービスでは万が一商品製造が不可能でキャンセルとなった場合について想定する必要があります。
仮に即時売上でクレジットカード決済を通していると、後からキャンセルした際に請求取り消しではなく返金対応となる可能性もあります。
この場合はカートフロー完了の時点で「仮決済」という処理を行い、利用限度額の確認→与信枠の確保を行うのが定番です。


開発者がこのタイプのシステムを構築すべき際に気を付けるべきは、第一に現在のスターテス管理を徹底することです。
ある受注が現在仮売上状態なのか実売り上げ済なのかなどの同期はもちろんですが、実は各ステータスから別のステータスに切り替る処理にはほぼ確実に制限時間が存在します。
よくあるのは、

  • 仮売上から実売り上げに変更可能なのは仮決済後 〇 日以内まで
  • 実売り上げに後に返金可能なのは 〇 日以内まで

などの制約でしょうか。システムに組み込むべきかはさておき、理解しておかないと慌てがちな部分なので各社提供の資料は確認しておきましょう。


また、仮決済後に決済代金を調整できるのかもサービスによっては重要な点です。
ほとんどの決済代行会社で最初に確保した額よりも少ない額に変更することは可能かと思われますが、増やせるかどうかは特に事前調査が必要でしょう。

まとめ

クレジットカード決済開発はいきなり挑戦すると、考えることの多さで圧倒されがちです。
可能であれば経験者に助言・チェックをお願いするのはもちろんのこと、分からないことは決済代行会社へちゃんと問い合わせましょう。


あと見過ごしがちなのですが、ある意味一番重要なのが社内のプロジェクトチームメイトやクライアントとの合意・認識のすり合わせだったりします。
開発者側が想定していた契約環境が無かった、API や機能が無かった、ではもはや開発者の徹夜でどうにかなる話ではなくなります。
「クレジット」決済なだけに、お互いの「信頼」は大切にしたいものですね。

プログラマー/N.Go

このメンバーの記事一覧へ

おすすめ記事