1635725673, 'app_id' => 'wx6e14cb98394e36bc', // 商户证书 'private_key' => config_path() .'certs/apiclient_key.pem', 'certificate' => config_path() .'certs/apiclient_cert.pem', // v3 API 秘钥 // 'secret_key' => '43A03299A3C3FED3D8CE7B820Fxxxxx', // v2 API 秘钥 'v2_secret_key' => '95d195Dcf6ec66156dfeeb4E7435faef', // 平台证书:微信支付 APIv3 平台证书,需要使用工具下载 // 下载工具:https://github.com/wechatpay-apiv3/CertificateDownloader // 'platform_certs' => [ // // '/path/to/wechatpay/cert.pem', // ], /** * 接口请求相关配置,超时时间等,具体可用参数请参考: * https://github.com/symfony/symfony/blob/5.3/src/Symfony/Contracts/HttpClient/HttpClientInterface.php */ 'http' => [ 'throw' => true, // 状态码非 200、300 时是否抛出异常,默认为开启 'timeout' => 5.0, // 'base_uri' => 'https://api.mch.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri ], ]; $app= new Application($config); $server = $app->getServer(); $server->handlePaid(function (Message $message, \Closure $next) { Log::error($message); // $message->out_trade_no 获取商户订单号 // $message->payer['openid'] 获取支付者 openid // 🚨🚨🚨 注意:推送信息不一定靠谱哈,请务必验证 // 建议是拿订单号调用微信支付查询接口,以查询到的订单状态为准 return $next($message); }); // 默认返回 ['code' => 'SUCCESS', 'message' => '成功'] return $server->serve(); } // 接收微信支付状态的通知 商城后台采购商品回调 public function notify() { // 配置信息 $config = [ 'app_id' => 'wx0b3defb62f0f910b',//注意这个APPID只能是公众号的id,没有的话要去申请,并且在微信支付平台里绑定 'mch_id' => '1635725673',//商户号 'key' => '95d195Dcf6ec66156dfeeb4E7435faef',//支付秘钥 'secret' => 'c02aa7ad9e4a5c423862e068b6cb4ad4', 'notify_url' => Request::instance()->domain().'/api/PayNotify/notify',//异步回调通知地址 ]; // 这个就是 easywechat 封装的了, 一行代码搞定, 照着写就行了 $app = Factory::payment($config); // 用 easywechat 封装的方法接收微信的信息, 根据 $message 的内容进行处理, 之后要告知微信服务器处理好了, 否则微信会一直请求这个 url, 发送信息 $response = $app->handlePaidNotify(function($message, $fail){ // 首先查看 order 表, 如果 order 表有记录, 表示已经支付过了 $order = Db::table('cms_store_product_order')->where('order_sn', $message['out_trade_no'])->find(); if ($order) { return true; // 如果已经生成订单, 表示已经处理完了, 告诉微信不用再通知了 } // 查看支付日志 $payLog = Db::table('cms_store_product_paylog')->where('out_trade_no', $message['out_trade_no'])->find(); if (!$payLog || $payLog['time_end']) { // 如果订单不存在 或者 订单已经支付过了 return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 } // 更新支付时间为当前时间 $paid_at = time(); // return_code 表示通信状态,不代表支付状态 if ($message['return_code'] === 'SUCCESS') { // 用户是否支付成功 if ($message['result_code'] === 'SUCCESS') { $post_id = $payLog['product_id']; // 创建订单记录 $order_arr = [ 'order_sn' => $message['out_trade_no'], 'total_fee' => bcdiv($message['total_fee'],'100',2), 'pay_log_id' => $payLog['id'], 'status' => 1, 'admin_id' => $payLog['admin_id'], 'paid_at' => $paid_at, 'product_id' => $post_id, 'number' => $payLog['number'], 'cart_id' => $payLog['cart_id'], ]; Db::table('cms_store_product_order')->strict(false)->field(true)->insert($order_arr); // 更新 PayLog, 这里的字段都是根据微信支付结果通知的字段设置的(https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8) $pay_log = [ 'appid' => $message['appid'], 'bank_type' => $message['bank_type'], 'total_fee' => $message['total_fee'], 'trade_type' => $message['trade_type'], 'is_subscribe' => $message['is_subscribe'], 'mch_id' => $message['mch_id'], 'nonce_str' => $message['nonce_str'], 'openid' => $message['openid'], 'sign' => $message['sign'], 'cash_fee' => $message['cash_fee'], 'fee_type' => $message['fee_type'], 'transaction_id' => $message['transaction_id'], 'time_end' => $paid_at, 'result_code' => $message['result_code'], 'return_code' => $message['return_code'], ]; Db::table('cms_store_product_paylog')->where('out_trade_no', $message['out_trade_no'])->update($pay_log); // 写入商户余额表 if($payLog['cart_id']){ //购物车 $time = time(); if(strpos($payLog['cart_id'],',')){ $cart_ids = explode(',',$payLog['cart_id']); foreach ($cart_ids as $k=>$v){ // 根据 id 查出价格 $where['cart_id'] = $v; $cart = Db::table('cms_store_cart')->where($where)->lock(true)->find(); if (empty($cart)) { continue; } // 根据商品id获取商户admin_id $wwww['product_id'] = $cart['product_id']; $store_product = Db::table('cms_store_product')->where($wwww)->lock(true)->find(); if (empty($store_product)) { continue; } // 更新购物车 $c_data['is_pay'] = 1; Db::table('cms_store_cart')->where($where)->update($c_data); // 减库存 Db::table('cms_store_product')->where('product_id', $cart['product_id'])->dec('stock',$cart['cart_num'])->update(); // 写入后台余额表 $is_money = Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->lock(true)->find(); if($is_money){ $total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']); Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->inc('money',$total_fee)->update(); }else{ $total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']); $m_data['admin_id'] = $store_product['admin_id']; $m_data['money'] = $total_fee; Db::table('cms_admin_money')->insert($m_data); } //写入后台余额记录表 $log_arr['type'] = 0; $log_arr['admin_id'] = $store_product['admin_id']; $log_arr['num'] = $total_fee; $log_arr['create_time'] = $time; $log_arr['status'] = 1; Db::table('cms_admin_money_log')->where('admin_id',$store_product['admin_id'])->strict(false)->field(true)->insert($log_arr); } }else{ $where['cart_id'] = $payLog['cart_id']; $cart = Db::table('cms_store_cart')->where($where)->lock(true)->find(); if ($cart) { // 根据商品id获取商户admin_id $wwww['product_id'] = $cart['product_id']; $store_product = Db::table('cms_store_product')->where($wwww)->lock(true)->find(); if ($store_product) { // 更新购物车 $c_data['is_pay'] = 1; Db::table('cms_store_cart')->where($where)->update($c_data); // 减库存 Db::table('cms_store_product')->where('product_id', $cart['product_id'])->dec('stock',$cart['cart_num'])->update(); //写入后台余额表 $is_money = Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->lock(true)->find(); if($is_money){ $total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']); Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->inc('money',$total_fee)->update(); }else{ $total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']); $m_data['admin_id'] = $store_product['admin_id']; $m_data['money'] = $total_fee; Db::table('cms_admin_money')->insert($m_data); } //写入后台余额记录表 $log_arr['type'] = 0; $log_arr['admin_id'] = $store_product['admin_id']; $log_arr['num'] = $total_fee; $log_arr['create_time'] = $time; $log_arr['status'] = 1; Db::table('cms_admin_money_log')->where('admin_id',$store_product['admin_id'])->strict(false)->field(true)->insert($log_arr); } } } }else{ // 根据商品id获取商户admin_id $www['product_id'] = $post_id; $store_product = Db::table('cms_store_product')->where($www)->find(); if (!empty($store_product)) { // 减库存 Db::table('cms_store_product')->where('product_id', $post_id)->dec('stock',$payLog['number'])->update(); //写入后台余额表 $is_money = Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->lock(true)->find(); if($is_money){ $total_fee = bcdiv($message['total_fee'],'100',2); Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->inc('money',$total_fee)->update(); }else{ $total_fee = bcdiv($message['total_fee'],'100',2); $m_data['admin_id'] = $store_product['admin_id']; $m_data['money'] = $total_fee; Db::table('cms_admin_money')->insert($m_data); } //写入后台余额记录表 $log_arr['type'] = 0; $log_arr['admin_id'] = $store_product['admin_id']; $log_arr['num'] = $total_fee; $log_arr['create_time'] = time(); $log_arr['status'] = 1; Db::table('cms_admin_money_log')->where('admin_id',$store_product['admin_id'])->strict(false)->field(true)->insert($log_arr); } } } } else { // 如果支付失败, 也更新 PayLog, 跟上面一样, 就是多了 error 信息 $pay_log = [ 'appid' => $message['appid'], 'bank_type' => $message['bank_type'], 'total_fee' => $message['total_fee'], 'trade_type' => $message['trade_type'], 'is_subscribe' => $message['is_subscribe'], 'mch_id' => $message['mch_id'], 'nonce_str' => $message['nonce_str'], 'openid' => $message['openid'], 'sign' => $message['sign'], 'cash_fee' => $message['cash_fee'], 'fee_type' => $message['fee_type'], 'transaction_id' => $message['transaction_id'], 'time_end' => $paid_at, 'result_code' => $message['result_code'], 'return_code' => $message['return_code'], 'err_code' => $message['err_code'], 'err_code_des' => $message['err_code_des'], ]; Db::table('cms_store_product_paylog')->where('out_trade_no', $message['out_trade_no'])->update($pay_log); return $fail('通信失败,请稍后再通知我'); } return true; // 返回处理完成 }); // 这里是必须这样返回的, 会发送给微信服务器处理结果 return $response; } }