route('agent_id'); $agent = Agent::find($agent_id); $config = config('wechat.payment.default'); $config = array_merge($config, [ 'app_id' => $agent->appid, 'mch_id' => $agent->mchid, 'key' => $agent->mchkey, ]); $app = Factory::payment($config); try { $response = $app->handlePaidNotify(function ($message, $fail) { // 请求成功 if ($message['return_code'] === 'SUCCESS') { //订单号带有pay_type后缀,主要是为了区分定金支付和尾款支付,前24位才是真正的订单号 $order_no = substr($message['out_trade_no'], 0, 24); $order = Order::query() ->where(['order_no' => $order_no]) ->first(); //已经处理过的订单直接返回true if ($order && in_array($order->status, [OrderStatus::PAID, OrderStatus::PAID_RETAINAGE])) { return true; } // 支付成功 if ($message['result_code'] === 'SUCCESS') { DB::beginTransaction(); try { $status = $order->status; $pay_type = $order->pay_type; //定金支付和首付款支付 if (in_array($pay_type, [1, 2])) { if ($pay_type == OrderStatus::UNPAID) { $order->status = OrderStatus::PAY_EARNEST; } else if ($status == OrderStatus::PAY_EARNEST) { $order->status = OrderStatus::PAID_RETAINAGE; } } else if ($pay_type == 0) { $order->status = OrderStatus::PAID; } $money = $message['total_fee'] / 100; $order->paid_at = time(); $order->paid_money = DB::raw('`paid_money` + ' . $money); $order->save(); //增加销量,库存在拍下时已经减了 AgentProduct::query() ->where('id', $order->agent_product_id) ->increment('sale', $order->num); Product::query() ->where('id', $order->product_id) ->increment('sale', $order->num); //资金流水 UserMoneyLog::query()->create([ 'user_id' => $order->user_id, 'agent_id' => $order->agent_id, 'money' => -$money, 'order_id' => $order->id, 'type' => 1, 'desc' => '购买产品:' . $order->title, 'created_at' => time(), //模型没有updated_at,无法自动写入时间 ]); DB::commit(); return true; } catch (Exception $e) { DB::rollBack(); $fail('Unknown error'); } } // 支付失败 else if ($message['result_code'] === 'FAIL') { return true; } } // 希望微信重试 $fail('Order not exists.'); }); } catch (InvalidSignException | Exception $e) { $time = time(); $filename = storage_path('logs/wxpay_notify_') . date('Y-m-d-H', $time) . '.log'; $data = '[' . date('Y-m-d H:i:s', $time) . ']' . PHP_EOL; $data .= '[message]:' . $e->getMessage() . $e->getFile() . $e->getLine() . PHP_EOL . PHP_EOL; file_put_contents($filename, $data, FILE_APPEND); return 'error'; } return $response; } //退款通知 public function refund() { // {"sign": "3F99E6044C503B0E0131F95A1410B630", "appid": "wxb35ef055a4dd8ad4", "mch_id": "1606181693", "openid": "oBYj55W0gLv5MYUnsYUuJfzYzmsg", "cash_fee": "1", "fee_type": "CNY", "time_end": "20210623222330", "bank_type": "OTHERS", "nonce_str": "60d343d820e94", "total_fee": "1", "trade_type": "JSAPI", "result_code": "SUCCESS", "return_code": "SUCCESS", "is_subscribe": "N", "out_trade_no": "2842908479209865216", "transaction_id": "4200001210202106237487333085"} $agent_id = request()->route('agent_id'); $agent = Agent::find($agent_id); $config = config('wechat.payment.default'); $config = array_merge($config, [ 'app_id' => $agent->appid, 'mch_id' => $agent->mchid, 'key' => $agent->mchkey, ]); $app = Factory::payment($config); try { $response = $app->handleRefundedNotify(function ($message, $reqInfo, $fail) { // 记录一下本地调试 file_put_contents(storage_path('/wxpay/refund' . date('Y-m-d-H') . '.log'), date('Y-m-d H:i:s') . PHP_EOL . json_encode($message) . PHP_EOL . json_encode($reqInfo), FILE_APPEND); // 请求成功 if ($message['return_code'] === 'SUCCESS') { //订单号带有pay_type后缀,主要是为了区分定金支付和尾款支付,前24位才是真正的订单号 $order_no = substr($message['out_trade_no'], 0, 24); $order = Order::query() ->where(['order_sn' => $order_no]) ->first(); // 退款成功 if ($reqInfo['refund_status'] === 'SUCCESS') { DB::beginTransaction(); try { $apply = RefundApply::query() ->where('refund_sn', $reqInfo['out_refund_no']) ->first(); if (!$apply) { $fail('退款单没找到'); } $apply->state = 2; $apply->save(); $order->state = UserGoodsOrder::REFUNDED; $order->save(); // 退库存 GoodsSpecs::query() ->where([ 'id' => $order->goods_specs_id, 'goods_id' => $order->goods_id, ]) ->update([ 'stock' => DB::raw('stock+' . $order->number . ''), ]); DB::commit(); return true; } catch (\Exception $e) { DB::rollBack(); $fail('Unknown error'); } } } $fail('Unknown error'); }); } catch (Exception $e) { return 'error'; } return $response; } }