接受代理預約
讓客人的AI代理查你的時段、預約、改期、取消;你在接單確認台確認。
已上線預約功能已上線。線上付款也已上線,第一家商家(一位私人教練)已於2026-10-22啟用線上付款。
這頁寫給商家,以及替商家串接的人。
運作方式
你的服務、價格與時段,由你逐項確認後才上架。客人請自己的AI預約,AI透過SOP的預約介面送出;你在接單確認台確認或婉拒,也會收到LINE通知。
步驟
- 客人 → 代理:請代理找服務
- 代理 → SOP:搜尋商家與空檔
- SOP → 代理:回傳服務、價格與空檔
- 客人 → 代理:選定時段
- 代理 → SOP:request_booking
- SOP → 代理:先佔名額:awaiting_payment、金額、期限、payment_handlers
- 客人 → 代理:在錢包裡核准確切金額
- 代理 → SOP:帶付款憑證呼叫complete_booking
- SOP → SOP:只扣一次款;商家婉拒或沒確認就全額退款
- SOP → 商家:通知新預約
- 商家 → SOP:新客人的預約由商家確認;逾時未確認就釋出並退款
- SOP → 代理:回傳預約狀態(已成立或待確認)與付款結果
- 代理 → 客人:告知已成立,或等待商家確認
代理能做什麼
| 操作 | MCP工具 | REST |
|---|---|---|
| 查空檔 | get_availability | GET availability |
| 建立預約 | request_booking | POST bookings |
| 查詢預約 | get_booking_status | GET bookings/{booking_id} |
| 改期 | modify_booking | PATCH bookings/{booking_id} |
| 取消 | cancel_booking | DELETE bookings/{booking_id} |
| 付款 | complete_booking | POST bookings/{booking_id}/complete |
每個操作的參數與回應見連接預約服務;以下用範例說明商家端會遇到什麼。
查空檔
代理先查你的空檔。每個時段都有固定的slot_id,之後建立、改期都用它;回應也會附剩餘名額與價格。
查詢可預約時段
curl
curl -sS "https://mcp.srct.tw/api/v1/businesses/coach-dunken/availability?service_id=pt&days=2" \
-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", "/api/v1/businesses/coach-dunken/availability?service_id=pt&days=2"))
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", "/api/v1/businesses/coach-dunken/availability?service_id=pt&days=2"));
})();
回應範例
HTTP 200
{
"ok": true,
"service_id": "pt",
"bookable_here": true,
"payment": "venue",
"timezone": "Asia/Taipei",
"earliest_bookable": "120 minutes from now",
"online_cancellation": "Online cancellation closes 24 hours before the start time; after that, contact the business directly.",
"quantity_unit": "位",
"slots": [
{
"slot_id": "2026-10-22T08:00",
"slot": "2026-10-22T08:00",
"start": "2026-10-22T08:00:00+08:00",
"label": "10/22(四)08:00",
"remaining": 1,
"price": {
"amount": 1800000,
"currency": "twd",
"per": "person or place",
"text": "NT$18,000/10堂"
},
"resource": {
"teacher": "Dunken"
}
},
{
"slot_id": "2026-10-22T09:00",
"slot": "2026-10-22T09:00",
"start": "2026-10-22T09:00:00+08:00",
"label": "10/22(四)09:00",
"remaining": 1,
"price": {
"amount": 1800000,
"currency": "twd",
"per": "person or place",
"text": "NT$18,000/10堂"
},
"resource": {
"teacher": "Dunken"
}
},
…
]
}已對正式服務實際執行(唯讀):為顯示而截短;…表示省略的部分。price.amount的單位是幣別最小單位(新臺幣乘以100);時間為Asia/Taipei。時段會隨呼叫當天而不同。
建立預約
客人同意服務、時間、人數與聯絡資料後,代理送出預約。結果依你的設定而定:到店付款的預約會立即成立(confirmed)或等你確認(pending);線上付款的預約先是awaiting_payment,付款完成才通知你。
建立預約(到店付款)
curl
# This creates a real booking at a real business. Use a slot value from the availability response.
curl -sS -X POST "https://mcp.srct.tw/api/v1/businesses/<BUSINESS_ID>/bookings" \
-H "User-Agent: my-agent/1.0" \
-H "Content-Type: application/json" \
-d '{"service_id":"pt","slot":"<SLOT>","quantity":1,"customer_name":"Example Customer","phone":"0900000000","email":"customer@example.com"}'
Python
# This creates a real booking at a real business. Use a slot value from the availability response.
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))
BUSINESS_ID = "<BUSINESS_ID>"
status, body = call("POST", f"/api/v1/businesses/{BUSINESS_ID}/bookings", {
"service_id": "pt",
"slot": "<SLOT>", # the "slot" value from the availability response
"quantity": 1,
"customer_name": "Example Customer",
"phone": "0900000000",
"email": "customer@example.com",
})
show(status, body)
# Keep booking_id and status_token: every later call for this booking needs both.
Node.js
// This creates a real booking at a real business. Use a slot value from the availability response.
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>";
(async () => {
show(await call("POST", `/api/v1/businesses/${BUSINESS_ID}/bookings`, {
service_id: "pt",
slot: "<SLOT>", // the "slot" value from the availability response
quantity: 1,
customer_name: "Example Customer",
phone: "0900000000",
email: "customer@example.com",
}));
// Keep booking_id and status_token: every later call for this booking needs both.
})();
回應範例
HTTP 201
{
"ok": true,
"booking": {
"booking_id": "2QAC3NW5",
"status": "pending",
"status_text": "Waiting for the business to confirm",
"business_id": "coach-dunken",
"business_name": "Dunken教練",
"service_id": "pt",
"service_name": "PT一對一教練課",
"slot": "2026-10-25T08:00",
"start": "2026-10-25T08:00:00+08:00",
"label": "10/25(日)08:00",
"quantity": 1,
"quantity_unit": "位",
"payment": "Pay at the venue",
"details": [
"老師:Dunken"
],
"why_pending": "First booking with this business from these contact details, so the business confirms it.",
"confirm_by": "2026-10-22T01:00: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-24T08:00:00+08:00"
},
"status_token": "<STATUS_TOKEN>",
"status_token_note": "Needed with booking_id to check, pay, change or cancel this booking later. It gives access to this booking only, and … does not show it again.",
"contact_note": "If this booking cannot be cancelled with cancel_booking, the customer can contact the business directly: …"
}已對本機服務實際執行:對本機的連接器副本執行,其中放了正式商家服務的副本,所以回應欄位與正式環境相同。status_token已換成<STATUS_TOKEN>。以新的聯絡資料第一次預約,要等商家確認(status為pending)。
改期
代理可以替客人改時段或人數,原時段的名額會釋出。已付款的預約只能改時段;改人數會改變金額,要取消後重新預約。改期和線上取消在同一個截止時間前都可以做。
改期
curl
curl -sS -X PATCH "https://mcp.srct.tw/api/v1/businesses/<BUSINESS_ID>/bookings/<BOOKING_ID>" \
-H "User-Agent: my-agent/1.0" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <STATUS_TOKEN>" \
-d '{"slot":"<NEW_SLOT>"}'
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))
BUSINESS_ID = "<BUSINESS_ID>"
BOOKING_ID = "<BOOKING_ID>" # from the create response
STATUS_TOKEN = "<STATUS_TOKEN>" # from the create response (shown once)
AUTH = {"Authorization": f"Bearer {STATUS_TOKEN}"}
NEW_SLOT = "<NEW_SLOT>" # another "slot" value from the availability response
show(*call("PATCH", f"/api/v1/businesses/{BUSINESS_ID}/bookings/{BOOKING_ID}", {"slot": NEW_SLOT}, AUTH))
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 AUTH = { Authorization: `Bearer ${STATUS_TOKEN}` };
const NEW_SLOT = "<NEW_SLOT>"; // another "slot" value from the availability response
(async () => {
show(await call("PATCH", `/api/v1/businesses/${BUSINESS_ID}/bookings/${BOOKING_ID}`, { slot: NEW_SLOT }, AUTH));
})();
回應範例
HTTP 200
{
"ok": true,
"changed": {
"from": {
"slot": "2026-10-25T08:00",
"quantity": 1
},
"to": {
"slot": "2026-10-26T08:00",
"quantity": 1
}
},
"booking": {
"booking_id": "2QAC3NW5",
"status": "pending",
"status_text": "Waiting for the business to confirm",
"business_id": "coach-dunken",
"business_name": "Dunken教練",
"service_id": "pt",
"service_name": "PT一對一教練課",
"slot": "2026-10-26T08:00",
"start": "2026-10-26T08:00:00+08:00",
"label": "10/26(一)08:00",
"quantity": 1,
"quantity_unit": "位",
"payment": "Pay at the venue",
"details": [
"老師:Dunken"
],
"why_pending": "First booking with this business from these contact details, so the business confirms it.",
"confirm_by": "2026-10-22T01:00: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"
}
}已對本機服務實際執行:本機的連接器副本。原時段釋出、新時段保留;回應有from與to。
取消
客人透過AI取消,名額釋出,你的確認台會留下紀錄。線上取消的截止時間由你設定;超過之後,客人要直接聯絡你。客人取消已付款的預約後會退款,金額扣除金流手續費與平台手續費。
取消預約
curl
curl -sS -X DELETE "https://mcp.srct.tw/api/v1/businesses/<BUSINESS_ID>/bookings/<BOOKING_ID>" \
-H "User-Agent: my-agent/1.0" \
-H "Authorization: Bearer <STATUS_TOKEN>"
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))
BUSINESS_ID = "<BUSINESS_ID>"
BOOKING_ID = "<BOOKING_ID>" # from the create response
STATUS_TOKEN = "<STATUS_TOKEN>" # from the create response (shown once)
AUTH = {"Authorization": f"Bearer {STATUS_TOKEN}"}
show(*call("DELETE", f"/api/v1/businesses/{BUSINESS_ID}/bookings/{BOOKING_ID}", headers=AUTH))
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 AUTH = { Authorization: `Bearer ${STATUS_TOKEN}` };
(async () => {
show(await call("DELETE", `/api/v1/businesses/${BUSINESS_ID}/bookings/${BOOKING_ID}`, undefined, AUTH));
})();
回應範例
HTTP 200
{
"ok": true,
"booking": {
"booking_id": "2QAC3NW5",
"status": "cancelled",
"status_text": "Cancelled",
"business_id": "coach-dunken",
"business_name": "Dunken教練",
"service_id": "pt",
"service_name": "PT一對一教練課",
"slot": "2026-10-26T08:00",
"start": "2026-10-26T08:00:00+08:00",
"label": "10/26(一)08:00",
"quantity": 1,
"quantity_unit": "位",
"payment": "Pay at the venue",
"details": [
"老師:Dunken"
],
"cancelled_by": "customer"
}
}已對本機服務實際執行:本機的連接器副本。到店付款的預約沒有退款欄位;線上付款請看refund_result。
結構化錯誤
錯誤一律回code與message,讓代理知道發生什麼事、能不能重試。例如客人選的時段剛被別人約走,回capacity_full(REST為409),並附幾個替代時段,代理可以換一個再約。
處理結構化錯誤:時段已被訂走
curl
# This creates a real booking at a real business. Use a slot value from the availability response.
curl -sS -X POST "https://mcp.srct.tw/api/v1/businesses/<BUSINESS_ID>/bookings" \
-H "User-Agent: my-agent/1.0" \
-H "Content-Type: application/json" \
-d '{"service_id":"pt","slot":"<FULL_SLOT>","quantity":1,"customer_name":"Example Customer","phone":"0900000000","email":"customer@example.com"}'
Python
# This creates a real booking at a real business. Use a slot value from the availability response.
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))
BUSINESS_ID = "<BUSINESS_ID>"
status, body = call("POST", f"/api/v1/businesses/{BUSINESS_ID}/bookings", {
"service_id": "pt",
"slot": "<FULL_SLOT>", # a slot that is already full
"quantity": 1,
"customer_name": "Example Customer",
"phone": "0900000000",
"email": "customer@example.com",
})
show(status, body)
# status 409, body["error"]["code"] == "capacity_full": offer the customer one of body["next_slots"] and call again.
Node.js
// This creates a real booking at a real business. Use a slot value from the availability response.
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>";
(async () => {
const result = await call("POST", `/api/v1/businesses/${BUSINESS_ID}/bookings`, {
service_id: "pt",
slot: "<FULL_SLOT>", // a slot that is already full
quantity: 1,
customer_name: "Example Customer",
phone: "0900000000",
email: "customer@example.com",
});
show(result);
// status 409, body.error.code === "capacity_full": offer the customer one of body.next_slots and call again.
})();
回應範例
HTTP 409
{
"error": {
"code": "capacity_full",
"message": "Only 0 left in this slot. Choose another slot."
},
"next_slots": [
"2026-10-22T08:00",
"2026-10-22T09:00",
"2026-10-22T10:00"
]
}已對本機服務實際執行:本機的連接器副本;每次執行前,該時段已先被另一位客人訂走。next_slots列出可改選的時段。
| 代碼 | 意思 | REST狀態 |
|---|---|---|
capacity_full | 這個時段的名額不夠 | 409 |
invalid_slot | 時段不存在或已不可預約 | 409 |
duplicate | 同一組聯絡資料、服務與時段重複送出 | 409 |
too_late_to_cancel | 超過線上取消的截止時間 | 409 |
payment_declined | 付款被拒絕,可換付款方式重試 | 402 |
payment_expired | 付款期限已過,名額已釋出 | 410 |
rate_limited | 次數超過上限 | 429 |
付了款卻沒約成:自動退款
線上付款的預約在這些情況會立即全額退款:你婉拒或取消、你沒在時限內確認。客人自己在截止前線上取消時,卡片付款的退款扣除金流手續費與平台手續費。退款失敗的,系統每5分鐘重試一次。
步驟
- 代理 → SOP:帶憑證呼叫complete_booking
- SOP → SOP:扣款成功
- 商家 → SOP:商家婉拒,或逾時未確認
- SOP → SOP:自動全額退款
- 代理 → SOP:或:客人在截止前自己取消
- SOP → SOP:退款扣除金流手續費與平台手續費
- SOP → 代理:回報退款金額與扣除的手續費
客人取消已付款的預約:扣除手續費後退款
curl
curl -sS -X DELETE "https://mcp.srct.tw/api/v1/businesses/<BUSINESS_ID>/bookings/<BOOKING_ID>" \
-H "User-Agent: my-agent/1.0" \
-H "Authorization: Bearer <STATUS_TOKEN>"
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))
BUSINESS_ID = "<BUSINESS_ID>"
BOOKING_ID = "<BOOKING_ID>" # from the create response
STATUS_TOKEN = "<STATUS_TOKEN>" # from the create response (shown once)
# When the customer cancels a card-paid booking before the cutoff, it is refunded minus the
# payment processing fee and the platform fee. If the business declines it or does not confirm it, it is refunded in full.
show(*call("DELETE", f"/api/v1/businesses/{BUSINESS_ID}/bookings/{BOOKING_ID}", headers={"Authorization": f"Bearer {STATUS_TOKEN}"}))
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)
// When the customer cancels a card-paid booking before the cutoff, it is refunded minus the
// payment processing fee and the platform fee. If the business declines it or does not confirm it, it is refunded in full.
(async () => {
show(await call("DELETE", `/api/v1/businesses/${BUSINESS_ID}/bookings/${BOOKING_ID}`, undefined, { Authorization: `Bearer ${STATUS_TOKEN}` }));
})();
回應範例
HTTP 200
{
"ok": true,
"booking": {
"booking_id": "WQEMHR2E",
"status": "cancelled",
"status_text": "Cancelled",
"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": "Refunded NT$518 of NT$600 (the Stripe processing fee and the platform fee were deducted because the customer cancelled)",
"details": [],
"payment_details": {
"mode": "online",
"status": "refunded",
"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",
"refund": "refunded",
"refund_amount": {
"value": 51800,
"currency": "twd",
"text": "NT$518"
},
"refund_fees": {
"stripe": "NT$39",
"platform": "NT$43",
"reason": "customer_cancel"
}
},
"cancelled_by": "customer"
}
}回應取自服務的自動測試:取自連接器的測試環境:連接器程式碼原樣執行,Stripe由測試套件的假Stripe伺服器取代,所以transaction_id(pi_1)與金流手續費(USD1.20,換算NT$39)都是測試值。沒有任何實際扣款。
你在接單確認台看到什麼
- 等待付款的預約另列一區,不能按確認;付款完成後才通知你。
- 付款完成後,LINE通知會標明已付款金額,不含卡號與客人個資。
- 確認頁顯示付款狀態、卡別與末四碼。
- 婉拒或取消已付款的預約,會立即退款並顯示結果。
- 匯出的CSV多了付款方式、付款狀態、金額、付款時間與退款時間。
商家設定
- 付款方式:預設是到店付款;線上付款要在上架時設定。價格為0的服務一律不收款。
- 付款時限:5至1440分鐘,沒設定時是15分鐘。
- 設為線上付款,但收款設定還沒完成時,建立預約會回
payment_unavailable,不會建立預約。 - 線上取消的截止時間與確認規則,由你決定。
線上付款由Seller Tech U.S.A. LLC經Stripe處理;手續費與撥款時程寫在報價單。
今天的狀態
預約介面已上線。商家可以選擇到店付款或線上付款;第一家商家(一位私人教練)已於2026-10-22啟用線上付款。
開始之前
- 你的服務:名稱、價格與時長。
- 可預約的時段,以及每個時段可收幾位。
- 取消與改期的截止時間。
- 是否收線上付款;收的話,撥款需要的資料。
重送不會重複
代理在網路錯誤後重送請求,不會多出一筆預約或多扣一次款:代理帶Idempotency-Key,SOP在48小時內回傳原本的結果;卡片扣款本身也另外帶了給Stripe的冪等鍵。
上線之前
我們和你一起整理資料,每一項由你確認後才上線。線上付款要你提出後才會開啟。