PHP code example of yoolo-mine / wecom-crypto

1. Go to this page and download the library: Download yoolo-mine/wecom-crypto library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

yoolo-mine / wecom-crypto example snippets


use YooloMine\WecomCrypto\WXBizMsgCrypt;

$wxcpt = new WXBizMsgCrypt(
    config('wecom_crypto.token'),
    config('wecom_crypto.encodingAesKey'),
    'different_receive_id_for_this_app'
);

'providers' => [
    // ...
    YooloMine\WecomCrypto\Providers\WecomCryptoServiceProvider::class,
],

use YooloMine\WecomCrypto\CallBack\ErrorCode;

// 解析单例(使用 .env 或 config/wecom_crypto.php 中的配置)
$wxcpt = app('wxcrypt');

$result = $wxcpt->VerifyURL(
    $request->query('msg_signature'),
    $request->query('timestamp'),
    $request->query('nonce'),
    $request->query('echostr')
);

if ($result === ErrorCode::IllegalAesKey) {
    // EncodingAESKey 长度不是 43
}
if ($result === ErrorCode::ValidateSignatureError) {
    // 签名校验失败
}
if (is_int($result) && $result < 0) {
    // 其他错误码,见下方「错误码」
}

// 成功:$result 为解密后的明文字符串,直接返回给企业微信
return response($result);

$sMsg = '';
$errCode = $wxcpt->DecryptMsg(
    $request->query('msg_signature'),
    $request->query('timestamp'),
    $request->query('nonce'),
    $request->getContent(),
    $sMsg
);

if ($errCode !== ErrorCode::OK) {
    // 根据错误码处理,见下方「错误码」
    return response()->json(['error' => $errCode], 400);
}

// $sMsg 为解密后的 XML 字符串
$xml = simplexml_load_string($sMsg);
// 后续业务逻辑...

$sEncryptMsg = '';
$errCode = $wxcpt->EncryptMsg(
    $replyXmlString,      // 要回复的 XML 明文
    $request->query('timestamp'),
    $request->query('nonce'),
    $sEncryptMsg
);

if ($errCode !== ErrorCode::OK) {
    return response()->json(['error' => $errCode], 500);
}

// $sEncryptMsg 为加密后的完整 XML,可直接返回
return response($sEncryptMsg)->header('Content-Type', 'text/xml');

use YooloMine\WecomCrypto\WXBizMsgCrypt;

$wxcpt = new WXBizMsgCrypt(
    'your_token',
    'your_encoding_aes_key_43_chars',
    'your_corp_id_or_receive_id'
);
// 之后调用 VerifyURL、DecryptMsg、EncryptMsg 同上

use App\Http\Controllers\WecomCallbackController;

// 企业微信应用回调:GET 用于校验 URL,POST 用于接收消息
Route::match(['get', 'post'], 'wecom/callback', [WecomCallbackController::class, 'handle'])
    ->name('wecom.callback');

protected $except = [
    'wecom/callback',
];



namespace App\Http\Controllers;

use Illuminate\Http\Request;
use YooloMine\WecomCrypto\CallBack\ErrorCode;

class WecomCallbackController extends Controller
{
    /**
     * 企业微信回调入口:GET 校验 URL,POST 接收加密消息
     */
    public function handle(Request $request)
    {
        $wxcpt = app('wxcrypt');

        if ($request->isMethod('get')) {
            return $this->verifyUrl($request, $wxcpt);
        }

        return $this->receiveMessage($request, $wxcpt);
    }

    /**
     * 验证回调 URL(企业微信后台配置 URL 时触发)
     */
    protected function verifyUrl(Request $request, $wxcpt)
    {
        $result = $wxcpt->VerifyURL(
            $request->query('msg_signature'),
            $request->query('timestamp'),
            $request->query('nonce'),
            $request->query('echostr')
        );

        if (is_int($result) && $result !== 0) {
            return response('', 400);
        }

        return response($result);
    }

    /**
     * 接收企业微信 POST 的加密消息,解密后处理
     */
    protected function receiveMessage(Request $request, $wxcpt)
    {
        $sMsg = '';
        $errCode = $wxcpt->DecryptMsg(
            $request->query('msg_signature'),
            $request->query('timestamp'),
            $request->query('nonce'),
            $request->getContent(),
            $sMsg
        );

        if ($errCode !== ErrorCode::OK) {
            return response()->json(['errcode' => $errCode], 400);
        }

        $xml = simplexml_load_string($sMsg);
        if ($xml === false) {
            return response()->json(['errcode' => -1, 'errmsg' => 'invalid xml'], 400);
        }

        // 根据 MsgType 等字段处理业务(文本、事件等)
        $msgType = (string) ($xml->MsgType ?? '');
        switch ($msgType) {
            case 'text':
                $content = (string) ($xml->Content ?? '');
                // 可选:构造回复 XML 后调用 EncryptMsg 再返回
                return $this->replyText($request, $wxcpt, $xml, $content);
            case 'event':
                return $this->handleEvent($xml);
            default:
                return response('');
        }
    }

    protected function replyText(Request $request, $wxcpt, $xml, string $content)
    {
        $from = (string) ($xml->FromUserName ?? '');
        $to   = (string) ($xml->ToUserName ?? '');
        $createTime = time();

        $replyXml = sprintf(
            '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>',
            $from,
            $to,
            $createTime,
            htmlspecialchars('收到:' . $content)
        );

        $sEncryptMsg = '';
        $errCode = $wxcpt->EncryptMsg(
            $replyXml,
            $request->query('timestamp'),
            $request->query('nonce'),
            $sEncryptMsg
        );

        if ($errCode !== ErrorCode::OK) {
            return response()->json(['errcode' => $errCode], 500);
        }

        return response($sEncryptMsg)->header('Content-Type', 'text/xml; charset=UTF-8');
    }

    protected function handleEvent($xml)
    {
        $event = (string) ($xml->Event ?? '');
        // 处理订阅、点击等事件
        return response('');
    }
}
bash
php artisan vendor:publish --tag=wecom-crypto-config