本文目录导读:

在PHP项目中实现用户电子签约,通常需要结合第三方电子签名平台(如e签宝、法大大、上上签等)或自建签名服务(基于数字证书、时间戳等,技术门槛较高),以下是基于第三方平台的推荐实现方案及核心步骤:
选择电子签名服务商
国内主流平台:
- e签宝(成熟、API丰富,适合企业级)
- 法大大(法律效力强,覆盖合同全流程)
- 上上签(移动端体验好,集成简单)
- 腾讯电子签(微信生态支持好,成本透明)
选型建议:根据合同量、法律合规要求、预算(按份或年费)、对接复杂度选择。
核心实现流程(以e签宝为例)
注册与API接入
- 注册开发者账号,获取 AppId、AppSecret、API网关地址。
- 安装PHP SDK(原生HTTP请求或使用Composer包,如
guuzzlehttp/guzzle)。 - 配置签名算法(通常为SHA256withRSA或HMAC-SHA256,平台会提供签名示例)。
用户实名认证(必要前提)
根据合同类型,要求用户完成实名(个人:身份证+人脸识别;企业:营业执照+法人授权)。
- 对接实名认证API:平台提供
身份证OCR、企业四要素验证、人脸识别接口。 - 保存认证凭证:平台返回的
用户ID(如accountId)、证件号、认证状态。
发起签署流程(核心步骤)
// 1. 构造签署请求参数
$data = [
'contractId' => '自定义合同ID', // 业务系统合同唯一标识
'docs' => [ // 待签文件(支持PDF/Word/图片)
['fileId' => '上传文件后的fileId', 'fileName' => '采购合同.pdf']
],
'signers' => [ // 签署方
[
'signerType' => 0, // 0个人,1企业
'thirdSignerId' => '用户业务ID', // 我方用户ID
'name' => '张三',
'mobile' => '13800138000',
'signPos' => [ // 签署位置(可指定坐标或关键字)
['width' => 200, 'height' => 50, 'page' => 1, 'x' => 100, 'y' => 500],
['keyWord' => '签署栏:'] // 也可按关键字定位
],
'signType' => 2 // 0手写、1数字证书、2自动(静默签)
]
],
'noticeConfig' => [ // 通知设置
'signNoticeTypes' => ['sms', 'email'],
'noticeTemplateId' => 'xxx'
]
];
// 2. 调用平台API(如e签宝的 /v2/signflow/create)
$response = sendRequest('POST', '/v2/signflow/create', $data);
if ($response['code'] == 0) {
$flowId = $response['data']['signFlowId']; // 签署流程ID
// 生成签署链接(跳转式使用)
$shortUrl = $response['data']['url'];
// 或获取扫码签署二维码
}
签署方式选择
- 跳转签署:用户通过短信/邮件收到的链接,在平台页面完成刷脸/短信验证(推荐)。
- 嵌入式签署:在自有系统内通过iframe嵌入平台签署页面(需平台支持,注意X-Frame-Options)。
- API静默签(企业用户):提前授权后,不跳转页面,直接通过API完成签名(常用于内部流程)。
签署完成回调
- 配置平台回调URL(如
https://你的域名/api/sign/callback)。 - 接收回调参数:
flowId、signStatus(2=签署完成)、signedUrl(签署后文件下载地址)。 - 更新数据库:合同状态改为“已签署”,保存PDF下载地址。
// 回调处理(需验签)
public function handleCallback(Request $request) {
$sign = $request->header('X-Essign-Signature'); // 平台签名
if (verifySign($request->getContent(), $sign)) {
$flowId = $request->input('flowId');
// 更新合同状态
DB::table('contracts')->where('flow_id', $flowId)->update([
'status' => 2,
'signed_at' => now(),
'pdf_url' => $request->input('signedUrl')
]);
return 'success';
}
throw new \Exception('签名验证失败');
}
关键注意事项
- 法律效力:确保使用平台提供的 数字证书(CA证书),而非简单图片签名(无法律效力)。
- 合同模板:可预定义模板(如租赁合同模板),签署时动态填充变量(姓名、金额、日期)。
- 时间戳:几乎全部平台自动加盖可信时间戳,无需自行处理。
- 数据安全:
- API通信使用HTTPS,参数需签名加密(参考平台签名算法)。
- 用户敏感信息(身份证号、手机号)尽可能脱敏处理(如只取前6后4位)。
- 成本控制:部分平台支持“预充值”或“按月订阅”,关注有效期内未签署合同的退款规则。
自建方案(极简版,不推荐正式场景)
如果仅用于内部测试或低法律要求场景(如免责声明确认),可简单实现:
// 1. 生成哈希摘要
$hash = hash('sha256', $contractContent . $userId . time());
// 2. 存储用户确认记录
DB::table('signatures')->insert([
'user_id' => $userId,
'contract_hash' => $hash,
'ip' => request()->ip(),
'user_agent' => request()->userAgent(),
'signed_at' => now()
]);
// 3. 在前端展示“电子签名”图片(用户手写或点击确认)
⚠️ 此方案无法提供 CA认证、防篡改、可信时间戳,不具备法律效力,不能用于正式商业合同。
推荐技术栈集成
- Laravel + e签宝 SDK:利用Laravel的队列处理签名回调,事件监听同步合同状态。
- ThinkPHP + 法大大:用 GuzzleHttp 封装 API,支持批量签署。
- TP5 + 腾讯电子签:小程序内通过JSSDK直接唤起签署界面(适合移动端)。
总结核心步骤
- 选择合规电子签名平台。
- 用户完成实名认证(个人/企业)。
- 调用平台API创建签署流程(上传文件 + 指定签署方 + 签署位置)。
- 用户通过链接/扫码完成签署(平台处理活体检测、时间戳)。
- 监听回调更新合同状态,存储电子合同文件。
对于大多数PHP项目,接入第三方平台(如e签宝、法大大)是唯一可行的方案,切忌自建签名功能(法律风险高、技术复杂),选择时建议优先考虑“能够提供 PHP SDK 或 RESTful API 的成熟平台”,并留意“合同签署后的证据存证”服务(如存证到司法链)。