AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Jpyc Ec Purchase

skill-mameta29-jpyc-skill-jpyc-ec-purchase · by Mameta29

Purchase products from JPYC EC Platform shops using JPYC stablecoin via x402 — one-shot HTTP-native gasless payments designed for AI agents.

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add skill-mameta29-jpyc-skill-jpyc-ec-purchase

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-mameta29-jpyc-skill-jpyc-ec-purchase)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Jpyc Ec Purchase? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

JPYC EC Purchase Skill

AI エージェントが JPYC EC Platform (https://ec.jpyc-service.com) のショップ から商品を購入するためのスキルです。決済プロトコルは x402 v2 (coinbase/x402 仕様、2025-12 リリース) に 準拠し、JPYC (日本円ステーブルコイン、1 JPYC = 1 JPY) を EIP-3009 transferWithAuthorization 署名で支払います。

特徴:

  • ガス代不要: エージェント側はゼロ。プラットフォームの facilitator が gas を支払う
  • 1 ショット決済: HTTP 1 往復で settle が完了 (注文作成と署名提出を分けない)
  • マルチチェーン: Ethereum / Polygon / Avalanche / Kaia / Sepolia / Amoy /

Fuji / Kairos / Arc に対応

  • AI 向け設計: 認証なし、ウォレットアドレス + 署名 = identity

Prerequisites

  • JPYC 残高のあるウォレットの秘密鍵 (EIP-712 署名用)
  • viem または同等の EIP-712 署名ライブラリ

Environments

| 環境 | Base URL | 対応チェーン ID | |------|---------|-----------------| | Production | https://ec.jpyc-service.com | 1 (Ethereum), 137 (Polygon), 43114 (Avalanche), 8217 (Kaia) | | Staging | https://stg-ec.jpyc-service.com | 11155111 (Sepolia), 80002 (Amoy), 43113 (Fuji), 1001 (Kairos), 5042002 (Arc) |

メインネット ID をステージングに、テストネット ID を本番に送ると、その環境では そのチェーンが使えないため弾かれます。/api/v1/checkout では 400 invalid_body (preferred_chain_id is not available in this environment)、/api/v1/balance/check では INVALID_CHAIN が返ります。


Purchase Flow (x402)

注文は POST /api/v1/checkout に一本化されています。人間ユーザーの storefront も AI エージェントも同じエンドポイントを使います。エージェントは 以下の 3 ステップで完走します。

1. GET  /api/v1/products/{productId}   ← 各商品の配送/バリエーション要件確認
2. POST /api/v1/checkout (no PAYMENT-SIGNATURE)
                                       ← 402 challenge + reservation_id + 金額サマリ
3. POST /api/v1/checkout (with PAYMENT-SIGNATURE, body は reservation_id のみ)
                                       ← 200 + 注文成立 + tx_hash

/api/v1/checkoutカート単位 (複数商品 OK)。1 商品だけ買う場合も items 配列に 1 件入れるだけです。

Step 1 — Product info & branching

商品の 必須条件 を取得します。これを必ず先に呼んでください。スキップすると ステップ 2 で 400 shipping_required / 400 invalid_variant が返り、エージェント は再度ユーザーに情報を聞き直す必要があります。

GET https://ec.jpyc-service.com/api/v1/products/{productId}

レスポンス:

{
  "ok": true,
  "data": {
    "product": {
      "id": "uuid",
      "slug": "matcha-latte",
      "name": "商品名",
      "description": "...",
      "price_jpyc": "1500.000000000000000000",
      "stock": 42,
      "image_urls": ["https://..."],
      "category": "飲料",
      "subcategory": "お茶",
      "tags": ["organic", "limited"],
      "requires_shipping": true,
      "grants_free_shipping": false,
      "variants": {
        "options": [{ "name": "サイズ", "values": ["S", "M", "L"] }],
        "skus": [{ "options": { "サイズ": "M" }, "price_jpyc": "1500.0" }]
      },
      "review_avg_rating": 4.7,
      "review_count": 12,
      "has_nft_discount": false
    },
    "shop": {
      "id": "uuid",
      "slug": "example-shop",
      "name": "ショップ名",
      "wallet_address": "0x...",
      "available_chains": [137, 43114],
      "default_chain_id": 137,
      "is_demo": false,
      "x402_enabled": true,
      "checkout_options": [
        {
          "id": "noshi",
          "name": "のし",
          "required": true,
          "type": "select",
          "values": [
            { "label": "あり", "surcharge_jpyc": "100" },
            { "label": "なし", "surcharge_jpyc": "0" }
          ]
        },
        {
          "id": "message",
          "name": "メッセージカード",
          "required": false,
          "type": "text",
          "max_length": 100
        }
      ]
    }
  }
}

判定 — Step 2 に進む前に、商品とショップの 必須条件をすべて満たす情報を 集めてあるか を必ずこの表で確認してください。checkout_options は商品ではなく ショップ単位 の設定です。

| フィールド | 条件 | エージェントの行動 | |-----------|------|-------------------| | product.requires_shipping === true | 配送先住所が必須 | ユーザーに 氏名・郵便番号・都道府県・市区町村以降の住所・電話番号 を聞き、shipping ブロックに入れる (email は別途必須) | | product.variants !== null | バリエーション選択が必須 | ユーザーに どの組み合わせ を選ぶか聞き、items[].variant_selections に入れる (例: { "サイズ": "M", "色": "白" }) | | shop.checkout_options[] の各要素で required === true | そのオプションの値が必須 | ユーザーに値を聞き、checkout_options{ option_id: 値 } で入れる。required:false のものは省略可。詳細は下の「checkout_options」節 | | shop.x402_enabled === false | このショップは x402 購入不可 | 購入を中止し、ユーザーに「このショップは AI エージェント経由の購入に対応していません」と伝える。POST /checkout しても 400 x402_disabled で弾かれる | | shop.available_chains | このチェーン以外は払えない | ユーザーに preference があれば pass、なければサーバが先頭を使う | | shop.is_demo === true | デモショップ | JPYC 残高ゼロでも完走できる。実際の送金は起きず tx_hash はダミー。x402 フローの動作確認に使える (後述) |

checkout_options (ショップ定義の購入オプション)

shop.checkout_options は、のし・到着時間指定・メッセージカードなど ショップが 独自に定義した購入時オプション の配列です。各要素の構造:

  • id — オプション識別子。POST /checkoutcheckout_options ではこの id

をキーに値を渡す

  • name — ユーザー向け表示名 (例: 「のし」)
  • requiredtrue ならそのオプションの値は必須。値を送らずに `POST

/checkout すると 400 invalidcheckoutoption になる。false` は省略可

  • type"select"values から 1 つ選ぶ)/ "text"(自由入力、max_length

まで)/ "checkbox"(true/false)

  • values (select のみ) — 選択肢。各 label と追加料金 surcharge_jpyc
  • surcharge_jpyc — 選んだ値に応じて合計金額に加算される (Step 2 の 402 で

確定するので、エージェント側で足し算する必要はない)

POST /checkout に渡す形式 (Step 2 参照):

"checkout_options": { "noshi": "あり", "message": "お誕生日おめでとう" }

required:true のオプションが 1 つでもあるショップでは、checkout_options を 省略すると Step 2 で弾かれます。ショップに checkout_options がある場合は、 required を確認して必須のものを必ずユーザーに尋ねてください。

> デモショップ (shop.is_demo === true) について: x402 購入フロー > (402 → 署名 → 注文確定) を JPYC を持たずに体験するためのショップです。 > リクエスト/レスポンスの形・署名手順は通常ショップと完全に同一ですが、 > settle で on-chain 送金が行われません (facilitator を経由しない)。 > - JPYC 残高ゼロのウォレットでも settle が成功する > - tx_hash0xde30… で始まるダミー値 (注文ごとにユニーク)。ブロック > エクスプローラでは引けないので、エクスプローラ URL を提示しないこと。 > デモ判定は data.is_demo === true で行うこと (tx_hash の中身に依存しない) > - settle 成功レスポンスの data.is_demotrue で返る > - 署名 (EIP-712) の検証はサーバ側で行われるため、不正な署名は弾かれる

> ヒント: image_urls空配列もありえる。サムネ表示で image_urls[0] > を使う場合は必ず存在チェックすること。

エラー:

  • 404 PRODUCT_NOT_FOUND — 商品が存在しないか非公開
  • 500 INTERNAL_ERROR — サーバエラー

Step 2 — Request 402 challenge

PAYMENT-SIGNATURE ヘッダ なし で POST。サーバは在庫を 5 分間仮押さえし、 402 + PAYMENT-REQUIRED ヘッダ + 金額サマリを返します。

POST https://ec.jpyc-service.com/api/v1/checkout
Content-Type: application/json

{
  "shop_id": "uuid-of-shop",
  "preferred_chain_id": 137,
  "items": [
    { "product_id": "uuid-1", "quantity": 1, "variant_selections": { "サイズ": "M" } },
    { "product_id": "uuid-2", "quantity": 2 }
  ],
  "customer_email": "yamada@example.com",
  "shipping": {
    "name": "山田太郎",
    "zip": "150-0001",
    "prefecture": "東京都",
    "address1": "渋谷区神宮前1-2-3",
    "address2": "サンプルマンション101",
    "tel": "090-1234-5678"
  },
  "is_gift": false,
  "customer_note": "プレゼント用に包装してください"
}

フィールド:

| フィールド | 必須 | 説明 | |-----------|------|------| | shop_id | ✅ | 全 items が同一ショップに属している必要がある | | items[] | ✅ | product_id + quantity (+ variant_selections)。最低 1 件 | | items[].variant_selections | variants !== null の商品で必須 | { option_name: value } | | customer_email | ✅ | 注文確認メールの宛先。x402 経路でも必須 | | preferred_chain_id | 任意 | 全 itemsavailable_chains の積集合のいずれか | | shipping | いずれかの item が requires_shipping のとき必須 | name / zip / prefecture / address1 / tel | | is_gift / gift_recipient | 任意 | 贈り物のとき is_gift: true + gift_recipient | | checkout_options | 任意 | ショップ定義のオプション (のし等) の選択値 | | customer_note | 任意 | ショップへの伝言 (max 2000 文字) |

レスポンス (HTTP 402):

HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi...   (base64url JSON of PaymentRequired)
Content-Type: application/json

{
  "ok": false,
  "error": { "code": "payment_required", "message": "PAYMENT-SIGNATURE header is required" },
  "data": {
    "reservation_id": "res_a1b2c3d4...",
    "expires_at_unix_ms": 1731486100000,
    "summary": {
      "subtotal_jpyc": "5000",
      "discount_jpyc": "0",
      "shipping_jpyc": "500",
      "checkout_options_surcharge_jpyc": "0",
      "total_jpyc": "5500"
    }
  }
}

summary を使って、署名前にユーザーへ正しい合計金額を提示してください。

> 注意: summary の各値は文字列で、小数桁数は項目により不揃いです > (total_jpyc"3500"shipping_jpyc"500.000000000000000000" の > ように 18 桁付きで返ることがある)。表示前に parseFloat / Number で正規化 > してください。実際に署名する金額は summary ではなく > PAYMENT-REQUIRED.accepts[0].amount (atomic units) を使うこと。

PAYMENT-REQUIRED ヘッダを base64url デコードすると以下の x402 v2 PaymentRequired 構造体になります:

{
  "x402Version": 2,
  "error": "PAYMENT-SIGNATURE header is required",
  "resource": {
    "url": "https://ec.jpyc-service.com/api/v1/checkout",
    "description": "商品名 × 1",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:137",
      "amount": "1500000000000000000000",
      "asset": "0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29",
      "payTo": "0xShopWallet...",
      "maxTimeoutSeconds": 90,
      "extra": {
        "assetTransferMethod": "eip3009",
        "name": "JPY Coin",
        "version": "1",
        "decimals": 18,
        "symbol": "JPYC"
      }
    }
  ],
  "extensions": {
    "x402.jpyc-ec.reservation_id": "res_a1b2c3d4..."
  }
}

> 重要 (デコード方法): ヘッダは base64url (RFC 4648 §5、- _ を使う変種) > でエンコードされています。Node なら Buffer.from(header, "base64url") で > デコード可。シェルの base64 -d は環境差 (macOS の BSD 版は base64url を > サポートせず壊れます) があるので、シェル経由でデコードしたい場合は > tr '_-' '/+' してパディングを補ってから base64 -d するか、Node/Python の > base64.urlsafe_b64decode を使ってください。SKILL-acli.md に詳細あり。

ユーザーに見せて確認 すべき情報:

  • 合計金額: amount を 10^18 で割って JPYC 表示 (例: 1500000000000000000000 → 1500 JPYC)
  • 支払先: payTo (ショップのウォレット)
  • チェーン: network (CAIP-2)

エラー:

  • 400 invalid_body — リクエストボディが zod schema に合わない。**`quantity , // 署名者

to: , // ショップ wallet value: BigInt(), // atomic units validAfter: 0n, // 即座に有効 validBefore: BigInt(Math.floor(Date.now() / 1000) + 90), // now + 90s nonce: // 0x + 64 hex }


`primaryType` は `"TransferWithAuthorization"` (※ 既存の `ReceiveWithAuthorization`
ではない。x402 では facilitator が msg.sender になるため `Transfer` 系を使う)。

#### 3b. PaymentPayload 構築

x402 v2 の `PaymentPayload` を組み立てます:

```json
{
  "x402Version": 2,
  "accepted": ,
  "payload": {
    "signature": "0x",  // 上の署名 (r + s + v)
    "authorization": {
      "from": "0x",
      "to": "0x",
      "value": "",
      "validAfter": "0",
      "validBefore": "",
      "nonce": "0x"
    }
  }
}

これを base64url エンコード して PAYMENT-SIGNATURE ヘッダに乗せます。

3c. Settle リクエスト
POST https://ec.jpyc-service.com/api/v1/checkout
Content-Type: application/json
PAYMENT-SIGNATURE: eyJ4NDAyVmVyc2lvbiI6Mi...   (base64url JSON)

{
  "reservation_id": "res_a1b2c3d4..."
}

> 2 回目の body は reservation_id だけです。items 等は再送しません > (1 回目で reservation snapshot に固定済み)。

成功レスポンス (HTTP 200):

HTTP/1.1 200 OK
PAYMENT-RESPONSE: eyJzdWNjZXNzIjp0cnVlLC...   (base64url JSON of SettlementResponse)
Content-Type: application/json

{
  "ok": true,
  "data": {
    "order_id": "uuid",
    "order_number": "ORD-20260514-GOSFBI",
    "tx_hash": "0x",
    "network": "eip155:137",
    "payer": "0x",
    "amount_atomic": "1500000000000000000000",
    "is_demo": false
  }
}

注文は order_status=3 (collected = 決済完了) で確定済み。on-chain transfer も完了 しているので追加の署名や確認は不要です。tx_hash は対応するブロックエクスプローラ (Polygonscan / Etherscan / Snowtrace 等) でそのまま検索できます。

> data.is_demo: true ならデモショップの注文です。on-chain 送金は > 行われておらず、tx_hash0xde30… で始まるダミー値 (注文ごとにユニーク) で > エクスプローラでは引けません。is_demo: true のときはユーザーに「これは > デモ決済で、実際の JPYC 送金は行われていません」と明示してください。

エラー (status / code):

| Status | Code | 意味 | エージェントの行動 | |--------|------|------|-------------------| | 400 | invalid_payment_payload | base64 や JSON が壊れている | 再構築 | | 400 | payload_mismatch | 署名内容が reservation と不一致 | step 2 からやり直し | | 402 | invalid_exact_evm_payload_signature | 署名が不正 / 期限切れ | 再署名 | | 402 | invalid_exact_evm_payload_authorization_valid_before | 90s 超過 | step 2 からやり直し (新しい reservation を取得) | | 402 | insufficient_funds | JPYC 残高不足 | ユーザーに「残高不足です」と通知 | | 404 | reservation_not_found | reservation 5 分超過 (※決済済み reservation への再送では返らない — 下記「冪等リプレイ」参照) | step 2 からやり直し | | 404 | product_disappeared | 商品が削除された | 別の商品提案 | | 409 | insufficient_stock | 在庫切れ | 別の商品提案 | | 409 | shop_wallet_changed | ショップがウォレット変更 | step 2 からやり直し | | 429 | rate_limited | 30 req/60s/IP | 数秒待ってリトライ | | 502 | facilitator_insufficient_native_balance | facilitator (relayer) の gas 切れ | リトライ (運営に自動通知される。復旧まで数分かかることがある) | | 502 | settlement_failed | facilitator が settle 失敗 (上記以外) | リトライ。繰り返すなら運営に問い合わせ | | 502 | unexpected_settle_error | facilitator が分類不能な例外を捕捉 | リトライ。繰り返すなら運営に問い合わせ | | 502 | facilitator_unreachable | 決済サービスに接続不可 (資金は動いていない) | リトライ | | 502 | settle_precondition_failed | settle 前の記録に失敗 (資金は動いていない) | リトライ | | 502 | authorization_already_used | この nonce は既にオンチェーンで消費済み = 支払いは成立している | settlement_state_unknown と同じ扱い: 再署名せず GET /orders で注文を確認 (自動復旧される) | | 502 | settlement_state_unknown | 決済結果が不明 (資金が動いている可能性あり) | 絶対に即再署名・再購入しない。2〜3 分待って GET /orders?customer_address=... を確認。注文があれば決済成功 (自動復旧)。無ければ安全に再試行できる |

> 冪等リプレイ (2026-07 追加): 同じ reservation_id + PAYMENT-SIGNATURE で > settle を再送した場合、既に決済済みなら同じ注文情報が 200 で返る。 > トランスポートエラー (接続断・タイムアウト) 後のリトライは安全。 > settlement_state_unknown を受けた場合のみ、上記の手順で状態確認を挟むこと。


Other Useful Endpoints

Shop / product discovery

| Endpoint | 用途 | |---------|------| | GET /api/v1/shops | 全ショップ一覧 | | GET /api/v1/shops/{slug}/products | ショップ内の商品一覧 | | GET /api/v1/shops/{slug}/nft-discounts | NFT 割引ルール (購入時に該当 NFT 所持で割引) | | GET /api/v1/products/{id} | 商品詳細 (step 1) | | GET /api/v1/products/{id}/reviews | 商品レビュー一覧 | | GET /api/v1/categories | カテゴリ・タグの一覧 |

> product.slug について: 商品レスポンスの slug は人間可読な商品URL用の > 値です (商品ページURL = /shops/{shop.slug}/products/{slug ?? id}null の > 場合は id を使う)。チェックアウトの items[].product_id には必ず商品の > id (UUID) を使ってくださいslug は URL 表示専用で、API リクエストの > 識別子としては使いません。

Agent discovery surface

REST API を直接叩く以外に、プラットフォームはエージェント向けの発見・ 対話レイヤーを公開している。

| Endpoint | 用途 | |---------|------| | GET /.well-known/commerce-manifest | プラットフォームの能力・エンドポイント・x402 決済レール一覧 (Open Agentic Commerce 形式) | | GET /.well-known/agent-card.json | A2A Agent Card | | GET /api/v1/openapi.yaml | OpenAPI 3.1 仕様 | | GET /llms.txt | LLM 向け Markdown インデックス | | POST /mcp | MCP サーバー (Streamable HTTP)。商品検索・購入ツールを提供 |

MCP ホスト (Claude Desktop / Cursor 等) からは POST /mcp に接続すると、 search_products / get_product / quote_checkout / submit_payment などのツールが使える。本スキルの REST 手順は、MCP を使わず HTTP を直接 叩くエージェント向け。

Order tracking

GET https://ec.jpyc-service.com/api/v1/orders?customer_address=0x...

レスポンス: orders[] (注文履歴、x402 経由も既存経路の注文も両方返る)。

order_status の意味:

  • 3決済完了 (/api/v1/checkout 経由の注文は最初からこの状態)
  • 9 — 期限切れ
  • 1 / 2 — 旧フロー (未署名 / 署名済み回収待ち) の名残。新規注文では発生しない

各注文には refunds[] フィールドが付き、ショップが過去に行った返金履歴 (完了したものだけ) が時系列で並ぶ。1 注文に対して複数回の部分返金がある ケースを含む。各 refund は { amount_jpyc, tx_hash, chain_id, completed_at } の形。pending/failed の内部状態は外部に出さない。実際の受領金額を計算する 場合は total_jpyc - sum(refunds[].amount_jpyc) をすると良い。

発送状況order_status (決済) とは独立して、物理商品の発送状況が 次のフィールドで返る:

  • shipping_statusnull (配送不要 or 発送準備前) / "pending" (発送準備中) /

"shipped" (発送済み) / "delivered" (配送完了)

  • shipped_at — 発送日時 (ISO8601, nullable)
  • tracking_number — 追跡番号 (nullable)
  • shipping_carrier — 配送業者名 (nullable)

決済完了 (order_status: 3) でも shipping_statusnull/pending の うちはまだ発送されていない。ユーザーに「発送済みか」を答えるときは order_status ではなく shipping_status を見ること。デジタル商品や配送先の ない注文では shipping_status は常に null

Digital product download

商品が is_digital: true のデジタル商品 (ダウンロード商品) の場合、決済完了 (order_status: 3) 後にダウンロード URL を発行できる。

本人確認は SIWE (Sign-In with Ethereum) 署名チャレンジ。ウォレットアドレス は公開情報のため、自己申告アドレスでは本人確認にならない。購入ウォレットの 秘密鍵で署名できることを証明する必要がある (署名のみ・送金は発生しない)。

手順:

  1. nonce を取得 (5 分有効・使い捨て):
POST https://ec.jpyc-service.com/api/auth/siwe/nonce
Content-Type

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Mameta29](https://github.com/Mameta29)
- **Source:** [Mameta29/jpyc-skill](https://github.com/Mameta29/jpyc-skill)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.