本文目录导读:

- 目录导读
- 为什么企业需要将审批流程接入PHP系统?
- 企业微信审批API的核心机制与权限准备
- PHP对接审批的前置环境搭建
- 实战代码:创建审批模板与提交审批实例
- 回调机制:实时获取审批状态变更
- 常见错误排查与性能优化建议
- 高频问题问答(FAQ)
- 构建可扩展的审批中台
PHP集成企业微信审批全攻略:从API调用到实战部署
目录导读
- 为什么企业需要将审批流程接入PHP系统?
- 企业微信审批API的核心机制与权限准备
- PHP对接审批的前置环境搭建
- 实战代码:创建审批模板与提交审批实例
- 回调机制:实时获取审批状态变更
- 常见错误排查与性能优化建议
- 高频问题问答(FAQ)
- 构建可扩展的审批中台
为什么企业需要将审批流程接入PHP系统?
许多企业正在使用企业微信内置的审批功能(如请假、报销、合同审批),但业务系统(如OA、ERP或自研CRM)往往需要自动触发审批,或者将审批结果同步回内部数据库,如果每次都在企业微信里手动操作,不仅效率低下,还会导致数据孤岛。
通过PHP调用企业微信“审批”API,你可以实现:
- 自动化发起:当业务系统触发条件(如订单超限)时,自动创建一个审批实例。
- 双向同步:审批通过后,自动更新业务系统中的状态字段。
- 个性化流程:根据业务场景动态指定审批人、抄送人。
这本质上是通过企业微信的“自建应用”能力,将https://qyapi.weixin.qq.com/cgi-bin/oa/...地址下的接口与你的PHP后端进行对接。
问答1: 必须购买企业微信的付费版本才能使用审批API吗? 不需要,审批API是基础能力,只要你的企业微信完成了企业认证(免费),并创建了自建应用,即可调用,但每日有调用次数限制(默认600次/分钟,按应用维度),足够大多数业务场景使用。
企业微信审批API的核心机制与权限准备
1 两个关键Token
对接审批API,你需要两种凭证:
- access_token:调用任何API都需要,有效期2小时,通过
corpid和corpsecret换取。 - suite_token(如果你开发的是第三方应用才需要);对于自建应用,只用access_token。
2 审批相关的三个核心接口
| 接口名称 | 功能 | 请求方法 |
|---|---|---|
oa/approval/create_template |
创建审批模板(可选,可用现成模板) | POST |
oa/approval/submit |
提交审批申请 | POST |
oa/approval/get |
获取审批实例详情(状态) | POST |
3 必须开启的权限
在企业微信管理后台 → 应用管理 → 自建应用 → 权限管理中,需要勾选:
- “审批” -> “提交审批申请”及“获取审批数据”。
- “通讯录” -> “成员信息读取”(为了解析审批人ID)。
PHP对接审批的前置环境搭建
1 技术准备
推荐使用PHP 7.4+,开启curl扩展,无需安装复杂框架,原生PHP即可。
2 获取access_token的缓存策略
access_token的稳定性直接决定成功率,建议用文件缓存或Redis缓存,避免每次请求都去换取。
function getAccessToken($corpId, $secret, $cacheFile = 'token.json') {
if (file_exists($cacheFile)) {
$data = json_decode(file_get_contents($cacheFile), true);
if ($data['expires_at'] > time()) return $data['access_token'];
}
$url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpId}&corpsecret={$secret}";
$resp = file_get_contents($url);
$result = json_decode($resp, true);
if ($result['errcode'] == 0) {
file_put_contents($cacheFile, json_encode([
'access_token' => $result['access_token'],
'expires_at' => time() + 7200 - 200 // 提前200秒过期
]));
return $result['access_token'];
}
throw new Exception('获取token失败: ' . $result['errmsg']);
}
实战代码:创建审批模板与提交审批实例
1 直接使用企业微信内置模板(无需创建模板)
如请假、报销等,系统已有模板,你只需要拿到template_id(可通过oa/approval/get_template_detail查询)。
2 提交一个加班审批申请(核心代码)
$accessToken = getAccessToken($corpId, $secret);
// 1. 定义审批申请内容
$data = [
'creator_userid' => 'ZhangSan', // 发起人
'template_id' => '3TkQq4zvCwxxxxxxxxxx', // 预设模板
'use_template_approver' => 1, // 使用模板默认审批人
'approver' => [
['attr' => 2, 'userid' => ['LiSi']] // 2: 指定成员审批
],
'apply_data' => [
'contents' => [
[
'control' => 'Text',
'id' => 'TextField-1',
'value' => ['text' => '加班原因:项目上线']
],
[
'control' => 'Date',
'id' => 'DateField-2',
'value' => ['date' => ['2025-04-01', '2025-04-03']] // 加班起止日期
]
]
],
'summary_list' => [
['summary_info' => [['text' => '加班申请', 'lang' => 'zh']]]
]
];
// 2. 调用提交接口
$url = "https://qyapi.weixin.qq.com/cgi-bin/oa/approval/submit?access_token={$accessToken}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$res = json_decode($result, true);
if ($res['errcode'] === 0) {
echo "审批发起成功,sp_no: " . $res['sp_no']; // 唯一审批编号
} else {
echo "错误码: " . $res['errcode'] . " - " . $res['errmsg'];
}
关键参数解释:
apply_data.contents必须与模板中的字段ID对应,否则报错,你可以通过get_template_detail打印出所有control和id。approver数组支持多种组合:attr=1表示上级逐级审批;attr=2指定成员;attr=3指定角色。
问答2: 如果审批模板动态字段很多,PHP如何处理? 建议先通过
oa/approval/get_template_detail获取模板结构,将字段映射为数组,然后根据业务逻辑动态填充,切忌硬编码JSON,后期维护成本高。
回调机制:实时获取审批状态变更
单纯的轮询API会消耗大量配额,推荐使用回调URL方式。
1 配置回调
在企业微信管理后台→自建应用→接收消息→设置API接收,你需要提供一个PHP接口URL(如https://yourdomain.com/wechat/callback.php),并验证URL有效性(需解密echostr)。
2 接收审批状态回调的简易代码
// 验证签名并解密数据(此处省略企业微信加解密库代码,建议使用官方提供的WXBizMsgCrypt类)
$msg = decryptMsg($encrypt); // 解密后的XML
$xml = simplexml_load_string($msg, 'SimpleXMLElement', LIBXML_NOCDATA);
$event = (string)$xml->Event;
if ($event === 'open_approval_change') {
$spNo = (string)$xml->SpNo; // 审批编号
$status = (string)$xml->Status; // 2: 审批中 3: 已通过 4: 已驳回
// 更新你的业务数据库状态
$pdo->prepare("UPDATE business_table SET approve_status=? WHERE sp_no=?")
->execute([$status, $spNo]);
}
注意事项:
- 回调需要返回字符串
success,否则企业微信会重试5次。 - 建议在回调处理中加日志记录,便于排查丢失数据。
常见错误排查与性能优化建议
1 高频错误码速查表
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| 40098 | 模板ID不存在 | 确认模板ID拼写,或先调用创建模板接口 |
| 41016 | 审批人userid不合法 | 检查userid是否存在于通讯录且在职 |
| 301002 | 审批流程中的“申请人”与“审批人”重复 | 调整审批人设置,或使用“上级审批”模式 |
| 45033 | 接口调用超过频率限制 | 升级企业版本或降低并发,增加缓存 |
2 性能优化三条铁律
- 批量获取审批详情:如果每天有几千条审批,不要每条调用
/oa/approval/get,改用批量接口(按时间范围拉取,每页100条)。 - Redis缓存模板结构:模板字段不常变,缓存12小时,避免频繁请求模板详情接口。
- 异步处理:发起审批时,可以放入Redis队列,后台worker消费,避免用户等待HTTP响应。
高频问题问答(FAQ)
Q1: PHP版本有要求吗?企业微信API支持PHP 5.6吗?
A: 建议PHP 7.2以上,虽然无硬性要求,但低版本不支持CURLFile等特性,且加密库(用于回调解密)在新版本更稳定。
Q2: 审批附件(如图片)怎么提交?
A: 企业微信审批API暂不支持直接上传附件流,需要先使用媒体API上传文件,拿到media_id,然后在contents中使用Media控件(control类型为“Media”),传入media_id数组。
Q3: 如何实现“多个审批人依次审批”和“会签”?
A: 在approver字段中,使用多级数组:
'approver' => [
['attr' => 2, 'userid' => ['A']], // 第一级:A审批
['attr' => 2, 'userid' => ['B','C']] // 第二级:B、C会签
]
默认为依次审批;如果想改为会签,设置use_template_approver=0,并在每个元素加"mode": 1(1表示会签,2表示或签)。
Q4: 发起审批后,如何撤销? A: 企业微信API不提供撤销接口,目前只能通过提供“审批单据管理”的后台权限,由管理员人工撤回,或者你在业务系统层面做状态标识,引导用户重新发起。
Q5: 审批回调URL能同时接收多个应用的事件吗? A: 不能,回调URL是每个自建应用独立设置的,如果你有多个应用涉及审批,需要分别部署不同的回调端点。
构建可扩展的审批中台
通过PHP对接企业微信审批,绝非简单的几个接口调用,真正的价值在于将审批流嵌入到业务闭环中,建议在架构上做到:
- 抽象审批层:封装一个
ApprovalClient类,统一处理token、提交、查询、回调。 - 事件驱动:后端监听审批回调,触发后续操作(如自动开具发票、归档合同)。
- 日志与监控:记录每次API请求的耗时和错误码,及时报警。
务必在企业微信的“开发者工具”中充分测试模拟审批场景,确保你掌握了全部字段含义,利用好官方文档中“审批-API”章节,配合本文的实战代码,相信你能快速打通企业内部流程自动化。
(完)