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 = $this->byTypeGetPayType($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); return false; } } // 订单返回回调(支付宝) public function alipay_notify($merchant_id, Request $request) { $input = $request->input(); self::$MERCHANT_ID = $merchant_id; self::$MERCHANT = AdminMerchant::byIdNoStatus($merchant_id); if (!self::$MERCHANT) { Log::error('[支付]:参数错误'); } $result = alipay_mini_config(self::$MERCHANT)->payment()->common()->verifyNotify($input); //返回 true/false if (!$result) { Log::error("调用失败,原因:" . $result->msg . "," . $result->subMsg); return; } $type = $this->getTypeTag($input['out_trade_no']); $class = $this->byTypeGetModel($type); $model = new $class; $order = $model->where('no', $input['out_trade_no'])->first(); if (!$order) { echo 'success'; return; //支付宝禁止多次重复 } if ((int)$order->pay_status === Order::PAY_STATUS_OK) { echo 'success'; return; //支付宝禁止多次重复 } if ($input['trade_status'] === 'TRADE_SUCCESS') { //成功支付 //所有订单需要实现 $order->pay_status = Order::PAY_STATUS_OK; $order->pay_time = now(); $order->pay_type = $this->byTypeGetPayType($type, 'alipay'); $order->pay_money = $input['total_amount']; $order->save(); $order->pay_order_callback(); echo 'success'; return; //支付宝禁止多次重复 } else { Log::warning('[alipaymini-pay]:支付不是成功状态'); return true; } } //支付宝预授权回调 返回确认状态跟支付状态不一样 public function alipay_yushouquan_notify($merchant_id, Request $request) { $input = $request->input(); self::$MERCHANT_ID = $merchant_id; self::$MERCHANT = AdminMerchant::byIdNoStatus($merchant_id); if (!self::$MERCHANT) { Log::error('[支付]:参数错误'); } $result = alipay_mini_config(self::$MERCHANT)->payment()->common()->verifyNotify($input); //返回 true/false if (!$result) { Log::error("调用失败,原因:" . $result->msg . "," . $result->subMsg); return; } $model = new DepositOrder(); $order = $model->where('no', $input['out_order_no'])->first(); if (!$order) { echo 'success'; return; //支付宝禁止多次重复 } if ((int)$order->pay_status === DepositOrder::PAY_STATUS_OK) { echo 'success'; return; //支付宝禁止多次重复 } if ($input['status'] === 'SUCCESS') { //预授权成功 //所有订单需要实现 $order->pay_status = DepositOrder::PAY_STATUS_OK; $order->pay_time = now(); $order->pay_type = DepositOrder::PAY_TYPE_ALIPAYMINI_CREDIT; $order->pay_money = $input['amount'];//冻结金额 $order->save(); $order->pay_order_shouquan_callback(); echo 'success'; return; //支付宝禁止多次重复 } else { Log::warning('[alipaymini-pay-shouquan]:预授权不是成功状态'); return true; } } /** * 退款结果通知回调 * @return mixed * User: Mead */ public function refundNotify($merchant_id) { try { self::$MERCHANT_ID = $merchant_id; self::$MERCHANT = AdminMerchant::byIdNoStatus($merchant_id); if (!self::$MERCHANT) { Log::error('[支付]:参数错误'); } $payment = Factory::payment(wechat_pay_config(self::$MERCHANT)); 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()); } } protected function byTypeGetPayType($type, $pay_source) { if ($pay_source == 'wechat') { $pay_type = Order::PAY_TYPE_WECHAT; // switch ($type) { // case config('bike.no_tag') . DepositOrder::NO_TAG: //// 缴纳押金 // $pay_type = DepositOrder::PAY_TYPE_WECHAT; // break; // case config('bike.no_tag') . RechargeOrder::NO_TAG: //// 充值 // $pay_type = RechargeOrder::PAY_TYPE_WECHAT; // break; // case config('bike.no_tag') . Order::NO_TAG: //// 骑行订单 // $pay_type = Order::PAY_TYPE_WECHAT; // break; // case config('bike.no_tag') . RefundLog::NO_TAG: //// 退款 // $pay_type = RefundLog::PAY_TYPE_WECHAT; // break; // case config('bike.no_tag') . CardRidingOrder::NO_TAG: //// 骑行卡 // $pay_type = CardRidingOrder::PAY_TYPE_WECHAT; // break; // case config('bike.no_tag') . DepositCardOrder::NO_TAG: // // 免押金卡 // $pay_type = DepositCardOrder::PAY_TYPE_WECHAT; // break; // case config('bike.no_tag') . PunishmentOrder::NO_TAG: // // 罚单 // $pay_type = PunishmentOrder::PAY_TYPE_WECHAT; // break; // } return $pay_type; } if ($pay_source == 'alipay') { $pay_type = Order::PAY_TYPE_ALIPAYMINI; switch ($type) { case config('bike.no_tag') . DepositOrder::NO_TAG: // 缴纳押金 $pay_type = DepositOrder::PAY_TYPE_ALIPAYMINI; break; case config('bike.no_tag') . RechargeOrder::NO_TAG: // 充值 $pay_type = RechargeOrder::PAY_TYPE_ALIPAYMINI; break; case config('bike.no_tag') . Order::NO_TAG: // 骑行订单 $pay_type = Order::PAY_TYPE_ALIPAYMINI; break; case config('bike.no_tag') . RefundLog::NO_TAG: // 退款 $pay_type = RefundLog::PAY_TYPE_ALIPAYMINI; break; case config('bike.no_tag') . CardRidingOrder::NO_TAG: // 骑行卡 $pay_type = CardRidingOrder::PAY_TYPE_ALIPAYMINI; break; case config('bike.no_tag') . DepositCardOrder::NO_TAG: // 免押金卡 $pay_type = DepositCardOrder::PAY_TYPE_ALIPAYMINI; break; case config('bike.no_tag') . PunishmentOrder::NO_TAG: // 罚单 $pay_type = PunishmentOrder::PAY_TYPE_ALIPAYMINI; break; } return $pay_type; } } /** * 根据订单号实例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 { $merchant_id = $request->get('merchant_id'); self::$MERCHANT_ID = $merchant_id; self::$MERCHANT = AdminMerchant::byIdNoStatus($merchant_id); if (!self::$MERCHANT) { Log::error('[支付]:参数错误'); } $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 = Factory::payment(wechat_pay_config(self::$MERCHANT)); 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 substr($types[0], 2, 1); } /** * 检查订单是否支付成功 * @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($merchant_id) { try { Log::info($_SERVER); self::$MERCHANT_ID = $merchant_id; self::$MERCHANT = AdminMerchant::byIdNoStatus($merchant_id); if (!self::$MERCHANT) { Log::error('[支付]:参数错误'); } $payment = Factory::payment(wechat_pay_config(self::$MERCHANT)); 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->exception($exception); } } /** * 支付宝 * 处理租车订单支付结果 * User: Mead */ public function alipay_rent_notify($merchant_id, Request $request) { $input = $request->input(); Log::info($_SERVER); self::$MERCHANT_ID = $merchant_id; self::$MERCHANT = AdminMerchant::byIdNoStatus($merchant_id); if (!self::$MERCHANT) { Log::error('[支付]:参数错误'); } $result = alipay_mini_config(self::$MERCHANT)->payment()->common()->verifyNotify($input); //返回 true/false // file_put_contents('alipay_notify.txt', date('Y-m-d H:i:s', time()) .PHP_EOL);//FILE_APPEND. PHP_EOL . json_encode($input) if (!$result) { Log::error("调用失败,原因:" . $result->msg . "," . $result->subMsg); return; } $type = $this->getTypeTag($input['out_trade_no']); $rentOrder = RentOrder::query(); if ($type === makeNoTag(RentOrder::NO_TAG)) { $order = $rentOrder->where('no', $input['out_trade_no'])->first(); if (!$order || (int)$order->pay_status === RentOrder::PAY_STATUS_OK) { // 如果订单不存在 或者 订单已经支付过了 return 'success'; return true; } if ($input['trade_status'] === 'TRADE_SUCCESS') { //成功支付 $order->pay_status = RentOrder::PAY_STATUS_OK; $order->pay_time = now(); $order->pay_type = RentOrder::PAY_TYPE_ALIPAYMINI; $order->pay_money = $input['total_amount']; $order->order_total_money = $order->pay_money; $order->status = RentOrder::STATUS_COMPLETE_ORDER; $order->save(); $order->pay_rent_over_order_callback(); echo 'success'; return; //支付宝禁止多次重复 } else { Log::warning('[alipaymini-pay]:' . json_encode($input, true)); echo 'success'; return; //支付宝禁止多次重复 } } } /** * 响应成功 * @return mixed * User: Mead */ public function success() { return $this->response->array([ 'status' => true ]); } /** * 响应失败 * @param string $msg * @return mixed * User: Mead */ public function error($msg = '请求失败') { return $this->response->array([ 'status' => false, 'msg' => $msg ]); } }