appid = $config['appid']; $this->oid_partner = $config['oid_partner']; $this->api_url = $config['api_url']; $this->key = $config['key']; $this->private_key_path = $config['private_key_path']; $this->public_key_path = $config['public_key_path']; $this->sign_type = 'RSA'; $this->col_oidpartner = $config['col_oidpartner']; } function send($data) { $uid = json_decode($data['remark'],true)['uid']; $request_data = [ 'no_order'=>$data['trade_no'], 'oid_partner'=>$this->oid_partner, 'appid'=>$this->appid, 'openid'=>$data['openid'], 'busi_partner'=>'101001', 'money_order'=>$data['price']/100, 'user_id'=>$uid, "col_oidpartner"=>$this->col_oidpartner, 'dt_order'=>date('YmdHis'), 'notify_url'=>env('LIANLIAN_PAY_CALL_BACK_URL'), 'pay_type'=>'W', 'risk_item'=>'', 'sign_type'=>$this->sign_type, ]; $request_data['risk_item'] = json_encode([ 'frms_ware_category'=>'1004', 'user_info_mercht_userno'=>$uid, 'user_info_dt_register'=>'20171112103052', 'user_info_bind_phone'=>'18606947570' ]); $request_data = $this->buildRequestPara($request_data); $result = $this->getHttpResponseJSON($this->api_url,$request_data); \Log::info('lianlian res---------------------'); \Log::info($result); $res = json_decode($result,true); if ($res['ret_code'] == '0000') { //$pay_data = json_decode($res["payLoad"], true); return $res["payLoad"]; }else{ return $res; } } /** * 生成要请求给连连支付的参数数组 * @param $para_temp * @return */ function buildRequestPara($para_temp) { //除去待签名参数数组中的空值和签名参数 $para_filter = $this->paraFilter($para_temp); //对待签名参数数组排序 $para_sort = $this->argSort($para_filter); //生成签名结果 $mysign = $this->buildRequestMysign($para_sort); //签名结果与签名方式加入请求提交参数组中 $para_sort['sign'] = $mysign; $para_sort['sign_type'] = strtoupper(trim($this->sign_type)); foreach ($para_sort as $key => $value) { $para_sort[$key] = $value; } return $para_sort; //return urldecode(json_encode($para_sort)); } /** * 除去数组中的空值和签名参数 * @param $para * return 去掉空值与签名参数后的新签名参数组 */ function paraFilter($para) { $para_filter = array(); while (list ($key, $val) = each ($para)) { if($key == "sign" || $val == "")continue; else $para_filter[$key] = $para[$key]; } return $para_filter; } /** * 对数组排序 * @param $para * return 排序后的数组 */ function argSort($para) { ksort($para); reset($para); return $para; } /** * 生成签名结果 * @param $para_sort * return 签名结果字符串 */ function buildRequestMysign($para_sort) { //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 $prestr = $this->createLinkstring($para_sort); $mysign = ""; switch (strtoupper(trim($this->sign_type))) { case "MD5" : $mysign = $this->md5Sign($prestr, $this->key); break; case "RSA" : $private_key = Storage::disk('public')->get($this->private_key_path); $mysign = $this->Rsasign($prestr, $private_key); break; default : $mysign = ""; } return $mysign; } /** * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 * @param $para * return 拼接完成以后的字符串 */ public function createLinkstring($para) { $arg = ""; while (list ($key, $val) = each ($para)) { $arg.=$key."=".$val."&"; } //去掉最后一个&字符 $arg = substr($arg,0,count($arg)-2); //file_put_contents("log.txt","转义前:".$arg."\n", FILE_APPEND); //如果存在转义字符,那么去掉转义 if(get_magic_quotes_gpc()){$arg = stripslashes($arg);} //file_put_contents("log.txt","转义后:".$arg."\n", FILE_APPEND); return $arg; } /** * 签名字符串 * @param $prestr 需要签名的字符串 * @param $key 私钥 * return 签名结果 */ public function md5Sign($prestr, $key) { $prestr = $prestr ."&key=". $key; return md5($prestr); } /** * 签名验证 * @param $prestr * @param $sign * @param $key * @return bool */ public function md5Verify($prestr, $sign, $key) { $prestr = $prestr ."&key=". $key; $mysgin = md5($prestr); if($mysgin == $sign) { return true; } else { return false; } } /**RSA签名 * $data签名数据(需要先排序,然后拼接) * 签名用商户私钥,必须是没有经过pkcs8转换的私钥 * 最后的签名,需要用base64编码 * return Sign签名 */ public function Rsasign($data,$priKey) { //转换为openssl密钥,必须是没有经过pkcs8转换的私钥 $res = openssl_get_privatekey($priKey); //调用openssl内置签名方法,生成签名$sign openssl_sign($data, $sign, $res,OPENSSL_ALGO_MD5); //释放资源 openssl_free_key($res); //base64编码 $sign = base64_encode($sign); return $sign; } /**RSA验签 * $data待签名数据(需要先排序,然后拼接) * $sign需要验签的签名,需要base64_decode解码 * 验签用连连支付公钥 * return 验签是否通过 bool值 */ public function Rsaverify($data, $sign) { \Log::info('Rsaverify param is'); \Log::info($data); \Log::info($sign); //读取连连支付公钥文件 $pubKey = Storage::disk('public')->get($this->public_key_path); \Log::info($pubKey); //转换为openssl格式密钥 //$res = openssl_get_publickey($pubKey); $res = openssl_pkey_get_public($pubKey); \Log::info('public key--is'); \Log::info($res); //调用openssl内置方法验签,返回bool值 $result = openssl_verify($data, base64_decode($sign), $res,OPENSSL_ALGO_MD5); //释放资源 openssl_free_key($res); //返回资源是否成功 return $result; } /** * * 签名验证 */ public function rsaCheck($data){ $sign = $data['sign']; $no_sign_data = $this->argSort($this->paraFilter($data)); //$private_key = Storage::disk('public')->get($this->private_key_path); //$check_sing = $this->Rsasign($this->createLinkstring($no_sign_data),$private_key); $res = $this->Rsaverify($this->createLinkstring($no_sign_data),$sign); \Log::info('lianlian-----------------check'); \Log::info($res); return $res; } public function getHttpResponseJSON($url, $para) { $json = json_encode($para); $curl = curl_init($url); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //信任任何证书 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($curl, CURLOPT_POSTFIELDS, $json); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($json)) ); $responseText = curl_exec($curl); curl_close($curl); return $responseText; } }