123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- <?php
- namespace app\ais\event;
- use app\common\model\SystemMemberPayment;
- use EasyWeChat\Factory;
- class Micro
- {
- protected static $mch_id; //商户号
- protected static $mch_key; //32位密钥
- protected static $mch_private_key; //商户私钥
- protected static $wechat_serial_no; // 平台证书序列号
- protected static $serial_no = '275E949C1475DFCE8DDBEB5AC195D9DFABF48906'; // 商户证书序列号
- protected static $apiv3_key = '37Qx18rqjVVAWPXnuMSsL7hqbsxMFLSr'; // APIv3 密钥
- protected static $wechat_cert; // 平台证书
- //初始化配置
- public static function config(int $miniapp_id,$flag = false){
- $config = SystemMemberPayment::config($miniapp_id,'wepay');
- if(empty($config)) return;
- self::$mch_id = $config['mch_id'];
- self::$mch_key = $config['key'];
- self::$mch_private_key = self::getPrivateKey($config['key_path']);
- //如果需要,ture为获取平台证书
- if($flag){
- $data = [
- // 必要配置
- 'mch_id' => $config['mch_id'], // 服务商的商户号
- 'key' => $config['key'], // API 密钥
- 'apiv3_key' => self::$apiv3_key, // APIv3 密钥
- 'cert_path' => $config['cert_path'], // XXX: 绝对路径!!!!
- 'key_path' => $config['key_path'], // XXX: 绝对路径!!!!
- ];
- $response = Factory::microMerchant($data)->certficates->get();
- self::$wechat_cert = $response['certificates'];
- self::$wechat_serial_no = $response['serial_no'];
- }
- }
- //获取商户私钥
- public static function getPrivateKey($key){
- return openssl_get_privatekey(file_get_contents($key));
- }
- //签名
- public static function sign($url,$http_mothod,$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no){
- $url_parts = parse_url($url);
- $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
- $message =
- $http_mothod . "\n".
- $canonical_url . "\n".
- $timestamp . "\n".
- $nonce . "\n".
- $body . "\n";
- openssl_sign($message,$raw_sign,$mch_private_key,'sha256WithRSAEncryption');
- $sign = base64_encode($raw_sign);
- $token = sprintf('mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"', $merchant_id,$nonce,$sign,$timestamp,$serial_no);
- return $token;
- }
- //发送请求
- protected static function curl($url,$data = [],$sign,$method = "POST"){
- //设置header头
- $header = [
- 'Accept:application/json',
- 'User-Agent:'.self::$mch_id,
- 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
- 'Content-Type:application/json',
- 'Wechatpay-Serial:' . self::$wechat_serial_no ?? self::$serial_no,
- ];
- $curl = curl_init();
- curl_setopt($curl,CURLOPT_URL,$url);
- curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
- curl_setopt($curl,CURLOPT_HEADER,false);
- curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
- curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
- if($method == "POST"){
- curl_setopt($curl,CURLOPT_POST,true);
- curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
- }
- $result = curl_exec($curl);
- curl_close($curl);
- return $result;
- }
- //加密
- private static function getEncrypt($str){
- //$str是待加密字符串
- $encrypted = '';
- if (openssl_public_encrypt($str,$encrypted,self::$wechat_cert,OPENSSL_PKCS1_OAEP_PADDING)) {
- //base64编码
- $sign = base64_encode($encrypted);
- } else {
- throw new \Exception('encrypt failed');
- }
- return $sign;
- }
- //随机字符串
- public static function nonce_str(){
- return date('YmdHis',time().rand(10000,99999));
- }
- /**
- * 上传图片到微信服务器
- * @param integer $appid 来源小程序
- * @return void
- */
- public static function uploadMedia(int $miniapp_id,string $filename){
- self::config($miniapp_id);
- $url = 'https://api.mch.weixin.qq.com/v3/merchant/media/upload';
- $fi = new \finfo(FILEINFO_MIME_TYPE);
- $mime_type = $fi->file($filename);
- $data['filename'] = pathinfo($filename, PATHINFO_BASENAME);
- $meta['filename'] = pathinfo($filename, PATHINFO_BASENAME);
- $meta['sha256'] = hash_file('sha256', $filename);
- $boundary = uniqid(); //分割符号
- $sign = self::sign($url,'POST',time(),self::nonce_str(),json_encode($meta),self::$mch_private_key,self::$mch_id,self::$serial_no);//$http_method要大写
- $header[] = 'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36';
- $header[] = 'Accept:application/json';
- $header[] = 'Authorization:WECHATPAY2-SHA256-RSA2048 '.$sign;
- $header[] = 'Content-Type:multipart/form-data;boundary='.$boundary;
- $boundaryStr = "--{$boundary}\r\n";
- $out = $boundaryStr;
- $out .= 'Content-Disposition: form-data; name="meta"'."\r\n";
- $out .= 'Content-Type: application/json'."\r\n";
- $out .= "\r\n";
- $out .= json_encode($meta)."\r\n";
- $out .= $boundaryStr;
- $out .= 'Content-Disposition: form-data; name="file"; filename="'.$data['filename'].'"'."\r\n";
- $out .= 'Content-Type: '.$mime_type.';'."\r\n";
- $out .= "\r\n";
- $out .= file_get_contents($filename)."\r\n";
- $out .= "--{$boundary}--\r\n";
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- //避免https 的ssl验证
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_SSLVERSION, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $out);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_TIMEOUT, 30);
- // 模拟来源
- curl_setopt($ch, CURLOPT_REFERER, "");
- $response = curl_exec($ch);
- if ($error = curl_error($ch)) {
- return $error;
- }
- curl_close($ch);
- return $response;
- }
- //进件
- public static function submit($miniapp_id,$params){
- self::config($miniapp_id,true);
- $params['contact_info']['contact_name'] = self::getEncrypt($params['contact_info']['contact_name']);
- $params['contact_info']['contact_id_number'] = self::getEncrypt($params['contact_info']['contact_id_number']);
- $params['contact_info']['mobile_phone'] = self::getEncrypt($params['contact_info']['mobile_phone']);
- $params['contact_info']['contact_email'] = self::getEncrypt($params['contact_info']['contact_email']);
- $params['bank_account_info']['account_number'] = self::getEncrypt($params['bank_account_info']['account_number']);
- $params['bank_account_info']['account_name'] = self::getEncrypt($params['bank_account_info']['account_name']);
- $params['subject_info']['identity_info']['id_card_info']['id_card_name'] = self::getEncrypt($params['subject_info']['identity_info']['id_card_info']['id_card_name']);
- $params['subject_info']['identity_info']['id_card_info']['id_card_number'] = self::getEncrypt($params['subject_info']['identity_info']['id_card_info']['id_card_number']);
- if($params['subject_info']['identity_info']['owner'] == 1){
- $params['subject_info']['identity_info']['owner'] = true;
- }else{
- $params['subject_info']['identity_info']['owner'] = false;
- }
- $url = 'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/';
- $sign = self::sign($url, 'POST', time(), self::nonce_str(), json_encode($params), self::$mch_private_key, self::$mch_id, self::$serial_no);
- $result = self::curl($url, json_encode($params), $sign);
- return json_decode($result,true);
- }
- //查询进件
- public static function query($miniapp_id,$no){
- self::config($miniapp_id);
- $url = 'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/business_code/' . $no;
- $sign = self::sign($url, 'GET', time(), self::nonce_str(), '', self::$mch_private_key, self::$mch_id, self::$serial_no);
- $result = self::curl($url, '', $sign, 'GET');
- return json_decode($result,true);
- }
- //修改结算帐号
- public static function modify($miniapp_id,$params){
- self::config($miniapp_id,true);
- $params['account_number'] = self::getEncrypt($params['account_number']);
- $url = sprintf('https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/%s/modify-settlement', $params['sub_mchid']);
- $sign = self::sign($url, 'POST', time(), self::nonce_str(), json_encode($params), self::$mch_private_key, self::$mch_id, self::$serial_no);
- $result = self::curl($url, json_encode($params), $sign);
- return json_decode($result,true);
- }
- //查询结算账户
- public static function settlement($miniapp_id,$sub_mchid){
- self::config($miniapp_id);
- $url = sprintf('https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/%s/settlement', $sub_mchid);
- $sign = self::sign($url, 'GET', time(), self::nonce_str(), '', self::$mch_private_key, self::$mch_id, self::$serial_no);
- $result = self::curl($url, '', $sign, 'GET');
- return json_decode($result,true);
- }
- }
|