error = 0; $this->error_code = 0; $this->msg = null; $this->data = null; $this->from_string($string); } public function to_array() { return (array)$this; } public function to_string() { return json_encode($this, JSON_UNESCAPED_UNICODE); } public function from_array($array) { foreach ($array as $key => $value) { if (property_exists($this, $key)) { $this->$key = $value; } } return true; } public function from_string($string) { return $this->from_array((array)json_decode($string)); } } /** * @note 获取当前页面的完整连接 * @return string */ function getLocaleUrl() { $is_https = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] == 'https'); $request_scheme = $is_https ? 'https://' : 'http://'; $hostname = $_SERVER['SERVER_NAME']; $hostport = (($is_https && '443' == $_SERVER['SERVER_PORT']) || (!$is_https && '80' == $_SERVER['SERVER_PORT'])) ? '' : ':' . intval($_SERVER['SERVER_PORT']); return $request_scheme . $hostname . $hostport . $_SERVER['PHP_SELF']; } /** * @date 2017-03-04 * @note 给参数按key的顺序排序。(支持递归) * @param mixed $parameter 要排序的参数 * @return array * @auth 应俊 */ function SortParam($parameter) { $parameter = (array)$parameter; foreach ($parameter as $k => $v) { if (is_array($v) || is_object($v)) { $parameter[$k] = SortParam($v); } } // 调用strcmp函数来排序,该函数区分大小写。 uksort($parameter, 'strcmp'); return $parameter; } /** * @date 2017-03-06 * @note 转换参数成字符串形式按key=value的形式,用&分隔)。 * @param mixed $parameter 要转换的参数 * @return string * @auth 应俊 */ function ConvertParam($parameter) { $parameter = (array)$parameter; $return = ''; foreach ($parameter as $k => $v) { if (is_array($v) || is_object($v)) { $return .= sprintf('&%s={%s}', $k, ConvertParam($v)); } else { $return .= sprintf('&%s=%s', $k, $v); } } $sublen = mb_strlen('&', USEDCHARSET); $retlen = mb_strlen($return, USEDCHARSET); $return = mb_substr($return, $sublen, $retlen - $sublen, USEDCHARSET); return $return; } /** * @date 2017-03-04 * @note 为参数生成签名 * @param mixed $parameter 要签名的参数 * @param string $signkey 签名key * @return string * @auth 应俊 */ function SignParameter($parameter, $signkey = '') { // 1:先把参数按参数名(key)从小到大排序 $parameter = SortParam($parameter); // 2:连接参数成一个字符串(按key=value的形式,用&分隔)。 $return = ConvertParam($parameter); // 3:结尾加上key=签名key $return .= '&key=' . $signkey; // 4:md5加密这个字符串 return md5($return); } /** * @param mixed $data * @return array|mixed */ function ChangePostData($data) { switch (gettype($data)) { case 'array': { foreach ($data as $key => $value) { $data[$key] = ChangePostData($value); } break; } case 'object': { $array = (array)$data; foreach ($array as $key => $value) { $data->$key = ChangePostData($value); } break; } default: { $data = preg_replace_callback('/\+/', function ($r) { return '%2B'; }, $data); $data = preg_replace_callback('/\&/', function ($r) { return '%26'; }, $data); break; } } return $data; } /** * @note 发送post请求 * @param string $url * @param mixed $data * @return string */ function SendPost($url, $data) { $data = http_build_query(ChangePostData($data)); $opts = array( 'http' => array( 'method' => 'POST', 'header' => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n", 'content' => $data, ), ); $context = stream_context_create($opts); $ret = file_get_contents($url, false, $context); $ret = trim($ret, "\xEF\xBB\xBF"); return $ret; } ?> 支付测试 function submit() { var fee = document.getElementById('fee').value; if ('' == fee || undefined == fee) { alert('请输入要支付的金额(单位为分)'); return; } var script = ""; $('#mainbody').append(script); $('#frm').submit(); }
支付测试
EOL; } else /// 有fee参数表示已提交页面中输入的支付金额 { /// 通过接口获取门店所支援的支付方式 $data = array( 'appid' => $app_id, /// appid 'devkey' => $dev_key, /// 开发者key 'market_key' => $market_key, /// 门店key 'level' => 1, /// 支付类型(1: 线上, 2: 扫码, 3: app) 'version' => 1, /// 版本号 ); $data['sign'] = SignParameter($data, $sign_key); $result = new ResultObject(rawurldecode(SendPost('https://api.tscce.cn/api/newpay/querylist', $data))); if (0 == $result->error && count($result->data) > 0) /// 成功 { /// 这里为了演示, 只判断了第一个支付方式, 实际应该先判断当前用户的运行环境, 然后才去决定使用哪种支付通道(微信或支付宝等) $pay_type = $result->data[0]->type_id; $order_id = date('YmdHis') . rand(1000, 9999); /// 随机生成一个订单号 $notice_url = dirname(getLocaleUrl()) . '/notice.php'; /// 通知页面地址 $return_url = getLocaleUrl() . "?sid={$sid}&scode={$scode}"; /// 回调地址 $fee = $_REQUEST['fee']; $data = array( 'appid' => $app_id, /// appid 'devkey' => $dev_key, /// 开发者key 'sid' => $sid, /// sid 'scode' => $scode, /// scode 'orderid' => $order_id, /// 订单号 'fee' => $fee, /// 支付金额(单位分) 'title' => 'test', /// 支付标题 'notice_url' => $notice_url, /// 回调页面地址(异步) 'return_url' => $return_url, /// 回调页面地址(同步) 'paytype' => $pay_type, /// 支付类型(可通过接口获取所有支持的类型列表) 'p1' => 'p1', /// 附加的其他参数, 回调时会原样返回, 参数名可自定义 'p2' => 'p2', /// 附加的其他参数, 回调时会原样返回, 参数名可自定义 'version' => 1, /// 接口版本号, 整型, 目前只支持1 ); $data['sign'] = SignParameter($data, $sign_key); $html = <<