first(); if($order_good){ if($order_good->state == 3){ // 已退款 return true; } if($order_good->recharge > 0){ DB::beginTransaction(); try { // todo: $shop_order = WxShopOrder::where('id', $order_good->order_id)->first(); $updated_at = Carbon::now(); $nr = '您购买的:「' . $order_good->name . '(规格:' . $order_good->product . ')」×' . $order_good->quantity . '件的退款申请已处理完毕'; // 退款记录 $refund_record = new WxRefund(); $refund_record->user_id = $order_good->buyer_user_id; $refund_record->order_good_id = $order_good->id; $refund_record->order_id = $order_good->order_id; $refund_record->goods_id = $order_good->goods_id; $refund_record->product_id = $order_good->product_id; $refund_record->amount = $order_good->recharge; $refund_record->goods_type = $order_good->goods_type; $refund_record->save(); if($event_type == 'REFUND.SUCCESS'){ WxShopOrderGoods::where('id', $order_good->id)->update([ 'refund_no' => $out_refund_no, 'state' => 3, 'refund_from' => $refund_from, 'refund_amount' => $refund_amount, 'refund_time' => $refund_time, 'refund_account' => $refund_account ]); }else if($event_type == 'REFUND.ABNORMAL' || $event_type == 'REFUND.CLOSED'){ WxShopOrderGoods::where('id', $order_good->id)->update([ 'state' => 3, 'updated_at' => $updated_at ]); $financial_type = 3; if($order_good->goods_type == 7){ $financial_type = 29; } if($shop_order->serial_number){ UserUtils::update_user_financial($order_good->buyer_user_id,$financial_type, $order_good->recharge, '您收到了一笔来自「' . $order_good->name . '(规格:' . $order_good->product . ')」×' . $order_good->quantity . '件的退款,退款金额¥' . $order_good->recharge ); } }else{ return false; } UserUtils::add_user_notice(6002, $order_good->buyer_user_id, '商品退款通知', $nr, 100); $result_ = DB::table('wx_shop_order_goods as wg') ->select(DB::raw('COUNT(*) as total_count, SUM(CASE WHEN state = 3 THEN 1 ELSE 0 END) as state_3_count')) ->where('wg.order_id', $order_good->id) ->first(); if ($result_->total_count == $result_->state_3_count) { WxShopOrder::where('id', $order_good->order_id)->update([ 'pay_status' => 3, 'status' => 4, 'updated_at' => $updated_at ]); } if(in_array($order_good->goods_type, FieldUtils::getShopGoodTypes())){ WxShopGoods::where('id', $order_good->goods_id)->decrement('buys', (int)($order_good->quantity)); WxShopGoodsProduct::where('id', $order_good->product_id)->increment('stock', (int)($order_good->quantity)); }else{ if($order_good->goods_type == 6){ WxUsedGood::where('id', $order_good->goods_id)->update([ 'status' => 6 ]); } } DB::commit(); return true; } catch (\Exception $e) { DB::rollBack(); _logger_(__file__, __line__, $e->getMessage()); return false; } } } } /** * 所有支付的 处理支付通知 函数 * @param $out_trade_no * @param $transaction_id * @param $payment_time * @param $payed * @param $which_pay 0:微信 1:支付宝 2:易支付 3:苹果 */ private function _notify($out_trade_no, $transaction_id, $payment_time, $payed, $which_pay = 0){ try { // 判断订单是 来自商品 还是 来自充电或者开通会员。 $WxOrder = WxOrder::where('order_number', $out_trade_no)->first(); if ($WxOrder) { // 处理重复通知 if(in_array($WxOrder->order_state, [1, 3, 4, 5, 6])){ return true; } // 先检查是否需要微信发货管理 $is_need_deliver_info_manage = false; if($WxOrder->order_serial_platform === 0 && $WxOrder->order_serial_platform_type == 'mini'){ if(Settings::get('need_mini_deliver_info_manage', 0) == 1){ $is_need_deliver_info_manage = true; } } if($is_need_deliver_info_manage){ if($which_pay != $WxOrder->order_serial_platform){ _logger_(__file__, __line__, '理论上不应出现这种情况,order_id:'.$WxOrder->id); } WxOrder::where('order_number', $out_trade_no)->update(['order_state' => 3, 'order_serial_number' => $transaction_id]); $WxOrder->order_serial_number = $transaction_id; // 尝试通知 $weapp = new WeApp('mini'); $manage = $weapp->getDeliverInfoManage(); $manage->virtualDeliverOrder($WxOrder); }else{ //修改订单状态 WxOrder::where('order_number', $out_trade_no)->update(['order_state' => 1, 'order_serial_number' => $transaction_id, 'order_serial_platform'=>$which_pay]); //执行订单逻辑 OrderUtils::order_obtains($WxOrder, $which_pay); } } else { // 处理重复通知 if(WxShopOrder::where('order_id', $out_trade_no)->whereIn('pay_status', [2])->exists()){ return true; } $WxShopOrder = WxShopOrder::where('order_id', $out_trade_no)->first(); if($WxShopOrder){ //SHOP $discounts_amount = $WxShopOrder->discounts_amount; $pay_way = ShopUtils::generate_payway_text($discounts_amount,0, $which_pay === 0 ? $payed : 0, $which_pay === 1 ? $payed : 0, 0, $WxShopOrder->coins_num, $which_pay === 3 ? $payed : 0, $which_pay === 2 ? $payed : 0); WxShopOrder::where('id', $WxShopOrder->id) ->update(['pay_status' => 2, 'status' => 1, 'serial_number' => $transaction_id, 'serial_platform'=>$which_pay, 'payment_time' => $payment_time, 'payed' => $payed, 'pay_way'=>$pay_way]); $this->usedGoodPaied($WxShopOrder->id); $is_need_deliver_info_manage = false; if($WxShopOrder->serial_platform === 0 && $WxShopOrder->serial_platform_type == 'mini'){ if(Settings::get('need_mini_deliver_info_manage', 0) == 1){ if(WxShopOrderGoods::where('order_id', $WxShopOrder->id)->whereIn('goods_type', [2,3,4])->where('state', 0)->exists()){ $is_need_deliver_info_manage = true; } } } if(!$is_need_deliver_info_manage){ ShopUtils::paied_content_process($WxShopOrder->id); } ShopUtils::split_shop_order_by_seller($WxShopOrder->id); ShopUtils::split_shop_order_by_type($WxShopOrder->id); ShopUtils::order_buys_and_stock($WxShopOrder->id); if($is_need_deliver_info_manage){ WxShopOrder::withTrashed()->where('id', $WxShopOrder->id)->orWhere('parent_order_id', $WxShopOrder->id)->update([ 'status' => 9 ]); ShopOrderDeliverInfoManage::dispatch('virtual-upload', $WxShopOrder->id, null); } UserUtils::assistant_notice('admin', '您的商城有新的订单。'); }else{ return false; } } return true; } catch (\Exception $e) { _logger_(__file__, __line__, $e->getMessage()); return false; } } public function usedGoodPaied($order_id){ $goods_ids = []; WxShopOrderGoods::where('order_id', $order_id)->where('goods_type', 6)->get(['goods_id'])->map(function ($v) use (&$goods_ids){ $goods_ids[] = $v->goods_id; return $v; }); if($goods_ids){ foreach ($goods_ids as $used_id){ WxUsedGood::where('id', $used_id)->update([ 'status' => 5 ]); } } } /** * 微信app支付通知 */ public function wechat_app(){ $config = json_decode(Cache::get('app_pay_config'), true); if(_empty_($config)){ CheckBatchCahceDataLossJob::dispatch(); } Pay::config($config); $result = Pay::wechat()->callback(); if($result){ if($result->event_type == 'TRANSACTION.SUCCESS'){ $out_trade_no = $result->resource['ciphertext']['out_trade_no']; $transaction_id = $result->resource['ciphertext']['transaction_id']; $payment_time = Utils::strTimeFormat($result->resource['ciphertext']['success_time']);//支付回调支付时间 $total_fee = $result->resource['ciphertext']['amount']['total']; $payed = $total_fee / 100; if($this->_notify($out_trade_no, $transaction_id, $payment_time, $payed, 0)){ return Pay::wechat()->success(); } }else if($result->event_type == 'REFUND.SUCCESS' || $result->event_type == 'REFUND.ABNORMAL' || $result->event_type == 'REFUND.CLOSED'){ $event_type = $result->event_type; $out_refund_no = $result->resource['ciphertext']['out_refund_no']; $transaction_id = $result->resource['ciphertext']['transaction_id']; $refund_time = Utils::strTimeFormat($result->resource['ciphertext']['success_time']);//支付回调支付时间 $user_received_account = $result->resource['ciphertext']['user_received_account']; $refund_fee = $result->resource['ciphertext']['amount']['refund']; $refund = $refund_fee / 100; if($this->_refund($event_type, $out_refund_no, $transaction_id, $refund_time, $refund, $user_received_account, 0)){ return Pay::wechat()->success(); } } } } /** * 苹果支付 通知url * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function apple_app(Request $request){ $orderId = $request->orderId; $productId = $request->productid; $user_id = $request->username; $transaction = $request->transaction; $restore = (int)($request->restore ?? 0); _logger_(__file__, __line__, $transaction); if($restore == 1){ if(_empty_($transaction)){ return $this->fail(200001); } }else{ if(_empty_($orderId) || _empty_($productId) || _empty_($user_id) || _empty_($transaction)){ return $this->fail(200001); } } if( _empty_(_array_key($transaction, 'transactionDate', '')) || _empty_(_array_key($transaction, 'transactionIdentifier', '')) || _empty_(_array_key($transaction, 'transactionState', '')) || _empty_(_array_key($transaction, 'transactionReceipt', '')) ){ return $this->fail(200001); } if($restore === 0){ Cache::put('transactionIdentifier:'._array_key($transaction, 'transactionIdentifier', ''), json_encode(['orderId'=>$orderId, 'user_id'=>$user_id, 'productid'=>$productId]), 3600 * 24); }else{ if(Cache::has('transactionIdentifier:'._array_key($transaction, 'transactionIdentifier', ''))){ $cache_data = Cache::get('transactionIdentifier:'._array_key($transaction, 'transactionIdentifier', '') ); if($cache_data){ $cache_data = json_decode($cache_data, true); $orderId = $cache_data['orderId']; $productId = $cache_data['productid']; $user_id = $cache_data['user_id']; } } if(_empty_($orderId) || _empty_($productId)){ return $this->fail(200001); } } $is_shop_order = false; $order = null; $notify_data = [ ]; if(strpos($productId, 'apple_pay_product_recharge') === 0){ $productid_num = (int)(str_replace('apple_pay_product_recharge_', '', $productId)); $order = WxOrder::find($orderId); $notify_data['type'] = 3; $notify_data['num'] = $productid_num; }else if(strpos($productId, 'apple_pay_product_vip') === 0){ $product_price = (int)(str_replace('apple_pay_product_vip_', '', $productId)); $order = WxOrder::find($orderId); $notify_data['type'] = 1; $notify_data['price'] = $product_price; } if(_empty_($order)){ return $this->fail(200004, [], '没有与此orderId对应的订单'); } // 已经处理过的订单 if($is_shop_order){ if($order->pay_status != 1){ return $this->fail(200010, [], '该订单已经通知过'); } }else{ if($order->order_state != 0){ return $this->fail(200010, [], '该订单已经通知过'); } } $is_sand_box = false; $applePay = new ApplePay(_array_key($transaction, 'transactionReceipt', ''), Settings::get('apple_pay_password', '')); if ($applePay->verifyReceipt($is_sand_box)) { $result = $applePay->query($productId, function ($tradeNo, $returnData) use ($order, $is_shop_order, $notify_data) { // _logger_(__file__, __line__, $returnData); if($is_shop_order){ }else{ if($notify_data['type'] == 1){ return $this->_notify($order->order_number, $tradeNo, current_time(), 0, 3); }else if($notify_data['type'] == 3){ return $this->_notify($order->order_number, $tradeNo, current_time(), 0, 3); } } }); if ($result) { return $this->success(); } else { return $this->fail(200004, [], $applePay->getError()); } } else { return $this->fail(200004, [], $applePay->getError()); } } public function alipay_app(){ $config = json_decode(Cache::get('app_pay_config'), true); if(_empty_($config)){ CheckBatchCahceDataLossJob::dispatch(); } Pay::config($config); $result = Pay::alipay()->callback(); // 否则当支付处理 if($result->alipay_trade_app_pay_response){ $result = $result->alipay_trade_app_pay_response; } if($result->trade_status == 'TRADE_SUCCESS' || $result->code == 10000){ $out_trade_no = $result->out_trade_no; $transaction_id = $result->trade_no; $payment_time = $result->timestamp;//支付回调支付时间 $payed = $result->total_amount; if($this->_notify($out_trade_no, $transaction_id, $payment_time, $payed, 1)){ return Pay::alipay()->success(); } } } public function alipay_wap(){ $config = json_decode(Cache::get('app_pay_config'), true); if(_empty_($config)){ CheckBatchCahceDataLossJob::dispatch(); } Pay::config($config); $result = Pay::alipay()->callback(); _logger_(__file__, __line__, $result); if($result->alipay_trade_wap_pay_response){ $result = $result->alipay_trade_wap_pay_response; } if($result->trade_status == 'TRADE_SUCCESS' || $result->code == 10000){ $out_trade_no = $result->out_trade_no; $transaction_id = $result->trade_no; $payment_time = $result->timestamp;//支付回调支付时间 $payed = $result->total_amount; if($this->_notify($out_trade_no, $transaction_id, $payment_time, $payed, 1)){ return Pay::alipay()->success(); } } } public function yi_app(Request $request){ if(_empty_($request->out_trade_no) || _empty_($request->sign)){ return ''; } $epay_config = json_decode(Cache::get('yi_pay_config'), true); if(_empty_($epay_config)){ CheckBatchCahceDataLossJob::dispatch(); } $epay = new EPay(); $epay->key($epay_config['app_secret']); //签名验证 $data = $request->input(); if(!$epay->signVerify($data)){ exit(); } // 交易状态## 交易成功 if($data['trade_status']=='TRADE_SUCCESS'){ $out_trade_no=$data['out_trade_no'];//网站自己生成的订单号 $transaction_id=$data['trade_no'];//第三方平台产生的订单号 $total_fee=$data['money'];//金额 $payment_time = date('Y-m-d H:i:s', time()); $payed=(float)$total_fee; if($this->_notify($out_trade_no, $transaction_id, $payment_time, $payed, 2)){ echo "success"; } } return ''; } /** 微信支付v2版本通知url * @return string */ public function index() { $xml = file_get_contents('php://input'); libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $valArr = json_decode(json_encode($xmlstring), true); $out_trade_no = $valArr['out_trade_no'];//支付回调订单号 $transaction_id = $valArr['transaction_id'];//支付回调支付号 $time_end = $valArr['time_end'];//支付回调支付时间 $payment_time = date('Y-m-d H:i:s', strtotime($time_end)); $total_fee = $valArr['total_fee'];//支付回调支付金额 $payed = $total_fee / 100; if (_empty_($out_trade_no)) { die('错误'); } _logger_(__file__, __line__, $out_trade_no.'开始处理微信小程序支付通知'); if($this->_notify($out_trade_no, $transaction_id, $payment_time, $payed, 0)){ return $this->successXml(); } } private function successXml() { $arr = ['return_code' => 'SUCCESS', 'return_msg' => 'OK']; $xml = ""; foreach ($arr as $key => $val) { if (is_array($val)) { $xml .= "<" . $key . ">" . arrayToXml($val) . ""; } else { $xml .= "<" . $key . ">" . $val . ""; } } $xml .= ""; return $xml; } }