--- title: "チェックアウトの連携" description: "シームレスなチェックアウトソリューションを連携し、各国の最適な支払い方法でお客様をサポートしましょう。" source: "https://docs.tokenz.one/ja/v1/checkout/get-started" api_version: "v1" locale: "ja" version_status: "legacy" docs_stage: "prod" --- # チェックアウトの連携 シームレスなチェックアウトソリューションを連携し、各国の最適な支払い方法でお客様をサポートしましょう。 ## 前提条件 連携を実装する前に、Tokenz から API クレデンシャル (秘密キー) を取得していることを確認してください。 クレデンシャルは Tokenz Dashboard の Developers → API keys でご確認いただけます。 Tokenz チェックアウトの仕組みの詳細については、[Tokenz チェックアウト](https://docs.tokenz.one/ja/v1/) でご確認ください。 ## サーバーのセットアップ #### Python ```python import os from flask import Flask, request, redirect from flask_cors import CORS import requests # ご自身のキーに置き換えてください SECRET_KEY = os.environ.get("SECRET_KEY", "secret_test_YOUR_KEY_HERE") app = Flask(__name__, static_url_path="") CORS(app) root = "../client/build" @app.route("/", methods=["GET"]) def index(): return redirect("http://localhost:3080") ``` #### PHP ```php run(); ``` #### Go ```go package main import ( "encoding/json" "fmt" "io" "net/http" "os" "strings" "time" "github.com/gin-gonic/gin" ) func main() { router := gin.Default() router.StaticFile("/demo.css", "../client/build/demo.css") router.StaticFile("/", "../client/build/index.html") router.StaticFile("/payment-success", "../client/build/payment-success.html") router.StaticFile("/payment-canceled", "../client/build/payment-canceled.html") ... router.Run(":5001") } ``` #### NodeJS ```js import express from "express"; const app = express(); const port = 3000; app.get("/", (req, res) => { res.send( "
", ); }); app.listen(port, () => { console.log(`Sandbox listening on port ${port}`); }); ``` ## Checkout Session の作成 サーバーに Checkout Session (チェックアウトセッション) を作成するエンドポイントを追加します。 Checkout Session では、Tokenz がホストする支払いページでお客様に表示される項目、注文金額、通貨および利用可能な支払い方法を管理します。 ### 項目の定義 お客様によるクライアント側からの操作を防ぐため、商品の価格や在庫などの機密情報は、必ずサーバー側に保管してください。 Checkout Session の作成時に商品情報を定義します。 **税について。** このクイックスタート(およびサンプルペイロード)は、Tokenz アカウントのデフォルトである Merchant of Record(MoR)モデルを前提としています。MoR では Tokenz が税を自動的に計算・徴収するため、各商品の `taxCategory` を設定するだけで済みます。アカウントが特別に Payment Gateway モデルに設定されている場合は、すべての Checkout Session にトップレベルの `tax` オブジェクト(最小通貨単位、例:`"tax": { "amount": 0, "currency": "USD" }`)を追加で含める必要があり、含めない場合は `order.tax-required` エラーで拒否されます。お使いのアカウントのモデルが不明な場合は、Tokenz の担当者にご確認ください。 ### 成功 URL とキャンセル URL の提供 成功ページとキャンセルページの URL を指定します。Tokenz がお客様をリダイレクトできるようこれらのページは公開されている必要があります。 また、成功とキャンセルの両方のステータスを同じ URL で処理することも可能です。 ### [オプション] 利用可能な支払い方法の定義 このチェックアウトでお客様に提供する支払い方法のリストを指定します。 支払い方法が指定されていない場合、または空のリストが送信された場合、すべての利用可能な支払い方法が表示されます。 ### Tokenz チェックアウトにお客様をリダイレクトする セッションを作成したら、レスポンスで返されるチェックアウトページの URL にお客様をリダイレクトします。 #### Python ```python @app.route("/create-tokenz-checkout", methods=['POST']) def create_tokenz_checkout(): CALLBACK_URL_PREFIX = request.headers['referer'] headers = {"Authorization": f'Bearer {SECRET_KEY}'} print(headers) payload = { "amount": { "currency": "JPY", "amount": 5200 }, "itemDetails": [ { "product": { "label": "ひとにぎりのエメラルド", "description": "80+8", "images": [ "https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp" ], "quantity": 3, "price": { "currency": "JPY", "amount": 1200 }, "taxCategory": "DIGITAL_GOODS_AND_SERVICES" } }, { "product": { "label": "エメラルドの荷車", "description": "100+10", "images": [], "quantity": 1, "price": { "currency": "JPY", "amount": 1600 }, "taxCategory": "DIGITAL_GOODS_AND_SERVICES" } } ], "customerInfo": {}, "successUrl": "http://localhost:9000/success", "pendingUrl": "http://localhost:9000/pending", "cancelUrl": "http://localhost:9000/cancel", } res = requests.post( "https://api.tokenz.one/v1/checkoutsession", json=payload, headers=headers ) session = res.json() return redirect(session["url"], 303) ``` #### PHP ```php $app->map(['get', 'post'], '/', function ($request, $response, $args) { $fileName = trim($request->getUri()->getBasePath(), '/'); if ($request->isPost()) { $client = new \GuzzleHttp\Client(); try { $checkoutSessionResponse = $client->request('POST', 'https://api.tokenz.one/v1/checkoutsession', [ 'body' => '{ "amount": { "currency": "JPY", "amount": 5200 }, "itemDetails": [ { "product": { "label": "ひとにぎりのエメラルド", "description": "80+8", "images": [ "https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp" ], "quantity": 3, "price": { "currency": "JPY", "amount": 1200 }, "taxCategory": "DIGITAL_GOODS_AND_SERVICES" } }, { "product": { "label": "エメラルドの荷車", "description": "100+10", "images": [], "quantity": 1, "price": { "currency": "JPY", "amount": 1600 }, "taxCategory": "DIGITAL_GOODS_AND_SERVICES" } } ], "customerInfo": {}, "successUrl": "http://localhost:9000/success", "pendingUrl": "http://localhost:9000/pending", "cancelUrl": "http://localhost:9000/cancel" }', 'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer secret_test_YOUR_KEY_HERE', ], ]); $checkoutSession = json_decode($checkoutSessionResponse->getBody()); } catch (Exception $e) { echo $e; echo \GuzzleHttp\Psr7\Message::toString($e->getResponse()); } return $response->withRedirect($checkoutSession->url, 302); } else { $filePath = __DIR__ . '/../client/build/' . $fileName; switch (pathinfo($filePath, PATHINFO_EXTENSION)) { case 'css': $mimeType = 'text/css'; break; default: $mimeType = 'text/html'; } $body = $response->getBody(); $body->write(file_get_contents($filePath)); return $response ->withHeader('Content-Type', $mimeType . '; charset=UTF-8') ->withBody($body); } }); ``` #### Go ```go router.POST("/create-tokenz-checkout", func(c *gin.Context) { url := "https://api.tokenz.one/v1/checkoutsession" payload := strings.NewReader( `{ "amount": { "currency": "JPY", "amount": 5200 }, "itemDetails": [ { "product": { "label": "ひとにぎりのエメラルド", "description": "80+8", "images": [ "https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp" ], "quantity": 3, "price": { "currency": "JPY", "amount": 1200 }, "taxCategory": "DIGITAL_GOODS_AND_SERVICES" } }, { "product": { "label": "エメラルドの荷車", "description": "100+10", "images": [], "quantity": 1, "price": { "currency": "JPY", "amount": 1600 }, "taxCategory": "DIGITAL_GOODS_AND_SERVICES" } } ], "customerInfo": {}, "successUrl": "http://localhost:9000/success", "pendingUrl": "http://localhost:9000/pending", "cancelUrl": "http://localhost:9000/cancel" }`) req, _ := http.NewRequest("POST", url, payload) req.Header.Add("Content-Type", "application/json") req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", os.Getenv("SECRET_KEY"))) resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() bodyBytes, _ := io.ReadAll(resp.Body) var result Response if err := json.Unmarshal(bodyBytes, &result); err != nil { fmt.Println("Can not unmarshal JSON") } checkoutUrl := result.URL c.Redirect(http.StatusSeeOther, checkoutUrl) }) ``` #### NodeJS ```js app.post("/create-tokenz-checkout", (req, res) => { const API_ENDPOINT = "https://api.tokenz.one/v1/checkoutsession"; const payload = { amount: { currency: "JPY", amount: 5200, }, itemDetails: [ { product: { label: "ひとにぎりのエメラルド", description: "80+8", images: [ "https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp", ], quantity: 3, price: { currency: "JPY", amount: 1200, }, taxCategory: "DIGITAL_GOODS_AND_SERVICES", }, }, { product: { label: "エメラルドの荷車", description: "100+10", images: [], quantity: 1, price: { currency: "JPY", amount: 1600, }, taxCategory: "DIGITAL_GOODS_AND_SERVICES", }, }, ], customerInfo: {}, successUrl: "http://localhost:9000/success", pendingUrl: "http://localhost:9000/pending", cancelUrl: "http://localhost:9000/cancel" }; fetch(API_ENDPOINT, { method: "POST", body: JSON.stringify(payload), headers: { "content-type": "application/json", authorization: "Bearer " + process.env.SECRET_KEY, }, }) .then((response) => response.json()) .then((session) => { console.log(session); res.redirect(303, session.url); }); }); ``` ## チェックアウトの構築 ### 成功ページを追加する Checkout Session の `successUrl` として指定した URL に表示する成功ページを作成し、注文確認メッセージや注文の詳細をお客様に表示します。 お客様がチェックアウトを正常に完了すると、このページにリダイレクトされます。 ```htmlご利用いただき誠にありがとうございます。ご質問がある場合は、 orders@example.comまでご連絡ください。
お客様のお支払いは現在処理中です。処理が完了次第お知らせいたします。 If you have any questions, please email orders@example.com.
Forgot to add something to your cart? Shop around then come back to pay!