膛币柜台 · 开店接口草案
草案,还没有开放。 规矩主人 10-27 已经定了(见第五节),接口细节还可以在 PR 里改。 机器可读版:ledger.openapi.json。
一、为什么要统一记账
膛币是全群通用的:签到、打牌、生日都在发,酒馆点酒在花。以后群友自己开店(咖啡店、茶店、麦当劳……),钱也得记在同一本账上,不能每家店各记一份——否则一个人在 A 店有钱、在 B 店没钱,币就不叫通用了。
所以账只有一本,在膛币柜台。荷官、奶豆、以后的每家店,都是柜台的客户端,各拿一把钥匙,各有各的权限。
二、收钱的流程
店只能开单,不能直接扣别人的钱。钱从顾客转到店里,必须顾客自己点头。
- 顾客在群里跟你的店说要买什么(怎么点单由你的店自己定)。
- 你的店调
POST /v1/shop/orders开单,拿到付款码(比如A7K2)。 - 荷官在群里发一张付款卡片(写着哪家店、买了什么、多少膛币),顾客点「付款」就付了。机器人顾客点不了按钮,发
!付 A7K2也行,效果一样。 - 荷官认出是谁在付(用荷官自己的飞书应用核对身份,别人冒充不了),让柜台把钱从顾客转到店的账户,并在群里说一声。
- 你的店查单(
GET /v1/shop/orders/{order_id})看到status变成paid,或者收到柜台推来的通知,就可以“上菜”了。
细节:
- 只让点单的人付:开单时带上顾客点单那条飞书消息的 id(
customer_message_id),就只有那条消息的发送者能付,别人拿到付款码也付不了。不带的话谁拿着付款码都能付(适合“请客”)。 - 过期:默认 10 分钟不付就过期,最长 30 分钟,可以用
expires_in改。 - 撤单:没付的单可以撤(
cancel);付了的只能退款。 - 退款:
refund从店的账户退回给顾客,可以部分退,店里余额不够就退不了。 - 重发不重复记账:写操作都带
key(你自己生成的唯一串),网络抖动重发同一个key,柜台返回第一次的结果,不会开两张单、退两次款。
三、账户和分账
| 账户 | 写法 | 例子 |
|---|---|---|
| 真人 | u:<飞书 union_id> |
u:on_8f3c2a… |
| 机器人 | b:<名字> |
b:naidou |
| 店 | s:<店名> |
s:mcd |
- 顾客付的钱全额进店的账户(
s:…),柜台不抽成。开店时可以登记分账比例,自动分给店主、店员(比如店主八成、店员两成);不登记就全留在店里。 - 店里的钱,店主随时可以转到自己的个人钱包(
POST /v1/shop/withdraw),只能转给店主本人。 - 店不能发币。膛币只有柜台按规矩发(签到、牌局、生日……),规矩只有一份,谁也不能自己多发。
- 打赏照旧用
!打赏 @某人 金额,不走店。
四、钥匙和安全
- 一家店一把钥匙(
Authorization: Bearer <店铺钥匙>),开店时主人私下给,别发在群里。钥匙只能操作自己店的单和账户。 - 想收通知的话,开店时登记一个通知地址,另给一把通知密钥。通知的签名和游戏厅协议一样(
X-Tavern-Timestamp+X-Tavern-Signature),验签方法见 游戏厅协议第四节。 - 钥匙泄露了找主人换,旧钥匙立刻作废。
五、规矩(主人 10-27 定)
- 开店要主人审核:私下找主人申请(店名、店主、分账比例、通知地址),同意了才给钥匙。开了以后卖什么、定什么价是店主自己的事,主人不改。
- 柜台不抽成:顾客付多少,店里进多少。
- 不设上限:单笔、每天都不封顶。
- 店里的钱可以转给店主个人。
- 付款用卡片:顾客点卡片上的「付款」;机器人顾客点不了按钮,用
!付 <付款码>。
六、上线要做的
- 柜台:加订单表、店铺钥匙、退款、转给店主和通知。
- 荷官:发付款卡片、认卡片上的「付款」和
!付 <付款码>指令,替顾客确认身份。 - 公网入口:柜台现在只在内网,计划用 Cloudflare Tunnel 开到
https://api.linkong.dev/ledger,只开/v1/health和/v1/shop/…,荷官和奶豆用的内部接口不对外。