協定與標準
SOP用到哪些協定與標準,以及每一項做到哪裡。
各項現況不同,見下表。
步驟
- 代理 → SOP:MCP tools/list,或REST /api/v1
- SOP → 代理:回傳工具與預約端點
- 代理 → SOP:request_booking
- SOP → 代理:UCP格式的payment_handlers(com.stripe.payments)
- 代理 → SOP:帶Shared Payment Token呼叫complete_booking
- 代理 → SOP:或用MPP、x402支付付款連結(測試網)
- SOP → 代理:/openapi.json描述付款連結
對照表
| 協定或標準 | 用途 | 現況 |
|---|---|---|
| MCP(Model Context Protocol) | 讓代理呼叫工具 | 已上線(Streamable HTTP,9個工具) |
| REST API | 與MCP共用同一套核心 | 已上線 |
OpenAPI探索文件/openapi.json | 描述付款連結(可付款的操作) | 已上線(付款資訊只有測試網) |
UCP的payment handler(com.stripe.payments) | 告訴代理能用哪些付款處理方式 | 已上線(預約回應使用這個格式) |
UCP的其他部分(結帳、身分連結、訂單,以及探索檔/.well-known/ucp) | 跨平台的完整商務流程 | 規劃中(沒有實作) |
| MPP與x402 | 用HTTP 402讓代理直接付款 | 測試網 |
| ACP與AP2 | 其他代理商務協定 | 規劃中(沒有實作) |
MCP與REST
兩者共用同一套預約核心,行為一致。工具清單與端點見連接預約服務。
UCP
Universal Commerce Protocol(UCP)是開放標準(ucp.dev),涵蓋結帳、身分連結、訂單追蹤與付款憑證交換。SOP的預約回應用UCP的payment handler格式描述付款方式;完整的UCP結帳與/.well-known/ucp探索檔(規劃中)目前沒有實作。
MPP與x402
兩者都是用HTTP 402讓代理直接付款的開放協定。SOP目前只在測試網提供,見機器付款。
探索文件
/openapi.json是目前唯一的機器可讀探索文件,會把可付款的操作標上x-payment-info。
讀取探索文件:/openapi.json
curl
curl -sS "https://mcp.srct.tw/openapi.json" \
-H "User-Agent: my-agent/1.0"
Python
import json
import urllib.error
import urllib.request
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))
show(*call("GET", "/openapi.json"))
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));
}
(async () => {
show(await call("GET", "/openapi.json"));
})();
回應範例
HTTP 200
{
"openapi": "3.1.0",
"info": {
"title": "… booking payments",
"version": "1.0.0",
"description": "Pay for … bookings with x402 or MPP. Create the booking first with the MCP tool request_booking or POST /api/v1/businesses/{business_id}/bookings; use the payment_link it returns."
},
"servers": [
{
"url": "https://mcp.srct.tw"
}
],
"x-service-info": {
"categories": [
"booking",
"fitness",
"services"
],
"docs": {
"homepage": "https://mcp.srct.tw/",
"apiReference": "https://mcp.srct.tw/docs"
}
},
"paths": {
"/pay/{business_id}/{booking_id}": {
"post": {
"summary": "Pay for a booking (x402 or MPP)",
"parameters": [
{
"name": "business_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "booking_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "t",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"description": "pay token from the booking's payment_link"
}
],
"x-payment-info": {
"offers": [
{
"intent": "charge",
"method": "evm",
"amount": null,
"currency": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"description": "USDC on Base Sepolia (test network); also accepted as x402 exact"
},
{
"intent": "charge",
"method": "tempo",
"amount": null,
"currency": "0x20c0000000000000000000000000000000000000",
"description": "pathUSD on Tempo test network (Moderato)"
}
]
},
"responses": {
"200": {
"description": "Paid: booking and payment result"
},
"402": {
"description": "Payment Required: x402 PAYMENT-REQUIRED and MPP WWW-Authenticate challenges"
},
"409": {
"description": "Booking not payable"
},
"410": {
"description": "Payment window passed"
}
}
},
"get": {
"summary": "Pay for a booking (x402 or MPP)",
"parameters": [
{
"name": "business_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "booking_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "t",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"description": "pay token from the booking's payment_link"
}
],
"x-payment-info": {
"offers": [
{
"intent": "charge",
"method": "evm",
"amount": null,
"currency": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"description": "USDC on Base Sepolia (test network); also accepted as x402 exact"
},
{
"intent": "charge",
"method": "tempo",
"amount": null,
"currency": "0x20c0000000000000000000000000000000000000",
"description": "pathUSD on Tempo test network (Moderato)"
}
]
},
"responses": {
"200": {
"description": "Paid: booking and payment result"
},
"402": {
"description": "Payment Required: x402 PAYMENT-REQUIRED and MPP WWW-Authenticate challenges"
},
"409": {
"description": "Booking not payable"
},
"410": {
"description": "Payment window passed"
}
}
}
}
}
}已對正式服務實際執行(唯讀)
付款處理方式的欄位
| 欄位 | 內容 |
|---|---|
id | stripe_payments |
type | com.stripe.payments |
version | 2026-06-25 |
available_instruments | card,以及帶config.network_id的link |
config.environment | 正式環境是livemode,測試是testmode |
config.business_profile | 憑證必須發給的Stripe profile |
目前不提供Apple Pay與Google Pay。
安全性
- 憑證有範圍:一個金額、一段時間、一個收款方。
- SOP不經手原始卡號。
- 每筆預約有自己的
status_token,只能存取那一筆預約。 - 寫入有頻率限制;Stripe送給SOP的webhook都會驗簽章。
相關頁面
- 連接預約服務:搜尋商家、查空檔、建立與管理預約
- 機器付款(MPP與x402,測試網):MPP與x402,目前只在測試網
- 付款憑證:Shared Payment Token,以及商家、代理與平台三種角色