Browse Source

doc:增加微信集成方案文档

Yin Bin 4 months ago
parent
commit
139eb19b66
1 changed files with 943 additions and 0 deletions
  1. 943 0
      doc/系统设计/系统架构/微信集成解决方案.md

+ 943 - 0
doc/系统设计/系统架构/微信集成解决方案.md

@@ -0,0 +1,943 @@
+# 微信集成解决方案(PHP版)
+
+## 一、环境准备
+
+### 安装微信SDK
+```bash
+# 安装EasyWeChat SDK
+composer require w7corp/easywechat:~6.0
+```
+
+## 二、基础配置
+
+### 2.1 微信公众号配置
+```php
+// config/wechat.php
+return [
+    'official_account' => [
+        'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', ''),
+        'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', ''),
+        'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', ''),
+        'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''),
+    ],
+    'redis' => [
+        'host' => env('REDIS_HOST', '127.0.0.1'),
+        'password' => env('REDIS_PASSWORD', null),
+        'port' => env('REDIS_PORT', 6379),
+        'database' => 0,
+    ],
+];
+```
+
+### 2.2 环境变量配置
+```env
+# .env
+WECHAT_OFFICIAL_ACCOUNT_APPID=your_appid
+WECHAT_OFFICIAL_ACCOUNT_SECRET=your_secret
+WECHAT_OFFICIAL_ACCOUNT_TOKEN=your_token
+WECHAT_OFFICIAL_ACCOUNT_AES_KEY=your_aes_key
+```
+
+## 三、微信通知系统实现
+
+### 3.1 消息模板定义
+```php
+// app/Constants/WxTemplateConstants.php
+<?php
+
+namespace App\Constants;
+
+class WxTemplateConstants
+{
+    // 会员用户模板
+    const MEMBER_APPOINTMENT_REMINDER = [
+        'template_id' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+        'title' => '预约提醒',
+        'data' => [
+            'first' => '您有新的预约提醒',
+            'keyword1' => '预约项目',
+            'keyword2' => '预约时间',
+            'keyword3' => '预约地点',
+            'remark' => '请准时到达'
+        ]
+    ];
+
+    // 技师模板
+    const TECHNICIAN_NEW_ORDER = [
+        'template_id' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+        'title' => '新订单通知',
+        'data' => [
+            'first' => '您有新的订单',
+            'keyword1' => '订单编号',
+            'keyword2' => '服务项目',
+            'keyword3' => '预约时间',
+            'remark' => '请及时确认'
+        ]
+    ];
+}
+```
+
+### 3.2 通知服务实现
+```php
+// app/Services/WxNotificationService.php
+<?php
+
+namespace App\Services;
+
+use EasyWeChat\Factory;
+use App\Constants\WxTemplateConstants;
+
+class WxNotificationService
+{
+    private $app;
+
+    public function __construct()
+    {
+        $this->app = Factory::officialAccount(config('wechat.official_account'));
+    }
+
+    /**
+     * 发送会员预约提醒
+     */
+    public function sendMemberAppointmentReminder($openId, $data)
+    {
+        $template = WxTemplateConstants::MEMBER_APPOINTMENT_REMINDER;
+        return $this->sendTemplate($openId, $template['template_id'], [
+            'first' => ['value' => $template['data']['first']],
+            'keyword1' => ['value' => $data['service_name']],
+            'keyword2' => ['value' => $data['appointment_time']],
+            'keyword3' => ['value' => $data['location']],
+            'remark' => ['value' => $template['data']['remark']]
+        ]);
+    }
+
+    /**
+     * 发送技师新订单通知
+     */
+    public function sendTechnicianNewOrder($openId, $data)
+    {
+        $template = WxTemplateConstants::TECHNICIAN_NEW_ORDER;
+        return $this->sendTemplate($openId, $template['template_id'], [
+            'first' => ['value' => $template['data']['first']],
+            'keyword1' => ['value' => $data['order_no']],
+            'keyword2' => ['value' => $data['service_name']],
+            'keyword3' => ['value' => $data['appointment_time']],
+            'remark' => ['value' => $template['data']['remark']]
+        ]);
+    }
+
+    /**
+     * 发送模板消息
+     */
+    private function sendTemplate($openId, $templateId, $data)
+    {
+        try {
+            $result = $this->app->template_message->send([
+                'touser' => $openId,
+                'template_id' => $templateId,
+                'data' => $data
+            ]);
+
+            // 记录日志
+            \Log::info('WxNotification', [
+                'openId' => $openId,
+                'templateId' => $templateId,
+                'data' => $data,
+                'result' => $result
+            ]);
+
+            return $result;
+        } catch (\Exception $e) {
+            \Log::error('WxNotification Error', [
+                'message' => $e->getMessage(),
+                'openId' => $openId,
+                'templateId' => $templateId
+            ]);
+            throw $e;
+        }
+    }
+}
+```
+
+### 3.3 队列处理
+```php
+// app/Jobs/SendWxNotificationJob.php
+<?php
+
+namespace App\Jobs;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use App\Services\WxNotificationService;
+
+class SendWxNotificationJob implements ShouldQueue
+{
+    use InteractsWithQueue, Queueable, SerializesModels;
+
+    private $openId;
+    private $type;
+    private $data;
+
+    public function __construct($openId, $type, $data)
+    {
+        $this->openId = $openId;
+        $this->type = $type;
+        $this->data = $data;
+    }
+
+    public function handle(WxNotificationService $service)
+    {
+        try {
+            switch ($this->type) {
+                case 'member_appointment':
+                    $service->sendMemberAppointmentReminder($this->openId, $this->data);
+                    break;
+                case 'technician_order':
+                    $service->sendTechnicianNewOrder($this->openId, $this->data);
+                    break;
+            }
+        } catch (\Exception $e) {
+            // 失败重试
+            if ($this->attempts() < 3) {
+                $this->release(30);
+            }
+        }
+    }
+}
+```
+
+### 3.4 使用示例
+```php
+// 在业务代码中使用
+use App\Jobs\SendWxNotificationJob;
+
+// 发送会员预约提醒
+dispatch(new SendWxNotificationJob($openId, 'member_appointment', [
+    'service_name' => '全身按摩',
+    'appointment_time' => '2024-01-20 14:30',
+    'location' => 'xxx店'
+]));
+
+// 发送技师新订单通知
+dispatch(new SendWxNotificationJob($openId, 'technician_order', [
+    'order_no' => 'ORDER2024011001',
+    'service_name' => '全身按摩',
+    'appointment_time' => '2024-01-20 14:30'
+]));
+```
+
+## 四、错误处理与监控
+
+### 4.1 异常处理
+```php
+// app/Exceptions/WxNotificationException.php
+<?php
+
+namespace App\Exceptions;
+
+class WxNotificationException extends \Exception
+{
+    protected $data;
+
+    public function __construct($message, $data = [])
+    {
+        parent::__construct($message);
+        $this->data = $data;
+    }
+
+    public function getData()
+    {
+        return $this->data;
+    }
+}
+```
+
+### 4.2 监控实现
+```php
+// app/Services/WxMonitorService.php
+<?php
+
+namespace App\Services;
+
+use Illuminate\Support\Facades\Redis;
+
+class WxMonitorService
+{
+    /**
+     * 记录发送统计
+     */
+    public function recordSendStats($type, $success = true)
+    {
+        $date = date('Y-m-d');
+        $key = "wx:stats:{$date}:{$type}";
+
+        Redis::hincrby($key, $success ? 'success' : 'fail', 1);
+        Redis::expire($key, 86400 * 7); // 保存7天
+    }
+
+    /**
+     * 获取发送统计
+     */
+    public function getSendStats($type, $date = null)
+    {
+        $date = $date ?: date('Y-m-d');
+        $key = "wx:stats:{$date}:{$type}";
+
+        $stats = Redis::hgetall($key);
+        $total = array_sum($stats);
+
+        return [
+            'total' => $total,
+            'success' => (int)($stats['success'] ?? 0),
+            'fail' => (int)($stats['fail'] ?? 0),
+            'success_rate' => $total > 0 ? round($stats['success'] / $total * 100, 2) : 0
+        ];
+    }
+}
+```
+
+## 五、配置说明
+
+### 5.1 微信公众平台配置
+1. 登录微信公众平台
+2. 获取开发者ID(AppID)和开发者密码(AppSecret)
+3. 设置服务器配置
+4. 配置消息模板
+
+### 5.2 注意事项
+1. 所有配置信息应该放在环境变量中
+2. 定期检查access_token的有效性
+3. 做好日志记录和异常处理
+4. 考虑消息发送的频率限制
+
+## 六、微信公众号登录系统
+
+### 6.1 数据库设计
+```sql
+-- 微信用户表
+CREATE TABLE `wx_users` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `openid` varchar(64) NOT NULL COMMENT '微信openid',
+  `unionid` varchar(64) DEFAULT NULL COMMENT '微信unionid',
+  `nickname` varchar(50) DEFAULT NULL COMMENT '微信昵称',
+  `avatar` varchar(255) DEFAULT NULL COMMENT '头像',
+  `user_id` bigint(20) DEFAULT NULL COMMENT '关联用户ID',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_openid` (`openid`),
+  KEY `idx_user_id` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信用户表';
+```
+
+### 6.2 前端实现
+```javascript
+// resources/js/wechat-auth.js
+
+// 获取微信授权URL
+function getWxAuthUrl() {
+    const redirectUri = encodeURIComponent(window.location.origin + '/wechat/callback');
+    const appId = process.env.MIX_WECHAT_APPID;
+    return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`;
+}
+
+// 检查是否在微信浏览器中
+function isWechatBrowser() {
+    const ua = navigator.userAgent.toLowerCase();
+    return ua.indexOf('micromessenger') !== -1;
+}
+
+// 微信登录处理
+function handleWechatLogin() {
+    if (isWechatBrowser()) {
+        // 检查是否已有token
+        const token = localStorage.getItem('token');
+        if (!token) {
+            // 跳转到微信授权页面
+            window.location.href = getWxAuthUrl();
+        }
+    }
+}
+```
+
+### 6.3 后端实现
+
+#### 6.3.1 路由配置
+```php
+// routes/web.php
+Route::prefix('wechat')->group(function () {
+    Route::get('/auth', 'WechatAuthController@auth');
+    Route::get('/callback', 'WechatAuthController@callback');
+});
+```
+
+#### 6.3.2 控制器实现
+```php
+// app/Http/Controllers/WechatAuthController.php
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\WechatAuthService;
+use Illuminate\Http\Request;
+
+class WechatAuthController extends Controller
+{
+    protected $wechatAuthService;
+
+    public function __construct(WechatAuthService $wechatAuthService)
+    {
+        $this->wechatAuthService = $wechatAuthService;
+    }
+
+    /**
+     * 发起微信授权
+     */
+    public function auth()
+    {
+        $redirectUrl = url('/wechat/callback');
+        return $this->wechatAuthService->getAuthUrl($redirectUrl);
+    }
+
+    /**
+     * 处理微信回调
+     */
+    public function callback(Request $request)
+    {
+        try {
+            $code = $request->input('code');
+            if (empty($code)) {
+                throw new \Exception('授权失败');
+            }
+
+            // 处理微信授权
+            $result = $this->wechatAuthService->handleCallback($code);
+
+            // 返回token给前端
+            return view('wechat.callback', ['token' => $result['token']]);
+        } catch (\Exception $e) {
+            \Log::error('WechatAuth Error', ['message' => $e->getMessage()]);
+            return response()->json(['message' => '授权失败'], 400);
+        }
+    }
+}
+```
+
+#### 6.3.3 服务层实现
+```php
+// app/Services/WechatAuthService.php
+<?php
+
+namespace App\Services;
+
+use App\Models\WxUser;
+use App\Models\User;
+use EasyWeChat\Factory;
+use Illuminate\Support\Str;
+
+class WechatAuthService
+{
+    protected $app;
+
+    public function __construct()
+    {
+        $this->app = Factory::officialAccount(config('wechat.official_account'));
+    }
+
+    /**
+     * 获取授权URL
+     */
+    public function getAuthUrl($redirectUrl)
+    {
+        $response = $this->app->oauth->scopes(['snsapi_userinfo'])
+            ->redirect($redirectUrl);
+        return $response;
+    }
+
+    /**
+     * 处理微信回调
+     */
+    public function handleCallback($code)
+    {
+        try {
+            // 获取OAuth用户信息
+            $user = $this->app->oauth->user();
+            $original = $user->getOriginal();
+
+            // 查找或创建微信用户
+            $wxUser = WxUser::firstOrCreate(
+                ['openid' => $original['openid']],
+                [
+                    'unionid' => $original['unionid'] ?? null,
+                    'nickname' => $original['nickname'],
+                    'avatar' => $original['headimgurl']
+                ]
+            );
+
+            // 关联或创建系统用户
+            $systemUser = $this->findOrCreateSystemUser($wxUser, $original);
+
+            // 生成token
+            $token = $this->generateToken($systemUser);
+
+            return [
+                'token' => $token,
+                'user' => $systemUser
+            ];
+        } catch (\Exception $e) {
+            \Log::error('WechatAuth Callback Error', [
+                'code' => $code,
+                'message' => $e->getMessage()
+            ]);
+            throw $e;
+        }
+    }
+
+    /**
+     * 查找或创建系统用户
+     */
+    private function findOrCreateSystemUser($wxUser, $wxInfo)
+    {
+        if ($wxUser->user_id) {
+            return User::find($wxUser->user_id);
+        }
+
+        // 创建新用户
+        $user = User::create([
+            'name' => $wxInfo['nickname'],
+            'avatar' => $wxInfo['headimgurl'],
+            'password' => bcrypt(Str::random(16))
+        ]);
+
+        // 关联微信用户
+        $wxUser->update(['user_id' => $user->id]);
+
+        return $user;
+    }
+
+    /**
+     * 生成JWT Token
+     */
+    private function generateToken($user)
+    {
+        return auth()->login($user);
+    }
+}
+```
+
+#### 6.3.4 回调页面实现
+```php
+// resources/views/wechat/callback.blade.php
+<!DOCTYPE html>
+<html>
+<head>
+    <title>微信授权回调</title>
+</head>
+<body>
+    <script>
+        // 存储token
+        localStorage.setItem('token', '{{ $token }}');
+
+        // 关闭当前页面,回到来源页
+        if (window.opener) {
+            window.opener.postMessage({ type: 'wechat_auth_success', token: '{{ $token }}' }, '*');
+            window.close();
+        } else {
+            window.location.href = '/'; // 或者跳转到指定页面
+        }
+    </script>
+</body>
+</html>
+```
+
+### 6.4 使用说明
+
+#### 6.4.1 前端集成
+```javascript
+// 在应用入口检查微信登录状态
+document.addEventListener('DOMContentLoaded', () => {
+    handleWechatLogin();
+});
+
+// 监听登录成功消息
+window.addEventListener('message', (event) => {
+    if (event.data.type === 'wechat_auth_success') {
+        // 存储token
+        localStorage.setItem('token', event.data.token);
+        // 刷新页面或更新状态
+        window.location.reload();
+    }
+});
+```
+
+#### 6.4.2 接口调用示例
+```php
+// 在需要微信登录的接口中添加中间件
+Route::middleware(['auth:api', 'wechat.auth'])->group(function () {
+    // 需要微信登录的路由
+});
+```
+
+### 6.5 安全考虑
+
+1. **Token安全**
+   - 使用HTTPS传输
+   - 设置合理的token过期时间
+   - 实现token刷新机制
+
+2. **数据安全**
+   - 用户信息加密存储
+   - 敏感信息脱敏处理
+   - 定期清理过期token
+
+3. **防护措施**
+   - 实现防重放攻击
+   - 添加请求频率限制
+   - 记录异常登录行为
+
+### 6.6 注意事项
+
+1. 确保微信公众号已获得网页授权能力
+2. 在微信公众平台正确配置授权回调域名
+3. 处理用户取消授权的情况
+4. 实现用户解绑功能
+5. 考虑多设备登录策略
+
+## 七、微信公众号支付集成
+
+### 7.1 数据库设计
+```sql
+-- 支付订单表
+CREATE TABLE `wx_payment_orders` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `order_no` varchar(64) NOT NULL COMMENT '商户订单号',
+  `transaction_id` varchar(64) DEFAULT NULL COMMENT '微信支付订单号',
+  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
+  `openid` varchar(64) NOT NULL COMMENT '用户openid',
+  `amount` int(11) NOT NULL COMMENT '支付金额(分)',
+  `description` varchar(128) NOT NULL COMMENT '商品描述',
+  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '支付状态:0未支付 1支付中 2已支付 3已退款 4已关闭',
+  `pay_time` datetime DEFAULT NULL COMMENT '支付时间',
+  `notify_data` text COMMENT '回调原始数据',
+  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uk_order_no` (`order_no`),
+  KEY `idx_user_id` (`user_id`),
+  KEY `idx_status` (`status`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信支付订单表';
+```
+
+### 7.2 配置文件
+```php
+// config/wechat.php
+return [
+    // ... 其他配置 ...
+
+    'payment' => [
+        'default' => [
+            'app_id' => env('WECHAT_PAYMENT_APPID', ''),
+            'mch_id' => env('WECHAT_PAYMENT_MCH_ID', ''),
+            'key' => env('WECHAT_PAYMENT_KEY', ''),
+            'cert_path' => storage_path('app/wechat/cert/apiclient_cert.pem'),
+            'key_path' => storage_path('app/wechat/cert/apiclient_key.pem'),
+            'notify_url' => env('WECHAT_PAYMENT_NOTIFY_URL', ''),
+        ],
+    ],
+];
+```
+
+### 7.3 支付服务实现
+
+#### 7.3.1 支付服务类
+```php
+// app/Services/WxPaymentService.php
+<?php
+
+namespace App\Services;
+
+use App\Models\WxPaymentOrder;
+use EasyWeChat\Factory;
+use Illuminate\Support\Str;
+
+class WxPaymentService
+{
+    protected $payment;
+
+    public function __construct()
+    {
+        $this->payment = Factory::payment(config('wechat.payment.default'));
+    }
+
+    /**
+     * 创建支付订单
+     */
+    public function createOrder($userId, $openid, $amount, $description)
+    {
+        // 创建商户订单号
+        $orderNo = date('YmdHis') . Str::random(6);
+
+        // 创建订单记录
+        $order = WxPaymentOrder::create([
+            'order_no' => $orderNo,
+            'user_id' => $userId,
+            'openid' => $openid,
+            'amount' => $amount,
+            'description' => $description,
+            'status' => 0
+        ]);
+
+        // 调用微信统一下单
+        $result = $this->payment->order->unify([
+            'body' => $description,
+            'out_trade_no' => $orderNo,
+            'total_fee' => $amount,
+            'trade_type' => 'JSAPI',
+            'openid' => $openid,
+        ]);
+
+        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
+            // 更新订单状态
+            $order->update(['status' => 1]);
+
+            // 生成支付参数
+            $params = $this->payment->jssdk->bridgeConfig($result['prepay_id']);
+
+            return [
+                'order_no' => $orderNo,
+                'params' => $params
+            ];
+        }
+
+        throw new \Exception($result['err_code_des'] ?? '创建支付订单失败');
+    }
+
+    /**
+     * 处理支付回调
+     */
+    public function handlePaymentNotify($message)
+    {
+        // 查找订单
+        $order = WxPaymentOrder::where('order_no', $message['out_trade_no'])->first();
+        if (!$order) {
+            return false;
+        }
+
+        // 验证支付金额
+        if ($message['total_fee'] != $order->amount) {
+            return false;
+        }
+
+        // 更新订单状态
+        $order->update([
+            'status' => 2,
+            'transaction_id' => $message['transaction_id'],
+            'pay_time' => date('Y-m-d H:i:s'),
+            'notify_data' => json_encode($message)
+        ]);
+
+        // 触发支付成功事件
+        event(new PaymentSuccessEvent($order));
+
+        return true;
+    }
+
+    /**
+     * 查询订单状态
+     */
+    public function queryOrder($orderNo)
+    {
+        $result = $this->payment->order->queryByOutTradeNumber($orderNo);
+
+        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
+            return [
+                'paid' => $result['trade_state'] === 'SUCCESS',
+                'transaction_id' => $result['transaction_id'] ?? null,
+                'trade_state' => $result['trade_state'],
+                'trade_state_desc' => $result['trade_state_desc']
+            ];
+        }
+
+        return false;
+    }
+
+    /**
+     * 申请退款
+     */
+    public function refund($orderNo, $refundAmount, $reason = '')
+    {
+        $order = WxPaymentOrder::where('order_no', $orderNo)->first();
+        if (!$order || $order->status != 2) {
+            throw new \Exception('订单状态不正确');
+        }
+
+        $result = $this->payment->refund->byOutTradeNumber($orderNo, date('YmdHis') . Str::random(6), $order->amount, $refundAmount, [
+            'refund_desc' => $reason
+        ]);
+
+        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
+            // 更新订单状态
+            $order->update(['status' => 3]);
+            return true;
+        }
+
+        throw new \Exception($result['err_code_des'] ?? '申请退款失败');
+    }
+}
+```
+
+### 7.4 控制器实现
+
+```php
+// app/Http/Controllers/WxPaymentController.php
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Services\WxPaymentService;
+use Illuminate\Http\Request;
+
+class WxPaymentController extends Controller
+{
+    protected $paymentService;
+
+    public function __construct(WxPaymentService $paymentService)
+    {
+        $this->paymentService = $paymentService;
+    }
+
+    /**
+     * 创建支付订单
+     */
+    public function createOrder(Request $request)
+    {
+        $this->validate($request, [
+            'amount' => 'required|integer|min:1',
+            'description' => 'required|string|max:127'
+        ]);
+
+        try {
+            $result = $this->paymentService->createOrder(
+                auth()->id(),
+                $request->user()->wx_user->openid,
+                $request->input('amount'),
+                $request->input('description')
+            );
+
+            return response()->json($result);
+        } catch (\Exception $e) {
+            return response()->json(['message' => $e->getMessage()], 400);
+        }
+    }
+
+    /**
+     * 支付回调
+     */
+    public function notify()
+    {
+        $response = $this->paymentService->payment->handlePaidNotify(function($message, $fail) {
+            $result = $this->paymentService->handlePaymentNotify($message);
+            return $result ? true : $fail('处理失败');
+        });
+
+        return $response;
+    }
+
+    /**
+     * 查询订单
+     */
+    public function query(Request $request)
+    {
+        $orderNo = $request->input('order_no');
+        $result = $this->paymentService->queryOrder($orderNo);
+
+        return response()->json($result ?: ['message' => '查询失败'], $result ? 200 : 400);
+    }
+}
+```
+
+### 7.5 路由配置
+```php
+// routes/api.php
+Route::prefix('payment')->middleware(['auth:api'])->group(function () {
+    Route::post('order', 'WxPaymentController@createOrder');
+    Route::get('query', 'WxPaymentController@query');
+});
+
+// routes/web.php
+Route::any('payment/notify', 'WxPaymentController@notify');
+```
+
+### 7.6 前端调用示例
+```javascript
+// 发起支付
+async function wxPay(amount, description) {
+    try {
+        // 1. 创建订单
+        const response = await axios.post('/api/payment/order', {
+            amount,
+            description
+        });
+
+        // 2. 调起支付
+        const params = response.data.params;
+        WeixinJSBridge.invoke('getBrandWCPayRequest', params, function(res) {
+            if (res.err_msg === 'get_brand_wcpay_request:ok') {
+                // 支付成功
+                alert('支付成功');
+            } else {
+                // 支付失败
+                alert('支付失败:' + res.err_msg);
+            }
+        });
+    } catch (error) {
+        console.error('支付失败', error);
+        alert('创建订单失败');
+    }
+}
+
+// 查询订单状态
+async function queryOrder(orderNo) {
+    try {
+        const response = await axios.get('/api/payment/query', {
+            params: { order_no: orderNo }
+        });
+        return response.data;
+    } catch (error) {
+        console.error('查询订单失败', error);
+        return null;
+    }
+}
+```
+
+### 7.7 安全考虑
+
+1. **支付安全**
+   - 必须使用HTTPS
+   - 验证签名
+   - 校验订单金额
+   - 防止重复支付
+   - 敏感信息加密存储
+
+2. **证书管理**
+   - 安全存储证书文件
+   - 定期更新证书
+   - 限制证书文件访问权限
+
+3. **异常处理**
+   - 处理网络超时
+   - 处理重复通知
+   - 记录详细日志
+
+### 7.8 注意事项
+
+1. 确保微信支付商户号已开通
+2. 正确配置支付回调域名
+3. 处理订单超时
+4. 实现订单关闭功能
+5. 考虑并发支付情况
+6. 实现退款功能
+7. 做好金额计算(避免浮点数精度问题)
+8. 定期对账