『改正割賦販売法でカード決済はこう変わる』を読んだ

2019年の1Qに読んだ本シリーズ:

改正 割賦販売法でカード決済はこう変わる

改正 割賦販売法でカード決済はこう変わる

概要

2018年6月から施行されている「改正割賦販売法」によって、クレジットカード加盟店がクレジットカードを扱う際の対応がどのように変わったのか、という点について解説されています。とくに、クレジットカードセキュリティのグローバルな基準であるPCI DSSと、国内でのクレジットカードセキュリティの実務指針である「実行計画」に対して、どのように対応していけばよいかについて説明されています。

割賦販売法はクレジットカードの根拠法です。なぜ割賦販売法が改正されたかというと、主にはカード情報流出対策として加盟店に対するカード情報保護義務を規制として追加するため、という理由があります(他にもある)。また、実務指針である「実行計画」は、オリンピックが開催される2020年までは毎年更新されるので、訪日外国人のカード決済を保護していくという意味合いも持っているようです。

なぜ読んだのか

EC系Webサービスを開発/運用しているとPCI DSSという言葉をよく聞くのですが、実態がよくわからないので知りたかったというのがあります。非保持化に関しては実装の経験が何度かありましたが、PCI DSSに対応する場合との違いについても知りたいと思っていました。また、そもそも非保持化などの対応が必要になった理由を知っておきたかったというところもあります。

メモ

PCI DSSと「実行計画」

PCI DSSはクレジットカードに関するグローバルな業界セキュリティ基準です。

PCI Security Standards Council公式サイト

一方、日本クレジット協会が発表している「実行計画」は、日本においてクレジットカードのセキュリティ対策をおこなう際の実務的な指針です。2019年版はこちらです。

関連資料 | 安全・安心なクレジットカード取引への取組み | 一般社団法人日本クレジット協会

クレジットカード情報の「非保持化」は実行計画で示されているものであり、日本国内でのみ採用している方式です。実行計画では、非保持化しない場合はPCI DSSへの対応を求めています。

ここで、「非保持化」とは、例えばECサイトをホストしているサーバが生のクレジットカード情報を保存/処理せず、そもそもクレジットカード情報自体がサーバを通過しない、ということを表しています。ただし、クレジットカードの電磁的なデータだけがその対象となり、紙媒体や通話録音データは保持に当たらない、と規定されています(厳重に保管する必要はある)。

また、非保持化という対応が許されるのは一般の加盟店だけであり、イシュア/アクワイアラ/決済代行業者や国外でサービスを提供する加盟店は、つねにPCI DSSに準拠している必要があります。

非保持化の方法

Webアプリケーションの開発者的に興味がありそうなのはここかと思います。EC加盟店で非保持化するためには次のような方式が利用できます。

  • リダイレクト(リンク型)決済
  • JavaScript型(トークン)決済

リダイレクト決済は、決済サービスのプロバイダが提供する決済用ページへ顧客を誘導する方式です。クレジットカードの処理をプロバイダへ完全に委譲できるのでセキュアですが、加盟店のページと別のドメインのページへとユーザを遷移させることになるので、カゴ落ちが起きやすくなるのが欠点です。

JavaScript型は、トークン化などのカード番号無効化処理をブラウザとPSPの間で実行し、そのトークンをEC加盟店のサーバが決済時に使う方式です。トークンはカード番号ではないので、非保持化の要件を満たしています。また、加盟店のページで決済が完結するのでカゴ落ちしづらいのもメリットと言えます。

他の方法として、加盟店のページに決済サービスのプロバイダが提供するモジュールを埋め込むモジュール型があります。これはカード情報を保存はしませんが通過はするので、バックドアが仕掛けられるとアウトという弱点があります。よって、この方式は非保持とは見なされていません。

PCI DSS準拠

非保持化ではなくPCI DSSに準拠したサービスとしていく場合、その要件に準拠していることをオンサイトレビューなどで示さなければなりません。この作業は件数が多く、負担も大きいので、まずは該当加盟店のカード情報取扱の状況に適した自己問診票 (SAQ) を選択することで、準拠するための項目を減らすことができます。例えば、EC加盟店でリダイレクト決済を使っている場合は、カード情報送受信に関する要件などは省略された要件の少ない問診票 (SQA A)が利用できる、などです。

加盟店用のフルセットのSAQであるSAQ-D加盟店だと331項目ありますが、これはけっこう大変そうです…

その他

2019年からは3Dセキュアの2.0が登場し、ワンタイムパスワードや、怪しい取引に限って3Dセキュアのパスワード入力を求めるリスクベース認証が導入されるようです。

まとめ

PCI DSSとは別に、国内では「実行計画」が存在し、それが非保持化もしくはPCI DSSへの準拠を求めていることがわかりました。また、PCI DSSへの対応の際には自己問診票の活用が大事そうということがわかりました。

全体的に説明が詳しく、EC加盟店の他に通販や対面の加盟店での対応方法も書いてあり、最近のクレジットカード事情がわかって便利かと思うので、興味のある人は読んでみてください。

『失敗から学ぶRDBの正しい歩き方』を読んだ

2019年の1Qに読んだ本シリーズ:

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

RDBのテーブル設計や運用に関するアンチパターンと、それをどうすれば改善できるかについてが解説されています。Software Designの連載がもとになっているので、各章の粒度が多すぎず少なすぎずでちょうどよく読みやすかったです。

内容はWebアプリケーションを作るときに知っておきたいことばかりでした。新しくWebアプリケーション開発の仕事を始めた人に最初にすすめる本としてもちょうどよさそうだと思います。個人的には履歴テーブル、フラグ、隠された状態あたりは最近考えることが多いので、現在どれぐらい実践できているか/できていないかを確認しながら読みました。

また、参考文献が充実しているのもよかったです。『データベースリファクタリング』『SQLパフォーマンス詳解』と use-the-index-luke.com 、専門家の人々のスライド資料、MySQLやPostgreSQL公式ドキュメントの該当箇所などなど、より詳細の文献へのポインタが示されており、参考になりました。

メモ

## 第2章 失われた事実

- 税率履歴テーブル
  - 税率、有効日、失効日
  - 注文から参照する
- ステータスは変化するごとにレコードを作り最新を現在とする
- パフォーマンス
  - マテビューかサマリテーブルで対処
- 代替案: レプリ遅延で以前の状態を確認 or ログをESに突っ込む
  - 2番目はonkさんがRailsDMで言ってた

## 第5章 フラグの闇

- 論理削除
  - 未削除と削除済みで同じ値を持つカラムが存在しうるのでユニークにならない
  - フラグのカーディナリティが低い
- 削除済みテーブルに移す or ビュー
- テーブルが肥大化すると後年パフォーマンス面で困るのでわける

## 第6章 ソートの依存

- order byの評価はほぼ最後
  - 一番最後はlimit
- データが大きいほどソートに時間がかかる
- whereで事前に絞る
  - indexを張ったカラム
  - カーディナリティが低い場合は遅い
- order by狙いのindex
  - b-treeのリーフノードはソート済み
  - リーフノードの最初から取り出しながらwhere句を適宜評価すると全部取り出さずに済むので速い
- ページネーションではoffsetよりはページの最初の要素のIDの一個前のID以上、というwhere句のほうが速い

## 第7章 隠された状態

- EAV → JSONで
- Polymorphic Association → 交差テーブルで
- スマートID → 正しく正規化
- 複数目的で使われるテーブル → 分割

## 第8章 JSONの甘い罠

- ユースケース
  - Web APIのレスポンス
  - OS情報
  - ユーザが任意で登録するプラグインの情報

## 第9章 強すぎる制約

- 大切なのはバランス感覚
- 一般的な事実の範囲に収まる制約とする
    - 都道府県が47個、消費税が3以上の整数(消費税が下がるケースは実質無い?)など
  - システムの仕様やビジネスルールに依存しない

## 第14章 ロックの功罪

- 現実のRDBMSはACIDのI (Isolation) を緩めて運用している
  - 厳守しようとするとserializableになる

『図解 カードビジネスの実務 第2版』を読んだ

2019年の1Qに読んだ本シリーズ:

クレジットのすべてがわかる! 図解 カードビジネスの実務<第2版>

クレジットのすべてがわかる! 図解 カードビジネスの実務<第2版>

概要

全体的に浅く広く、クレジットカードやそれに類するデビットカードなどについて説明されています。

  • クレジットカードの成り立ちと仕組みについて
  • クレジットカードの事業を運営する企業での業務について
  • オーソリゼーションシステムなど対外系システムやセキュリティについて

二つ目は本のタイトルのとおりで、分量を割いて説明されています。Webサービス開発者としては三つ目が気になるところです。

なぜ読んだか

EC系Webサービスを開発/運用していると、クレジットカード決済機能を実装したり、クレジットカードについての問い合わせ調査したりします。断片的には知識がありますが体系立った知識がない気がしたので、広く浅く知識を得るために読みました。

メモ

いくつかおもしろポイントがあったので書いておきます。

クレジットカードのビジネスモデル

クレジットカードによる購入(割賦販売法的には包括信用購入あっせん)は

  • 「期限の利益」を消費者に、
  • 「販売促進」を加盟店に、

それぞれ提供することで利息や手数料を得るビジネスモデルということが明記されていました。ここで、期限の利益とは支払いの期限を遅らせることで利用者が得られる利益のことです。また、販売促進については、キャッシュレス決済の手軽さや各種ポイント制度、売掛が確実に回収できることから効果があるということになります。

日本のクレジットカード

日本のクレジットカードは1枚にさまざまな支払い方法を備えていますが、これは「ジャパニーズペイメントオプション」と呼ばれるもので、海外カードは支払い方法ごとにカードが分かれているのが普通らしいです。また、分割払いなどは信用販売に由来しています。

スキーム

スキームはブランドホルダー(VISA/MasterCardなど)、イシュア、アクワイアラからなるインターチェンジ取引が世界的には標準ですが、従来の国内ブランドはアクワイアラが存在せずイシュアが直接加盟店を開拓するケースがあります(オンアス取引)。加盟店管理のコストからスケールはしないようです。

対外系システム

オーソリシステムは基幹系システムとは独立しています。理由はオーソリシステムは24時間365日稼働のオンラインシステムである一方、基幹系はメンテやバッチで止まることがあることによります。

その他

  • 仕向け
    • カード番号からカード発行会社を特定し、決済電文を送ること
  • デュアルメッセージ
    • オーソリ電文と売上電文を別々に送ること
    • 対面決済でクレジットカードを利用する際のプロセスに由来
  • シングルメッセージ
    • オーソリ電文と売上電文を同時に送ること
    • デビットカードなどで普及
  • デポジットオーソリ
    • ホテルなどでチェックアウトまで金額が確定しないので利用枠すべてをオーソリすること
    • 確実に売上か取消をおこなわないとカードが使えなくなる

まとめ

クレジットカードの従来の広まり方や使われ方に起因して、いくつかの仕組みが存在していることがわかりました。この点ではWeb経由での利用だと存在意義がよくわからなかったので参考になりました。さらっと読み通しておくと便利かと思います。

『WEB+DB PRESS Vol.108』でスキーマ駆動Web API開発についての特集記事を執筆しました

このたび、2018年12月22日に発売された『WEB+DB PRESS Vol.108』の特集1「効率急上昇!スキーマ駆動Web API開発」の企画と執筆に携わりました。id:june29さん、id:ackintoshさん両名との共著です。

WEB+DB PRESS Vol.108

WEB+DB PRESS Vol.108

  • 作者: 中野暁人,山本浩平,大和田純,曽根壮大,ZOZOTOWNリプレースチーム,権守健嗣,茨木暢仁,松井菜穂子,新多真琴,laiso,豊田啓介,藤原俊一郎,牧大輔,向井咲人,大島一将,上川慶,末永恭正,久保田祐史,星北斗,池田拓司,竹馬光太郎,粕谷大輔,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/12/22
  • メディア: 単行本
  • この商品を含むブログを見る

Web APIの仕様を表現するフォーマット(スキーマ)を用いたWeb API開発について、基礎的なところから紹介しています。本号はこの特集の他にもPostgreSQLやZOZOのシステムリプレイスなど、非常に興味深い内容が盛りだくさんなので、ご興味のある方はぜひ手にとっていただければと思います。

以上、宣伝でした。


以下、裏話的なことを書きます。

なぜ書いたのか

そもそも現在業務として携わっているWebサービスの開発でOpenAPI(いわゆるSwagger)を利用しています。ある程度わかっている人にOpenAPIについて知ってもらうにはWeb上にある次のようなリソースが役立ちます。

一方、新しくチームに入った人やそこまでWeb API開発に詳しくない人に対して、OpenAPIについて「読んどいて!」と言える文献があると、自分自身はもちろん、同じ境遇の他の人にも便利なものになるのではと感じていました。そして、REST APIのスキーマに関して最も有力な選択肢はOpenAPIなので、その説明を含めた文献があるとよさそうだと考えました。

また、これは執筆を始めたあとの話ですが、june29さんと「2018年時点でのWeb API開発のスナップショットみたいな記事だね」という話をして、それを意識して書くようにもしていました。

そういうわけで無事に企画が通り、今回寄稿することになったので、社内外で今後OpenAPIについて知ってもらいたいときは積極的にこの特集を勧めていこうと思っています。

補足

今回、OpenAPIに関しては最新版であるバージョン3を前提として、記法や活用方法を解説しました。OpenAPI 3がリリースされたのは2018年6月とまだ新しく、各種ツールのサポートも、Swagger公式やOpenAPI Generator以外の場合は特にですが、まちまちというのが現状です。そういう現状もあって、3章のサーバサイド開発のレスポンスバリデーションに関する部分は、仕組みの解説としてライブラリを使わない素朴な実装方法について書きました。

ここに関しては、今後いろいろなツールでOpenAPI 3がサポートされていくだろうと思うので、とくに主戦場であるRuby/Railsまわりなどは私としても情報発信は継続していきます。また、特集内のコラムで紹介したCommitteeに関しては、@ota42yさんが中心となって対応を進めていただいているので、私自身も試しつつ貢献できる部分はしていきたいと思っています。

また、スキーマの活用という点で、Protocol Buffersからのサーバ/クライアント生成が特徴的なgRPCをなぜ取り上げていないのか、という点は指摘としてあるかなと思います。ここに関しては、今回の執筆陣がgRPCに関する知見をそれほど持っておらず書かなかったというのが正直なところです。最近はgRPC-WebなどブラウザからgRPCのサービスをコールできる技術も出てきているようなので、詳しい知見を持つ方々にぜひ執筆してほしいという気持ちです…!

おわりに

よろしくお願いします!

Stripe Sources APIにおける決済の抽象化

この記事はGMOペパボ Advent Calendar 2018の23日目の記事です。

GMOペパボのAdvent Calendarと言っておきながら、Stripeが提供しているWeb APIの話をします。

Stripeの決済用Web APIでは、sourceという概念を通じて多様な決済方法を抽象化して表現しています。このsourceの概念がEC系Webサービス*1を開発している人間としては興味深いものだったので紹介します。

sourceとは

Stripe公式のリソースは次のあたりのものです。

stripe.com

stripe.com

sourceは多様な決済方法を取り扱うために導入されている概念です。sourceの状態がchargeable(課金可能)になると、買い手に対してcharge(課金)することができます。

もう少し詳しく説明すると、sourceは買い手が決済するために使う「モノ」を抽象化した概念であると言えます。その具象としては、クレジットカードやACH(銀行振込のようなもの)があります。1回きりの決済としてsourceに対して直接課金することもできますし、買い手に対して複数回課金するために買い手にsourceを関連付けておくこともできます。

Stripeのドキュメントとcurlがあれば、sourceを用いたWeb API経由での決済実行をすぐに体験できるので、興味がある人はぜひ触ってみてください(以下リンク先の"Try Now")。

stripe.com

たとえばクレジットカードであれば、JS経由でStripeへ直接カード情報を送信後にsourceのIDを得たあと、次のようにAPIを叩くと買い手へのsourceの関連付けと課金を実行できます。

$ curl https://api.stripe.com/v1/customers -u <key> -d email=<customer email> -d source=<source ID>
$ curl https://api.stripe.com/v1/charges -u <key> -d amount=100 -d currency=usd -d cutomer=<customer ID> -d source=<source ID>

sourceを特徴づける四つの性質

Stripeはsourceに対して次のような四つの性質を定義しています。これらの性質を使ってさまざまなsourceを分類しています。

pull/push

決済時の資金の移動方法です。

  • pull
    • 買い手の同意を得たあとに売り手側が資金を引き落とせる
  • push
    • 買い手側が明示的に資金を送る操作が必要
    • 送金後にsourceがchargeableになる

flow

買い手が決済を承認するための行動フローです。これを通過するとsourceがchargeableになります。

  • none
    • なにもしなくてもOK
  • redirect
    • リダイレクト先の銀行のページなどに遷移して承認する
    • sourceがリダイレクト先URLを持つ
  • code verification
    • 銀行口座など送金元口座の所有者であることを検証する
  • receiver
    • 買い手が送金する
    • sourceに送金先情報を含む

usage

sourceが何回使えるかを表します。

  • reusable
    • 一度flowを通ったあとは追加でchargeできるsource
    • sourceをcustomerに関連付けて、customerに対して課金することで実現
  • single_use
    • 決済するたびに買い手の明示的な同意が必要なsource
    • sourceに対して直接課金する

synchronous/asynchronous

課金の結果がいつ得られるかを表します。

  • synchronous
    • success/failureが即時わかる
  • asynchronous
    • 結果が数日後にわかる
    • sourceの状態はpendingからsuccess/failureに遷移する

決済方法の分類

上述した性質を用いると、sourceの具象である決済方法は次のように分類できます。

  • クレジットカード
    • pull/none/reusable/synchronous
    • 買い手に紐づけておけば、売り手が何度も課金できる
  • ACH(銀行振込のようなもの)
    • push/receiver/reusable/asynchronous
    • 買い手の入金操作が必要、かつ数日かかる(らしい)

その他の決済方法についても、Stripeのドキュメントで表がまとめてあります

sourceの利点

このあたりから私見が入ります。Stripeのsourceの利点は次のようなところだと思います。

  • さまざまな決済方法を同じような扱いかたで扱えるようになる
  • 決済ごとの特徴を決めるための性質を定義することで、新決済に対応しやすくなっている

一つ目については、Stripeのドキュメントを見るとわかるとおり、いろいろな決済方法について利用方法が説明されているのですが、どの決済方法でも概ねsource作成 → sourceへの課金 → Webhookによる結果の確認、という流れになっています。決済が複数あることで複雑化しそうな部分を適切な抽象化で吸収し、統一的なインタフェースとして提供できていることがわかります。

二つ目については、このsourceを用いた決済の抽象化方法を使うと、新しく導入する決済をsourceのインタフェースに載せやすくなります。例えば、Amazon Payや楽天PayのようないわゆるID決済や日本でよく使われる*2後払いについて考えてみます。これらの決済をsourceの性質で分類すると、おおよそ次のようになると思います。

  • ID決済
    • pull/redirect/reusable/synchronous な決済
    • 買い手と外部サービスIDを関連付け、外部サービスに遷移して認証し、あとで追加課金でき(ることが多い)、すぐに決済結果がわかる
  • 後払い
    • push/receiver/single_use/asynchronous な決済
    • 買い手がコンビニなどから明示的に送金し、決済ごとに買い手の承認が必要で、与信に人手を介する場合は結果が出るのに時間がかかる

このように複数の性質を用いて特徴を決定することで、新しい具象に対しても、類似する性質の既存決済と同じフローに載せやすくなっています。

まとめ

StripeのWeb APIにおいて多様な決済をうまく扱うための概念であるsourceについて紹介しました。今回はちょっと間に合わなかったのですが、このようなWeb APIをサーバサイドで実装する際にデータモデリングがどうなるかを考えると、なかなかおもしろいのではと思っています。

なお、id:takatoshionoさんに教えてもらったのがきっかけで、私はこのStripeのWeb APIについて知りました。ありがとうございました!