跳至內容
walaoraWalaora

Walaora API 參考文件

連接 POS、網店或內部系統。透過 HTTPS 傳送 JSON,每項整合使用一個 API 金鑰。

只可在顧客知情的情況下傳送其資料;只有在顧客明確同意時,才將 marketingConsent 設為 true。

身份驗證

在「控制台 → API 與 Webhooks」建立金鑰(商業版或企業版方案)。每次請求均須附上金鑰。金鑰只會顯示一次;如有外洩,請立即撤銷。限制:每個金鑰每分鐘 120 次請求。

Authorization: Bearer wl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

端點

Base URL: https://walaora.com/api/v1

GET/programs

列出會員計劃。

GET/customers?phone=0551234567&tag=vip

搜尋顧客(每頁 50 名,?page=2…)。 ?tag=vip 列出帶有該標籤的顧客;每位顧客都包含其標籤。

POST/customers

為顧客登記加入計劃。內容:{ programId, name, phone, email?, marketingConsent?, locale? }。新建立時傳回 201,已登記則傳回 200。

GET/cards/{serial}

按顧客卡上 / QR 碼上的代碼取得會員卡。

POST/cards/{serial}/earn

印花計劃:{ stamps?: 1–10 }。積分計劃:{ amount },以工作空間貨幣計算。可選 { branchId }。 多印章卡:請傳入卡上某個印章組的 setId。

POST/cards/{serial}/redeem

兌換一項可用獎賞,或傳送 {"rewardId"} 兌換獎賞目錄中以印花/積分計價的獎賞。

POST/cards/{serial}/sell

預付套餐:出售一個套餐,次數加到卡上(在您的櫃檯付款)。Webhook:package.sold。

POST/cards/{serial}/use

預付套餐:扣除一次(用完或到期時拒絕)。員工卡:在每日上限內記錄福利。Webhook:package.used、perk.used。

GET/coupons/{code}

查詢優惠券但不使用:傳回其所屬優惠、能否使用;如不能使用,說明原因(已使用、已到期或已暫停)。

POST/coupons/{code}/redeem

使用一次優惠券。可選 { amount }(消費金額,以工作空間貨幣計算)及 { branchId }。已使用或優惠已結束時傳回 409。Webhook:coupon.redeemed。

GET/coupon-offers

列出優惠券優惠及其面額、截止日期,以及現在能否建立券碼(usable)。

POST/coupon-offers/{id}/coupons

為某個優惠建立券碼。{ customerId } 給該顧客一個券碼(顯示在其會員卡頁面);或 { count: 1–500 } 個不綁定顧客的券碼,用於列印或分享。成功回傳 201 及券碼;優惠已暫停或已結束時回傳 409。

curl -X POST https://walaora.com/api/v1/cards/ABCDE23456/earn \
  -H "Authorization: Bearer wl_live_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: receipt-10045" \
  -d '{"stamps": 1}'

重試與冪等性

POST 請求請附上 Idempotency-Key 標頭(任何唯一字串,例如你的收據編號)。在 24 小時內以相同金鑰重試,會傳回原本的回應,而不會重複蓋印。

錯誤

錯誤會傳回 JSON 內容 { error: { code, message } } 及 HTTP 狀態碼:401 金鑰無效 · 403 plan_required · 404 找不到 · 409 cooldown / no_reward / program_inactive · 422 驗證失敗 · 429 超出速率限制。

Webhooks

在控制台加入一個 HTTPS 端點並選擇事件。每次傳送均為 POST 請求,內容為 JSON { id, type, createdAt, data },並附有以下標頭:Walaora-Event、Walaora-Delivery 及 Walaora-Signature。請在 10 秒內以 2xx 回應。傳送失敗會在 1 分鐘、5 分鐘、30 分鐘、2 小時及 12 小時後重試。

事件

驗證簽署(Node.js)

import crypto from "node:crypto";

// rawBody: the exact request body string; header: req.headers["walaora-signature"]
export function verifyWalaora(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // replay window
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ""));
}