SOPSellers' Open Protocol

支払い認証情報

支払い認証情報は、1回の取引のための支払いの承認です。受け取り先、金額、期限を限定し、お客さまのAIエージェントが事業者に対して発行します。

公開中予約時の支払い認証情報は提供中です。2026年10月22日、最初の事業者(パーソナルトレーナー)がオンライン決済を有効にしました。

支払い認証情報とは

Shared Payment Token(SPT)はStripeの製品です。お客さまのAIエージェントが、お客さまが承認した支払い方法を使って、ある受け取り先に対して発行する支払いの承認です。この認証情報は、この取引、この金額、この期間、この受け取り先にだけ有効です。

受け取り先は、認証情報を使ってStripeの支払い(PaymentIntent)を作成して確定します。その後の返金やレポートは、お客さまの支払い方法を直接受け取った場合と同じように扱われます。

3つの役割

SPTには3つの役割があります。支払いを受ける事業者、認証情報を発行するエージェント、多数の事業者にサービスを提供するプラットフォームです。以下で、それぞれをフロー図で説明し、SOPの対応を示します。

事業者(Sellers)

事業者は、エージェントが送った認証情報を受け取り、課金します。SOPでは、この手順をSOPが代行します。受け取り先はSeller Tech U.S.A. LLCで、Stripeを通じて処理し、契約に従って貴店に入金します。手数料と入金時期は見積書に記載します。

事業者:SOPが支払い認証情報を受け取り決済
お客様エージェントSOP事業者支払い方法を承認SOP宛ての一回限りの認証情報を取得(金額・期限に上限)予約と一緒に認証情報を送る承認額を1回だけ決済予約成立。契約どおり精算サービスを提供
手順
  1. お客様 → エージェント:支払い方法を承認
  2. エージェント → エージェント:SOP宛ての一回限りの認証情報を取得(金額・期限に上限)
  3. エージェント → SOP:予約と一緒に認証情報を送る
  4. SOP → SOP:承認額を1回だけ決済
  5. SOP → 事業者:予約成立。契約どおり精算
  6. 事業者 → お客様:サービスを提供

予約のレスポンスに含まれるpayment_handlersは、「認証情報を誰に発行するか、いくら払うか、いつ期限が切れるか」をエージェントに伝えます。

支払い待ち予約に含まれるpayment_handlers

JSON

[
  {
    "id": "stripe_payments",
    "type": "com.stripe.payments",
    "version": "2026-06-25",
    "spec": "https://docs.stripe.com/agentic-commerce/ucp/stripe-payments-handler",
    "schema": "https://ucp.stripe.com/payments/2026-06-25/schema.json",
    "available_instruments": [
      {
        "type": "card"
      },
      {
        "type": "link",
        "config": {
          "network_id": "profile_xxxx"
        }
      }
    ],
    "config": {
      "environment": "testmode",
      "business_profile": "profile_xxxx"
    }
  }
]

ローカル環境で実行済み:上の支払い待ち予約のbooking.payment_handlersをそのまま抜き出しました。コネクターのローカルコピーでprofile IDはプレースホルダーです。本番のbusiness_profileは販売者の実際のStripe profile IDになります。

エージェント(Agents)

エージェントは、受け取り先からStripeのプロファイルを受け取り、お客さまの支払い方法を収集し、StripeでSPTを発行して、認証情報を受け取り先に渡します。認証が必要なとき(3Dセキュアなど)は、お客さまを案内します。手順はお客さまに代わって支払うをご覧ください。

エージェント:お客様が承認した認証情報でSOPに支払う
お客様エージェントSOPrequest_bookingpayment_handlers:com.stripe.paymentsとbusiness profile、金額、期限金額の承認を依頼承認そのプロファイル宛てにShared Payment Tokenを発行(金額・期限を限定)トークンでcomplete_booking支払い完了(確定または事業者の確認待ち)、またはrequires_actionと3Dセキュアのリンク完了を伝える、または3Dセキュアを案内
手順
  1. エージェント → SOP:request_booking
  2. SOP → エージェント:payment_handlers:com.stripe.paymentsとbusiness profile、金額、期限
  3. エージェント → お客様:金額の承認を依頼
  4. お客様 → エージェント:承認
  5. エージェント → エージェント:そのプロファイル宛てにShared Payment Tokenを発行(金額・期限を限定)
  6. エージェント → SOP:トークンでcomplete_booking
  7. SOP → エージェント:支払い完了(確定または事業者の確認待ち)、またはrequires_actionと3Dセキュアのリンク
  8. エージェント → お客様:完了を伝える、または3Dセキュアを案内

Shared Payment Tokenで支払いを完了する

curl

# Reuse the same Idempotency-Key when you retry this request after a network error.
curl -sS -X POST "https://mcp.srct.tw/api/v1/businesses/<BUSINESS_ID>/bookings/<BOOKING_ID>/complete" \
  -H "User-Agent: my-agent/1.0" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <STATUS_TOKEN>" \
  -H "Idempotency-Key: pay-$(uuidgen)" \
  -d '{"payment":{"instruments":[{"id":"instr_1","handler_id":"stripe_payments","type":"card","selected":true,"credential":{"type":"stripe_payment_token","token":"spt_..."}}]}}'

Python

import json
import urllib.error
import urllib.request
import uuid

BASE = "https://mcp.srct.tw"


def call(method, path, body=None, headers=None):
    req = urllib.request.Request(
        BASE + path,
        data=None if body is None else json.dumps(body).encode(),
        method=method,
        headers={"User-Agent": "my-agent/1.0", "Content-Type": "application/json", **(headers or {})},
    )
    try:
        with urllib.request.urlopen(req) as res:
            return res.status, json.loads(res.read())
    except urllib.error.HTTPError as err:  # 4xx and 5xx responses still carry a JSON body
        return err.code, json.loads(err.read())


def show(status, body):
    print("HTTP", status)
    print(json.dumps(body, ensure_ascii=False, indent=2))


BUSINESS_ID = "<BUSINESS_ID>"
BOOKING_ID = "<BOOKING_ID>"      # from the create response
STATUS_TOKEN = "<STATUS_TOKEN>"  # from the create response (shown once)

payment = {
    "instruments": [{
        "id": "instr_1",
        "handler_id": "stripe_payments",  # an id from payment_handlers
        "type": "card",
        "selected": True,
        "credential": {"type": "stripe_payment_token", "token": "spt_..."},  # the SPT the agent issued
    }]
}
headers = {
    "Authorization": f"Bearer {STATUS_TOKEN}",
    "Idempotency-Key": str(uuid.uuid4()),  # reuse the same key when you retry after a network error
}

show(*call("POST", f"/api/v1/businesses/{BUSINESS_ID}/bookings/{BOOKING_ID}/complete", {"payment": payment}, headers))

Node.js

const BASE = "https://mcp.srct.tw";

async function call(method, path, body, headers = {}) {
  const res = await fetch(BASE + path, {
    method,
    headers: { "User-Agent": "my-agent/1.0", "Content-Type": "application/json", ...headers },
    body: body === undefined ? undefined : JSON.stringify(body),
  });
  return { status: res.status, body: await res.json() };
}

function show({ status, body }) {
  console.log("HTTP", status);
  console.log(JSON.stringify(body, null, 2));
}

const BUSINESS_ID = "<BUSINESS_ID>";
const BOOKING_ID = "<BOOKING_ID>"; // from the create response
const STATUS_TOKEN = "<STATUS_TOKEN>"; // from the create response (shown once)

const payment = {
  instruments: [{
    id: "instr_1",
    handler_id: "stripe_payments", // an id from payment_handlers
    type: "card",
    selected: true,
    credential: { type: "stripe_payment_token", token: "spt_..." }, // the SPT the agent issued
  }],
};
const headers = {
  Authorization: `Bearer ${STATUS_TOKEN}`,
  "Idempotency-Key": `pay-${Date.now()}`, // reuse the same key when you retry after a network error
};

(async () => {
  show(await call("POST", `/api/v1/businesses/${BUSINESS_ID}/bookings/${BOOKING_ID}/complete`, { payment }, headers));
})();

レスポンス例

HTTP 200
{
  "ok": true,
  "booking": {
    "booking_id": "WQEMHR2E",
    "status": "pending",
    "status_text": "Waiting for the business to confirm",
    "business_id": "example-studio",
    "business_name": "Example Studio (test data)",
    "service_id": "small_group",
    "service_name": "Small-group strength class",
    "slot": "2026-10-25T10:00",
    "start": "2026-10-25T10:00:00+08:00",
    "label": "10/25(日)10:00",
    "quantity": 1,
    "quantity_unit": "seat",
    "payment": "Paid online: NT$600",
    "details": [],
    "payment_details": {
      "mode": "online",
      "status": "paid",
      "amount": {
        "value": 60000,
        "currency": "twd",
        "text": "NT$600"
      },
      "collected_by": "Seller Tech U.S.A. LLC through Stripe",
      "paid_at": "2026-10-22T11:51:00+08:00",
      "card": {
        "brand": "visa",
        "last4": "4242"
      },
      "method": "stripe_spt",
      "transaction_id": "pi_1"
    },
    "why_pending": "First booking with this business from these contact details, so the business confirms it.",
    "confirm_by": "2026-10-22T12:01:00+08:00",
    "hold": "Bookings that need the business's confirmation are held for 10 minutes. If the business does not confirm by then, the hold is released automatically and the customer can choose another slot.",
    "online_cancel_until": "2026-10-25T08:00:00+08:00"
  },
  "payment": {
    "status": "succeeded",
    "transaction_id": "pi_1",
    "instrument_type": "card"
  }
}

レスポンスはサービスの自動テストから取得:コネクターのテスト環境から取得しました。コネクターのコードはそのまま動かし、Stripeはテストスイートの偽Stripeサーバーに置き換えています。transaction_id(pi_1)と決済手数料(USD1.20、NT$39換算)はテスト値です。実際の課金は一切ありません。

プラットフォーム(Connect platforms)

多数の事業者にサービスを提供するプラットフォームは、認証情報を誰に発行するかを決めます。プラットフォーム自身のプロファイルか、各事業者のプロファイルです。SOPは現在、前者を採用しています。すべての事業者がSeller Tech U.S.A. LLCの支払いプロファイルを共有し、LLCが受け取り先として課金したうえで、契約に従って事業者に入金します。

プラットフォーム:SOPの1つの支払いプロファイルで複数の事業者に対応
お客様エージェントSOP事業者各事業者と使う支払いプロファイルを公開支払い方法を承認SOPのプロファイル宛てに認証情報を発行特定の事業者の予約と一緒に送る販売者として決済(Seller Tech U.S.A. LLC)予約を確定予約を通知し、契約どおり精算サービスを提供
手順
  1. SOP → エージェント:各事業者と使う支払いプロファイルを公開
  2. お客様 → エージェント:支払い方法を承認
  3. エージェント → エージェント:SOPのプロファイル宛てに認証情報を発行
  4. エージェント → SOP:特定の事業者の予約と一緒に送る
  5. SOP → SOP:販売者として決済(Seller Tech U.S.A. LLC)
  6. SOP → エージェント:予約を確定
  7. SOP → 事業者:予約を通知し、契約どおり精算
  8. 事業者 → お客様:サービスを提供

事業者ごとに独自の支払いプロファイルを持ち、事業者自身が受け取り先となり、SOPはプラットフォーム手数料のみを受け取る方式は、現在の状態が計画中で、実装していません。

対象地域と規約

StripeがSPTの提供地域として挙げているのは、現在、米国、カナダ、一部の欧州諸国です。各地域のお客さま、エージェント、事業者が利用できるかどうかは、Stripeの案内に従います。SPTは引き続きStripeのプレビュー機能であり、SPTを使うとStripeの関連する利用規約に同意したものとみなされます。

カード情報とPCI

SOPも事業者も、カード番号の全桁、有効期限、セキュリティコードを受け取りません。カード情報はStripeが処理します。予約記録にはカードブランドと下4桁だけが残り、事業者は確認ページでこの2点を見られます。