Checkify
開発者ドキュメント

バックエンドで確認します

ブラウザの埋め込みが完了したら、サインアップ、チェックアウト、または保護されたアクションを許可する前に、サーバーはサイト API キーを使用して結果を確認する必要があります。

サーバー検証は5分で完了します

  1. Checkify ブラウザ埋め込みをページに追加してください。
  2. 埋め込みによってCheckifyセッションが開始され、検証参照がフォームに書き込まれます。
  3. バックエンドは非表示フィールドの値を読み取ります。
  4. バックエンドは、その値をリクエストIDとしてPOST /v1/qr/results/verifyに送信します。
  5. 必要な請求が承認された場合、保護された措置を許可する。
  6. フロントエンドの状態だけを鵜呑みにしてはいけない。

非表示のフォームフィールドの名前は checkify_token かもしれませんが、その値は Checkify request_id です。

エンドツーエンドの流れ

1。サイトを作成します API キー

ビジネス ダッシュボードで、 開発者を開きます そして、統合するサイトのサイト API キーを作成します。サーバー環境変数にのみ保存します。ブラウザには決して送信しないでください。

フロントエンドSDKを使用していますか?

GET /v1/qr/pass/{PASS_ID}/start を手動で呼び出す必要はありません。Checkify JavaScript の埋め込み機能がセッションを開始し、request_id を受信して、それをフォームに自動的に書き込みます。

バックエンドに必要なことは以下のとおりです。

2. サーバー上でリクエストIDを受け取ります

フロントエンドのSDKは、ユーザーが検証を完了した後、Checkifyのrequest_idを非表示のフォームフィールドに書き込みます。デフォルトのフィールド名はcheckify_tokenです。これはフィールド名であり、別のトークンタイプではありません。このフィールドの値をrequest_idとして検証エンドポイントに送信してください。

モバイルアプリのハンドオフ処理では、ページURLにcheckify_request_idが返される場合があります。SDKは読み込み時にこれを読み取りますが、サーバー側では引き続き同じrequest_id値を検証します。

フロントエンドからフォームPOSTを送信

{
  "email": "user@example.com",
  "checkify_token": "56a57761-ff5b-42f0-9c97-6c13e223e017"
}

バックエンドからのリクエストを検証してください

{
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "required_claims": ["human_verified"],
  "required_fields": [],
  "consume": true
}

フロントエンドの統合は手動のみ

3. cURLを使用した手動テスト

バックエンド開発者は通常 /start を呼び出しません。このセクションは、カスタムフロントエンドを構築する場合、または埋め込みなしでテストする場合にのみ使用してください。zsh/bash では URL を引用符で囲むことで、? がグロブとして扱われないようにします。

/start には Origin ヘッダーが必要です

Pass startは、登録済みのWebサイトドメインからのみ機能します。ブラウザはOriginを自動的に送信しますが、cURLは送信しません。Origin(またはX-Checkify-Site-Url)には、[サイト]→[許可されたドメイン]にリストされているホスト名を指定してください。ホスト名は完全に一致している必要があります。checkify.meとwww.checkify.meは異なります。

最も一般的なテストの問題

/start が HTTP 403 を返した場合でも、パス ID は有効な可能性があります。一般的な原因は、リクエストされたドメインが許可されたドメインのリストに含まれていないか、www.example.com が登録されているにもかかわらず example.com が使用された(またはその逆)ことです。

統合テストには、専用のテストサイトを使用し、Checkify ダッシュボードで Pass を実行してください。サイト API キーには csk_ プレフィックスが付きます。テストキーの形式は別途用意されていません。成功フローと拒否フローの両方を確認するまでは、本番環境のチェックアウトに対してテストを実行しないでください。

# Step A — start a session (replace PASS_ID and YOUR_REGISTERED_DOMAIN)
curl -sS \
  -H "Accept: application/json" \
  -H "Origin: https://YOUR_REGISTERED_DOMAIN" \
  "https://checkify.me/v1/qr/pass/chk_live_YOUR_PASS_ID/start?request_type=human"

# Response includes request_id and qr_url — open qr_url and complete verification

# Step B — verify on your server (after the user completes verification)
curl -sS -X POST "https://checkify.me/v1/qr/results/verify" \
  -H "Authorization: Bearer $CHECKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "PASTE_request_id_FROM_STEP_A",
    "required_claims": ["human_verified"],
    "consume": true
  }'

検証呼び出しの際のみ、サイトのキー「API」を使用してください。検証呼び出しを行う前に、アプリで認証を完了してください。そうしないと、ステータスが保留状態になります。

ユースケースごとの必須クレーム

required_claims を設定して、保護対象アクションに必要な証明と一致させます。クレーム名は、Checkify がその検証セッションで承認したものと一致する必要があります。年齢確認には age_over_{N} (例: age_over_18) を使用します。埋め込みリクエストが一致するリクエストタイプを要求する場合、10 から 110 までの動的なしきい値がサポートされます。

使用事例 推奨される必須クレーム 注記
ボット / CAPTCHA の代替品 ["human_verified"] 実際のユーザーがCheckifyフローを完了したことを確認します。
13歳以上向けコンテンツまたは青少年向け製品 ["age_over_13"] パスのリクエストで年齢が13歳以上の場合に使用してください。
16歳以上向けコンテンツまたは地域ごとの年齢制限 ["age_over_16"] パスのリクエストで年齢が16歳以上の場合に使用してください。
電子タバコ、アルコール、または18歳以上限定 ["age_over_18"] 対象年齢の上限を、製品と市場に合わせて設定してください。
21歳以上限定商品(該当する場合) ["age_over_21"] パスのリクエストで年齢が21歳以上の場合に使用してください。
チャレンジ25またはより厳格な小売ポリシー ["age_over_25"] パスのリクエストで年齢が25歳以上の場合に使用してください。
カスタム年齢制限 ["age_over_N"] age_over_N(Nは10~110)を使用してください。これは埋め込みリクエストの種類に合わせて設定してください。

埋め込みリクエストタイプ → サーバークレーム

ブラウザのリクエストタイプは、サーバー側で検証するクレームと一致している必要があります。

埋め込みリクエストタイプ必須クレーム
human["human_verified"]
age_over_13["age_over_13"]
age_over_16["age_over_16"]
age_over_18["age_over_18"]
age_over_21["age_over_21"]
age_over_25["age_over_25"]
age_over_N["age_over_N"] (N = 10~110)

オプションの必須項目

required_claims に加え、統合が収集した場合は承認済みの特定の身元フィールド(国や年齢帯など)を要求できます。required_fields にフィールド名を渡してください。承認結果に欠ける場合、verify は error.details の missing_fields とともに missing_required_fields を返します。

4. サーバーでverifyを呼び出す

アクセスを許可する前に、サイトのAPIキーを使用してPOST /v1/qr/results/verifyを呼び出してください。Checkifyが結果を確認するまでは、ブラウザ参照(request_idまたは従来のポーリングトークン)は信頼できないものとして扱ってください。

POST https://checkify.me/v1/qr/results/verify
Authorization: Bearer YOUR_SITE_API_KEY
Content-Type: application/json

{
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "required_claims": ["human_verified"],
  "consume": true
}

送信することもできます token の代わりに request_id. API キーは Checkify サイトにスコープされています。リクエスト本文に site_id を送信する必要はありません。

実装例

# checkify_token from your form POST is sent as request_id
curl -sS -X POST "https://checkify.me/v1/qr/results/verify" \
  -H "Authorization: Bearer $CHECKIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
    "required_claims": ["human_verified"],
    "consume": true
  }'

いつ消費するか

最終的な保護アクションには consume: true を使用してください。 — チェックアウト、サインアップ、パスワードリセット、年齢制限付き購入、保護されたコンテンツへのアクセス

consume: false は、 — テスト、デバッグ、または最終確認ではないチェックで、結果を後で再度検証する必要がある場合

規制対象または高リスクのアクションについては、consume: true を優先してください。これにより、同じ検証結果が複数の保護された決定に再利用されるのを防ぎます。

規制対象アクションの失敗

バックエンドが Checkify にアクセスできない場合は、サーバー側で結果が確認されない限り、年齢制限付きチェックアウト、ギャンブルへのアクセス、アダルトコンテンツへのアクセス、電子タバコやアルコールの購入、その他の保護された操作を許可しないでください。

HTTPタイムアウトを短く設定してください(例:10秒)。一時的な5xxエラーやネットワークエラーの場合は1~2回再試行し、それでも解決しない場合はアクセスを拒否してください。インシデントはサーバー側でログに記録し、ユーザーにとって安全なメッセージを表示してください。内部のCheckifyエラーの詳細を顧客に公開しないでください。

try {
  const verdict = await verifyCheckifyResult(requestId);

  if (!verdict.allow) {
    return res.status(403).json({ error: "Verification required" });
  }

  // Continue protected action
} catch (err) {
  console.error("Checkify verification unavailable", err);

  return res.status(403).json({
    error: "Verification is temporarily unavailable. Please try again.",
  });
}

サーバー SDKs とツール

The Checkify monorepo includes @checkify/server (Node.js) and checkify-server (Python) packages for server-side verify calls. There is no published OpenAPI spec or Postman collection yet — use the examples on this page and POST /v1/qr/results/verify directly.

@checkify/server v1.0.0 が npm で公開されました。Python の checkify-server パッケージは、Checkify SDK モノレポに含まれています。

結果の有効期限

完了した検証は、QR_RESULT_MAX_AGE_SECONDS (デフォルトは900秒/15分) 後に期限切れとなります。期限切れ後、検証は result_expired を返します。ユーザーに再度検証を依頼してください。

ステータスポーリングエンドポイント(カスタムフロントエンド)

JavaScript と SDK は、標準の埋め込みのセッション状態を処理します。これらは、GET /v1/qr/pass/{pass_id}/start を手動で呼び出すカスタムフロントエンドを構築する場合にのみ使用してください。

応答処理

成功した場合、Checkify は HTTP 200 を success: true および status: completed とともに返します。必要なクレームが存在する場合(例: human_verified: true)のみアクセスを許可します。

{
  "success": true,
  "status": "completed",
  "message": "Verification result confirmed",
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "site_id": "YOUR_SITE_ID",
  "business_id": "YOUR_BUSINESS_ID",
  "approved_claims": {
    "human_verified": true
  },
  "approved_fields": [],
  "signed_result": {
    "payload": { "...": "..." },
    "signature": "...",
    "signature_algorithm": "EdDSA",
    "key_id": "checkify:default"
  }
}

署名結果

signed_result オブジェクトにより、バックエンドは検証時点で Checkify が必要なクレームを承認した改ざん耐性のある監査記録を保持できます。多くの統合では approved_claims だけで十分です。規制対象や高リスクの事業者は signed_result も保存できます。入れ子の proof_metadata には暗号的・運用的な証拠(assurance メタデータ、証拠種別、同意ハッシュなど)が含まれることがあり、身分証や生の生年月日ではありません。入れ子の assurance フィールドを認証や信頼保証と見なさないでください。certification_status と自社ポリシーを確認してください。必要以上の個人情報を保存しないでください。

顧客がアプリでの操作を完了していない場合、Checkify は HTTP 200 を成功: false、ステータス: pending で返します。保護された操作を拒否し、ユーザーに検証を完了するように求めます。

{
  "success": false,
  "status": "pending",
  "message": "Verification is not completed yet",
  "request_id": "56a57761-ff5b-42f0-9c97-6c13e223e017",
  "approved_claims": {},
  "signed_result": null
}
フィールド意味
successtrue 検証が完了し、要件が一致したとき
statuscompleted または pending
approved_claimsクレーム Checkify が承認されました。 human_verified: true
signed_result監査証跡用のオプションの署名付きペイロード

JSON エラーペイロード

検証が実行できない場合、Checkify は構造化された JSON ボディとともに HTTP 4xx/5xx を返します。サーバー側で error.code を確認し、error.details をログに記録します。エンドユーザーには一般的なメッセージを返します。

{
  "success": false,
  "error": {
    "code": "verification_failed",
    "message": "The verification did not include all required claims.",
    "details": {
      "missing_claims": ["age_over_18"]
    }
  }
}
コード HTTP 意味 推奨される対策
missing_authorization401認証ヘッダーが送信されませんでした。サーバー側のコードからのみ、認証情報「Bearer YOUR_SITE_API_KEY」を送信してください。
invalid_token401ベアラートークンが欠落しているか、形式が不正であるか、有効なサイトAPIキーではありません。ビジネスダッシュボードでキーを確認し、環境変数に保存してください。
expired_token401サイトのキー「API」は失効しました。新しいサイトキー「API」を作成し、サーバー上でローテーションしてください。
missing_required_field400 / 422JSON ボディに request_id または token がありません。非表示のフォームフィールドからrequest_idを渡すか、統合システムがまだポーリングトークンを使用している場合はポーリングトークンを渡してください。
invalid_request_id400参照を解析できなかったか、正規化後に空になっています。フロントエンドがCheckifyのリクエストIDを変更せずに送信するようにしてください。
result_not_found404その参照に関する検証リクエストは存在しません。この操作を拒否してください。ユーザーが非表示フィールドを改ざんしたか、古いセッションを送信した可能性があります。
result_expired410検証が完了してから時間が経ちすぎているため、この操作には信頼できません。ユーザーに再度スキャンしてもらい、新しいrequest_idを使用してverifyを呼び出してください。
verification_failed403 / 409サイト/ビジネスの不一致、既に消費された結果(HTTP 409)、または一般的な検証失敗。アクセスを拒否してください。error.details を確認し、クレーム/フィールド不足は missing_required_claims と missing_required_fields を参照してください。
missing_required_claims403developers_server.err_missing_required_claims_meaningdevelopers_server.err_missing_required_claims_action
missing_required_fields403developers_server.err_missing_required_fields_meaningdevelopers_server.err_missing_required_fields_action
unknown_required_attributes400developers_server.err_unknown_required_attributes_meaningdevelopers_server.err_unknown_required_attributes_action
business_not_operational403ビジネスアカウントはロックされているか、アーカイブされているか、または利用できません。事業主またはCheckifyサポートにお問い合わせください。アカウントが有効になるまで、保護された操作は許可しないでください。
validation_errors422JSON ボディのスキーマ検証に失敗しました (HTTP 422)。error.details.validation_errors を調べて、フィールドレベルのメッセージを確認してください。再試行する前に、request_id、required_claims、またはrequired_fields の型を修正してください。
rate_limited429短時間に検証呼び出しが多すぎる。指数バックオフを使用して再試行します。ページビューごとに検証するのではなく、保護されたアクションが発生したときのみ検証します。
server_error500+Checkify は、一時的なサーバーの問題により検証を完了できませんでした。1、2回再試行し、それでも失敗した場合はシステムを閉じて、インシデントをログに記録します。

Webhookと非同期検証

現在、サーバー検証は同期的に行われます。つまり、ユーザーが保護されたアクションを送信した際に、バックエンドがrequest_idを検証します。チェックアウト、サインアップ、アクセス制御フローでは、この方法が推奨されます。標準的な統合では、汎用検証Webhookは不要です。GoHighLevelやその他のパートナーとの統合では、ビジネスダッシュボードで個別の送信Webhook設定を使用する場合があります。

よくある間違い

セキュリティに関するリマインダー

非表示フィールドを証拠ではなく、信頼できない参照として扱います。アクセスを許可する前に、サーバー上のサイト API キーを必ず確認してください。サインアップやパスワードのリセットなどの 1 回限りのアクションには、 consume: true を使用します。

次のステップ