snippe-integration について
snippe-integrationは、タンザニアの決済事業者Snippeをアプリに導入する開発者向けスキルです。決済、送金、ホスト型チェックアウト、Webhookの安全な処理を言語に依存しない形で案内します。
主な機能
- 01決済、セッション、送金の作成
- 02Webhookの署名とタイムスタンプ検証
- 03重複イベントと再試行への対応
- 04APIエラーと入力検証の診断
活用シーン
- 01モバイルマネー、カード、QR決済の導入
- 02Snippeのホスト型チェックアウトの実装
- 03決済状況Webhookの安全な受信
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ neurotech-hq/ skills --skill snippe-integrationインストール後、Claude Code で/snippe-integrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/disbursements.mderrors.mdpayments.mdsessions.mdwebhooks.md詳細
Snippe Integration
Snippe はタンザニアの決済処理サービスです。このスキルは、正しい認証で API を呼び出し、正しいフィールド形式で決済/セッション/払い出しを作成し、Webhook の署名を安全に検証し、エラーを処理するなど、正確なインテグレーションの構築を支援します。間違えやすい微妙な点も含まれています。
ユーザーのアプリケーションから Snippe に接続するコードを記述します。ユーザーが使用する言語は Node.js、Python、PHP、Go、Ruby などさまざまです。このスキルではプロトコルレベルの知識を提供し、サンプルコードブロックをユーザーがすでに使用している言語に合わせて調整します。
API の基本
- ベース URL:
https://api.snippe.sh - API バージョン:
2026-01-25(現在の安定版) - 通貨:
TZSのみです。他の通貨を指定すると400 validation_errorが返されます。金額は最小通貨単位で整数として指定します(小数は使いません)。 - 認証:
Authorizationヘッダーに Bearer トークンを指定します。キーはsnp_...の形式で、Snippe Dashboard の Settings → API Keys から作成時に一度だけ表示されます。
Authorization: Bearer snp_your_api_key_here
API キーにはスコープが設定されます。加盟店はキーの作成時にスコープを選択します。
| スコープ | 許可される操作 |
|---|---|
collection:read | 決済と残高の表示 |
collection:create | 決済の作成 |
disbursement:read | 払い出しの表示 |
disbursement:create | 払い出しの作成 |
決済受け付けのみを行うサービス(チェックアウトなど)を構築する場合は、collection:* だけが必要です。アプリが実際に送金する場合を除き、disbursement:* を要求しないでください。
主な概念
Snippe には4つのリソースファミリーがあります。タスクに必要なものを理解することが、最初の判断になります。
| リソース | 用途 | エンドポイントのプレフィックス |
|---|---|---|
| Payments | 顧客から代金を受け取ります(モバイルマネー、カード、QR) | /v1/payments |
| Sessions | ホスト型チェックアウトページです。Snippe が UI を表示し、決済方法の選択を処理します | /api/v1/sessions |
| Disbursements | モバイルウォレットまたは銀行口座に送金します | /v1/payouts |
| Webhooks | URL へのリアルタイムのイベント配信 | (ご利用のサーバー) |
Payments と Sessions の違い — これは最もよくある選択の分岐点です。
- UI を全面的に制御し、決済フォームを自分で作成する場合は、Payments API を使用します。呼び出しごとに、1つのチャネル(モバイル/カード/QR)向けの決済インテントが1件作成されます。
- Snippe のホスト型モバイル最適化チェックアウトページを利用する場合は、Sessions を使用します。1つの URL で複数の決済方法に対応でき、SMS/WhatsApp での共有や、シンプルなアプリへの埋め込みに最適です。
クイックスタート:モバイルマネー決済を受け付ける
リクエストから決済確定までの最もシンプルなエンドツーエンドのフローです。
1. 決済を作成する
POST /v1/payments
Authorization: Bearer snp_your_api_key_here
Content-Type: application/json
Idempotency-Key: order-12345-attempt-1
{
"payment_type": "mobile",
"details": { "amount": 500, "currency": "TZS" },
"phone_number": "255781000000",
"customer": {
"firstname": "FirstName",
"lastname": "LastName",
"email": "[email protected]"
},
"webhook_url": "https://yoursite.com/webhooks/snippe",
"metadata": { "order_id": "ORD-12345" }
}
2. レスポンス
{
"status": "success",
"code": 201,
"data": {
"reference": "9015c155-9e29-4e8e-8fe6-d5d81553c8e6",
"status": "pending",
"payment_type": "mobile",
"amount": { "currency": "TZS", "value": 500 },
"expires_at": "2026-01-25T05:04:54Z"
}
}
顧客の電話に USSD プッシュが届きます。顧客が PIN を入力すると、Snippe は webhook_url に payment.completed(または payment.failed)を POST します。決済は承認されないまま4時間が経過すると期限切れになります。
3. (任意)ステータスをポーリングする
Webhook を受信できない場合や、Webhook に依存しない確認手段が必要な場合は、次のようにポーリングします。
GET /v1/payments/{reference}
Authorization: Bearer snp_your_api_key_here
リアルタイムのステータス確認には Webhook を優先し、ポーリングはフォールバックまたは照合手段としてのみ使用してください。
重要なルール(間違えやすい点)
連携が壊れたり、サポートチケットが発生したりする原因となる項目です。コードを書く際は、すべて確認してください。
- 通貨は TZS のみです。
USD、EUR、KESを送信すると、400 validation_errorが返されます。金額は最小単位で指定する整数です。500は 5.00 ではなく、500 TZS を意味します。 - 最低金額:決済は 500 TZS、払い出しは 5,000 TZS です。これらを下回る値を指定すると、検証エラーが返されます。
- 電話番号の形式:
255XXXXXXXXX(プラス記号なし)または+255XXXXXXXXX(プラス記号あり)を指定します。どちらも使用できますが、0781000000のような国内形式は使用できません。 Idempotency-Keyは 30 文字以下でなければなりません。 これは、原因が分かりにくいPAY_001エラーの最もよくある原因です。PAY_001が発生した場合は、上流のプロセッサーが停止していると考える前に、べき等性キーの長さを確認してください。同じキーで異なる本文を送信すると422が返され、同じキーで同じ本文を送信すると、キャッシュされたレスポンスが返されます(有効期間は 24 時間です)。POST /v1/paymentsとPOST /v1/payouts/sendには、必ずべき等性キーを含めてください。- Webhook の
data.amountは整数ではなくオブジェクトです。 Webhook ペイロードでは{"value": 50000, "currency": "TZS"}が届くため、.valueと.currencyを別々に解析してください。リクエスト本文ではdetails.amountが単純な整数なので、これは逆の形式です。ここでの解析形式の不一致は、よくあるバグです。 - Webhook の署名は、未加工のリクエスト本文に対して検証してください。 受信したバイト列を読み取り、JSON を解析して再シリアル化しないでください。再シリアル化すると空白やキーの順序が変わり、HMAC が一致しなくなります。Express では
express.raw({ type: "application/json" })を、Flask ではrequest.get_data(as_text=True)を使用してください。Go では、JSON をデコードする前にio.ReadAllでreq.Bodyを読み取ってください。 - リプレイ攻撃を防ぐため、タイムスタンプが 5 分より古い Webhook は拒否してください。 ペイロードを信頼する前に、現在時刻と
X-Webhook-Timestampを照合してください。 - HMAC の検証には、時間差が一定の比較関数(
crypto.timingSafeEqual、hmac.compare_digest、hash_equals、hmac.Equal)を使用してください。文字列を==で比較してはいけません。タイミング攻撃は実際に起こり得ますが、簡単に防止できます。 - Webhook イベントは
idで重複排除してください。 Snippe は同じイベントを複数回配信する場合があるため、ハンドラーはべき等でなければなりません。 - Webhook には 30 秒以内に 2xx を返し、その後に非同期で処理してください。 データベースにアクセスしたり、時間のかかる処理をその場で実行したりすると、再試行スケジュール(3 → 6 → 12 → 24 分、5 回の試行後に打ち切り)が発動します。
- レート制限は 1 分あたり 60 リクエストです。
X-Ratelimit-Limit、X-Ratelimit-Remaining、X-Ratelimit-Resetの各ヘッダーに従ってください。429が返された場合は、リセット時刻まで待ってから再試行してください。 - Webhook とリダイレクトの URL は HTTPS で、500 文字以下でなければなりません。 HTTP URL は拒否されます。
適切なリファレンスファイルの選択
現在のタスクに必要なものだけを読み込んでください。
| 作業内容 | 読み込むファイル |
|---|---|
| モバイルマネー、カード、QR 決済の作成 | references/payments.md |
| ホスト型チェックアウトページ、決済リンク、URL の共有 | references/sessions.md |
| 送金(給与、返金、ベンダーへの払い出し) | references/disbursements.md |
| Webhook の受信、署名の検証、再試行の処理 | references/webhooks.md |
| エラーレスポンスや検証エラーの原因究明 | references/errors.md |
各リファレンスファイルは単独で参照できます。複数のファイルを続けて読む必要はありません。複数の機能が関係するタスク(例:「決済を作成し、Webhook も処理する」)では、該当するファイルを両方読み込んでください。
払い出し前の残高確認
払い出しを作成する前に、残高が十分にあることを確認しておくとよいでしょう。
GET /v1/payments/balance
Authorization: Bearer snp_your_api_key_here
TZS 建ての available オブジェクトと balance オブジェクトが返されます。払い出しの手数料は金額に加算されるため、5,000 TZS を払い出す際に手数料が 1,500 TZS であれば、少なくとも 6,500 TZS の利用可能残高が必要です。まず GET /v1/payouts/fee?amount=... を使用して正確な手数料を計算してください。詳しくは references/disbursements.md に記載されています。
さらに詳しく
ここで問題が解決しない場合は、https://snippe.sh/docs/2026-01-25 にある公式ドキュメントをご覧ください。また、ドキュメントの URL の末尾に .mdx を追加すると、Markdown のソースを取得できます(例:https://snippe.sh/docs/2026-01-25/payments/mobile-money.mdx)。