config('wechat.mini_program.app_id'), 'secret' => config('wechat.mini_program.secret'), ]; // $official_config = [ // 'app_id' => config('wechat.app_id'), // 'secret' => config('wechat.secret'), // ]; // $app = Factory::miniProgram($mini_config); $app = \EasyWeChat::miniProgram(); $official_app = \EasyWeChat::officialAccount('new'); $this->app = $app; $this->official_app = $official_app; $this->sms = $sms; Carbon::setLocale('zh'); } public function officialApp($param='new') { $official_app = \EasyWeChat::officialAccount($param); return $official_app; } /** * 是否关注公众号 */ public function officialIsSubscribed($openid) { $app = \WechatService::officialApp(); if(!$openid){ return 0; } $wechatUser = $app->user->get($openid); $result = !empty($wechatUser)&&isset($wechatUser['subscribe']); $is_subscribe = $result?$wechatUser['subscribe']:0; return $is_subscribe; } public function paymentInstance() { $merchantId = config('wechat.service_payment.mch_id'); // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名 $merchantPrivateKeyFilePath = 'file://'.config('wechat.service_payment.key_path'); $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE); // 「商户API证书」的「证书序列号」 $merchantCertificateSerial = config('wechat.service_payment.serial'); // 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名 $platformCertificateFilePath = 'file://'.config('wechat.service_payment.cert_path'); $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC); // 从「微信支付平台证书」中获取「证书序列号」 $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath); // 构造一个 APIv3 客户端实例 $instance = Builder::factory([ 'mchid' => $merchantId, 'serial' => $merchantCertificateSerial, 'privateKey' => $merchantPrivateKeyInstance, 'certs' => [ $platformCertificateSerial => $platformPublicKeyInstance, ], ]); return $instance; } public function app(){ return $this->app; } public function server() { $this->official_app->server->push(function ($message) { // $message['FromUserName'] // 用户的 openid // $message['MsgType'] // 消息类型:event, text.... return "您好!欢迎使用 EasyWeChat"; }); // 在 laravel 中: $response = $this->official_app->server->serve(); // $response 为 `Symfony\Component\HttpFoundation\Response` 实例 // 对于需要直接输出响应的框架,或者原生 PHP 环境下 $response->send(); // 而 laravel 中直接返回即可: return $response; } //通用发短信任务 public function sentMessage($mobile, $message) { $this->sms->sentMessage( $mobile, $message); } public function constructWXH5Pay($pay_order, $user_id, $detail, $activity_id=null,$callback='') { $spbill_create_ip = $this->getClientIp(); // $spbill_create_ip = $_SERVER['REMOTE_ADDR']; // $spbill_create_ip = '113.97.32.78'; if(!$callback) $callback = config('app.url').'/api/mark/order/pay/'.$pay_order['trade_no']; $attributes = array( 'trade_type' => 'MWEB', // JSAPI,NATIVE,APP... 'body' => $detail, 'detail' => $detail, 'out_trade_no' => $pay_order['trade_no'], 'total_fee' => ($pay_order['cash']*100), 'notify_url' => $callback, // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'spbill_create_ip' => $spbill_create_ip, ); if ($detail == '购买认证') { $redirect_url = env('APP_URL').'/mobile/#/authentication'; }elseif ($detail == '会员充值') { $redirect_url = env('APP_URL').'/mobile/#/upgrade'; }elseif ($detail == '参加活动') { $redirect_url = env('APP_URL').'/mobile/#/activityDetail/'.$activity_id; }elseif ($detail == '福恋约见') { $redirect_url = env('APP_URL').'/mobile/#/'; }elseif ($detail == '奉献金') { $redirect_url = env('APP_URL').'/mobile/#/'; }elseif ($detail == '购买课程') { $redirect_url = env('APP_URL').'/mobile/#/'; } $result = $this->officialPay($attributes, $redirect_url); return $result; } public function constructWXPay($pay_order, $user_id, $detail='福币充值',$callback='') { $openid = Wechat::where('user_id', $user_id)->value('openid'); if(!$openid) $openid = Viewer::where('user_id', $user_id)->value('openid'); if(!$callback) $callback = config('app.url').'/api/mark/order/pay/'.$pay_order['trade_no']; $attributes = array( 'trade_type' => 'JSAPI', // JSAPI,NATIVE,APP... 'body' => $detail, 'detail' => $detail, 'out_trade_no' => $pay_order['trade_no'], 'total_fee' => ($pay_order['cash']*100), 'notify_url' => $callback, // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'openid' => $openid, ); $result = $this->pay($attributes); return $result; } public function constructMiniPay($trade_no, $openid, $total_fee, $body, $detail, $callback) { $attributes = array( 'trade_type' => 'JSAPI', // JSAPI,NATIVE,APP... 'body' => $body, 'detail' => $detail, 'out_trade_no' => $trade_no, 'total_fee' => ($total_fee*100), 'notify_url' => $callback, // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'openid' => $openid, ); $result = $this->pay($attributes); return $result; } public function constructSWXPay($order, $openid, $detail='',$callback='') { $attributes = array( 'trade_type' => 'JSAPI', // JSAPI,NATIVE,APP... 'body' => $detail, 'detail' => '打赏金额:'.$order['price'], 'out_trade_no' => $order['trade_no'], 'total_fee' => ($order['price']*100), 'notify_url' => $callback, // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'openid' => $openid, ); $result = $this->officialPay($attributes); return $result; } public function constructSWXServicePay($order, $openid, $body, $detail, $callback) { $attributes = array( 'trade_type' => 'JSAPI', // JSAPI,NATIVE,APP... 'body' => $body, 'detail' => $detail, 'out_trade_no' => $order['trade_no'], 'total_fee' => ($order['price']*100), 'notify_url' => $callback, // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'openid' => $openid, ); return $attributes; } public function constructWXAppPay($pay_order, $user_id, $detail="福币充值", $callback='',$link=false) { $spbill_create_ip = $this->getClientIp(); $attributes = array( 'trade_type' => 'APP', // JSAPI,NATIVE,APP... 'body' => '福币充值', 'detail' => '福币充值', 'out_trade_no' => $pay_order['trade_no'], 'total_fee' => ($pay_order['cash']*100), 'notify_url' => $callback, // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'spbill_create_ip' => $spbill_create_ip, ); $PayLog = new PayLog; $PayLog->type = 'activity'; $PayLog->user_id = $user_id; $PayLog->trade_no =$pay_order['trade_no']??''; $PayLog->remark = $callback; $PayLog->save(); $result = $this->appPay($attributes,$link); return $result; } public function isLovePay() { return true; $ios_version = request()->header('app-version'); $and_version = request()->header('version-name'); //\Log::info($ios_version); //\Log::info($and_version); if(request()->header('ios_version') || request()->header('and_version')) { return true; } $ios_arr = explode('.', $ios_version); $and_arr = explode('.', $and_version); if ($ios_version) { if ($ios_arr[0] > 1) { return true; }elseif ($ios_arr[0] >= 1 && $ios_arr[1] > 3) { return true; }elseif ($ios_arr[0] >= 1 && $ios_arr[1] >= 3 && $ios_arr[2] >= 8) { return true; } } if ($and_version) { if ($and_arr[0] > 1) { return true; }elseif ($and_arr[0] >= 1 && $and_arr[1] > 3) { return true; }elseif ($and_arr[0] >= 1 && $and_arr[1] >= 3 && $and_arr[2] >= 13) { return true; } } return false; } public function appPay($attributes,$link=false) { $attributes['body'] = mb_substr($attributes['body'], 0, 42, 'utf-8'); //新版本换成福恋智能 if(!$link){ $love_pay = $this->isLovePay(); }else{ $love_pay = true; } if ($love_pay) { $config = config('wechat.payment'); }else{ //旧版本用友福同享 $config = config('wechat.ufutx_payment'); } $config = config('wechat.payment'); $config['app_id'] = config('wechat.love_app_id'); $config['notify_url'] = $attributes['notify_url']; $config['body'] = '福币充值'; $payment = Factory::payment($config); $result = $payment->order->unify($attributes); // $jssdk = $payment->jssdk; $prepayId = ''; $code_url = null; if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ $prepayId = $result['prepay_id']; $result = $payment->jssdk->appConfig($prepayId);//第二次签名 } else { } return array( 'config' => $result, 'attributes' => $attributes, ); } public function getClientIp() { if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) { $ip = getenv('HTTP_CLIENT_IP'); } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) { $ip = getenv('HTTP_X_FORWARDED_FOR'); } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) { $ip = getenv('REMOTE_ADDR'); } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) { $ip = $_SERVER['REMOTE_ADDR']; } else { $ip = '0.0.0.0'; } return preg_match('/[\d\.]{7,15}/', $ip, $matches) ? $matches[0] : ''; } public function officialPay($attributes, $redirect_url='') { try { $attributes['body'] = mb_substr($attributes['body'], 0, 42, 'utf-8'); if(config('wechat.payment.debug')){ return [ // 'js'=> $this->app->js->config(['chooseWXPay']), 'config'=>[ "appId"=> "wxc41491431733671e", "nonceStr"=> "5cab16345cfbd", "package"=> "prepay_id=wx081736523006918b9335320e1318134367", "paySign"=> "394FBA790DD24032EFBD54122FF1373B", "signType"=> "MD5", "timestamp"=> "1554716212", ], 'attributes'=>$attributes, 'pay_qrcode'=>'http://shop.ufutx.com/qrcode/pay/wx20170606161524da84bf4e090195877403', ]; } $config = config('wechat.payment'); $config['app_id'] = config('wechat.official_account.new.app_id'); $config['notify_url'] = $attributes['notify_url']; $payment = Factory::payment($config); $result = $payment->order->unify($attributes); $jssdk = $payment->jssdk; $prepayId = ''; $code_url = null; if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ $prepayId = $result['prepay_id']; // 这个很重要。有了这个才能调用支付。 // if($attributes['trade_type'] == 'NATIVE'){ // // $code_url = $this->generatePayQrCode($result['code_url'], $prepayId); // $code_url = $result['code_url']; // } } else { throw new \Exception($result['err_code_des']??'支付失败', 1); } $config = $jssdk->sdkConfig($prepayId); // 这个方法是取得js里支付所必须的参数用的。 没这个啥也做不了,除非你自己把js的参数生成一遍 return array( 'config' => $config, 'attributes' => $attributes, 'mweb_url' => isset($result['mweb_url'])?$result['mweb_url'].'&redirect_url='.urlencode($redirect_url):'', ); } catch (\Exception $e) { $this->getError($e); return false; } } /** * 服务商下单 * @param $attributes * @param $sub_merchant_id * @param null $is_share 是否启用分帐 * @return array|false */ public function officialServicePay($attributes, $sub_merchant_id,$is_share = null) { try { $config = config('wechat.service_payment'); $config['notify_url'] = $attributes['notify_url']; if($is_share){ $attributes['profit_sharing'] = 'Y'; } $app = Factory::payment($config); $app->setSubMerchant($sub_merchant_id); $result = $app->order->unify($attributes); if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ $config['appId'] = config('wechat.official_account.new.app_id'); $prepayId = $result['prepay_id']; $jssdk = $app->jssdk; $config = $jssdk->sdkConfig($prepayId); }else{ $attributes = $result; } return ['config'=>$config, 'attributes'=>$attributes]; } catch (Exception $e) { $this->getError($e); return false; } } public function pay($attributes) { try { $attributes['body'] = mb_substr($attributes['body'], 0, 42, 'utf-8'); $config = config('wechat.payment'); $config['app_id'] = config('wechat.mini_program.app_id'); $config['notify_url'] = $attributes['notify_url']; if(config('wechat.payment.debug')){ return array( 'config' => $config, 'attributes' => $attributes, 'mweb_url' => '', ); } $payment = Factory::payment($config); $result = $payment->order->unify($attributes); $jssdk = $payment->jssdk; $prepayId = ''; $code_url = null; if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ $prepayId = $result['prepay_id']; // 这个很重要。有了这个才能调用支付。 // if($attributes['trade_type'] == 'NATIVE'){ // // $code_url = $this->generatePayQrCode($result['code_url'], $prepayId); // $code_url = $result['code_url']; // } } else { throw new \Exception($result['err_code_des']??'支付失败', 1); } $config = $jssdk->sdkConfig($prepayId); // 这个方法是取得js里支付所必须的参数用的。 没这个啥也做不了,除非你自己把js的参数生成一遍 return array( // 'js' => $this->app->js->config(['chooseWXPay']), 'config' => $config, 'attributes' => $attributes, 'mweb_url' => isset($result['mweb_url'])?$result['mweb_url']:'', ); } catch (\Exception $e) { $this->getError($e); return false; } } //发红包 public function sendNormalRedPack($trade_no, $send_name, $total_amount, $openid, $wishing, $act_name, $remark='') { if(config('wechat.payment.debug')){ return true; } $config = config('wechat.payment'); $config['app_id'] = config('wechat.app_id'); $payment = Factory::payment($config); $redpack = $payment->redpack; $redpackData = [ 'mch_billno' => $trade_no, 'send_name' => $send_name, 're_openid' => $openid, 'total_num' => 1, //固定为1,可不传 'total_amount' => $total_amount, //单位为分,不小于100 'wishing' => $wishing, // 'client_ip' => '192.168.0.1', //可不传,不传则由 SDK 取当前客户端 IP 'act_name' => $act_name, 'remark' => $remark, // ... ]; // \Log::info($redpackData); // \Log::info($config); $result = $redpack->sendNormal($redpackData); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ //\Log::info($trade_no.'红包订单错误'.json_encode($result)); // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); return false; } return ; } public static function sendNormalRedPackV2($trade_no, $send_name, $total_amount, $openid, $wishing, $act_name='', $remark='') { if(config('wechat.payment.debug')){ return true; } try { $config = config('wechat.payment'); $config['app_id'] = config('wechat.app_id'); $payment = Factory::payment($config); $redpack = $payment->redpack; $redpackData = [ 'mch_billno' => $trade_no, 'send_name' => $send_name, 're_openid' => $openid, 'total_num' => 1, //固定为1,可不传 'total_amount' => $total_amount, //单位为分,不小于100 'wishing' => $wishing, // 'client_ip' => '192.168.0.1', //可不传,不传则由 SDK 取当前客户端 IP 'act_name' => $act_name, 'remark' => $remark, // ... ]; $result = $redpack->sendNormal($redpackData); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ //\Log::info($trade_no.'红包订单错误'.json_encode($result)); return $result; // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); // return false; } } catch (Exception $e) { // $this->sms->sentMessage('15872844805', $trade_no.'红包订单错误'); // \Log::debug($trade_no.'红包订单错误:'.$e->getMessage()); return false; } return false; } //发红包 public function sendGroupRedPack($trade_no, $send_name, $total_num=3, $total_amount, $openid, $wishing, $act_name='', $remark='') { $config = config('wechat.payment'); $config['app_id'] = config('wechat.app_id'); $payment = Factory::payment($config); $redpack = $payment->redpack; $redpackData = [ 'mch_billno' => $trade_no, 'send_name' => $send_name, 're_openid' => $openid, 'total_num' => $total_num, //固定为1,可不传 'total_amount' => $total_amount, //单位为分,不小于100 'wishing' => $wishing, // 'client_ip' => '192.168.0.1', //可不传,不传则由 SDK 取当前客户端 IP 'act_name' => $act_name, 'remark' => $remark, // ... ]; $result = $redpack->sendGroup($redpackData); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; // $this->sms->sentMessage('15872844805', '裂变红包发送成功'); }else{ //\Log::info($trade_no.'红包订单错误'.json_encode($result)); return $result; // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); //$this->sms->sentMessage('15872844805', $trade_no.'红包发送失败, 错误原因'.$result['return_msg'].'业务结果'.$result['result_code']); return false; } return false; } public static function checkNormalRedPack($trade_no=1576766055175987) { $res = (object)null; $config = config('wechat.payment'); $config['app_id'] = config('wechat.app_id'); $app = Factory::payment($config); $result = $app->transfer->queryBalanceOrder($trade_no); $res->result = $result; $res->status = false; if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ $res->status = true; }else{ //\Log::info($trade_no.'红包订单错误'.json_encode($result)); // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); } return $res; } //企业付款 小程序 public static function userTransfer($trade_no, $openid, $amount, $desc) { //\Log::info('transfer2'); //测试不检查 if(config('wechat.payment.debug')){ return true; } try { $config = config('wechat.payment'); $config['app_id'] = config('wechat.mini_program.app_id'); $app = Factory::payment($config); $arr = [ 'partner_trade_no' => $trade_no, // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号) 'openid' => $openid, 'check_name' => 'NO_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名 // 're_user_name' => '王小帅', // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名 'amount' => $amount, // 企业付款金额,单位为分 'desc' => $desc, // 企业付款操作说明信息。必填 ]; $result = $app->transfer->toBalance($arr); // dd($result); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ //\Log::info($result); //\Log::info($trade_no.'订单转账错误, 错误返回码'.json_encode($result)); // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); return false; } } catch (\Exception $e) { // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误'); \Log::debug($trade_no.'订单转账错误:'.$e->getMessage()); return false; } } //企业付款 公众号 public function officialUserTransfer($trade_no, $openid, $amount, $desc) { //\Log::info('transfer2'); //测试不检查 if(config('wechat.payment.debug')){ return true; } $app_id = config('wechat.app_id'); $result = $this->transfer($app_id, $trade_no, $openid, $amount, $desc); return $result; } public function transfer($app_id, $trade_no, $openid, $amount, $desc) { try { $config = config('wechat.payment'); $config['app_id'] = $app_id; $app = Factory::payment($config); $arr = [ 'partner_trade_no' => $trade_no, // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号) 'openid' => $openid, 'check_name' => 'NO_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名 // 're_user_name' => '王小帅', // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名 'amount' => $amount, // 企业付款金额,单位为分 'desc' => $desc, // 企业付款操作说明信息。必填 ]; $result = $app->transfer->toBalance($arr); // dd($res) if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return null; }else{ //\Log::info($trade_no.'订单转账错误, 错误返回码'.json_encode($result)); // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); return $result; } } catch (Exception $e) { $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误'); \Log::debug($trade_no.'订单转账错误:'.$e->getMessage()); return true; } } //企业付款 公众号 public function officialUserTransferV2($trade_no, $openid, $amount, $desc) { //\Log::info('transfer2'); //测试不检查 if(config('wechat.payment.debug')){ return true; } $app_id = config('wechat.official_account.new.app_id'); $result = $this->transferV2($app_id, $trade_no, $openid, $amount, $desc); return $result; } public function transferV2($app_id, $trade_no, $openid, $amount, $desc) { try { $config = config('wechat.payment'); $config['app_id'] = $app_id; $app = Factory::payment($config); $arr = [ 'partner_trade_no' => $trade_no, // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号) 'openid' => $openid, 'check_name' => 'NO_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名 // 're_user_name' => '王小帅', // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名 'amount' => $amount, // 企业付款金额,单位为分 'desc' => $desc, // 企业付款操作说明信息。必填 ]; $result = $app->transfer->toBalance($arr); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return null; }else{ \Log::info($trade_no.'订单转账错误, 错误返回码'.json_encode($result)); // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); return $result; } } catch (Exception $e) { $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误'); \Log::debug($trade_no.'订单转账错误:'.$e->getMessage()); return ["msg"=>$e->getMessage(), "err_code_des"=>$e->getMessage()]; } } //企业付款到个人银行卡 公众号 public function bankTransfer($trade_no,$bank_no,$enc_true_name, $bank_code,$amount,$desc) { //\Log::info('transferBank'); //测试不检查 // if(config('wechat.payment.debug')){ // return true; // } $app_id = config('wechat.official_account.new.app_id'); $result = $this->officialBankTransfer($app_id, $trade_no,$bank_no,$enc_true_name,$bank_code,$amount, $desc); return $result; } public function officialBankTransfer($app_id, $trade_no,$bank_no,$enc_true_name,$bank_code, $amount, $desc) { try { $config = config('wechat.payment'); $config['app_id'] = $app_id; $app = Factory::payment($config); $arr = [ 'partner_trade_no' => $trade_no, // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号) 'enc_bank_no' => $bank_no, //银行卡号 'enc_true_name'=>$enc_true_name, //银行卡对应的用户真实姓名 'bank_code' => $bank_code, // 银行编号 例1001 'amount' => $amount, // 付款金额:RMB分(支付总额,不含手续费) 'desc' => $desc, // 付款到银行卡付款说明,即订单备注 非必填 ]; $result = $app->transfer->toBankCard($arr); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return null; }else{ \Log::info($trade_no.'订单转账错误, 错误返回码'.json_encode($result)); $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); return $result; } } catch (Exception $e) { $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误'); \Log::debug($trade_no.'订单转账错误:'.$e->getMessage()); $this->getError($e); // return $result; } } //查询企业付款到个人银行卡 公众号 public function queryBankCardOrder($trade_no) { //\Log::info('transferBank'); //测试不检查 // if(config('wechat.payment.debug')){ // return true; // } $app_id = config('wechat.official_account.new.app_id'); $result = $this->queryBankOrder($app_id, $trade_no); return $result; } //查询企业付款到个人银行卡 公众号 public function queryBankOrder($app_id,$partner_trade_no) { try { $config = config('wechat.payment'); $config['app_id'] = $app_id; $app = Factory::payment($config); $result = $app->transfer->queryBankCardOrder($partner_trade_no); dd($result); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return null; }else{ //\Log::info($partner_trade_no.'订单转账错误, 错误返回码'.json_encode($result)); // $this->sms->sentMessage('15872844805', $trade_no.'订单转账错误, 错误原因'); return $result; } } catch (Exception $e) { // $this->sms->sentMessage('18171893605', $trade_no.'订单转账错误'); // \Log::debug($trade_no.'订单转账错误:'.$e->getMessage()); $this->getError($e); // return $result; } } public function transferred($trade_no) { $app_id = config('wechat.mini_program.app_id'); $result = $this->subTransferred($app_id, $trade_no); return $result; } public function officialTransferred($trade_no) { $app_id = config('wechat.official_account.new.app_id'); $result = $this->subTransferred($app_id, $trade_no); return $result; } public function subTransferred($app_id, $trade_no) { try { $config = config('wechat.payment'); $config['app_id'] = $app_id; $app = Factory::payment($config); $result = $app->transfer->queryBalanceOrder($trade_no); // \Log::info('result: '. json_encode($result)); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ \Log::info($trade_no.'订单检查转账错误, 错误返回码'.json_encode($result)); // $this->sms->sentMessage('15872844805', $trade_no.'订单检查转账错误, 错误原因'.$result['return_msg'].'业务结果'.$result['result_code']); return false; } } catch (Exception $e) { $this->sms->sentMessage('15872844805', $trade_no.'查询订单订单转账错误'); \Log::debug($trade_no.'订单检查转账错误:'.$e->getMessage()); return false; } } //查询订单支付成功? public function orderPaid($orderid){ //测试不检查 if(config('wechat.payment.debug')){ return true; } try{ $order = LoveOrder::where('trade_no', $orderid)->first(); $tourist_order = TouristOrder::where('trade_no', $orderid)->first(); if ((isset($order->pay_type) && $order->pay_type== 'wechat') || (isset($tourist_order->pay_type) && $tourist_order->pay_type == 'wechat')) {//app支付 $love_config = config('wechat.payment'); $love_config['app_id'] = config('wechat.love_app_id'); $payment = Factory::payment($love_config); $rs = $payment->order->queryByOutTradeNumber($orderid); //\Log::info($rs); if ($rs['return_code'] == 'FAIL' || $rs['result_code'] == 'FAIL') { //旧版本用友福同享 $ufutx_config = config('wechat.ufutx_payment'); $ufutx_config['app_id'] = config('wechat.love_app_id'); $payment = Factory::payment($ufutx_config); $rs = $payment->order->queryByOutTradeNumber($orderid); } }else{ $config = config('wechat.payment'); $config['app_id'] = config('wechat.mini_program.app_id'); $payment = Factory::payment($config); $rs = $payment->order->queryByOutTradeNumber($orderid); } if($rs['return_code'] == 'SUCCESS' && $rs['result_code'] == 'SUCCESS'){ if($rs['trade_state'] == 'SUCCESS'){ return true; }else{ \Log::debug($orderid.'交易状态:'.$rs['trade_state']); return false; } }else{ \Log::debug($orderid.'业务状态:'.$rs['err_code'].$rs['err_code_des']); return false; } }catch(\Exception $e){ //abort(505, $orderid.'订单查询异常:'.$e->getMessage()); \Log::debug($orderid.'订单查询异常:'.$e->getMessage()); return false; } } /** * 服务端查询H5订单支付是否成功? */ public function serverH5OrderPaid($order_id){ //测试不检查 if(config('wechat.payment.debug')){ return true; } try{ $order = TouristOrder::where('trade_no', $order_id)->first(); $love_config = config('wechat.payment'); $love_config['app_id'] = config('wechat.official_account.new.app_id'); $payment = Factory::payment($love_config); $rs = $payment->order->queryByOutTradeNumber($order_id); //\Log::info($rs); if($rs['return_code'] == 'SUCCESS' && $rs['result_code'] == 'SUCCESS'){ if($rs['trade_state'] == 'SUCCESS'){ return true; }else{ \Log::debug($order_id.'交易状态:'.$rs['trade_state']); return false; } }else{ \Log::debug($order_id.'业务状态:'.$rs['err_code'].$rs['err_code_des']); return false; } }catch(\Exception $e){ //abort(505, $orderid.'订单查询异常:'.$e->getMessage()); \Log::debug($order_id.'订单查询异常:'.$e->getMessage()); return false; } } //查询h5订单支付成功? public function officialOrderPaid($orderid){ //测试不检查 if(config('wechat.payment.debug')){ return true; } try{ $order = LoveOrder::where('trade_no', $orderid)->first(); if ($order->pay_type == 'h5') {//h5支付 $love_config = config('wechat.payment'); $love_config['app_id'] = config('wechat.official_account.new.app_id'); $payment = Factory::payment($love_config); $rs = $payment->order->queryByOutTradeNumber($orderid); //\Log::info($rs); } if($rs['return_code'] == 'SUCCESS' && $rs['result_code'] == 'SUCCESS'){ if($rs['trade_state'] == 'SUCCESS'){ return true; }else{ \Log::debug($orderid.'交易状态:'.$rs['trade_state']); return false; } }else{ \Log::debug($orderid.'业务状态:'.$rs['err_code'].$rs['err_code_des']); return false; } }catch(\Exception $e){ //abort(505, $orderid.'订单查询异常:'.$e->getMessage()); \Log::debug($orderid.'订单查询异常:'.$e->getMessage()); return false; } } /** * 退款订单查询 * @param string $refund_trade_no 退款订单号 * @return bool */ public function orderRefunded($refund_trade_no) { if(config('wechat.payment.debug')){ return true; } try{ $config = config('wechat.payment'); $config['app_id'] = config('wechat.mini_program.app_id'); $payment = Factory::payment($config); $rs = $payment->refund->queryByOutRefundNumber($refund_trade_no); if($rs['return_code'] == 'SUCCESS' && $rs['result_code'] == 'SUCCESS'){ return true; }else{ \Log::debug($refund_trade_no.'业务状态:'.$rs['err_code'].$rs['err_code_des']); $this->sms->sentMessage('15872844805', $refund_trade_no.'订单查询退款异常, 错误返回码'.$rs['err_code']); return false; } }catch(\Exception $e){ //abort(505, $orderid.'订单查询异常:'.$e->getMessage()); \Log::debug($refund_trade_no.'订单查询退款异常:'.$e->getMessage()); $this->sms->sentMessage('15872844805', $refund_trade_no.'订单查询退款异常'); return false; } } /** * 订单退款 * @param string $trade_no 原订单号 * @param string $refund_trade_no 退款订单号 * @param int $total_fee 总金额(分) * @param int $refund_fee 退款金额(分) * @param array $array 其他参数 * @return bool 是否成功 */ public function orderRefund($trade_no, $refund_trade_no, $total_fee, $refund_fee, $array=[]) { if(config('wechat.payment.debug')){ return true; } try { $array['notify_url'] = env('APP_URL').'/api/admin/order/refun/callback'; $config = config('wechat.payment'); $config['app_id'] = config('wechat.mini_program.app_id'); $config['notify_url'] = config('app.url').'/api/admin/order/refun/callback'; $payment = Factory::payment($config); $total_fee = (int)number_format($total_fee, 2, '', ''); $refund_fee = (int)number_format($refund_fee, 2, '', ''); Log::info("退款信息:"); Log::info($trade_no); Log::info($refund_trade_no); Log::info($total_fee); Log::info($refund_fee); Log::info("arr",$array); // 参数分别为:商户订单号、商户退款单号、订单金额、退款金额、其他参数 $result = $payment->refund->byOutTradeNumber($trade_no, $refund_trade_no, $total_fee, $refund_fee, $array); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return ['status'=>true,'err_msg'=>null]; }else{ \Log::info($refund_trade_no.'订单退款异常, 错误返回码'.json_encode($result));//err_code_des $this->sms->sentMessage('15872844805', $refund_trade_no.'订单退款异常, 业务结果'.$result['err_code']); return ['status'=>false,'err_msg'=>$result['err_code_des']]; } } catch (Exception $e) { $this->sms->sentMessage('15872844805', $refund_trade_no.'订单退款异常'); \Log::debug($refund_trade_no.'订单退款异常:'.$e->getMessage()); return false; } } /** * 聊天通知 */ public function chatMessageNotice($param=[]) { $template_id = config('wechat.tpls.chat_message_notice'); $page = 'pages/users/myMessage'; $openid = $param['openid']; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['name'], 'keyword2'=>$param['created_at'], 'keyword3'=>$param['message'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 等级升级通知 */ public function rankNotice($param=[]) { //\Log::info('测试'); $template_id = config('wechat.tpls.rank_notice'); $page = 'pages/tabBar/users/index'; $openid = $param['openid']; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['rank_name'], 'keyword2'=>'终身会员', 'keyword3'=>$param['privilege'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 访问通知 */ public function visitNotice($param=[]) { $template_id = config('wechat.tpls.visit_notice'); $page = 'pages/home/information?id='.$param['user_id']; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['user_name'], 'keyword2'=>$param['visit_time'], 'keyword3'=>$param['message'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 临时会员到期通知 */ public function VIPEndNotice($param=[]) { $template_id = config('wechat.tpls.vip_end_notice'); $page = 'pages/tabBar/home'; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['rank_name'], 'keyword2'=>$param['time'], 'keyword3'=>$param['message'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 临时会员到期通知 */ public function VIPStartNotice($param=[]) { $template_id = config('wechat.tpls.vip_start_notice'); $page = 'pages/tabBar/user'; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['rank_name'], 'keyword2'=>$param['name'], 'keyword3'=>$param['end_time'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 推荐提醒 * @param array $param [description] * @return [type] [description] */ public function recommendSingleNotice($param=[]) { $template_id = config('wechat.tpls.recommend_single'); $page = 'pages/home/information?id='.$param['user_id'].'&channel='.((isset($param['channel']))?$param['channel']:''); $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['name'], 'keyword2'=>$param['time'], 'keyword3'=>$param['message'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 好友申请通知 * @param array $param [description] */ public function addFriendNotice($param=[]) { $template_id = config('wechat.tpls.add_friend_notice'); $page = 'pages/users/friendRequest?id='.$param['user_id']; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['name'], 'keyword2'=>$param['time'], 'keyword3'=>$param['message'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 好友请求处理 * @param array $param [description] * @return [type] [description] */ public function dealFriendRequest($param=[]) { $template_id = config('wechat.tpls.deal_friend_request'); $page = 'pages/home/information?id='.$param['user_id']; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['name'], 'keyword2'=>$param['message'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } /** * 会员到期提醒 * @param array $param [description] * @return [type] [description] */ public function vipDeadline($param=[]) { $template_id = config('wechat.tpls.vip_deadline'); $page = 'pages/tabBar/home/indexv2'; $form_id = $param['form_id']; $data = [ 'keyword1'=>$param['rank_name'], 'keyword2'=>$param['remain_time'], 'keyword3'=>$param['deadline'], 'keyword4'=>$param['message'], ]; return $this->send($param['openid'], $template_id, $page, $form_id, $data); } public function agRecommendNotcie($param=[]) { $template_id = config('wechat.tpls.ag_recommend_notice'); $path = 'pages/home/information?id='.$param['user_id'].'&channel='.((isset($param['channel']))?$param['channel']:'');; $data = [ 'first'=> $param['title'], 'keyword1'=>$param['host'], 'keyword2'=>[ 'value'=>$param['user_info'], 'color'=>'#e74c3c' ], 'keyword3'=>date('Y-m-d H:i:s'), 'remark'=> $param['remark'], ]; $url = env('APP_URL')."/mobile/#/information/".$param['user_id']; return $this->sendToMiniProgram($param['openid'], $template_id, $path, $data, $url); } /** * 访客提醒 */ public function visitNoticeV2($param=[]) { $template_id = config('wechat.tpls.visit_notice_v2'); $path = 'pages/home/information?id='.$param['user_id']; $data = [ 'thing1'=>["value"=>$param['name']], 'time2'=>["value"=>$param['date']], 'thing9'=>["value"=>$param['from']], ]; $url = env('APP_URL')."/mobile/#/information/".$param['user_id']; if (isset($param['openid']) && $param['openid']) { return $this->sendToMiniProgram($param['openid'], $template_id, $path, $data, $url); } } /** 受邀请后,注册成功,提示邀请者 */ public function beRecommendNotcie($user_id,$nickname,$title,$touser_openid){ $template_id = config('wechat.tpls.be_invite_succeed_notice'); $path = 'pages/home/information?id='.$user_id; $data = [ 'first'=> $title, 'keyword1'=>$nickname, 'keyword2'=>date('Y-m-d H:i:s'), 'remark'=> '感谢您的使用', ]; $url = env('APP_URL')."/mobile/#/information/".$user_id; return $this->sendToMiniProgram($touser_openid, $template_id, $path, $data, $url); } /** 客服收到新消息 提示客服 */ public function remindServiceClient($user,$service){ $param['touser'] = $service->wechat ? $service->wechat->official_openid : null; $name = $user->nickname ?: $user->name; // $param['template_id'] = config('wechat.tpls.activity_audited_notice'); // $param['url'] = env('APP_URL').'/admin_pro/?#/platformMGT/activityMGT'; $param['data'] = [ 'first' => '有用户发来了新的消息', 'keyword1' => $name, //客户姓名 'keyword2' => $user->mobile,//客户手机 'remark' => '请及时处理', ]; $this->send($param['touser'], $param['template_id'], $param['url'], $param['data'], $param['miniprogram']??null); } public function ShareSuccessNotice($param=[]) { $url = env('APP_URL').'/red/packet/activity/wechat/auth'; $template_id = config('wechat.tpls.ag_recommend_notice'); $data = [ 'first'=> '【集九果分百万红包】分享成功', 'keyword1'=> $param['share_user_name'], 'keyword2'=>$param['user_name'], 'remark'=> '恭喜您!获得'.$param['chance'].'次收集果子机会,马上领取GO!', ]; $url = $param['url']; return $this->sendToOfficial($param['openid'], $template_id, $data, $url); } public function reportStatisticNotice($param=[]) { $template_id = 'aE8sNkjBajSdX8qcV2pwFhSNXQcCfjjKtwEXfbddVdA'; $data = [ 'first'=> $param['first'], 'keyword1'=> $param['keyword1'], 'keyword2'=>$param['keyword2'], 'keyword3'=>$param['keyword3'], 'remark'=> $param['remark'], ]; $url = ''; return $this->sendToOfficial($param['openid'], $template_id, $data, $url); } public function activitySuccessNotice($param=[]) { $template_id = config('wechat.tpls.activity_success_notice'); $path = 'pages/party/detail?party_id='.$param['activity_id']; $data = [ 'first'=> '活动报名通知', 'keyword1'=> $param['title'], 'keyword2'=> $param['start_time'], 'keyword3'=> $param['address'], 'remark'=> '用户'.$param['user_name'].'['.$param['user_mobile'].']报名活动成功', ]; // $url = env('APP_URL')."/mobile/#/information/".$param['activity_id']; return $this->sendToMiniProgram($param['openid'], $template_id, $path, $data); } public function sendToOfficial($openid, $template_id, $data, $url='') { try { $data = [ 'touser' => $openid, 'template_id' => $template_id, 'url' => $url, 'data' =>$data, ]; $result = $this->official_app->template_message->send($data); //Log::info($result); if ($result['errcode'] == 0) {//记录模板消息发送成功 $data['status'] = 1; $data['err_msg'] = null; }else{ $data['status'] = 0; $data['err_msg'] = $result['errmsg']; } $data['type'] = 'official'; $this->addTemplateMsgLog($data); return $result; } catch (\Exception $e) { $this->getError($e); return false; } } public function sendToMiniProgram($openid, $template_id, $path, $data, $url='') { try { $data = [ 'touser' => $openid, 'template_id' => $template_id, 'url'=> $url, 'miniprogram' => [ 'appid' => config('wechat.mini_program.app_id'), 'pagepath' => $path, ], 'data' => $data, ]; $result = $this->official_app->template_message->send($data); //Log::info($result); if ($result['errcode'] == 0) {//记录模板消息发送成功 $data['status'] = 1; $data['err_msg'] = null; }else{ $data['status'] = 0; $data['err_msg'] = $result['errmsg']; } $data['type'] = 'official'; $this->addTemplateMsgLog($data); } catch (\Exception $e) { $this->getError($e); return false; } } /** * 发送模板消息 */ public function send($openid, $template_id, $page, $form_id,$data=[]){ try { $all_data = [ 'touser' => $openid, 'template_id' => $template_id, 'page' => $page, 'form_id' => $form_id, 'data' =>$data, ]; $result = $this->app->template_message->send($all_data); //Log::info($result); if ($result['errcode'] == 0) {//记录模板消息发送成功 $all_data['status'] = 1; $all_data['err_msg'] = null; }else{ $all_data['status'] = 0; $all_data['err_msg'] = $result['errmsg']; } $all_data['type'] = 'mp'; $this->addTemplateMsgLog($all_data); } catch (\Exception $e) { $this->getError($e); return false; } } /** * 订阅消息 */ //活动报名成功订阅通知 public function activitySuccessSubNotice($param=[]) { $template_id = config('wechat.sub_tpls.activity_success_notice'); $page = "pages/party/detail?party_id=".$param['activity_id']; $data = [ 'thing2'=>["value"=>$param['title']], 'thing3'=>["value"=>$param['address']], 'time4'=>["value"=>$param['start_time']], 'phrase1'=>["value"=>"已报名"], ]; return $this->subSend($param['openid'], $template_id, $page, $data); } /** * 订单支付成功通知 */ public function orderSuccessSubNotice($param=[]) { $template_id = config('wechat.sub_tpls.order_success_notice'); $page = "pages/users/myPay"; $data = [ 'thing1'=>["value"=>$param['name']], 'amount5'=>["value"=>$param['price']], 'date6'=>["value"=>$param['updated_at']], 'thing8'=>["value"=>""], ]; return $this->subSend($param['openid'], $template_id, $page, $data); } /** * 签约提醒订阅消息 * @param array $param [description] * @return [type] [description] */ public function signInSubNotice($param=[]) { $template_id = config('wechat.sub_tpls.sign_in_notice'); $page = "pages/tabBar/welcome"; $data = [ 'thing7' => ['value' => $param['sign_num']], // 累计签到次数 'thing6' => ['value' => $param['award']], // 待领取奖励 'time8' => ['value' => date('Y-m-d H:i:s')], // 签到时间 'thing4' => ['value' => $param['prompt']], // 温馨提示 ]; return $this->subSend($param['openid'], $template_id, $page, $data); } /** * 被关注订阅消息 * @param array $param [description] * @return [type] [description] */ public function followedNotice($param=[]) { $template_id = config('wechat.sub_tpls.follow_notice'); $page = "pages/home/information?id=".$param['user_id']; $data = [ 'name1' => ['value' => $param['nickname']], // 用户昵称 'time2' => ['value' => $param['time']], // 关注时间 ]; return $this->subSend($param['openid'], $template_id, $page, $data); } public function friendRequestNotice($param=[]) { $template_id = config('wechat.sub_tpls.add_friend_notice'); $page = "pages/users/friendRequest"; $data = [ 'name3' => ['value' => $param['nickname']], // 用户昵称 'date1' => ['value' => $param['time']], // 申请时间 'thing2' => ['value' => $param['prompt']], // 提醒 ]; return $this->subSend($param['openid'], $template_id, $page, $data); } //活动结束发送问卷调查 public function sendActivityQuestionaireSurvey($param=[]) { $template_id = config('wechat.sub_tpls.activity_questionaire_servey_notice'); $page = "pages/users/questionnaire?type_id=".$param['activity_id']; $data = [ 'thing1' => ['value' => $param['nickname']], // 用户昵称 'thing2' => ['value' => $param['theme']], // 活动主题 'time3' => ['value' => $param['time']], // 活动时间 'thing4' => ['value' => $param['desc']], // 描述 ]; return $this->subSendV2($param['openid'], $template_id, $page, $data); } //团约组团成功通知(发送给拼团人员) public function sendJoinGroupNotice($param=[]) { //\Log::info('join_group_success_notice'); $template_id = config('wechat.sub_tpls.join_group_success_notice'); // $page = "pages/users/questionnaire?type_id=".$param['type_id'];/pages/party/SpellGroupOrder $page = "pages/party/SpellGroupData?order_id=".$param['order_id']."&history_id=".$param['history_id']; $desc = $param['status'] == 0 ? $param['team_desc'] : $param['desc']; $data = [ 'thing1' => ['value' => $param['title']], // 拼团商品名 'amount2' => ['value' => $param['price']], // 拼团价格 'thing3' => ['value' => $param['num']], // 拼团人数 'time4' => ['value' => $param['deadline']], // 到期时间 'thing5' => ['value' => $desc], // 温馨提示 ]; return $this->subSendV2($param['openid'], $template_id, $page, $data); } //拼团开始通知(发给团长的通知) public function stratGroupNotice($param){ $template_id = config('wechat.sub_tpls.start_group_notice'); $page = "pages/party/SpellGroupOrder?order_id=".$param['order_id']; $time = date('Y-m-d H:i:s'); //\Log::info('start_group_notice '.$template_id . 'openid='.$param['openid']); $data = [ 'thing1' => ['value' => $param['title']], // 拼团商品名 'time2' => ['value' => $time], // 开团时间 'thing3' => ['value' => $param['num']], // 拼团人数 'thing4' => ['value' => $param['lead_desc']], // 温馨提示 ]; return $this->subSendV2($param['openid'], $template_id, $page, $data); } public function subSendV2($openid, $template_id, $page, $data=[]) { try { if (empty($openid)) return false; $all_data = [ 'template_id'=>$template_id, 'touser'=>$openid, 'page'=>$page, 'data'=>$data, ]; $app = $this->app(); $result = $app->subscribe_message->send($all_data); //\Log::info($result); if ($result['errcode'] == 0) {//记录模板消息发送成功 $all_data['status'] = 1; $all_data['err_msg'] = null; }else{ $all_data['status'] = 0; $all_data['err_msg'] = $result['errmsg']; } $all_data['type'] = 'mp'; $this->addTemplateMsgLog($all_data); return $result; } catch (\Exception $e) { $this->getError($e); return false; } return true; } /** * [matchNotice description] * @param array $param [description] * @return [type] [description] */ public function matchNotice($param=[]) { $template_id = config('wechat.sub_tpls.match_notice'); $page = "pages/tabBar/welcome"; $data = [ 'thing1' => ['value' => $param['target_name']], // 对像名称 'thing2' => ['value' => $param['match_type']], // 匹配类型 'thing3' => ['value' => $param['tips']], // 温馨提示 ]; return $this->subSend($param['openid'], $template_id, $page, $data); } /** * 发送处理好友请求通知 * @param array $param [description] * @return [type] [description] */ public function dealFriendRequestNotice($param=[]) { $template_id = config('wechat.sub_tpls.deal_friend_request_notice'); if(!$template_id || is_bool($param) || empty($param['user_id'])){ return false; } $page = "pages/home/information?id=".$param['user_id']; $data = [ 'name1' => ['value' => $param['nickname']], // 昵称 'time2' => ['value' => $param['time']], // 时间 'thing3' => ['value' => $param['prompt']], // 提醒 ]; return $this->subSend($param['openid'], $template_id, $page, $data); } public function vistitLogNotice($param=[]) { $template_id = config('wechat.sub_tpls.day_visit_notice'); $page = "pages/users/visitor"; $data = [ 'thing1' => ['value' => $param['nickname_str']], // 访问列表 'time2' => ['value' => $param['time']], // 时间 ]; return $this->subSend($param['openid'], $template_id, $page, $data); } public function subSend($openid, $template_id, $page, $data=[]) { try { if (empty($openid)) return false; $all_data = [ 'template_id'=>$template_id, 'touser'=>$openid, 'page'=>$page, 'data'=>$data, ]; $app = $this->app(); $result = $app->subscribe_message->send($all_data); if ($result['errcode'] == 0) {//记录模板消息发送成功 $all_data['status'] = 1; $all_data['err_msg'] = null; }else{ $all_data['status'] = 0; $all_data['err_msg'] = $result['errmsg']; } $all_data['type'] = 'mp'; $this->addTemplateMsgLog($all_data); return $result; } catch (\Exception $e) { $this->getError($e); return false; } return true; } public function addTemplateMsgLog($data) { $where = $data['type'] == 'mp'?['openid'=>$data['touser']]:['official_openid'=>$data['touser']]; $user_id = Wechat::where($where)->value('user_id'); $log = new TemplateMsgLog; $log->user_id = $user_id; $log->openid = $data['touser']; $log->type = $data['type']; $log->template_id = $data['template_id']; $log->status = $data['status']; $log->err_msg = $data['err_msg']; $log->data = json_encode($data); $log->save(); return true; } /** * 获取关注公众号的用户列表 */ public function getOfficialAccountsUserOpenId(){ $result = $this->official_app->user->list(); if(!empty($result) && !empty($result['data']['openid'])){ $redis = Redis::connection('big_data'); $old_user_openId_list = $redis->keys('officialAccountsUserOpenIdList:*'); if(!empty($old_user_openId_list)){ $redis->del($old_user_openId_list); } $user_openId_list_key = 'officialAccountsUserOpenIdList:'.date('Y-m-d H:i:s'); $redis->set($user_openId_list_key,json_encode(['data'=>$result['data']['openid']])); return $result['data']['openid']; } } /** * 获取用户信息 * @param $openid * @return mixed */ public function getOfficialAccountUser($openid) { $result = $this->official_app->user->get($openid); return $result; } /** * 单次分帐 * @param $transaction_id //微信支付订单号 * @param $out_trade_no //商户分账单号,即商户订单号 * @param $receivers * @param $sub_merchant_id */ public function wechatShare($transaction_id,$out_trade_no,$receivers,$sub_merchant_id){ $config = config('wechat.service_payment'); $config['cert_path'] = storage_path('wechat/service-cert.pem'); $config['key_path'] = storage_path('wechat/service-key.pem'); $payment = Factory::payment($config); $payment->setSubMerchant($sub_merchant_id); $result = $payment->profit_sharing->share($transaction_id,$out_trade_no,$receivers); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ return false; } } /** * 多次分帐 未测试 注意:每次分帐要记下分帐订单号,否则不能进行下一次分帐 * @param $transaction_id //微信支付订单号 * @param $out_trade_no //商户分账单号,即商户订单号 * @param $receivers * @param $sub_merchant_id */ public function wechatMultiShare($transaction_id,$out_trade_no,$receivers,$sub_merchant_id){ $config = config('wechat.service_payment'); $config['cert_path'] = storage_path('wechat/service_cert.pem'); $config['key_path'] = storage_path('wechat/service_key.pem'); $payment = Factory::payment($config); $payment->setSubMerchant($sub_merchant_id); $result = $payment->profit_sharing->multiShare($transaction_id,$out_trade_no,$receivers); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ return false; } } /** * 追加分帐接收方 * @param $transaction_id //微信支付订单号 * @param $out_trade_no //商户分账单号,即商户订单号 * @return array|Support\Collection|object|\Psr\Http\Message\ResponseInterface|string * @throws EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws EasyWeChat\Kernel\Exceptions\InvalidConfigException * @throws \GuzzleHttp\Exception\GuzzleException */ public function addReceivers($receiver,$sub_merchant_id){ $config = config('wechat.service_payment'); $payment = Factory::payment($config); $payment->setSubMerchant($sub_merchant_id); $result = $payment->profit_sharing->addReceiver($receiver); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ return false; } } /** * 分帐完结 单次分帐不用此接口 * @param $transaction_id //微信支付订单号 * @param $out_trade_no //商户分账单号,即商户订单号 * @param $sub_merchant_id */ public function markOrderAsFinished($transaction_id,$out_trade_no,$sub_merchant_id){ $config = config('wechat.service_payment'); $config['cert_path'] = storage_path('wechat/service-cert.pem'); $config['key_path'] = storage_path('wechat/service-key.pem'); $payment = Factory::payment($config); $payment->setSubMerchant($sub_merchant_id); $params = [ "transaction_id" => $transaction_id, "out_order_no" => $out_trade_no, "description" => "分账完成" ]; $result = $payment->profit_sharing->markOrderAsFinished($params); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ return false; } } /** * 分帐查询 * @param $transaction_id //微信支付订单号 * @param $out_trade_no //商户分账单号,即商户订单号 * @param $sub_merchant_id */ public function wechatShareQuery($transaction_id,$out_trade_no,$sub_merchant_id){ $config = config('wechat.service_payment'); $payment = Factory::payment($config); $payment->setSubMerchant($sub_merchant_id); $result = $payment->profit_sharing->query($transaction_id,$out_trade_no); if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ return true; }else{ return false; } } /** * 商家批量转账到零钱 * @param $trade_no //商家批次单号 * @param $batch_name //批次名称 * @param $batch_remark //批次备注 * @param $total_amount //转账总金额 * @param $transfer_list //转账明细列表 */ public function transferBatches($trade_no, $batch_name, $batch_remark, $total_amount, $transfer_list) { // $transfer_list = [ // [ // 'out_detail_no' => \App\Facades\CommonUtilsService::getTradeNO(), // 'transfer_amount' => 1, // 'transfer_remark'=>'测试转账', // 'openid'=>'oPC_2vneOWpQbicNZQAUCxuwZ4mw', // 'user_name'=>'', // ] // ] try { $resp = $this->instance ->chain('v3/transfer/batches') ->post(['json' => [ 'appid' => config('wechat.official_account.new.app_id'), 'out_trade_no' => $trade_no, 'batch_name' => $batch_name, 'batch_remark' => $batch_remark, 'total_amount' => $total_amount, 'total_num' => count($transfer_list), 'transfer_detail_list' => $transfer_list, 'transfer_scene_id' => '', ]]); }catch (\Exception $e) { dd($e->getMessage()); } } /** * url link */ public function urlLink($params) { $app = $this->app(); $accessToken = $app->access_token; $token = $accessToken->getToken(); $access_token = $token['access_token']; $url = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=".$access_token; // dd($params); $client = new Client(); $response = $client->request('POST', $url, [ 'json' => $params ]); $res = json_decode($response->getBody(), true); if (isset($res['errcode']) && $res['errcode'] == 0) return $res['url_link']; throw new Exception("请求url link失败, ". $res['errmsg']); } /** * 申请服务商签约商户 */ public function applymentSub($business_code, $contact_info, $subject_info,$business_info, $settlement_info, $bank_account_info, $addition_info) { $instance = $this->paymentInstance(); $resp = $instance->chain('v3/applyment4sub/applyment/') ->post(['json' => [ 'business_code' => $business_code, 'contact_info' => $contact_info, 'subject_info' => $subject_info, 'business_info' => $business_info, 'settlement_info' => $settlement_info, 'bank_account_info' => $bank_account_info, 'addition_info' => $addition_info, ]]); return json_decode($resp->getBody()); } public function applymentWithCode($code) { $instance = $this->paymentInstance(); $resp = $instance ->chain("v3/applyment4sub/applyment/business_code/$code") ->get(); return json_decode($resp->getBody()); } public function applymentWithId($id) { $resp = $this->instance ->chain("v3/applyment4sub/applyment/applyment_id/$id") ->get(); return json_decode($resp->getBody()); } function getEncrypt($str) { //$str是待加密字符串 $public_key_path = 'file://'.config('wechat.payment.cert_path'); //平台证书路径 $public_key = file_get_contents($public_key_path); $encrypted = ''; if (openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING)) { //base64编码 $sign = base64_encode($encrypted); } else { throw new Exception('encrypt failed'); } return $sign; } public function mediaUpload($path) { $media = new MediaUtil($path); $instance = $this->paymentInstance(); $resp = $instance->chain("v3/merchant/media/upload") ->post([ "body" => $media->getStream(), "headers" => [ "content-type" => $media->getContentType(), ] ]); return json_decode($resp->getBody()); } public function partnerPay($order_id, $sub_mchid, $total, $openid, $trade_no, $notify_url, $desc) { // $openid = "oPC_2vneOWpQbicNZQAUCxuwZ4mw"; $attributes = [ 'sp_appid' => config('wechat.service_payment.app_id'), 'sp_mchid' => config('wechat.service_payment.mch_id'), 'sub_mchid' => $sub_mchid, 'description' => $desc, 'out_trade_no' => $trade_no, 'notify_url' => $notify_url, 'amount' => [ "total" => (int)number_format( $total * 100, 0,'',''), 'currency' => 'CNY' ], 'payer' => [ 'sp_openid' => $openid, ] ]; $instance = $this->paymentInstance(); $resp = $instance->chain('v3/pay/partner/transactions/jsapi') ->post(['json' => $attributes]); $res = json_decode($resp->getBody()); $prepay_id = $res->prepay_id; $config = $this->paySign($prepay_id); $config['prepay_id'] = $prepay_id; $attributes['order_id'] = $order_id; return ['config'=>$config, 'attributes'=>$attributes]; } public function partnerOrderPaid($trade_no, $sub_mchid) { $sp_mchid = config('wechat.service_payment.mch_id'); $instance = $this->paymentInstance(); $resp = $instance->chain("v3/pay/partner/transactions/out-trade-no/{$trade_no}?sp_mchid={$sp_mchid}&sub_mchid={$sub_mchid}") ->get(); return json_decode($resp->getBody()); } /** * 支付签名 * @param $prepay_id * @return array */ public function paySign($prepay_id) { $merchantPrivateKeyFilePath = 'file://'.config('wechat.service_payment.key_path'); $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath); $params = [ 'appId' => config('wechat.official_account.new.app_id'), 'timestamp' => (string)Formatter::timestamp(), 'nonceStr' => Formatter::nonce(), 'package' => 'prepay_id='.$prepay_id, ]; $params += ['paySign' => Rsa::sign( Formatter::joinedByLineFeed(...array_values($params)), $merchantPrivateKeyInstance ), 'signType' => 'RSA']; return $params; } }