handlePaidNotify(function ($message, $fail) { $type = isset($message['attach']) ? $message['attach'] : $this->getTypeTag($message['out_trade_no']); $class = $this->byTypeGetModel($type); $model = new $class; $order = $model->where('no', $message['out_trade_no'])->first(); if (!$order) { return false; } if ((int)$order->pay_status === Order::PAY_STATUS_OK) { // 如果订单不存在 或者 订单已经支付过了 return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 } if ($message['result_code'] === 'FAIL') { Log::warning('[wechat-pay]:' . json_encode($message, true)); return true; } else if ($message['return_code'] === 'SUCCESS') { // TODO: 你的发货逻辑 $order->pay_status = Order::PAY_STATUS_OK; $order->pay_time = now(); $order->pay_type = Order::PAY_TYPE_WECHAT; $order->pay_money = bcdiv($message['total_fee'], 100, 2); $order->save(); $order->pay_order_callback(); return true; } }); } catch (\Exception $exception) { Log::error($exception->getMessage()); } } /** * 退款结果通知回调 * @return mixed * User: Mead */ public function refundNotify() { try { $payment = app('wechat.payment'); return $payment->handleRefundedNotify(function ($message, $reqInfo, $fail) { if ($message['return_code'] === 'FAIL') { Log::warning('[wechat-pay-refund]:' . json_encode($message, true)); return true; } $no = $reqInfo['out_trade_no']; $type = $this->getTypeTag($no); Log::info("refund::{$type}==>{$no}"); $class = $this->byTypeGetModel($type); if (empty($class)) { //其他项目 Log::info("no_Tag:" . $no); // $this->sendOtherRefundOrder($reqInfo['out_trade_no'], 1); return false; } $model = new $class; $order = $model->where('no', $no)->first(); if (!$order) { return false; } $is_ok = ($message['return_code'] == 'SUCCESS' && $reqInfo['refund_status'] == 'SUCCESS'); if (!$is_ok) { Log::error($reqInfo); return true; } //除押金之外退款操作 if (!in_array($type, [makeNoTag(DepositOrder::NO_TAG), makeNoTag(RefundLog::NO_TAG)])) { if ($is_ok) { $order->refund_order_callback(); } return true; } if ((int)$order->is_refund === DepositOrder::REFUND_OK) { return true; } if ($is_ok) { $order->is_refund = DepositOrder::REFUND_OK; $order->save(); $order->refund_order_callback(); } return true; // 返回 true 告诉微信“我已处理完成” }); } catch (\Exception $exception) { Log::error($exception->getMessage()); } } /** * 根据订单号实例model * @param $type * @return string * User: Mead */ protected function byTypeGetModel($type) { $class = ''; switch ($type) { case config('bike.no_tag') . DepositOrder::NO_TAG: // 缴纳押金 $class = DepositOrder::class; break; case config('bike.no_tag') . RechargeOrder::NO_TAG: // 充值 $class = RechargeOrder::class; break; case config('bike.no_tag') . Order::NO_TAG: // 骑行订单 $class = Order::class; break; case config('bike.no_tag') . RefundLog::NO_TAG: // 退款 $class = RefundLog::class; break; case config('bike.no_tag') . CardRidingOrder::NO_TAG: // 骑行卡 $class = CardRidingOrder::class; break; case config('bike.no_tag') . DepositCardOrder::NO_TAG: // 免押金卡 $class = DepositCardOrder::class; break; case config('bike.no_tag') . PunishmentOrder::NO_TAG: // 罚单 $class = PunishmentOrder::class; break; } return $class; } /** * 发送给小斑马 * @param $no * @param int $is_order_no * @return bool * User: Mead */ public function sendOtherRefundOrder($no, $is_order_no = 0) { $re = curl_get("http://api.xbm.weilaibike.com/api/payments/wechat-refund-api?no={$no}&is-order-no={$is_order_no}"); if ($re['status']) { return true; } return false; } /** * 检查订单是否退款成功 * @param Request $request * @return mixed * User: Mead */ public function isOrderRefundPay(Request $request) { try { $no = $request->get('no'); $is_order_no = $request->get('is-order-no', 0); $type = $this->getTypeTag($no); if (!in_array($type, [makeNoTag(RefundLog::NO_TAG), makeNoTag(DepositOrder::NO_TAG)])) { return $this->error('订单号类型不对'); } $payment = app('wechat.payment'); if ($is_order_no) { $re = $payment->refund->queryByOutTradeNumber($no); } else { $re = $payment->refund->queryByOutRefundNumber($no); } Log::log('info', 'isOrderRefundPay', $re); $is_ok = (($re['return_code'] === 'SUCCESS') && ($re['result_code'] === 'SUCCESS')); if (!$is_ok) { $return = [ 'status' => false, 'code' => $re['err_code'], 'msg' => $re['err_code_des'] ]; return $return; } if ($re['refund_status_0'] !== 'SUCCESS') { $return = [ 'status' => false, 'code' => '', 'msg' => RefundLog::$tradeStateMaps[$re['refund_status_0']] ]; return $return; } $return = [ 'status' => true, 'msg' => '退款成功' ]; $order = DepositOrder::where('no', $re['out_trade_no'])->first(); if ((int)$order->is_refund === DepositOrder::REFUND_OK) { return $return; } if ($is_ok) { switch ($re['refund_status_0']) { case 'SUCCESS': //退款成功 $order->is_refund = DepositOrder::REFUND_OK; $order->save(); $order->refund_order_callback(); break; case 'REFUNDCLOSE': //退款关闭 $return = [ 'status' => false, 'msg' => '退款关闭' ]; break; case 'PROCESSING': //退款处理中 $return = [ 'status' => false, 'msg' => '退款处理中,请稍后再试。' ]; break; case 'CHANGE': //退款异常 $return = [ 'status' => false, 'msg' => $re['err_code_des'] ]; Log::error("isOrderRefundPay:", $re); RefundLog::where('deposit_id', $order->id)->update([ 'pay_status' => RefundLog::PAY_STATUS_ERROR, 'pay_time' => date('Y-m-d H:i:s'), 'result' => $re['err_code_des'] ]); break; } } else { $return = [ 'status' => false, 'code' => $re['err_code'], 'msg' => $re['err_code_des'] ]; } return $return; } catch (\Exception $exception) { return $this->error($exception->getMessage()); } } /** * 解析订单号tag * @param $no * @return mixed * User: Mead */ protected function getTypeTag($no) { preg_match('/[A-Z]*/', $no, $types); return $types[0]; } /** * 检查订单是否支付成功 * @param Request $request * @return mixed * User: Mead */ public function checkOrderPayStatus(Request $request) { try { $order_no = $request->get('order_no'); $type = substr($order_no, 0, 1); $class = $this->byTypeGetModel($type); $model = new $class; $pay_status = $model->where('no', $order_no)->value('pay_status'); return $this->response->array([ 'is_pay' => !!$pay_status ]); } catch (\Exception $exception) { Log::error($exception->getMessage()); } } /** * 处理租车订单支付结果 * User: Mead */ public function rentNotify() { try { $payment = app('wechat.payment'); return $payment->handlePaidNotify(function ($message, $fail) { $type = isset($message['attach']) ? $message['attach'] : $this->getTypeTag($message['out_trade_no']); $rentOrder = RentOrder::query(); if ($type === makeNoTag(RentOrder::NO_TAG)) { $order = $rentOrder->where('no', $message['out_trade_no'])->first(); if (!$order || (int)$order->pay_status === RentOrder::PAY_STATUS_OK) { // 如果订单不存在 或者 订单已经支付过了 return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了 } if ($message['result_code'] === 'FAIL') { Log::warning('[wechat-pay]:' . json_encode($message, true)); return true; } else if ($message['return_code'] === 'SUCCESS') { // TODO: 你的发货逻辑 $order->pay_status = RentOrder::PAY_STATUS_OK; $order->pay_time = now(); $order->pay_type = RentOrder::PAY_TYPE_WECHAT; $order->pay_money = bcdiv($message['total_fee'], 100, 2); $order->order_total_money = $order->pay_money; $order->status = RentOrder::STATUS_COMPLETE_ORDER; $order->save(); $order->pay_rent_over_order_callback(); return true; } } }); } catch (\Exception $exception) { return $this->errorNoValidation($exception->getMessage()); } } }