token = null; $ret = gettokthd($db, $tokenid); if (is_string($ret)) return $this->err($ret); $this->tokenid = $tokenid; $this->token = $ret; } function err($ret, $log = '') { savelogfile('WXPAY', $ret . $log); return $ret; } public function call($url, $post = null, $isbinary = false) { if (!$this->token) return 'token不存在'; if (strpos($url, '{accesstoken}') !== false) { $ret = $this->getaccesstoken(); if (is_string($ret)) return $ret; $url = str_replace('{accesstoken}', $ret['accesstoken'], $url); } if (strpos($url, '{appid}') !== false) $url = str_replace('{appid}', $this->token['appid'], $url); if (strpos($url, '{appsecret}') !== false) $url = str_replace('{appsecret}', $this->token['appsecret'], $url); $http = new \ciy\http(); $http->set_headeronce('Content-Type', 'application/json'); $http->set_headeronce('Accept', 'application/json'); if (is_array($post)) $post = json_encode($post, JSON_UNESCAPED_UNICODE); $http->request($url, $post); $statcode = $http->get_statcode(); if ($statcode != 200 && $statcode != 204) return $this->err('微信服务器无法连接,错误码:' . $statcode); $result = $http->get_data(); if ($isbinary) { if (@$result[0] != '{') return array('bin' => $result); } $json = json_decode($result, true); if ($json === null) return $this->err('微信服务器返回数据失败', $result); if (isset($json['errcode']) && $json['errcode'] != 0) return $this->err('微信服务器返回错误:' . @$json['errmsg']); return $json; } public function refund($param) { //退款 $result = $this->certcall('https://api.mch.weixin.qq.com', '/v3/refund/domestic/refunds', $param); if (is_string($result)) return $result; return $result; } public function transfer($param) { //提现 $param['appid'] = $this->token['appid']; $result = $this->certcall('https://api.mch.weixin.qq.com', '/v3/fund-app/mch-transfer/transfer-bills', $param); if (is_string($result)) return $result; $result['mchid'] = $this->token['mchid']; $result['appid'] = $this->token['appid']; return $result; } public function pay($param) { //支付 $param['appid'] = $this->token['appid']; $param['mchid'] = $this->token['mchid']; $result = $this->certcall('https://api.mch.weixin.qq.com', '/v3/pay/transactions/jsapi', $param); if (is_string($result)) return $result; $timestamp = time() . ''; $nonce = uniqid() . uniqid(); $pkey = openssl_pkey_get_private(file_get_contents($this->token['pem_path'])); $message = $this->token['appid'] . "\n" . $timestamp . "\n" . $nonce . "\nprepay_id=" . $result['prepay_id'] . "\n"; openssl_sign($message, $raw_sign, $pkey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); $ret['appId'] = $this->token['appid']; $ret['timeStamp'] = $timestamp; $ret['nonceStr'] = $nonce; $ret['package'] = 'prepay_id=' . $result['prepay_id']; $ret['signType'] = 'RSA'; $ret['paySign'] = $sign; return $ret; } private function certcall($domain, $url, $post) { if (!file_exists($this->token['pem_path'])) return $this->err('证书文件不存在', $this->token['pem_path']); $timestamp = time() . ''; $nonce = uniqid() . uniqid(); $post = json_encode($post, JSON_UNESCAPED_UNICODE); $message = "POST\n" . $url . "\n" . $timestamp . "\n" . $nonce . "\n" . $post . "\n"; $pkey = openssl_pkey_get_private(file_get_contents($this->token['pem_path'])); openssl_sign($message, $raw_sign, $pkey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); $token = 'mchid="' . $this->token['mchid'] . '",nonce_str="' . $nonce . '",timestamp="' . $timestamp . '",serial_no="' . $this->token['pem_no'] . '",signature="' . $sign . '"'; $http = new \ciy\http(); $http->set_headeronce('Content-Type', 'application/json'); $http->set_headeronce('Accept', 'application/json'); $http->set_headeronce('Authorization', 'WECHATPAY2-SHA256-RSA2048 ' . $token); $http->request($domain . $url, $post); $statcode = $http->get_statcode(); if ($statcode == 200 || $statcode == 204) { $result = $http->get_data(); $json = json_decode($result, true); if ($json === null) return array('code' => 1); if (isset($json['message'])) return $this->err('微信服务器返回错误:' . $json['message']); $json['code'] = 1; return $json; } else { $res['errmsg'] = 1; $result = $http->get_data(); $json = json_decode($result, true); if ($json === null) return $this->err('微信服务器无法连接pay', $result); if (isset($json['message'])) return $this->err('微信服务器返回错误:' . $json['message']); return $this->err('微信服务器返回json:' . $result); } } private function getaccesstoken() { global $db; if ($this->token['exptimes'] > time()) return array('accesstoken' => $this->token['accesstoken']); $http = new \ciy\http(); $http->set_headeronce('Content-Type', 'application/json'); $http->set_headeronce('Accept', 'application/json'); $http->request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $this->token['appid'] . '&secret=' . $this->token['appsecret']); $result = $http->get_data(); $json = json_decode($result, true); if ($json === null) return $this->err('微信服务器无法连接token', $result); if (toint(@$json['errcode']) != 0) return $this->err($json['errmsg']); $accesstoken = @$json['access_token']; if (empty($accesstoken)) return $this->err('微信token授权失败', $result); $exptimes = time() + toint($json['expires_in']); $updata = array(); $updata['accesstoken'] = $accesstoken; $updata['exptimes'] = $exptimes; $ret = settokthd($db, $this->tokenid, $updata); if (is_string($ret)) return $this->err($ret); return array('accesstoken' => $accesstoken); } }