mergeCommonPlugins([QueryBatchIdPlugin::class]); // need_query_detail:【是否查询转账明细单】 true-是;false-否,默认否。商户可选择是否查询指定状态的转账明细单,当转账批次单状态为“FINISHED”(已完成)时,才会返回满足条件的转账明细单 $result = $pay->pay($plugins ,['batch_id' => $batch_id, 'need_query_detail' => true, 'detail_status' => 'ALL']); $result_arr = $result->toArray(); if(!_empty_(_array_key($result_arr, 'transfer_batch', ''))){ // 查询成功 return $result_arr; }else{ if(_array_key($result_arr, 'code', '') == 'NOT_FOUND'){ WxUserWithdrawal::whereIn('wx_batch_id', $batch_id)->where('state', 3)->update([ 'state' => 2, 'refuse_tip' => '查询的转账批次单不存在', ]); }else{ _logger_(__file__, __line__, '微信商家转账到零钱-查询批次单失败-批次号'.$batch_id.'-:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE)); UserUtils::assistant_notice('admin', '微信商家转账到零钱失败-查询批次单失败-批次号'.$batch_id.'-:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE)); } return null; } }else{ throw new \Exception('暂时未实现'); } } /** * @param $provider * @param $pay_type * @param $list * 'transfer_detail_list' => [ [ 'out_detail_no' => (string)(time() + 5), // 商家明细单号 'transfer_amount' => 0.1 * 100, // 转账金额 'transfer_remark' => '商家付款到零钱', // 单条转账备注(微信用户会收到该备注) 'openid' => 'ozxxxxxxxxxx', // 转账用户的 openid ], ], * @param $batch_name 余额提现 * @param $batch_remark 平台转账到用户微信零钱 * @throws \Exception */ public function transferBatch($provider, $pay_type, $list, $batch_name = '余额提现', $batch_remark = '平台转账到用户微信零钱'){ $total_amount = 0; if(!_empty_($list)){ foreach ($list as $item){ $total_amount += $item['transfer_amount']; } } if($provider == 'wxpay'){ $config = json_decode(Cache::get('app_pay_config'), true); if(_empty_($config)){ CheckBatchCahceDataLossJob::dispatch(); } if($pay_type == 'app'){ $appid = Settings::get('app_app_id', ''); }else if($pay_type == 'mp'){ $appid = Settings::get('mp_app_id', ''); }else if($pay_type == 'mini'){ $appid = Settings::get('app_id', ''); }else{ $appid = Settings::get('app_id', ''); } $result = Pay::wechat($config)->transfer([ 'appid' => $appid, // 微信小程序的app_id 'out_batch_no' => (string)time(), // 商家批次单号 'batch_name' => $batch_name, // 该笔批量转账的名称 'batch_remark' => $batch_remark, // 转账说明 'total_amount' => (int)$total_amount, // 转账金额,单位:分 'total_num' => count($list), // 转账总笔数 'transfer_detail_list' => $list, ]); $result_arr = $result->toArray(); if(!_empty_(_array_key($result_arr, 'batch_id', ''))){ // 转账成功 return _array_key($result_arr, 'batch_id', ''); }else{ if(_array_key($result_arr, 'code', '') == 'NOT_ENOUGH'){ throw new \Exception('资金不足'); } _logger_(__file__, __line__, '微信商家转账到零钱(总'. ($total_amount/100) .'元)失败:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE)); UserUtils::assistant_notice('admin', '微信商家转账到零钱(总'. ($total_amount/100) .'元)失败:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE)); return null; } }else if($provider == 'alipay'){ throw new \Exception('暂时未实现'); $config = json_decode(Cache::get('app_pay_config'), true); if(_empty_($config)){ CheckBatchCahceDataLossJob::dispatch(); } if($pay_type == 'app'){ }else if($pay_type == 'mp'){ }else if($pay_type == 'mini'){ } $order = [ 'out_biz_no' => time(), 'trans_amount' => 0.1, 'product_code' => 'TRANS_ACCOUNT_NO_PWD', 'payee_info' => [ 'identity' => 'ghdhjw7124@sandbox.com', 'name' => '张三', 'identity_type' => 'ALIPAY_LOGON_ID', ], 'remark'=>'赔付金'//相当于转账里面的备注 ]; $result = Pay::alipay($config)->transfer($order); } } /** * @param $uid * @param $provider * @param $pay_type * @param $total_fee * @param $body * @param $out_trade_no * @param int $order_type 1: 普通订单 2:商城订单 * @return \Illuminate\Http\JsonResponse */ public function payHandler($uid, $provider, $pay_type, $total_fee, $body, $out_trade_no, $order_type = 1){ global $__MINI_GLOBAL_DEVICE__; if($__MINI_GLOBAL_DEVICE__ == 'h5'){ if($provider == 'wxpay'){ if($pay_type != 'mp' && $pay_type != 'h5'){ $pay_type = 'h5'; } }else{ $pay_type = 'h5'; } } if($provider == 'wxpay'){ $config = json_decode(Cache::get('app_pay_config'), true); if(_empty_($config)){ CheckBatchCahceDataLossJob::dispatch(); } if($order_type == 1){ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'wx_order_'); }else{ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'wx_shoporder_'); } $config['wechat']['default']['return_url'] = route('pay.return', ['out_trade_no'=>$outTradeNoPre]); // 微信支付 if($pay_type == 'app'){ // $openid = WxUser::where('id', $uid)->value('weixin_app_openid'); // 支付 $order = [ 'out_trade_no' => $out_trade_no, 'description' => $body, 'amount' => [ 'total' => (int)($total_fee * 100), ], ]; $pay_data = Pay::wechat($config)->app($order); $pay_data['query_state_no'] = $outTradeNoPre; if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'app', 'order_serial_platform'=>0]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'app', 'serial_platform'=>0]); } return $this->success($pay_data); }else if($pay_type == 'h5'){ global $__MINI_GLOBAL_IP__; $order = [ 'out_trade_no' => $out_trade_no, 'description' => $body, 'amount' => [ 'total' => (int)($total_fee * 100), ], 'scene_info' => [ 'payer_client_ip' => $__MINI_GLOBAL_IP__, 'h5_info' => [ 'type' => 'Wap', ] ], ]; $pay_data = Pay::wechat($config)->wap($order); $h5_url = $pay_data->h5_url; $cache_html = ' Redirecting '; $r = Cache::put($outTradeNoPre, $cache_html, $seconds = 300); if($r){ if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'h5', 'order_serial_platform'=>0]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'h5', 'serial_platform'=>0]); } return $this->success(['direct'=>route('pay.direct', ['out_trade_no'=>$outTradeNoPre]), 'query_state_no'=>$outTradeNoPre]); }else{ return $this->fail(200005, ['msg'=>'系统写入缓存时失败,请联系管理员']); } }else if($pay_type == 'yi') { $epay_config = json_decode(Cache::get('yi_pay_config'), true); if(_empty_($epay_config)){ CheckBatchCahceDataLossJob::dispatch(); } if($order_type == 1){ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_order_'); }else{ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_shoporder_'); } $return_url = route('pay.return', ['out_trade_no' => $outTradeNoPre]); $epay = new EPay(); $epay->key($epay_config['app_secret']); // 发起订单 try { $pay_data = $epay->pid($epay_config['app_id']) ->url($epay_config['provider_url']) ->outTradeNo($out_trade_no) ->type('wxpay') ->notifyUrl($epay_config['notify_url']) ->returnUrl($return_url) ->money($total_fee) ->name($body) ->sitename($epay_config['site']) ->submit() ->getHtmlForm(); $r = Cache::put($outTradeNoPre, Utils::payDirectHtmlForApp('', $pay_data), $seconds = 300); if ($r) { if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'yi', 'order_serial_platform'=>0]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'yi', 'serial_platform'=>0]); } return $this->success(['direct' => route('pay.direct', ['out_trade_no' => $outTradeNoPre]), 'query_state_no' => $outTradeNoPre]); } else { return $this->fail(200005, ['msg' => '系统写入缓存时失败,请联系管理员']); } } catch (\Exception $e) { _logger_(__file__, __line__, $e->getMessage()); return $this->fail(200006, ['msg' => '易支付生成订单出错']); } }else if($pay_type == 'code' || $pay_type == 'code_pc') { // native支付 $order = [ 'out_trade_no' => $out_trade_no, 'description' => $body, 'amount' => [ 'total' => (int)($total_fee * 100), ], ]; $pay_data = Pay::wechat($config)->scan($order); if($pay_data && $pay_data->code_url){ if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>$pay_type, 'order_serial_platform'=>0]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>$pay_type, 'serial_platform'=>0]); } return $this->success(['url'=>$pay_data->code_url, 'code'=>QrCode::size(300)->generate($pay_data->code_url), 'query_state_no'=>$outTradeNoPre]); } return $this->fail(200006, $pay_data); }else if($pay_type == 'mp') { $order = [ 'out_trade_no' => $out_trade_no, 'description' => $body, 'amount' => [ 'total' => (int)($total_fee * 100), ], 'payer' => [ 'openid' => WxUser::where('id', $uid)->value('weixin_mp_openid'), ], ]; _logger_(__file__, __line__, '111111111111111111'); try { $result = Pay::wechat($config)->mp($order); if($result && $result->paySign){ if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'mp', 'order_serial_platform'=>0]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'mp', 'serial_platform'=>0]); } // todo优化: 返回二维码,以及url 微信文档:https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/jsapi-transfer-payment.html _logger_(__file__, __line__, $result->toArray()); return $this->success([ 'appId' => $result->appId, 'timeStamp' => $result->timeStamp, 'nonceStr' => $result->nonceStr, 'package' => $result->package, 'signType' => $result->signType, 'paySign' => $result->paySign, 'prepayid' => $result->prepayid, 'query_state_no' => $outTradeNoPre ]); } }catch (\Exception $e){ _logger_(__file__, __line__, $e->getMessage()); return $this->fail(200006); } }else if($pay_type == 'mini') { $order = [ 'out_trade_no' => $out_trade_no, 'description' => $body, 'amount' => [ 'total' => (int)($total_fee * 100), 'currency' => 'CNY', ], 'payer' => [ 'openid' => WxUser::where('id', $uid)->value('weixin_openid'), ], ]; try { $result = Pay::wechat($config)->mini($order); if($result && $result->paySign){ if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'mini', 'order_serial_platform'=>0]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'mini', 'serial_platform'=>0]); } // todo优化: 返回二维码,以及url 微信文档:https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/jsapi-transfer-payment.html return $this->success([ 'appId' => $result->appId, 'timeStamp' => $result->timeStamp, 'nonceStr' => $result->nonceStr, 'package' => $result->package, 'signType' => $result->signType, 'paySign' => $result->paySign, 'query_state_no' => $outTradeNoPre ]); } }catch (\Exception $e){ _logger_(__file__, __line__, $e->getMessage()); return $this->fail(200006); } } }else if($provider == 'alipay'){ $config = json_decode(Cache::get('app_pay_config'), true); if(_empty_($config)){ CheckBatchCahceDataLossJob::dispatch(); } if($order_type == 1){ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'ali_order_'); }else{ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'ali_shoporder_'); } $config['alipay']['default']['return_url'] = route('pay.return', ['out_trade_no'=>$outTradeNoPre]); $config['alipay']['default']['notify_url'] = env('APP_URL'). '/api/v1/app/ali/notify/app'; // 支付宝支付 if($pay_type == 'app'){ $order = [ 'out_trade_no' => $out_trade_no, 'total_amount' => $total_fee, 'subject' => $body, ]; if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'app', 'order_serial_platform'=>1]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'app', 'serial_platform'=>1]); } return Pay::alipay($config)->app($order); // $pay_data->query_state_no = $outTradeNoPre; }else if($pay_type == 'h5'){ $config['alipay']['default']['notify_url'] = env('APP_URL'). '/api/v1/app/ali/notify/wap'; $order = [ 'out_trade_no' => $out_trade_no, 'total_amount' => $total_fee, 'subject' => $body, 'quit_url' => env('APP_URL'), ]; $pay_data = Pay::alipay($config)->wap($order); $pay_data = $pay_data->getBody(); $r = Cache::put($outTradeNoPre, Utils::payDirectHtmlForApp('', $pay_data), $seconds = 300); if($r){ if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'h5', 'order_serial_platform'=>1]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'h5', 'serial_platform'=>1]); } return $this->success(['direct'=>route('pay.direct', ['out_trade_no'=>$outTradeNoPre]), 'query_state_no'=>$outTradeNoPre]); }else{ return $this->fail(200005, ['msg'=>'系统写入缓存时失败,请联系管理员']); } }else if($pay_type == 'yi') { $epay_config = json_decode(Cache::get('yi_pay_config'), true); if(_empty_($epay_config)){ CheckBatchCahceDataLossJob::dispatch(); } if($order_type == 1){ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_order_'); }else{ $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_shoporder_'); } $return_url = route('pay.return', ['out_trade_no' => $outTradeNoPre]); $epay = new EPay(); $epay->key($epay_config['app_secret']); // 发起订单 try { $pay_data = $epay->pid($epay_config['app_id']) ->url($epay_config['provider_url']) ->outTradeNo($out_trade_no) ->type('alipay') ->notifyUrl($epay_config['notify_url']) ->returnUrl($return_url) ->money($total_fee) ->name($body) ->sitename($epay_config['site']) ->submit() ->getHtmlForm(); $r = Cache::put($outTradeNoPre, Utils::payDirectHtmlForApp('', $pay_data), $seconds = 300); if ($r) { if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'yi', 'order_serial_platform'=>1]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'yi', 'serial_platform'=>1]); } return $this->success(['direct' => route('pay.direct', ['out_trade_no' => $outTradeNoPre]), 'query_state_no' => $outTradeNoPre]); } else { return $this->fail(200005, ['msg' => '系统写入缓存时失败,请联系管理员']); } } catch (\Exception $e) { _logger_(__file__, __line__, $e->getMessage()); return $this->fail(200006, ['msg' => '易支付生成订单出错']); } }else if($pay_type == 'code' || $pay_type == 'code_pc') { $order = [ 'out_trade_no' => $out_trade_no, 'total_amount' => $total_fee, 'subject' => $body, ]; $pay_data = Pay::alipay($config)->scan($order); if($pay_data && $pay_data->code_url){ if($order_type == 1){ WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>$pay_type, 'order_serial_platform'=>1]); }else{ WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>$pay_type, 'serial_platform'=>1]); } return $this->success(['url'=>$pay_data->code_url, 'code'=>QrCode::size(300)->generate($pay_data->code_url), 'query_state_no'=>$outTradeNoPre]); } return $this->fail(200006, $pay_data); } } } }