Server : Apache System : Linux iZ2vcgyutqttsd1p850kl8Z 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 User : www ( 1000) PHP Version : 5.6.40 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv Directory : /www/wwwroot/saimikebio.com/mobile/include/modules/payment/a/ |
<?php /** * ECSHOP 中国银联在线支付 * ============================================================================ * 版权所有 2005-2010 上海商派网络科技有限公司,并保留所有权利。 * 网站地址: http://www.ecshop.com; * ---------------------------------------------------------------------------- * 这不是一个自由软件!您只能在不用于商业目的的前提下对程序代码进行修改和 * 使用;不允许对程序代码以任何形式任何目的的再发布。 * ============================================================================ * $Author: z1988.com $ * $Id: unionpay.php 17063 2015-08-006Z z1988.com $ */ if (!defined('IN_ECTOUCH')) { die('Hacking attempt'); } // 包含配置文件 $payment_lang = ROOT_PATH . 'lang/' .$GLOBALS['_CFG']['lang']. '/payment/'.basename(__FILE__);; if (file_exists($payment_lang)) { global $_LANG; include_once($payment_lang); } /* 模块的基本信息 */ if (isset($set_modules) && $set_modules == TRUE) { $i = isset($modules) ? count($modules) : 0; /* 代码 */ $modules[$i]['code'] = basename(__FILE__, '.php'); /* 描述对应的语言项 */ $modules[$i]['desc'] = 'unionpay_desc'; /* 是否支持货到付款 */ $modules[$i]['is_cod'] = '0'; /* 是否支持在线支付 */ $modules[$i]['is_online'] = '1'; /* 作者 */ $modules[$i]['author'] = 'ECSHOP教程网'; /* 网址 */ $modules[$i]['website'] = 'http://www.ecshopjcw.com'; /* 版本号 */ $modules[$i]['version'] = '1.0.0'; /* 配置信息 */ $modules[$i]['config'] = array( array('name' => 'unionpay_evn', 'type' => 'select', 'value' => '0'), array('name' => 'unionpay_account_pm', 'type' => 'text', 'value' => '777290058117684'), array('name' => 'unionpay_sign_cert_pwd_pm', 'type' => 'text', 'value' => '000000'), array('name' => 'unionpay_sign_cert_path_pm', 'type' => 'text', 'value' => 'PM_700000000000001_acp.pfx'), array('name' => 'unionpay_verify_cert_path_pm', 'type' => 'text', 'value' => 'verify_sign_acp.cer'), array('name' => 'unionpay_encrypt_cert_path_pm', 'type' => 'text', 'value' => 'encrypt.cer'), //array('name' => 'unionpay_verify_dir_pm', 'type' => 'text', 'value' => ''), array('name' => 'unionpay_account', 'type' => 'text', 'value' => ''), array('name' => 'unionpay_sign_cert_pwd', 'type' => 'text', 'value' => ''), array('name' => 'unionpay_sign_cert_path', 'type' => 'text', 'value' => ''), array('name' => 'unionpay_verify_cert_path', 'type' => 'text', 'value' => ''), array('name' => 'unionpay_encrypt_cert_path', 'type' => 'text', 'value' => ''), //array('name' => 'unionpay_verify_dir', 'type' => 'text', 'value' => ''), ); return; } /** * 支付插件类 */ class unionpay { private $dir ; private $site_url; /** * 生成支付代码 * @param array $order 订单信息 * @param array $payment 支付方式信息 */ private $api_url = array( 0 => array( 'front_trans_url' => 'https://101.231.204.80:5000/gateway/api/frontTransReq.do', // 前台请求地址 'back_trans_url' => 'https://101.231.204.80:5000/gateway/api/backTransReq.do', // 后台请求地址 'single_query_url' => 'https://101.231.204.80:5000/gateway/api/queryTrans.do', //单笔查询请求地址 ), 1 => array( 'front_trans_url' => 'https://gateway.95516.com/gateway/api/frontTransReq.do', 'back_trans_url' => 'https://gateway.95516.com/gateway/api/backTransReq.do', 'single_query_url' => 'https://gateway.95516.com/gateway/api/queryTrans.do', //单笔查询请求地址 ), ); function config($payment) { // 初始化变量 $unionpay_evn = $payment['unionpay_evn']; // 环境 $lib_path = ROOT_PATH . 'includes/modules/payment/unionpay/'; $lib_path = dirname(__FILE__).'/'. basename(__FILE__, '.php') .'/'; $data = array(); if ( $unionpay_evn == '1' ){ // 生产环境 $data['unionpay_verify_dir'] = $lib_path.'certs/'; $data['unionpay_account'] = $payment['unionpay_account']; $data['unionpay_sign_cert_pwd'] = $payment['unionpay_sign_cert_pwd']; $data['unionpay_sign_cert_path'] = $data['unionpay_verify_dir'] . $payment['unionpay_sign_cert_path']; $data['unionpay_verify_cert_path'] = $data['unionpay_verify_dir'] . $payment['unionpay_verify_cert_path']; $data['unionpay_encrypt_cert_path'] = $data['unionpay_verify_dir'] . $payment['unionpay_encrypt_cert_path']; $data['front_trans_url'] = $this->api_url[1]['front_trans_url']; $data['single_query_url'] = $this->api_url[1]['single_query_url']; }elseif( $unionpay_evn == '0' ){// PM环境 $data['unionpay_verify_dir'] = $lib_path.'certs/pm/'; $data['unionpay_account'] = $payment['unionpay_account_pm']; $data['unionpay_sign_cert_pwd'] = $payment['unionpay_sign_cert_pwd_pm']; $data['unionpay_sign_cert_path'] = $data['unionpay_verify_dir'] . $payment['unionpay_sign_cert_path_pm']; $data['unionpay_verify_cert_path'] = $data['unionpay_verify_dir'] . $payment['unionpay_verify_cert_path_pm']; $data['unionpay_encrypt_cert_path'] = $data['unionpay_verify_dir'] . $payment['unionpay_encrypt_cert_path_pm']; $data['front_trans_url'] = $this->api_url[0]['front_trans_url']; $data['single_query_url'] = $this->api_url[0]['single_query_url']; } // cvn2加密 1:加密 0:不加密 define("SDK_CVN2_ENC", 0); // 有效期加密 1:加密 0:不加密 define("SDK_DATE_ENC", 0); // 卡号加密 1:加密 0:不加密 define("SDK_PAN_ENC", 0); // 签名证书路径 define("SDK_SIGN_CERT_PATH", $data['unionpay_sign_cert_path']); // 签名证书密码 define("SDK_SIGN_CERT_PWD", $data['unionpay_sign_cert_pwd']); // 验签证书 define("SDK_VERIFY_CERT_PATH", $data['unionpay_verify_cert_path']); // 密码加密证书 define("SDK_ENCRYPT_CERT_PATH", $data['unionpay_encrypt_cert_path']); // 验签证书路径 define("SDK_VERIFY_CERT_DIR", $data['unionpay_verify_dir']); // 前台请求地址 define("SDK_FRONT_TRANS_URL", $data['front_trans_url']); //单笔查询请求地址 define("SDK_SINGLE_QUERY_URL", $data['single_query_url']); //文件下载目录 define("SDK_FILE_DOWN_PATH", $lib_path.'file/'); //日志 目录 define("SDK_LOG_FILE_PATH", $lib_path.'logs/'); //日志级别 define("SDK_LOG_LEVEL", 'INFO'); return $data; } /** * 生成支付代码 * * @param array $order * 订单信息 * @param array $payment * 支付方式信息 */ function get_code($order, $payment) { $charset = 'UTF-8'; $data = $this->config($payment); $parameter = array( 'version' => '5.0.0', // 接口版本号 'encoding' => $charset, 'certId' => $this->getSignCertId(), //证书ID 'txnType' => '01', //交易类型 'txnSubType' => '01', //交易子类 'bizType' => '000201', //业务类型 'frontUrl' => return_url(basename(__FILE__, '.php')), //前台通知地址 'backUrl' => return_url(basename(__FILE__, '.php')), //后台通知地址 'signMethod' => '01', //签名方法 'channelType' => '07', //渠道类型 'accessType' => '0', //接入类型 'merId' => $data['unionpay_account'], //商户代码 'orderId' => $order['order_sn'] . '' . $this->_formatSN($order['log_id']), // 请求号,唯一 'txnTime' => date('YmdHis', intval($order['add_time']) > 0 ? intval($order['add_time']) : time() ), //订单发送时间 'txnAmt' => $order['order_amount'] * 100, //交易金额 单位分 'currencyCode' => '156', //交易币种 'defaultPayType' => '0001', //默认支付方式 'reqReserved' =>$order['order_sn'] .'-'. $order['log_id'], //请求方保留域,透传字段,查询、通知、对账文件中均会原样出现 ); $this->sign($parameter); // 前台请求地址 $front_uri = SDK_FRONT_TRANS_URL; // 构造 自动提交的表单 $html_form = $this->create_html($parameter, $front_uri); return $html_form; } /** * 查询交易 */ public function verify_query($order, $payment) { $charset = 'UTF-8'; $data = $this->config($payment); $params = array( 'version' => '5.0.0', //版本号 'encoding' => $charset, //编码方式 'certId' => $this->getSignCertId(), //证书ID 'signMethod' => '01', //签名方法 'txnType' => '00', //交易类型 'txnSubType' => '00', //交易子类 'bizType' => '000000', //业务类型 'accessType' => '0', //接入类型 'channelType' => '08', //渠道类型 'orderId' => $order['order_sn'] . '0' . $order['log_id'], //请修改被查询的交易的订单号 'merId' => $data['unionpay_account'], //商户代码,请修改为自己的商户号 'txnTime' => date('YmdHis', $order['add_time']), //请修改被查询的交易的订单发送时间 ); $this->sign($params); $result = $this->sendHttpRequest($params, SDK_SINGLE_QUERY_URL); //返回结果展示 $result_arr = $this->coverStringToArray($result); if ($this->verify($result_arr)) { if ($result_arr['respCode'] == '00') { //改变订单支付方式 $merId = $result_arr ['merId']; $orderId = $result_arr ['orderId']; $queryId = $result_arr ['queryId']; $reqReserved = $result_arr ['reqReserved']; $respCode = $result_arr ['respCode']; $respMsg = $result_arr ['respMsg']; $settleAmt = $result_arr ['settleAmt']; $txnAmt = $result_arr ['txnAmt']; // 获取支付订单号log_id if(!strpos($reqReserved, '-')) return false; $order_sn_arr = explode('-', $reqReserved); $order_sn = $order_sn_arr[0]; $pay_id = (int)$order_sn_arr[1]; $payment_amount = (int)$settleAmt; $action_note = $respCode . ':' . $respMsg . 'orderId:' . $orderId . $GLOBALS['_LANG']['unionpay_txn_id'] . ':' . $queryId; // 完成订单。 order_paid($pay_id, PS_PAYED, $action_note); return true; } } //echo $this->verify($result_arr) ? '验签成功' : '验签失败'; } /** * 银联同步响应操作 * * @return boolean */ public function respond($data=array()) { if (isset($_POST ['signature'])) { $payment = get_payment($_GET['code']); $data = $this->config($payment); if ($this->verify($_POST)) { $merId = $_POST ['merId']; $orderId = $_POST ['orderId']; $queryId = $_POST ['queryId']; $reqReserved = $_POST ['reqReserved']; $respCode = $_POST ['respCode']; $respMsg = $_POST ['respMsg']; $settleAmt = $_POST ['settleAmt']; $txnAmt = $_POST ['txnAmt']; if ($_POST['respCode'] == '00') { // 获取支付订单号log_id if(!strpos($reqReserved, '-')) return false; $order_sn_arr = explode('-', $reqReserved); $order_sn = $order_sn_arr[0]; $pay_id = (int)$order_sn_arr[1]; $payment_amount = (int)$settleAmt; $action_note = $respCode . ':' . $respMsg . 'orderId:' . $orderId . $GLOBALS['_LANG']['unionpay_txn_id'] . ':' . $queryId; // 完成订单。 order_paid($pay_id, PS_PAYED, $action_note); return true; } } else { return false; } } else { echo '签名为空'; } } /** * 银联异步通知 * * @return string */ public function notify($data = array()) { if (!empty($_POST)) { $this->respond($data); } else { exit("fail"); } } /** * 签名证书ID * * @return unknown */ function getSignCertId() { // 签名证书路径 return $this->getCertId(SDK_SIGN_CERT_PATH); } /** * 取证书ID(.pfx) * * @return unknown */ function getCertId($cert_path) { $pkcs12certdata = file_get_contents($cert_path); openssl_pkcs12_read($pkcs12certdata, $certs, SDK_SIGN_CERT_PWD); $x509data = $certs ['cert']; openssl_x509_read($x509data); $certdata = openssl_x509_parse($x509data); $cert_id = $certdata ['serialNumber']; return $cert_id; } /** * 签名 * * @param String $params_str */ function sign(&$params) { if (isset($params['transTempUrl'])) { unset($params['transTempUrl']); } // 转换成key=val&串 $params_str = $this->coverParamsToString($params); $params_sha1x16 = sha1($params_str, FALSE); // 签名证书路径 $cert_path = SDK_SIGN_CERT_PATH; $private_key = $this->getPrivateKey($cert_path); // 签名 $sign_falg = openssl_sign($params_sha1x16, $signature, $private_key, OPENSSL_ALGO_SHA1); if ($sign_falg) { $signature_base64 = base64_encode($signature); // $log->LogInfo("签名串为 >" . $signature_base64); $params ['signature'] = $signature_base64; } else { echo "签名失败"; exit; } } /** * 返回(签名)证书私钥 - * * @return unknown */ function getPrivateKey($cert_path) { $pkcs12 = file_get_contents($cert_path); openssl_pkcs12_read($pkcs12, $certs, SDK_SIGN_CERT_PWD); return $certs ['pkey']; } /** * 数组 排序后转化为字体串 * * @param array $params * @return string */ function coverParamsToString($params) { $sign_str = ''; // 排序 ksort($params); foreach ($params as $key => $val) { if ($key == 'signature') { continue; } $sign_str .= sprintf("%s=%s&", $key, $val); // $sign_str .= $key . '=' . $val . '&'; } return substr($sign_str, 0, strlen($sign_str) - 1); } /** * 构造自动提交表单 * * @param unknown_type $params * @param unknown_type $action * @return string */ function create_html($params, $action) { global $_LANG; $encodeType = isset($params ['encoding']) ? $params ['encoding'] : 'UTF-8'; $html = <<<eot <form id="pay_form" name="pay_form" action="{$action}" method="post"> eot; foreach ($params as $key => $value) { $html .= " <input type=\"hidden\" name=\"{$key}\" id=\"{$key}\" value=\"{$value}\" />\n"; } $html .= ' <div style="text-align:center"><input type="submit" value="'. $_LANG['pay_button'] .'" class="J-btn-submit c-btn6"></div> </form>'; return $html; } /** * 验签 * * @param String $params_str * @param String $signature_str */ function verify($params) { global $log; // 公钥 $public_key = $this->getPulbicKeyByCertId($params ['certId']); // echo $public_key . '<br/>'; // 签名串 $signature_str = $params ['signature']; unset($params ['signature']); $params_str = $this->coverParamsToString($params); // $log->LogInfo('报文去[signature] key=val&串>' . $params_str); $signature = base64_decode($signature_str); //echo date('Y-m-d', time()); $params_sha1x16 = sha1($params_str, FALSE); //$log->LogInfo('摘要shax16>' . $params_sha1x16); $isSuccess = openssl_verify($params_sha1x16, $signature, $public_key, OPENSSL_ALGO_SHA1); //$log->LogInfo($isSuccess ? '验签成功' : '验签失败' ); return $isSuccess; } /** * 根据证书ID 加载 证书 * * @param unknown_type $certId * @return string NULL */ function getPulbicKeyByCertId($certId) { global $log; //$log->LogInfo ( '报文返回的证书ID>' . $certId ); // 证书目录 $cert_dir = SDK_VERIFY_CERT_DIR; //$log->LogInfo ( '验证签名证书目录 :>' . $cert_dir ); $handle = opendir($cert_dir); if ($handle) { while ($file = readdir($handle)) { clearstatcache(); $filePath = $cert_dir . '/' . $file; if (is_file($filePath)) { if (pathinfo($file, PATHINFO_EXTENSION) == 'cer') { if ($this->getCertIdByCerPath($filePath) == $certId) { closedir($handle); //$log->LogInfo ( '加载验签证书成功' ); return $this->getPublicKey($filePath); } } } } //$log->LogInfo ( '没有找到证书ID为[' . $certId . ']的证书' ); } else { //$log->LogInfo ( '证书目录 ' . $cert_dir . '不正确' ); } closedir($handle); return null; } /** * 取证书ID(.cer) * * @param unknown_type $cert_path */ function getCertIdByCerPath($cert_path) { $x509data = file_get_contents($cert_path); openssl_x509_read($x509data); $certdata = openssl_x509_parse($x509data); $cert_id = $certdata ['serialNumber']; return $cert_id; } /** * 取证书公钥 -验签 * * @return string */ function getPublicKey($cert_path) { return file_get_contents($cert_path); } /** * 后台交易 HttpClient通信 * @param unknown_type $params * @param unknown_type $url * @return mixed */ function sendHttpRequest($params, $url) { $opts = $this->getRequestParamString($params); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不验证证书 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //不验证HOST curl_setopt($ch, CURLOPT_SSLVERSION, 3); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-type:application/x-www-form-urlencoded;charset=UTF-8' )); curl_setopt($ch, CURLOPT_POSTFIELDS, $opts); /** * 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。 */ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 运行cURL,请求网页 $html = curl_exec($ch); // close cURL resource, and free up system resources curl_close($ch); return $html; } /** * 字符串转换为 数组 * * @param unknown_type $str * @return multitype:unknown */ function coverStringToArray($str) { $result = array(); if (!empty($str)) { $temp = preg_split('/&/', $str); if (!empty($temp)) { foreach ($temp as $key => $val) { $arr = preg_split('/=/', $val, 2); if (!empty($arr)) { $k = $arr ['0']; $v = $arr ['1']; $result [$k] = $v; } } } } return $result; } /** * 组装报文 * * @param unknown_type $params * @return string */ function getRequestParamString($params) { $params_str = ''; foreach ($params as $key => $value) { $params_str .= ($key . '=' . (!isset($value) ? '' : urlencode($value)) . '&'); } return substr($params_str, 0, strlen($params_str) - 1); } /** * 格式订单号 */ function _formatSN($sn) { return str_repeat('0', 9 - strlen($sn)) . $sn; } }