fincode でクレジットカード決済を実装したので処理の流れをまとめました

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3637323630392f62616333643735642d393561642d336638652d363836322d3231656562383161653461652e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669033/9dc2770d-16d6-46c8-c381-2f269892952e.png)

# はじめに
とある案件でクレジットカード決済機能を実装することになり、その際 fincode を使用して実装しました。今回は fincode でどういった流れで実装するのか、どのような機能があるのかを自分の頭を整理するのも兼ねてまとめていきます。

# fincode とは
fincode はECサイト等にオンライン決済機能を実装したいときに使用する決済代行サービスです。REST APIで各機能が提供されていて、スムーズに実装を進めることができます。クレジットカード決済、コンビニ決済、PayPay、ApplePay、口座振替に対応しています。今回は、実際に実装を行った **Webアプリでのクレジットカード決済** にフォーカスした記事となります。

:::note info
口座振込は最近リリースされました :tada:（2023/12/05）([Product Blog](https://blog.fincode.jp/product_blog/471-2/))
:::

https://www.fincode.jp/

https://www.fincode.jp/payments

# クレジットカード決済実装方法は大きく２つ

fincode ではリダイレクト型とトークン発行型の２種類の実装方法があります。

## リダイレクト型
[リダイレクト型](https://docs.fincode.jp/payment/redirect_type)は、決済開始時に fincode が用意した決済用ページに遷移しそのページで決済を行い、決済が完了後プロダクトサイトにリダイレクトするという方法です。

決済用ページは、決済URL作成APIを実行し、そのレスポンスに含まれるURLに遷移します。この時、成功URL（決済成功時にリダイレクトするURL）、キャンセルURL（決済失敗時にリダイレクトするURL）を設定することで、決済後の遷移先を設定できます。
なお、決済・キャンセルURLへの遷移はPOSTでの遷移となるため注意が必要です。私が Next.js で実装した際は、route handler で　Next　で API を仲介役として作成し、まずその API にリダイレクト、その後、プロダクトページにリダイレクトするように作成しました。

リダイレクト型は、細かな処理はできないですが、簡単に決済処理を導入することができます。~~しかし、3Dセキュア認証を導入する場合はリダイレクト型ではできません。（fincode のドキュメントになかったからできないはず。。）
3Dセキュア認証も導入するには次のトークン発行型で実装する必要があります。~~

追記: 
[決済URL作成](https://docs.fincode.jp/api#tag/%E3%83%AA%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E5%9E%8B/operation/postSessions)のリクエストで`card.tds_typeを"2"`にするとリダイレクト型でも3Dセキュア認証を利用できるみたいです！（コメントで教えていただきました）

## トークン発行型
[トークン発行型](https://docs.fincode.jp/payment/execution)は、カード番号などのカード情報ををトークン化してそのトークンを使って決済処理を行う方法です。この方法では、リダイレクトより実装が大変にはなるものの、自由度の高い決済機能を実装することができます。また、先程言及した３Dセキュア認証を実装することもできます。

トークン発行型のざっくりとしたフローは以下のようになっています。

```mermaid
flowchart TD
start["「クレジットカードで購入」押下"] --"入力フォーム表示"--> input["クレジットカード入力"]
input --> button["「購入する」押下"]
button --> getToken["fincode API トークン取得"]
getToken --"成功"--> register["fincode API 決済登録"]
getToken --"失敗"--> error["エラー表示"]
register --"成功"--> payment["fincode API 決済実行"]
register --"失敗"--> error
payment --"成功(3Dセキュア認証あり)"----> secure2["fincode API 3Dセキュア2.0認証"]
payment --"成功(3Dセキュア認証なし)"--> success["購入完了"]
payment --"失敗"--> error
secure2 --"成功"--> success["購入完了"]
secure2 --"失敗"--> error
```

fincode API と書かれている部分はそれぞれ fincode の提供している REST API を実行します（参考: [fincode API リファレンス](https://docs.fincode.jp/api)）。決済登録では、何円のものを決済するのか、などの決済情報を登録し、決済実行では、取得したトークンを使って実際に決済を行います。


# 3Dセキュア認証について
3Dセキュア認証とは、オンラインで行われるカード決済において不正利用を防止するために使用される本人認証の仕組みです。ネットでクレジットカードで買い物をした時、カード会社のパスワード入力画面に遷移したことがある方も多いと思います。あれです。fincode では3Dセキュア認証もサポートされています。ちなみに厳密には3Dセキュア2.0認証というのですが、本記事では省略して3Dセキュア認証と言います。
fincode 3Dセキュア認証を含めたトークン型決済処理をシーケンス図にしてみました。

## 3Dセキュア認証を含むトークン型決済処理のシーケンス図
※補足
図で使われている用語について
- `acs_url`: 3Dセキュア認証ページURL
    - 決済実行 API のレスポンスに含まれています。
- `tds2_ret_url`: 加盟店戻りURL
    - 加盟店で設定します。
        - Next.js を使用している場合は route handler で API を作るのが良いと思います。
    - この URL に3Dセキュアサーバーからのデータが返されます。
- `challenge_url`: 3Dセキュア認証チャレンジURL
    - 3Dセキュア認証時にPW入力等が求められた場合に遷移するURLです。
    - 3Dセキュアサーバーからのデータに含まれています。
- オーソリ: 店舗がクレジットカード会社に利用者の与信情報を照会し、決済可能かどうかを確認する手続きのことです（[参考](https://www.google.com/search?q=%E3%82%AA%E3%83%BC%E3%82%BD%E3%83%AA)）。

```mermaid
sequenceDiagram
	autonumber

	participant user as 購入者
    participant market as プロダクトサイト
    participant fincode as fincode
	participant 3ds as 3Dセキュアサーバー
	participant card as カード会社

    user->>+market: カード情報（ナンバー・CVC）入力<br/>購入ボタン押下
    market->>+fincode: 決済情報送信
	fincode-->>-market: トークン発行
	market->>+fincode: 決済登録
	fincode-->>-market: 決済登録結果
	market->>+fincode: トークンを使って決済実行
	fincode-->>-market: 決済実行結果
	market-->>user: リダイレクト（acs_url）
	user->>+card: ３Dセキュア認証初期化
	card-->>-user: リダイレクト
	user->>market: リダイレクト（tds2_ret_url）
	market->>+fincode: ３Dセキュア認証実行API
    fincode->>3ds: 認証処理
    3ds-->>fincode: 
	fincode-->>-market: ３Dセキュア認証実行結果
	opt 認証チャレンジを行う場合
        market-->>user: リダイレクト（challenge_url）
    	user->>3ds: ３Dセキュアチャレンジ開始
		3ds-->>user: 
		user->>3ds: 本人認証
		3ds-->>user: リダイレクト
		user->>market: リダイレクト（tds2_ret_url）
		market->>+fincode: ３Dセキュア認証実行API
		fincode-->>-market: ３Dセキュア認証実行結果
	end
	market->>+fincode: 認証後決済API
	fincode->>+card: オーソリ
	card-->>-fincode: オーソリ結果
	fincode-->>-market: 認証後決済結果
```

3Dセキュア認証の部分をピックしてテキストでも書いてみます。↓

1. 決済実行API実行後、レスポンスに含まれる`acs_url`にリダイレクトし、3Dセキュア認証初期化を行う
2. 3Dセキュア認証初期化後、コールバックを`tds2_ret_url`で受け取る
3. 受け取ったデータをもとにステータスで場合分けを行い、以下の処理を行う
    1. 3Dセキュア認証初期化完了 or 3Dセキュア認証初期化スキップ
        1. 3Dセキュア認証実行APIを実行
        2. チャレンジ認証が必要な場合は`challenge_url`に遷移する
        3. 実行後、「3Dセキュア認証初期化後、コールバックを`tds2_ret_url`で受け取る」に戻る
        4. 何かしらでエラーが発生している場合はエラーを返しプロダクトサイトにリダイレクト
    2. 3Dセキュア認証結果受け取り準備済み
        1. 3Dセキュア認証結果確認APIを実行
        2. 3Dセキュア認証が成功していたら認証後決済処理を行う
        3. 認証後決済処理完了後、プロダクトサイトにリダイレクト
        4. 何かしらでエラーが発生している場合はエラーを返しプロダクトサイトにリダイレクト

詳しいことはドキュメントにも書いてあるので見てみてください。（[3Dセキュア2.0認証を使用する]()）

# fincode のその他の機能
今回は実際に実装した「3Dセキュア認証を含むトークン型決済処理」について詳しく書きましたが、他にも fincode では以下のような事ができます。
- [顧客登録](https://docs.fincode.jp/api#tag/%E9%A1%A7%E5%AE%A2)
    - カード番号の登録などができるようになります。 
- [一括決済](https://docs.fincode.jp/payment/bulk)
    - 大量の決済を一度にまとめて決済することが出来ます。
- [サブスクリプション](https://docs.fincode.jp/payment/subscription)
    - 登録済みの顧客に対して月額いくらみたいな決済ができます。
- [プラットフォーム](https://docs.fincode.jp/platform)
    - 店を「プラットフォーム」と「テナント」に分け、プラットフォームが様々な面でテナントを管理できるようになります。プラットフォームで利用料を設定し、各テナントから徴収するといった運用が可能になります。言葉だと説明しづらいのでドキュメント覗いてみてください（丸投げ）。

他にもあるのでぜひ[ドキュメント](https://docs.fincode.jp/)も読んでみてください。

# fincode を使ってみた感想
## いい点
数年前に他の決済代行サービスを使ったことがあったのですが、似たような使い勝手でクレジットカード決済を実装することができました。ほとんどの機能が REST API で提供されているので、特別難しい実装をする必要がなく、どのプロダクトでも導入しやすいと思いました。また、スタートアップビジネス向けと謳っているだけあり、テスト環境の即時提供、迅速なWeb審査、といった実装以外でのスピード感もあります。

## いまいちな点
フロントエンド（JavaScript）向けのライブラリである[fincodeJS](https://docs.fincode.jp/api)が CDN で提供されていることです。npmパッケージ化されたりしていると、とーても使いやすくなるので今後の展開に期待したいです。

# おわりに
fincode についてざっくりまとめてみました。fincode の利用を検討している方の参考になれば幸いです。