Open Source
开源关键代码
这里展示的是平台最核心、最容易让人关心透明度的部分:资金托管、购买校验、私有文件读取控制和卖家入账逻辑。 我们把关键链路拆开公开,方便检查每一步是怎么工作的。
托管合约
这是一个最小可读的资金托管骨架。买家付款后,资金先进入平台托管层,便于后续分账、退款和风控处理。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract EAMarketVault {
address public owner;
event Deposited(address indexed from, uint256 amount);
event Withdrawn(address indexed to, uint256 amount);
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}
function deposit() external payable {
require(msg.value > 0, "empty deposit");
emit Deposited(msg.sender, msg.value);
}
function withdraw(address payable to, uint256 amount) external onlyOwner {
require(to != address(0), "bad to");
require(address(this).balance >= amount, "insufficient balance");
(bool ok, ) = to.call{value: amount}("");
require(ok, "transfer failed");
emit Withdrawn(to, amount);
}
}订单校验
购买完成后,服务器会先查订单状态,再确认该买家是否真的拿到了购买权限。这里的判断是后端进行的,不依赖浏览器状态。
export async function verifyPaidOrder({ orderId, buyerId }) {
const { data: order } = await supabase
.from("orders")
.select("id,status,buyer_id,total_cents,paid_at")
.eq("id", orderId)
.single();
if (!order || order.buyer_id !== buyerId) return { ok: false };
if (order.status !== "paid") return { ok: false };
const { data: purchase } = await supabase
.from("purchases")
.select("id,granted_at")
.eq("buyer_id", buyerId)
.eq("order_id", orderId)
.maybeSingle();
return {
ok: true,
hasAccess: Boolean(purchase),
};
}私有存储策略
这一段展示的是私有文件读取策略的思路。实际项目里我们会把产品文件与商品记录关联起来,再结合购买记录放行。
create policy "read only purchased files"
on storage.objects
for select
using (
bucket_id = 'private-products'
and exists (
select 1
from purchases
where purchases.product_id = storage.objects.product_id
and purchases.buyer_id = auth.uid()
)
);卖家入账与出金
卖家收入不是“实时可提”的单一数字,而是拆成累计收入、冻结收入、可提现余额三个部分。 这样可以支持 24 小时申诉期、手动审核、自动打款和余额风控。
export async function settleSellerBalance(sellerId: string, amountCents: number) {
const available = Math.max(0, amountCents);
if (available <= 0) return;
await supabase.from("seller_balances").upsert({
seller_id: sellerId,
available_cents: available,
updated_at: new Date().toISOString(),
});
}关键说明
• 平台不把用户文件做成公开直链,买家下载前必须先通过购买权限校验。
• 如果卖家下架商品,已购用户仍然保留历史购买记录和下载权限。
• 订单、投诉、提现、余额和销量都在服务器侧存储,前端只是展示结果。
• 自动打款或手动打款都要先检查余额和风控状态,避免重复出金。
• 开源页面展示的是架构关键点,不是把所有业务配置和密钥直接暴露出来。