fincodeの構築方法~トークン決済編~
fincode開発チームです! fincodeを使って決済実行してみた 第二弾・トークン決済編をご紹介します! 今回は、fincodeが提供している決済フローのうち、トークンJSを使って構築してみました。 (第一弾・決済JS編はこちら) トークンJSを使った決済フローは以下になります。 ■決済登録API + トークンJS + 決済実行APIのフロー まず決済登録APIを呼び出し、オーダーIDや取引IDを取得します。 次にフロント側でトークンJSを実行し、カード情報(カード番号・有効期限など)のトークン化を行います。 最後に決済実行APIを呼び出し、オーソリを実行します。 今回もフロントはVue.js、バックエンドはnode.js(+ Express)で実装しました。 実装メモ: ■フロント ・axiosでバックエンドのAPIを呼び出し、決済登録API・決済実行APIのレスポンスを受け取っている ・カード情報を引数に設定してトークンJSを呼び出す ・トークンJSでエラーの場合はエラーコードがリスト形式で複数返る ・APIキーはパブリックキーを使う Vue.js <script src="https://js.fincode.jp/v1/fincode.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script> let fincode = Fincode('p_prod_XXXXXXXXXXXXXXXX'); const app = new Vue({ el: '#app', data() { return { card: { card_no: '', expire: '', holder_name: '', security_code: '' }, expire_mm: '', expire_yy: '', amount: "500", id: '', access_id: '', } }, methods: { submit() { this.card.expire = this.expire_yy + this.expire_mm; //axiosでリクエストデータ送信(①fincode決済登録呼び出しAPI) axios.post("http://localhost:3000/payment", { amount: this.amount }) .then((res) => { console.log(res); //決済登録APIのレスポンスを設定 this.id = res.data.id;; this.access_id = res.data.access_id; //トークンJS実行 fincode.tokens(this.card, (status, response) => { if (200 === status) { // トークンJS リクエスト正常時の処理 console.log(response); // 決済実行APIのリクエストパラメータを設定 const transaction = { id: this.id, access_id: this.access_id, token: response.list[0].token, //トークンJSで取得した値 }; //axiosでリクエストデータ送信(②fincode決済実行呼び出しAPI) axios.post("http://localhost:3000/execute", { data: transaction }).then((res) => { // リクエスト正常時の処理 console.log(res); alert("決済が完了しました"); }) .catch((err) => { console.log(err); }); } else { // トークンJS リクエストエラー時の処理 console.log(response); response.errors.forEach(error => { alert(error.error_message + "(" + error.error_code + ")"); }); } }, () => { // トークンJS 通信エラー処理。 alert("通信エラーが発生しました。しばらく経ってから再度お試しください。"); } ); }) .catch((err) => { console.log(err); }); }, } }); </script> ■バックエンド 2つのAPIを作成し、fincodeのAPIを呼び出す。 ①決済登録呼び出しAPI ・requestモジュールでfincode(決済登録API)にPOST通信 ・決済登録APIのレスポンスをフロントに渡す ②決済実行呼び出しAPI ・requestモジュールでfincode(決済実行API)にPUT通信 ・決済実行APIのレスポンスをフロントに渡す ※①②とも、fincodeと通信する際のAPIキーはシークレットキーを使う。 node.js(①決済登録呼び出しAPI) var express = require('express'); var router = express.Router(); /* ①fincode決済登録呼び出しAPI * http://localhost:3000/payment にPOSTを投げると、 * 決済登録APIのレスポンスをJSON形式で返す。 */ router.post('/', function (req, res, next) { "use strict"; const console = require("console"); const request = require("request"); const API_KEY = "Bearer m_prod_XXXXXXXXXXXXXXXX"; const BASE_URL = "https://api.fincode.jp"; const endpoint = "/v1/payments"; const DATA = { pay_type: "Card", job_code: "CAPTURE", amount: req.body.amount, }; const options = { url: BASE_URL + endpoint, proxy: PROXY_URL, headers: { "Content-Type": "application/json; charset=utf-8", Authorization: API_KEY, }, json: DATA, } main(); function main() { request.post(options, (error, response, body) => { if (200 != response.statusCode) { console.log("ERROR"); console.log(body); } else { console.log("SUCCESS"); console.log(body); res.header('Content-Type', 'application/json; charset=utf-8') res.send(body); } } ); } }); module.exports = router; node.js(②決済実行呼び出しAPI) var express = require('express'); var router = express.Router(); /* ②fincode決済実行呼び出しAPI * http://localhost:3000/execute にPOSTを投げると、 * 決済実行APIのレスポンスをJSON形式で返す。 */ router.post('/', function (req, res, next) { "use strict"; const console = require("console"); const request = require("request"); const API_KEY = "Bearer m_prod_XXXXXXXXXXXXXXXX"; const BASE_URL = "https://api.fincode.jp"; const ID = req.body.data.id; const DATA = { pay_type: "Card", access_id: req.body.data.access_id, token: req.body.data.token, method: "1", }; console.log(DATA); main(); function main() { var endpoint = "/v1/payments/{id}".replace("{id}", ID); request.put( { url: BASE_URL + endpoint, proxy: PROXY_URL, headers: { "Content-Type": "application/json; charset=utf-8", Authorization: API_KEY, }, json: DATA, }, (error, response, body) => { if (200 != response.statusCode) { console.log("ERROR"); console.log(body); } else { console.log("SUCCESS"); console.log(body); res.header('Content-Type', 'application/json; charset=utf-8'); res.send(body); } } ); } }); module.exports = router; 上記を実行した結果、ダッシュボードから決済成功したことを確認できました。 (参考)決済実行APIからのレスポンス SUCCESS { acs: '0', shop_id: 's_21121014979', id: 'o_0TiOWd3DT5uWD-0nCOiZ4g', pay_type: 'Card', status: 'CAPTURED', access_id: 'a_Jou6XFKoT6KUjHNpG6XXKw', process_date: '2022/04/25 10:16:23.681', job_code: 'CAPTURE', item_code: '0000990', amount: 500, tax: 0, total_amount: 500, customer_group_id: null, customer_id: null, card_no: '************1234', card_id: null, expire: '2411', holder_name: 'Test', card_no_hash: '0e4802a01114169feded374beed5f7d810be72c4aed0118285169b2b57fd55ec', method: '1', pay_times: null, forward: '15250', issuer: '9999999', transaction_id: '2204251016602250501600919723', approve: ' 067736', auth_max_date: null, client_field_1: null, client_field_2: null, client_field_3: null, tds_type: '0', tds2_type: null, tds2_ret_url: null, tds2_status: null, merchant_name: null, send_url: null, subscription_id: null, error_code: null, created: '2022/04/25 10:16:22.771', updated: '2022/04/25 10:16:23.681' } あわせて読みたい開発者におすすめの記事 fincodeの決済APIの利用する仕組みと方法 エンジニアファーストの決済ソリューション–fincodeの強みとは

