Skip to main content

公众号回调

前言

公众号的回调有普通消息和事件推送,这里用普通消息中的文本消息作为示例

具体回调类型和xml包体数据可查看公众号文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

第一步:接收参数

微信公众号会发送一个POST请求给你,但是也会携带url参数,url参数是给你验证签名用的,具体的文本消息数据是xml格式的,放在包体里面

接收的数据是xml格式,所以返回给微信的数据也要是xml格式的

控制器代码

/**
* 测试公众号回调
*/
public function offMsgCallback(Request $request)
{
// 获取URL参数
$queryData = $request->validate([
'signature' => 'required|string',
'timestamp' => 'required|integer',
'nonce' => 'required|integer',
'openid' => 'required|string',
]);
// 获取xml包体参数
$xmlData = $request->getContent();
// 处理回调
$result = $this->weChatTestService->offMsgCallback($queryData,$xmlData);
// 返回XML数据
return ApiResponse::xml_success($result);
}

控制器返回xml文本数据的封装方法

/**
* 返回xml文本
*/
public static function xml_success(string $xmlText)
{
return response($xmlText)->header('Content-Type', 'text/xml');
}

接收到的文本xml包体示例:

<xml>
// 开发者微信号
<ToUserName><![CDATA[toUser]]></ToUserName>

// 发送方账号(一个OpenID)
<FromUserName><![CDATA[fromUser]]></FromUserName>

// 消息创建时间 (整型)
<CreateTime>1348831860</CreateTime>

// 消息类型,文本为text
<MsgType><![CDATA[text]]></MsgType>

// 文本消息内容
<Content><![CDATA[this is a test]]></Content>

// 消息id,64位整型
<MsgId>1234567890123456</MsgId>

// 消息的数据ID(消息如果来自文章时才有)
<MsgDataId>xxxx</MsgDataId>

// 多图文时第几篇文章,从1开始(消息如果来自文章时才有)
<Idx>xxxx</Idx>
</xml>

第二步:处理XML文本数据

一般我们接收到的参数都是转化为数组数据的,所以这里我们要把接收到的xml回调文本处理成array数据,然后再进行自己的业务处理

Service 服务层

/**
* 公众号信息回调,测试公众号的数据是明文的
*/
public function offMsgCallback(array $queryData, string $xmlText): string
{
// 验证签名
$signature = WeChat::offSignature($this->offToken, $queryData['timestamp'], $queryData['nonce']);
if ($queryData['signature'] !== $signature) {
abort(400, '签名错误');
}

// 转化为array
$xmlData = WeChat::offExtract($xmlText);

// 自己的业务处理...

// 返回的xml文本数据
$xml = "这里根据自己的情况返回适应的xml文本数据";

return $xml;
}

转化代码示例如下:

/**
* 将xml文本转化为array
*
* @param string $xmlText xml文本
*
* @return array
*/
public static function offExtract(string $xmlText): array
{
$simpleXml = simplexml_load_string($xmlText, 'SimpleXMLElement', LIBXML_NOCDATA);

return Utils::jsonDecode(Utils::jsonEncode($simpleXml), true);
}

第三步:返回XML文本数据(被动回复用户)

注意:在接收到回调的时候,如果要回复用户的消息,需要在5秒内回复

可回复用户多种类型的数据,具体参数可查看公众号文档: https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html

下面是一个回复用户文本消息的xml示例:

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>