碰一碰爆店码是一套给线下门店用的「顾客帮你发内容」营销系统:顾客用手机碰一下桌面上的 NFC 卡片,或者扫一下二维码,就能把门店准备好的短视频、图文一键发布到自己的抖音、快手、小红书、视频号,让每一次到店都变成一次免费曝光。
本文把整套系统的业务逻辑、功能模块、技术架构、数据库设计、核心代码、部署方式讲清楚,并附上商用变现路径与必须回避的合规红线和常见问题。
一、它到底解决什么问题
线下门店做本地生活,最贵的三件事:达人探店贵、投流成本高、顾客发完就走。碰一碰爆店码的思路是把第三条反过来 —— 顾客在店里等餐、等待服务的那几十秒,本来就有刷手机的习惯;把「刷」变成「发」,门店就白得一个推广位。
| 获客方式 | 单次成本 | 内容可信度 | 可复制性 |
|---|---|---|---|
| 平台付费投流 | 按曝光计价,持续投入 | 官方广告位,用户有防备心 | 停投即停量 |
| 达人探店团购 | 单条几百到几千元 | 较高 | 依赖达人档期与配合 |
| 碰一碰爆店码 | 一张卡片几元,可重复使用 | 来自真实顾客的账号 | 门店自持,长期复用 |
关键差别在于内容由谁的账号发出去。门店自己的号可能只有几百播放;顾客的账号背后是他自己的社交关系链,同一份素材换一个账号发布,触达的人完全不同。
二、原理:碰一下之后发生了什么
- 触碰唤起:NFC 卡片(NTAG213 / 215 / 216 一类)里写入一条 URL,手机贴近后系统自动弹出「在浏览器中打开」的提示,点击即进入 H5 落地页。没有 NFC 的手机用卡片上的二维码兜底。
- 识别来源:URL 上带
card_id与签名参数,服务端据此查出这张卡绑定了哪家门店、用哪套素材、归属哪个代理。 - 平台授权:落地页引导顾客用抖音、快手、小红书或视频号扫码授权登录。这一步必须走平台官方开放接口 —— 系统拿到的是用户主动授予的发布凭证,而不是账号密码。
- 素材下发:服务端从门店素材库按规则挑一条(随机文案、随机话题、随机封面),降低多条内容高度同质化带来的限流风险。
- 一键发布:调用平台发布接口,以顾客本人账号发布,带上门店定位、话题与团购链接。
- 数据回流:发布成功后回写记录,门店后台能看到谁在什么时候发了哪条、播放与互动多少;代理端按规则计佣。
整套系统的合法性完全建立在「用户本人知情且主动授权」之上。绕过官方接口、模拟客户端协议去代替用户发内容,属于平台明令禁止的行为,账号会被封,也有法律风险,商用版本不要碰这条线。
三、功能模块拆解
1. 商家端(小程序 / H5)
- 门店信息与定位管理,一店一码、一店多卡
- 素材库:批量上传视频与图文,支持文案模板、话题库、封面库
- 活动配置:发布奖励(赠品、优惠券、积分)、每日上限、时段限制
- 数据看板:触碰次数、扫码次数、发布成功数、播放量、到店核销
- 卡片管理:激活、绑定、挂失、补卡
2. 平台管理端
- 商户入驻审核、套餐与到期管理
- 全局素材与敏感词审核,发布内容留痕可追溯
- 代理层级、佣金比例、结算与提现审核
- 系统设置:平台授权配置(AppID / Secret)、短信、支付、对象存储
3. 代理 / 分销端
- 专属推广码,下级商户归属自动绑定
- 佣金明细、阶梯比例、提现申请
- 下级商户数据与业绩排行
4. 硬件侧
- NFC 卡、台卡、桌贴的批量写卡与二维码生成
- 可选「碰一碰 + 二维码」二合一物料
四、技术架构与技术栈
市面上交付的商用版本,主流是「PHP 后端 + uni-app 多端 + Vue 管理后台」,也有 Java(SpringBoot)与 Node.js 版本。模块划分一致,差别只在语言与生态。
| 层 | 常见选型 | 说明 |
|---|---|---|
| 后端服务 | PHP 8 + ThinkPHP 6 / Java + SpringBoot / Node.js + NestJS | 业务 API、平台授权、任务调度 |
| 数据库 | MySQL 5.7 / 8.0 | 业务主库,数据量上来后可做读写分离 |
| 缓存与队列 | Redis | 登录态、限流、发布任务队列 |
| 管理后台 | Vue 3 + Element Plus | 平台 / 商家 / 代理三套视角 |
| 用户端 | uni-app(编译到微信小程序 + H5) | 一套代码多端,落地页走 H5 |
| 文件存储 | 阿里云 OSS / 腾讯云 COS / 七牛 | 素材与视频存放,走 CDN 分发 |
| 定时任务 | 宝塔计划任务 / Supervisor | token 刷新、数据同步、佣金结算 |
五、数据库核心表设计
系统能不能跑顺,主要看「卡 → 门店 → 素材 → 任务 → 记录」这条链路是否闭环。核心表如下(MySQL 示例,字段为节选):
-- 门店
CREATE TABLE `store` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`merchant_id` bigint UNSIGNED NOT NULL COMMENT '所属商户',
`agent_id` bigint UNSIGNED DEFAULT 0 COMMENT '归属代理,用于分佣',
`name` varchar(80) NOT NULL,
`city` varchar(40) DEFAULT '',
`address` varchar(160) DEFAULT '',
`poi_id` varchar(64) DEFAULT '' COMMENT '平台门店 POI,发布时带定位用',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '1正常 0停用',
`expire_at` datetime DEFAULT NULL COMMENT '套餐到期',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_merchant` (`merchant_id`),
KEY `idx_agent` (`agent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- NFC 卡片:一张卡 = 一个推广入口
CREATE TABLE `card` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`store_id` bigint UNSIGNED NOT NULL,
`uid` char(14) NOT NULL COMMENT 'NFC 芯片 UID,防伪与防复制',
`scene` varchar(32) NOT NULL DEFAULT 'default' COMMENT '卡位场景,用于区分素材组',
`state` tinyint NOT NULL DEFAULT 1 COMMENT '1已激活 2挂失 0未激活',
`scan_cnt` int UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_uid` (`uid`),
KEY `idx_store` (`store_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 发布记录:每一笔都由一条任务产生,也是分佣与对账的账本
CREATE TABLE `publish_record` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`store_id` bigint UNSIGNED NOT NULL,
`card_id` bigint UNSIGNED NOT NULL,
`platform` tinyint NOT NULL COMMENT '1抖音 2快手 3小红书 4视频号',
`openid` varchar(64) NOT NULL COMMENT '发布者在该平台的授权标识',
`material_id` bigint UNSIGNED NOT NULL,
`item_id` varchar(64) DEFAULT '' COMMENT '平台返回的作品 ID',
`play_cnt` int UNSIGNED NOT NULL DEFAULT 0,
`status` tinyint NOT NULL DEFAULT 0 COMMENT '0待发布 1成功 2失败',
`fail_reason` varchar(128) DEFAULT '',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_store_time` (`store_id`, `created_at`),
KEY `idx_openid` (`openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
其余如 merchant、material、agent、commission、stat_daily 按同样思路展开即可。publish_record 是整条链路的账本,分佣、对账、风控都从它出发,记得把失败原因也落库。
六、核心代码
1. 生成卡片链接(带签名,防伪造)
<?php
// 卡片 URL 必须在服务端生成并签名,客户端只负责跳转。
// 否则任何人改一下 card_id,就能把别人的门店素材发到自己号上。
function cardUrl(array $card, string $secret, string $baseUrl): string
{
$params = [
'cid' => $card['id'],
'sid' => $card['store_id'],
't' => time(),
];
ksort($params);
$params['sign'] = hash_hmac('sha256', http_build_query($params), $secret);
return $baseUrl . '/go?' . http_build_query($params);
}
2. 落地页取数(签名校验 + 出素材)
<?php
$secret = getenv('CARD_SECRET');
$params = $_GET;
$sign = $params['sign'] ?? '';
unset($params['sign']);
ksort($params);
if (!hash_equals(hash_hmac('sha256', http_build_query($params), $secret), $sign)) {
exit('链接无效');
}
// 链接 30 分钟过期,防止被批量转发刷量
if (time() - (int) $params['t'] > 1800) {
exit('链接已过期,请重新碰一碰');
}
$store = $db->table('store')
->where('id', $params['sid'])
->where('status', 1)
->find();
// 同一门店多条素材轮播,避免所有顾客都发同一条
$material = $db->table('material')
->where('store_id', $params['sid'])
->where('status', 1)
->orderRaw('RAND()')
->find();
if (!$store || !$material) {
exit('门店暂未配置活动');
}
3. 平台授权 token 的获取与刷新
<?php
// 以抖音开放平台为例:client_token 用于服务端调用,有效期 2 小时,必须缓存。
// 每次请求现取会被限流,这是最常见的线上故障来源之一。
function douyinClientToken(Redis $redis, string $appId, string $secret): string
{
$key = 'dy:client_token';
if ($token = $redis->get($key)) {
return $token;
}
$resp = http_post('https://open.douyin.com/oauth/client_token/', [
'client_key' => $appId,
'client_secret' => $secret,
'grant_type' => 'client_credential',
]);
$data = json_decode($resp, true);
if (($data['data']['error_code'] ?? -1) !== 0) {
throw new RuntimeException('获取 token 失败:' . $resp);
}
$token = $data['data']['access_token'];
$redis->setex($key, 6600, $token); // 留 10 分钟余量
return $token;
}
4. 分销佣金结算(必须幂等)
<?php
// 只有「发布成功」才计佣,且同一条记录只能结算一次,否则重试会重复打款。
function settleCommission(PDO $pdo, int $recordId): void
{
$pdo->beginTransaction();
try {
$rec = $pdo->query("SELECT * FROM publish_record WHERE id = {$recordId} FOR UPDATE")->fetch();
if (!$rec || $rec['status'] != 1 || $rec['settled'] == 1) {
$pdo->commit();
return;
}
$store = $pdo->query("SELECT agent_id FROM store WHERE id = {$rec['store_id']}")->fetch();
$rate = commissionRate($store['agent_id']); // 阶梯比例
$amount = bcmul((string) unitPrice(), (string) $rate, 2); // 金额一律用 bcmath,别用浮点
$pdo->prepare('INSERT INTO commission (agent_id, record_id, amount, created_at) VALUES (?,?,?,NOW())')
->execute([$store['agent_id'], $recordId, $amount]);
$pdo->prepare('UPDATE publish_record SET settled = 1 WHERE id = ?')
->execute([$recordId]);
$pdo->commit();
} catch (Throwable $e) {
$pdo->rollBack();
throw $e;
}
}
以上是通用实现思路。拿到具体源码后,请以源码内的实际类名、方法名与接口版本为准 —— 各平台开放接口迭代频繁,接入前务必对照官方最新文档。
七、部署与运行环境
- 服务器:2 核 4G 起步(单商户场景);十家以上商户建议 4 核 8G 并配独立数据库。国内节点需完成 ICP 备案。
- 环境:Nginx 1.20+、PHP 8.0+(或 Java 8+ / Node 18+)、MySQL 5.7+、Redis 5+。
- 域名与证书:H5 落地页必须 HTTPS —— NFC 与小程序跳转都要求安全域名,并在平台后台配好业务域名白名单。
- 平台侧配置:申请抖音 / 快手 / 小红书开放平台应用,拿到 AppID 与 Secret,配置授权回调域名;涉及团购核销的还需本地生活服务商或商家资质。
- 定时任务:token 刷新、发布结果回查、播放数据同步、佣金日结,缺一个都会出现「发了没数据」。
- 素材与 CDN:视频走对象存储 + CDN,不要放服务器本地,否则几十家门店并发上传就会打满带宽。
八、商用模式
| 模式 | 做法 | 收入结构 |
|---|---|---|
| 卖源码 | 一次性交付全套代码 + 部署文档,提供安装指导 | 单次授权费,可加授权域名数限制 |
| 卖代理 | 发展区域代理,由代理向门店收年费 | 代理首批款 + 后续续费分成 |
| SaaS 年费 | 自己运营平台,门店按年付费开号 | 持续年费 + 增值物料 |
| 物料与代运营 | 卖 NFC 卡片、台卡,或帮门店做素材 | 硬件差价 + 月度服务费 |
四种可以叠加。真正决定复购的不是系统本身,而是门店能不能看到到店转化 —— 所以数据看板里「触碰 → 发布 → 到店」这条链路要尽量做实,而不是只统计播放量。
九、合规与风险
- 必须走官方开放接口。任何模拟客户端、破解签名、批量养号的做法,平台一旦识别就是封号,还可能触及《反不正当竞争法》及计算机信息系统相关法规。
- 用户授权要留痕。落地页必须明示「将要发布到你本人的账号」,并提供拒绝与撤回入口;不满足《个人信息保护法》的告知同意要求,是这类系统最常见的法律风险点。
- 内容责任在商家。医疗、金融、招商加盟等特殊行业有广告审查要求,素材审核与敏感词过滤不能省。
- 注意平台风控阈值。同一门店短时间大量发布同一素材,极易被判为异常营销。素材随机化、发布频次限制、时段分散,都是必要的工程手段。
- 硬件合规。NFC 卡片作为商品销售时,是否涉及 3C 与无线电发射设备相关要求,需按实际销售形态确认。
十、常见问题
Q1:所有手机都能碰一碰吗?
不能。iPhone 需要 iPhone 7 及以上、系统 iOS 11+,且 NFC 后台读取默认开启;安卓机型需在设置里打开 NFC 开关。所以物料一定要做成「NFC + 二维码」双入口,扫码兜底。
Q2:会不会被平台判定为刷量?
取决于行为是否真实。由真实顾客、在自己账号、发布差异化内容,属于正常分享;同一批账号反复发布同一条素材则高度可疑。系统的素材随机化与频次控制就是为此设计的。
Q3:需要平台资质吗?
调用发布类接口通常需要企业主体应用,涉及本地生活团购核销的还需要服务商或商家资质。个人主体能开通的能力有限,选型时要先确认清楚。
Q4:源码交付一般包含什么?
商用版本通常包含:服务端源码、管理后台源码、用户端(小程序 + H5)源码、数据库结构与初始数据、部署文档与接口说明。是否含后续升级、是否限制授权域名,需要在合同里写清楚。
Q5:能不能只买系统不买卡?
可以。卡片只是入口载体,二维码、桌贴、易拉宝同样能承载同一个链接 —— 系统只认链接上的卡片 ID 与签名。
写在最后
碰一碰爆店码不是一个复杂的算法产品,它的价值在于把「门店想要曝光」和「顾客愿意分享」这两件事,用一张几块钱的卡片接上了。真正拉开差距的是三件事:素材是否足够本地化、数据链路是否真实闭环、分佣与代理体系是否算得清。源码解决的是第一层的工程问题,后两层靠运营与渠道设计。
如果你正在评估这套系统,需要源码交付、二次开发或私有化部署,欢迎通过站内联系方式与我们沟通具体场景。

