= self::$ErrorSum) return exception('请配置支付宝公钥私钥APPID'); if ((!self::$alipayAppId || !self::$alipayPublicKey || !self::$alipayPrivateKey) && !$confing) self::confing(true); if (isset($confing['returnUrl'])) self::$returnUrl = $confing['returnUrl']; if (isset($confing['notifyUrl'])) self::$returnUrl = $confing['notifyUrl']; if (isset($confing['signType'])) self::$signType = $confing['signType']; if (isset($confing['charset'])) self::$charset = $confing['charset']; if (isset($confing['alipay_app_id'])) self::$alipayAppId = $confing['alipay_app_id']; if (isset($confing['alipay_public_key'])) self::$alipayPublicKey = $confing['alipay_public_key']; if (isset($confing['alipay_private_key'])) self::$alipayPrivateKey = $confing['alipay_private_key']; if (isset($confing['appCertPublicKey'])) self::$appCertPublicKey = $confing['appCertPublicKey']; if (isset($confing['alipayCertPublicKey'])) self::$alipayCertPublicKey = $confing['alipayCertPublicKey']; if (isset($confing['alipayRootCert'])) self::$alipayRootCert = $confing['alipayRootCert']; if (!self::$alipayAppId || !self::$alipayPublicKey || !self::$alipayPrivateKey) exception('请配置支付宝公钥私钥APPID'); self::$ErrorCount = 0; } /** * 设置加密方式 * @param $signType * @return $this */ public function setSignType($signType) { self::$signType = $signType; return $this; } /** * 设置同步回调地址 * @param $returnUrl * @return $this */ public function setReturnUrl($returnUrl) { self::$returnUrl = $returnUrl; return $this; } /** * 设置异步回调地址 * @param $notifyUrl */ public function setNotifyUrl($notifyUrl) { self::$notifyUrl = $notifyUrl; return $this; } /** * 设置业务参数 * @param array $biz_content * @return string */ protected static function setBizContent(array $biz_content = []) { if (isset($biz_content['passback_params'])) $biz_content['passback_params'] = urlencode($biz_content['passback_params']); if (isset($biz_content['trade_no']) && empty($biz_content['trade_no'])) unset($biz_content['trade_no']); $bizContent = json_encode($biz_content); //打印业务参数 self::$isDeBug && self::WriteLog($bizContent); return $bizContent; } /** * 获取同步回调地址 * @return mixed */ public function getReturnUrl() { return self::$returnUrl; } /** * 获取异步回调地址 * @return mixed */ public function getNotifyUrl() { return self::$notifyUrl; } /** * 读取系统配置赋值给静态变量 并加载支付宝官方支付sdk * @param bool $isReturn * @return AlipayTradeWapService */ public static function confing($isReturn = false) { $confing = SystemConfigService::more([ 'alipay_public_key', 'alipay_app_id', 'alipay_private_key', 'appCertPublicKey', 'alipayCertPublicKey', 'alipayRootCert', ]); self::$alipayAppId = isset($confing['alipay_app_id']) ? trim($confing['alipay_app_id']) : ''; self::$alipayPublicKey = isset($confing['alipay_public_key']) ? trim($confing['alipay_public_key']) : ''; self::$alipayPrivateKey = isset($confing['alipay_private_key']) ? trim($confing['alipay_private_key']) : ''; self::$returnUrl = SystemConfigService::get('site_url') . Url::build('wap/alipay/alipay_success_synchro'); self::$notifyUrl = SystemConfigService::get('site_url') . Url::build('wap/alipay/alipay_success_notify'); self::$alipayRootCert =$confing['alipayRootCert'] ? ROOT_PATH .'public' .$confing['alipayRootCert'] : ''; self::$alipayCertPublicKey =$confing['alipayCertPublicKey'] ? ROOT_PATH .'public' .$confing['alipayCertPublicKey'] : ''; self::$appCertPublicKey =$confing['appCertPublicKey'] ? ROOT_PATH .'public' .$confing['appCertPublicKey'] : ''; vendor('alipay.AopSdk'); if ($isReturn == false) return new self; } /** * 静态调用初始化数据 * @return AlipayTradeWapService */ public static function init() { return self::confing(); } /** * 支付宝异步回调 */ public static function handleNotify() { self::init()->AliPayNotify(function ($data, $result) { if ($result && isset($data->out_trade_no) && $data->passback_params) { if ($data->passback_params == 'special') { StoreOrder::where('order_id', $data->out_trade_no)->where('type', 0)->update(['trade_no' => $data->trade_no]); } elseif ($data->passback_params == 'signup') { EventSignUp::where('order_id', $data->out_trade_no)->update(['trade_no' => $data->trade_no]); } elseif ($data->passback_params == 'member') { StoreOrder::where('order_id', $data->out_trade_no)->where('type', 1)->update(['trade_no' => $data->trade_no]); } elseif ($data->passback_params == 'goods') { StoreOrder::where('order_id', $data->out_trade_no)->where('type', 2)->update(['trade_no' => $data->trade_no]); } elseif ($data->passback_params == 'testpaper') { TestPaperOrder::where('order_id', $data->out_trade_no)->update(['trade_no' => $data->trade_no]); } elseif ($data->passback_params == 'datadownload') { DataDownloadOrder::where('order_id', $data->out_trade_no)->update(['trade_no' => $data->trade_no]); } elseif ($data->passback_params == 'recharge') { UserRecharge::where('order_id', $data->out_trade_no)->update(['trade_no' => $data->trade_no]); } HookService::listen('wechat_pay_success', $data, null, true, PaymentBehavior::class); } }); } /** * 支付宝异步回调 * @param callable $notifyFn 闭包函数 参数1,回调返回的参数,回调结果 * @return bool */ protected function AliPayNotify(callable $notifyFn) { $post = Request::instance()->post(); $result = self::AliPaycheck($post); if ($result) { //商户订单号 $post['out_trade_no'] = isset($post['out_trade_no']) ? $post['out_trade_no'] : ''; //支付宝交易号 $post['trade_no'] = isset($post['trade_no']) ? $post['trade_no'] : ''; //交易状态 $post['trade_status'] = isset($post['trade_status']) ? $post['trade_status'] : ''; //备注 $post['attach'] = isset($post['passback_params']) ? urldecode($post['passback_params']) : ''; //异步回调成功执行 try { if (is_callable($notifyFn)) $notifyFn((object)$post, $result); } catch (\Exception $e) { self::$isDeBug && self::WriteLog('支付宝支付成功,订单号为:' . $post['out_trade_no'] . '.回调报错:' . $e->getMessage()); } echo 'success'; } else { echo 'fail'; } self::$isDeBug && self::WriteLog($result); return true; } /** * 支付宝同步回调 * @return array */ public function AliPayReturn() { //获取返回参数 $get = Request::instance()->get(); //验签成功与否 $result = self::AliPaycheck($get); //记录日志 self::$isDeBug && self::WriteLog(compact('result', 'get')); return compact('result', 'get'); } /** * 验签方法 * @param $arr 验签支付宝返回的信息,使用支付宝公钥。 * @return boolean */ protected static function AliPaycheck($post) { $aop = new \AopClient(); $aop->alipayrsaPublicKey = self::$alipayPublicKey; return $aop->rsaCheckV1($post, self::$alipayPrivateKey, self::$signType); } /** * 初始化参数 * @param $request * @param bool $ispage * @return mixed|\SimpleXMLElement|string|\提交表单HTML文本 * @throws \Exception */ protected static function AopclientRequestExecute($request, $ispage = false, $isapp = false) { $privateKey = self::$alipayPrivateKey; $alipayConfig = new \AlipayConfig(); $alipayConfig->setPrivateKey($privateKey); $alipayConfig->setServerUrl("https://openapi.alipay.com/gateway.do"); $alipayConfig->setAppId(self::$alipayAppId); $alipayConfig->setCharset("UTF-8"); $alipayConfig->setSignType("RSA2"); $alipayConfig->setEncryptKey(""); $alipayConfig->setFormat("json"); $alipayConfig->setAppCertPath(self::$appCertPublicKey); $alipayConfig->setAlipayPublicCertPath(self::$alipayCertPublicKey); $alipayConfig->setRootCertPath(self::$alipayRootCert); $aop = new \AopCertClient($alipayConfig); // 开启页面信息输出 $aop->debugInfo = true; if (!$isapp) { if ($ispage) { $result = $aop->pageExecute($request, "post"); return $result; } else $result = $aop->Execute($request); } else { $result = $aop->sdkExecute($request); } //打开后,将报文写入log文件 self::$isDeBug && self::WriteLog($result); return $result; } /** * alipay.trade.wap.pay 下单支付手机网站支付版本 * @param $out_trade_no 下单号 * @param $total_amount 订单金额 单位元 * @param $subject 订单标题 * @param $passback_params 订单备注 会原样返回通常用于回调监听函数 * @param $product_code 销售产品码,商家和支付宝签约的产品码 * @param $ispage 是否直接输出 * @return $response 支付宝返回的信息 */ public function AliPayWap($out_trade_no, $total_amount, $subject, $returnUrl = '', $passback_params, $product_code = 'QUICK_MSECURITY_PAY', $ispage = true) { $request = new \AlipayTradeWapPayRequest(); $request->setNotifyUrl(self::$notifyUrl); $request->setReturnUrl($returnUrl ? $returnUrl : self::$returnUrl); $request->setBizContent(self::setBizContent(compact('out_trade_no', 'total_amount', 'subject', 'passback_params', 'product_code'))); return self::AopclientRequestExecute($request, $ispage); } // 支付宝提现 public function WithdrawalQuery($extract){ if(!self::$alipayPrivateKey) return array("code"=>"400",'sub_msg'=>"请先配置支付宝提现信息"); $privateKey = self::$alipayPrivateKey; $alipayConfig = new \AlipayConfig(); $alipayConfig->setPrivateKey($privateKey); $alipayConfig->setServerUrl("https://openapi.alipay.com/gateway.do"); $alipayConfig->setAppId(self::$alipayAppId); $alipayConfig->setCharset("UTF-8"); $alipayConfig->setSignType("RSA2"); $alipayConfig->setEncryptKey(""); $alipayConfig->setFormat("json"); $alipayConfig->setAppCertPath(self::$appCertPublicKey); $alipayConfig->setAlipayPublicCertPath(self::$alipayCertPublicKey); $alipayConfig->setRootCertPath(self::$alipayRootCert); $alipayClient = new \AopCertClient($alipayConfig); $alipayClient->isCheckAlipayPublicCert = true; try { //code... $request = new \AlipayFundTransUniTransferRequest(); $randomNumber = ""; for ($i = 0; $i < 12; $i++) { $randomNumber .= mt_rand(0, 9); } $data = array(); $data['out_biz_no'] = $randomNumber; $data['remark'] = "发放佣金"; $data['business_params'] = array( 'payer_show_name_use_alias' => true ); $data['biz_scene'] = "DIRECT_TRANSFER"; $data['payee_info'] = array( 'identity' => $extract['alipay_code'], 'identity_type' => "ALIPAY_LOGON_ID", 'name' => $extract['real_name'] ); $data['trans_amount'] = $extract['extract_price']; $data['product_code'] = "TRANS_ACCOUNT_NO_PWD"; $data['order_title'] = "佣金发放"; $tosign = json_encode($data); $request->setBizContent($tosign); $responseResult = $alipayClient->execute($request); $responseApiName = str_replace(".","_",$request->getApiMethodName())."_response"; $response = $responseResult->$responseApiName; $error = json_decode(json_encode($response), TRUE); return $error; } catch (\Throwable $th) { //throw $th; var_dump($th->getMessage()); } } public function applyQuery($uid) { // f5c7072d28fe95ab632b90d357798ea4 $certify_id = Db::name('user')->where('uid',$uid)->value('certify_id'); $user = Db::name('user')->where('uid',$uid)->find(); if (!$certify_id) return array( 'status' => "N", 'cert_name' => $user['cert_name'], 'cert_no' => $user['cert_no'], );; if ($certify_id == "T") return array( 'status' => "Y", 'cert_name' => $user['cert_name'], 'cert_no' => $user['cert_no'], ); $privateKey = self::$alipayPrivateKey; $alipayConfig = new \AlipayConfig(); $alipayConfig->setPrivateKey($privateKey); $alipayConfig->setServerUrl("https://openapi.alipay.com/gateway.do"); $alipayConfig->setAppId(self::$alipayAppId); $alipayConfig->setCharset("UTF-8"); $alipayConfig->setSignType("RSA2"); $alipayConfig->setEncryptKey(""); $alipayConfig->setFormat("json"); $alipayConfig->setAppCertPath(self::$appCertPublicKey); $alipayConfig->setAlipayPublicCertPath(self::$alipayCertPublicKey); $alipayConfig->setRootCertPath(self::$alipayRootCert); $aop = new \AopCertClient($alipayConfig); $aop->isCheckAlipayPublicCert = true; $request = new \AlipayUserCertifyOpenQueryRequest(); $data = array(); $data['certify_id'] = $certify_id; $tosign = json_encode($data); $request->setBizContent($tosign); $result = $aop->execute($request); $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $error = json_decode(json_encode($result), TRUE)["alipay_user_certify_open_query_response"]["code"]; if($error == 40004){ $status = "N"; }else{ $status = json_decode(json_encode($result), TRUE)["alipay_user_certify_open_query_response"]["passed"]; } $data = array( 'status' => $status, 'cert_name' => $user['cert_name'], 'cert_no' => $user['cert_no'], ); return $data; } public function applyVerify($data) { //判断是从app/抖音/快手 switch ($data['type']) { case 1: $scheme = "adr://"; # code... //原App break; case 2: $scheme = "snssdk1128://"; # code... //抖音 break; case 3: $scheme = "kwai://"; # code...//快手 break; case 4: $scheme = "https://demo.zhishi.tczxkj.com/h5/#/pages/merchant/index"; # code...//H5 break; } $privateKey = self::$alipayPrivateKey; $alipayConfig = new \AlipayConfig(); $alipayConfig->setPrivateKey($privateKey); $alipayConfig->setServerUrl("https://openapi.alipay.com/gateway.do"); $alipayConfig->setAppId(self::$alipayAppId); $alipayConfig->setCharset("UTF-8"); $alipayConfig->setSignType("RSA2"); $alipayConfig->setEncryptKey(""); $alipayConfig->setFormat("json"); $alipayConfig->setAppCertPath(self::$appCertPublicKey); $alipayConfig->setAlipayPublicCertPath(self::$alipayCertPublicKey); $alipayConfig->setRootCertPath(self::$alipayRootCert); $aop = new \AopCertClient($alipayConfig); $aop->isCheckAlipayPublicCert = true; $request = new \AlipayUserCertifyOpenInitializeRequest(); $newsigndata = array(); $newsigndata['outer_order_no'] = md5(time()); $newsigndata['biz_code'] = "FACE"; $newsigndata['identity_param']['identity_type'] = "CERT_INFO"; $newsigndata['identity_param']['cert_type'] = "IDENTITY_CARD"; $newsigndata['identity_param']['cert_name'] = $data['cert_name']; $newsigndata['identity_param']['cert_no'] = $data['cert_no']; $newsigndata['merchant_config']['return_url'] = $scheme; $newsigndata['face_contrast_picture'] = "xydasf=="; $tosign = json_encode($newsigndata); $request->setBizContent($tosign); $result = $aop->execute($request); $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $resultCode = $result->$responseNode->code; Log::error("上面认证拿到的certify_id获取失败"); Log::error(json_encode($result)); $certify_id = json_decode(json_encode($result), TRUE)["alipay_user_certify_open_initialize_response"]["certify_id"]; // 上面认证拿到的certify_id 作为参数传入 Db::name('user')->where('uid',$data['uid'])->update([ 'certify_id' => $certify_id, 'cert_name' => $data['cert_name'], 'cert_no' => $data['cert_no'], ]); if (!empty($resultCode) && $resultCode == 10000) { $request_start = new \AlipayUserCertifyOpenCertifyRequest(); $data = array(); $data['certify_id'] = $certify_id; $tosignstart = json_encode($data); $request_start->setBizContent($tosignstart); $result_start = $aop->pageExecute($request_start); // Log::error("实名认证接口"); // Log::error($result_start); // var_dump($result_start); return $result_start; // $responseNodeStart = str_replace(".", "_", $request_start->getApiMethodName()) . "_response"; // $resultCode = $result->$responseNodeStart->code; // if(!empty($resultCode)&&$resultCode == 10000){ // echo "成功"; // } else { // echo "失败"; // } } else { echo "失败"; } } /** * alipay.trade.wap.pay 下单支付手机网站支付版本 * @param $out_trade_no 下单号 * @param $total_amount 订单金额 单位元 * @param $subject 订单标题 * @param $passback_params 订单备注 会原样返回通常用于回调监听函数 * @param $product_code 销售产品码,商家和支付宝签约的产品码 * @param $ispage 是否直接输出 * @return $response 支付宝返回的信息 */ public function AliPayApp($out_trade_no, $total_amount, $subject,$passback_params, $product_code = 'QUICK_MSECURITY_PAY', $ispage = false) { $request = new \AlipayTradeAppPayRequest(); $request->setNotifyUrl(self::$notifyUrl); $request->setReturnUrl(self::$returnUrl); $request->setBizContent(self::setBizContent(compact('out_trade_no', 'total_amount', 'subject', 'passback_params', 'product_code'))); return self::AopclientRequestExecute($request, $ispage, true); } /**支付宝 当面付 * @param $out_trade_no * @param $total_amount * @param $subject * @param $passback_params * @param string $product_code * @param bool $ispage * @return mixed|\SimpleXMLElement|string|\提交表单HTML文本 * @throws \Exception */ public function AliPayNative($out_trade_no, $total_amount, $subject, $passback_params, $product_code = 'FACE_TO_FACE_PAYMENT', $ispage = false) { $request = new \AlipayTradePrecreateRequest(); $request->setNotifyUrl(self::$notifyUrl); $request->setReturnUrl(self::$returnUrl); $request->setBizContent(self::setBizContent(compact('out_trade_no', 'total_amount', 'subject', 'passback_params', 'product_code'))); $result = self::AopclientRequestExecute($request, $ispage); $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $resultCode = $result->$responseNode->code; $qr_code_url = $result->$responseNode->qr_code; if (!empty($resultCode) && $resultCode == 10000) { return $qr_code_url; } else { return ''; } } /** * alipay.trade.query (统一收单线下交易查询) * @param $out_trade_no 下单号 * @param $trade_no 支付宝订单号 * @param $passback_params 订单备注 会原样返回通常用于回调监听函数 * @return $response 支付宝返回的信息 */ public function AliPayQuery($out_trade_no, $trade_no, $passback_params) { $request = new \AlipayTradeQueryRequest(); $request->setBizContent(self::setBizContent(compact('out_trade_no', 'passback_params', 'trade_no'))); return self::AopclientRequestExecute($request); } /** * alipay.trade.refund (统一收单交易退款接口) * @param $out_trade_no 下单订单号 * @param $trade_no 支付宝订单号 * @param $refund_amount 退款金额 * @param $refund_reason 退款说明 * @param $passback_params 备注 * @return $response 支付宝返回的信息 */ public function AliPayRefund($out_trade_no, $trade_no, $refund_amount, $refund_reason, $passback_params) { $request = new \AlipayTradeRefundRequest(); $request->setBizContent(self::setBizContent(compact('out_trade_no', 'trade_no', 'refund_amount', 'refund_reason', 'passback_params'))); $result = self::AopclientRequestExecute($request); $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; $resultCode = $result->$responseNode->code; return $resultCode; } /** * alipay.trade.close (统一收单交易关闭接口) * @param $out_trade_no 订单号 * @param $trade_no 支付宝订单号 * @return $response 支付宝返回的信息 */ public function AliPayClose($out_trade_no, $trade_no) { $request = new \AlipayTradeCloseRequest(); $request->setBizContent(self::setBizContent(compact('out_trade_no', 'trade_no'))); return self::AopclientRequestExecute($request); } /** * 写入日志 * @param $content string | array | object * @return boolen * */ public static function WriteLog($content) { try { Log::init([ 'type' => 'File', 'path' => LOG_PATH . 'alipay/' ]); if (is_array($content)) $content = 'response: ' . var_export($content, true); if (is_object($content)) $content = 'response: ' . var_export($content, true); Log::write(date('Y-m-d H:i:s', time()) . ' ' . $content); } catch (\Exception $e) { } } }