Square Terminal APIを使った会計処理
以前、オリジナルのAndroidアプリから、Square Terminal端末と連携して会計処理をする仕事に携わりました。ほとんど情報がなく、公式のSquareドキュメントも情報が煩雑していて、目当ての情報を見つけることに非常に苦労しました。 プロジェクトの忘備録として大まかな手順をまとめておきます。この記事に掲載する内容に関してのご質問にはお答えできませんのでご了承ください。
お仕事依頼の場合は、こちらからご相談ください。
会計処理のおおまかな流れ
- Terminal APIを使ってデバイスコード発行(再発行しない限り一度のみ)
- Square Terminal端末へデバイスコードでログイン
- アプリケーション側で、請求金額とともにTerminal APIを叩く
- お客様に、Square Terminal でカードや電子マネーで支払いを処理してもらう
- セッションID情報を元に、HTTP経由で会計処理の状態をチェックし、アプリケーション側で条件分岐処理させる
Square Terminal APIの公式ドキュメント: Terminal API Quickstart
Square Terminal端末へデバイスコードでログイン
Square Terminal端末は、デフォルトで商品閲覧やPOS機能のようなものが提供されています。今回のプロジェクトでは、商品管理やPOS機能は自社側で開発するため、Square Terminal端末をカードリーダーとしてだけ使いたかったのです。このやり方を知るのに苦労しました😅
Square Terminal端末にログインする際に、メールアドレスなどのアカウントではなく、Terminal APIを使って発行したデバイスコードでログインすると、Square Terminal端末をカードリーダーとして使用することができます。すでにアカウントでログインしてしまった場際は、一旦ログアウトしましょう。
デバイスコード発行API
デバイスコードを発行するには、以下のAPIを叩きます。
curl https://connect.squareup.com/v2/devices/codes \
-X POST \
-H 'Square-Version: 2024-06-04' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"idempotency_key": "XXXXXXXXXXXXXXXX",
"device_code": {
"name": "Counter 1",
"product_type": "TERMINAL_API",
"location_id": "XXXXXXXXXXXXXXXX"
}
}'
ACCESS_TOKEN について
APIを叩く際は、こちらの提供されているWebアプリを利用すると便利です。
POST /v2/devices/codes - Square API Explorer
また、APIを叩く際にはACCESS_TOKEN が必要になります。ACCESS_TOKEN はSquare Developerの管理画面で、Applicationsを作成すると発行されます。機密情報なので基本的にサーバーサイドに置く必要があります。本番環境では下図のように、中間サーバーを通してアプリケーションからAPIへアクセスするのが良いでしょう。
デバイスコード発行後のレスポンス
{
"device_code": {
"id": "XXXXXXXXXXXXXXXX",
"name": "Counter 1",
"code": "XXXXXXXXXXXXXXXX",
"product_type": "TERMINAL_API",
"location_id": "XXXXXXXXXXXXXXXX",
"pair_by": "2024-05-03T01:35:55.000Z",
"created_at": "2024-05-03T01:30:56.121Z",
"status": "UNPAIRED",
"status_changed_at": "2024-05-03T01:30:55.000Z"
}
}
デバイス コードが作成されたら、販売者はそのデバイス コードを使用して 5 分以内に Square ターミナルにサインインする必要があります。 デバイス コードが 5 分以内に使用されない場合、デバイス コードは期限切れになり、新しいデバイス コードをリクエストする必要があります。 最初のサインイン後は、デバイス コードを再利用して、その後のサインイン試行で同じ Square ターミナルにサインインできます。
販売者がSquareターミナルにサインインした後、デバイス コードを指定すると、ステータスが PAIRED に変わり、端末デバイスの device_id 値が利用可能になります。 デバイスIDはSquare Terminalの下面に記載されているシリアル番号です。
販売者がサインインすると、Webhook イベント通知を通じて POS アプリケーションに通知されます。
Squareターミナル端末を一度ログアウトしておきます。発行されたデバイスコードを使ってログインします。ログイン後、いわゆるペアリング状態になります。
また、サンドボックスアカウントでデバイスコードを発行するとログインできませんでした。本番アカウントでデバイスコード発行したらログインできました。
デバイスコードは、発行するたびに端末のログインをやり直さなければならなくなるので、通常は一度のみの発行で良いのだと思います。
デバイス情報を取得
device code idなどがわからなくなった時に使えるリクエストです。
curl https://connect.squareup.com/v2/devices \
-H 'Square-Version: 2024-05-15' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json'
▼ レスポンス
{"devices": [{"id": "device:XXXXXXXXXXXXX","attributes": {"type": "TERMINAL","manufacturer": "Square","model": "Square Terminal (1st Gen, v2)","name": "Square ターミナル XXXX","manufacturers_id": "XXXXXXXXXXXXX","updated_at": "2024-05-18T02:35:32.503Z","version": "5.49.0024","merchant_token": "XXXXXXXXXXXXX"},"components": [{"type": "CARD_READER","card_reader_details": {"version": "3.61.116"}},{"type": "BATTERY","battery_details": {"visible_percent": 93,"external_power": "UNAVAILABLE"}},{"type": "WIFI","wifi_details": {"active": true,"ssid": "XXXXXXXXXXXXX","ip_address_v4": "192.168.175.238","secure_connection": "WPA_PSK","signal_strength": {"value": 3}}},{"type": "ETHERNET","ethernet_details": {"active": false}},{"type": "APPLICATION","application_details": {"application_type": "TERMINAL_API","version": "6.42","session_location": "XXXXXXXXXXXXX","device_code_id": "XXXXXXXXXXXXX"}},{"type": "APPLICATION","application_details": {"application_type": "SQUARE_POS","version": "6.40","session_location": "XXXXXXXXXXXXX"}}],"status": {"category": "AVAILABLE"}}]}
支払いフロー
Take Payments with the Terminal API
POS クライアントで CreateDeviceCode エンドポイントを呼び出し、 Square ターミナルとペアリングし、デバイス ID を取得します。 デバイスのペアリング成功の通知を待ちます。
POS クライアントは、購入者をチェックアウトして支払いを受け入れるためのリクエストをターミナル API に送信します。
Square はチェックアウトの詳細を Square ターミナルに送信し、購入者に支払いの詳細が表示されます。 購入者は、Square ターミナルに支払いカードを浸す、タップする、またはスワイプします。 SquareターミナルはSquareに支払いを通知します。 ターミナル API は、ターミナル チェックアウトが完了したことを POS バックエンドに通知します。
Get device code
curl https://connect.squareup.com/v2/devices/codes/ \
-H 'Square-Version: 2024-04-17' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json'
{
"device_codes": [
{
"id": "XXXXXXXXXXXXXXXX",
"name": "Counter 1",
"code": "XXXXXXXXXXXXXXXX",
"device_id": "XXXXXXXXXXXXXXXX",
"product_type": "TERMINAL_API",
"location_id": "XXXXXXXXXXXXXXXX",
"created_at": "2024-05-05T03:14:32.000Z",
"status": "PAIRED",
"status_changed_at": "2024-05-05T03:14:52.000Z",
"paired_at": "2024-05-05T03:14:52.000Z"
}
]
}
金額表示リクエスト
※tipなどの米国以外でサポートされいないフィールドを入力するとエラーになる
device_idは事前に取得しておくこと。以下は多分最小限のリクエストcurl https://connect.squareup.com/v2/terminals/checkouts \
-X POST \
-H 'Square-Version: 2024-04-17' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"checkout": {
"amount_money": {
"amount": 1,
"currency": "JPY"
},
"device_options": {
"device_id": "XXXXXXXXXXXXXXXX"
}
},
"idempotency_key": "XXXXXXXXXXXXXXXX"
}'
idempotency_keyとは「べき等性」といって、「ある操作を 1 回行っても複数回行っても結果が同じである」ことをいう概念のことです。
▼ レスポンス。会計キャンセル時には、checkout_idが必要になるなります。
{
"checkout": {
"id": "XXXXXXXXXXXXXXXX",
"amount_money": {
"amount": 1,
"currency": "JPY"
},
"device_options": {
"device_id": "XXXXXXXXXXXXXXXX",
"collect_signature": false,
"tip_settings": {
"allow_tipping": false
},
"skip_receipt_screen": false
},
"status": "PENDING",
"created_at": "2024-05-07T00:05:46.371Z",
"updated_at": "2024-05-07T00:05:46.371Z",
"app_id": "XXXXXXXXXXXXXXXX",
"location_id": "XXXXXXXXXXXXXXXX",
"payment_type": "CARD_PRESENT",
"payment_options": {
"autocomplete": true
}
}
}
チェックアウトリクエスト後、数分間の間に決済が完了しないと自動でキャンセルになります。
チェックアウトキャンセル処理
curl https://connect.squareup.com/v2/terminals/checkouts/jjJePcCcIXnqO/cancel \
-X POST \
-H 'Square-Version: 2024-04-17' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json'
{
"checkout": {
"id": "XXXXXXXXXXXXXXXX",
"amount_money": {
"amount": 1,
"currency": "JPY"
},
"device_options": {
"device_id": "XXXXXXXXXXXXXXXX",
"collect_signature": false,
"tip_settings": {
"allow_tipping": false
},
"skip_receipt_screen": false
},
"status": "CANCEL_REQUESTED",
"created_at": "2024-05-07T00:05:46.371Z",
"updated_at": "2024-05-07T00:07:02.486Z",
"app_id": "XXXXXXXXXXXXXXXX",
"cancel_reason": "SELLER_CANCELED",
"location_id": "XXXXXXXXXXXXXXXX",
"payment_type": "CARD_PRESENT",
"payment_options": {
"autocomplete": true
}
}
}
そのほかにも様々なAPIが用意されています。必要に応じて使い分けます。
SquareのWebhookについて
Webhookを使うと、API実行時のログなどを自社サーバーで購読できるようです。
name | url | API version |
---|---|---|
terminal-webhook | https://自社ドメイン/square/terminal-webhook.php | 2024-03-20 |
プロトタイプ開発では必要ないため、適当にエンドポイントを用意しておきました。中身の実装は不要です。
SquareのWebhookは、特定のイベントがSquareシステム内で発生した際に、登録された外部のURLに自動的に通知を送る仕組みです。例えば、新しい注文の作成や支払いの完了などのイベントがトリガーとなります。
Webhookのメリット
- リアルタイム性: イベントが発生するとすぐに通知が送られるため、リアルタイムでのデータ同期や処理が可能です。
- 効率性: ポーリングなどで定期的にAPIを確認する必要がなく、必要な時にのみデータを受け取れるため、システムリソースの節約につながります。
- 自動化の強化: 特定のイベントに基づいて自動的にプロセスを実行できるため、作業の自動化が進みます。
Webhookの実装について
Webhookを利用するには、外部サーバーが必要です。このサーバーは、Squareからの通知を受信するエンドポイントとして機能します。通知を受け取った後、そのデータをもとに必要な処理を行うことができます。
サーバーは、安全で信頼性の高い環境で運用する必要があり、HTTPSを使用してセキュアに通信を行うことが求められます。また、受信したデータの検証も重要です。Squareは、送信されたWebhook通知が正当であることを確認するために、署名キーを提供しています。これにより、受信したデータがSquareから送信されたものであることを検証できます。
SquareのWebhookを利用するためには、SquareのダッシュボードまたはAPIを通じて、Webhookを設定し、受け取りたいイベントの種類を指定する必要があります。