PHP-微信服务商进件、查询进件状态、图片上传接口

1、微信服务商进件,首先我们先来查看微信的官方文档,地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_1.shtml
2、商户上送敏感信息时使用微信支付平台公钥加密,证书序列号包含在请求HTTP头部的Wechatpay-Serial,详见接口规则

接下来我们就要写我们的程序了,我是在tp5下写的,如果你是在别的框架下,稍微改动下就可以。

	 /**
    *进件
     */
    public function add(){

        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){

            case "post":
                /*接收请求参数*/
                $param = $this->request->post();

                $param['subject_info']['identity_info']['owner'] = true;
                $param['contact_info']['contact_name'] = $this->getEncryptS($param['contact_info']['contact_name']);
                $param['contact_info']['mobile_phone'] = $this->getEncryptS($param['contact_info']['mobile_phone']);
                $param['contact_info']['contact_email'] = $this->getEncryptS($param['contact_info']['contact_email']);
                $param['contact_info']['contact_id_number'] = $this->getEncryptS($param['contact_info']['contact_id_number']);

                $param['subject_info']['identity_info']['id_card_info']['id_card_name'] = $this->getEncryptS($param['subject_info']['identity_info']['id_card_info']['id_card_name']);
                $param['subject_info']['identity_info']['id_card_info']['id_card_number'] = $this->getEncryptS($param['subject_info']['identity_info']['id_card_info']['id_card_number']);



                $url = 'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/' ;
                $merchant_id = '******'; //服务商商户号
                $serial_no = '********'; //服务商证书序列号
                $mch_private_key = $this->getPrivateKey('./cert/apiclient_key.pem');

                $timestamp = time();
                $nonce = $this->nonce_str();
                $sign           =$this->sign($url,'POST',$timestamp,$nonce,json_encode($param),$mch_private_key,$merchant_id,$serial_no);//进行签名操作
                //设置header
                $header         =[//设置发送的头信息
                    'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,//签名
                    'Accept:application/json',
                    'User-Agent:' . $merchant_id,//服务商的商户号
                    'Content-Type:application/json',
                    'Wechatpay-Serial:' . $this->getzhengshu()//获取平台证书的序列号,注意:是平台证书,不是上文的商户证书序列号
                ];

                $result=$this->curl($url,json_encode($param),$header);//curl方法见下文
                $result = json_decode($result, true);
                $this->ret_data = $result;

                break;

            default:

                $this->code = 1;
                $this->msg  = "请求方式错误";
                break;

        }
        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);

    }

    /*
    *查询
    */
    public function query()
    {

        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){

            case "post":
                //echo 1111;die;
                /*接收请求参数*/
                $no =  input('param.no') ? input('param.no') : '';

                /*判断必要参数是否存在*/
                if($no){

                    $url  = 'https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/applyment_id/'.$no;
                    $merchant_id = '******'; //服务商商户号
                    $serial_no = '*********'; //服务商证书序列号
                    $mch_private_key = $this->getPrivateKey('./cert/apiclient_key.pem');
                    $timestamp =time();
                    $nonce  = $this->nonce_str();
                    $body="";
                    $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名
                    $header = [
                        'Authorization: WECHATPAY2-SHA256-RSA2048 ' .$sign,
                        'Accept: application/json',
                        'User-Agent:' .$merchant_id,
                        'Content-Type :application/json',
                        'Wechatpay-Serial:' .$this->getzhengshu()
                    ];
                    $result = $this->curl($url,'',$header, 'GET');

                    $result = json_decode($result, true);
                    $this->ret_data = $result;

                }else{

                    /*定义返回参数*/
                    $this->code = 1;
                    $this->msg = "请求参数错误!!";

                }

                break;

            default:

                $this->code = 1;
                $this->msg  = "请求方式错误";
                break;

        }

        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);
    }

    /**
    *图片上传
     **/
    public function uploadMedia()
    {
        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){

            case "post":
                //echo 1111;die;
                /*接收请求参数*/
                $file = $this->request->file('file');

                /*判断必要参数是否存在*/
                if($file){
                    $fileInfo = $file->getInfo();

                    $url="https://api.mch.weixin.qq.com/v3/merchant/media/upload";//微信的上传地址
                    $merchant_id = '**********'; //服务商商户号
                    $serial_no = '***********'; //服务商证书序列号
                    $mch_private_key = $this->getPrivateKey('./cert/apiclient_key.pem');//读取商户api证书公钥 getPublicKey()获取方法
                    $timestamp=time();//时间戳
                    $nonce=$this->nonce_str();//随机字符串
                    $mime_type=$fileInfo['type'];
                    $meta=[
                        'filename'=>$fileInfo['name'],
                        'sha256'=>hash_file('sha256',$fileInfo['tmp_name'])
                    ];
                    $sign=$this->sign($url,'POST',$timestamp,$nonce,json_encode($meta),$mch_private_key,$merchant_id,$serial_no);
                    $boundary=uniqid();
                    $header=[
                        'Content-Type:multipart/form-data;boundary=' . $boundary,
                        'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
                        'Accept:application/json',
                        'User-Agent:' . $merchant_id
                    ];
                    $body='--' . $boundary . "\r\n";
                    $body.='Content-Disposition:form-data; name="meta"' . "\r\n";
                    $body.='Content-Type:application/json' . "\r\n\r\n";
                    $body.=json_encode($meta)."\r\n";
                    $body.='--' . $boundary . "\r\n";
                    $body.='Content-Disposition:form-data;name="file";filename="' . $meta['filename'] . '"' . "\r\n";
                    $body.='Content-Type:' .$mime_type."\r\n\r\n";
                    $body.=file_get_contents($fileInfo['tmp_name'])."\r\n";
                    $body.='--'.$boundary .'--'."\r\n";
                    $result=$this->curl($url,$body,$header);
                    var_dump($result);die;
                    $result=json_decode($result,true);
                    return $result['media_id'];//返回微信返回来的图片标识

                }else{

                    /*定义返回参数*/
                    $this->code = 1;
                    $this->msg = "请求参数错误!!";

                }

                break;

            default:

                $this->code = 1;
                $this->msg  = "请求方式错误";
                break;

        }

        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);

    }


    /**
    *加密字符串
     */
    private function getEncryptS($str) {
        //$str是要加密的字符串
        $public_key_path = './cert/cert.pem' ; //这是获取证书时存起的平台公钥
        $public_key = file_get_contents($public_key_path);
        $encrypted  = '';
        if (openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING)){
            //base64
            $sign = base64_encode($encrypted);
        }else{
            throw new \Exception('encrypt failed');
        }
        return $sign;
    }

    /**
    *获取证书
     **/
    public function getzhengshu(){
        $url="https://api.mch.weixin.qq.com/v3/certificates";//获取地址
        $timestamp=time();//时间戳
        $nonce=$this->nonce_str();//获取一个随机字符串
        $body="";
        $mch_private_key = $this->getPrivateKey('./cert/apiclient_key.pem'); //调用获取商户私钥方法传证书文件路径进去
        $merchant_id = '******'; //服务商商户号
        $serial_no = '*********'; //服务商证书序列号
        $sign=$this->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);

        $header=[
            'Authorization:WECHATPAY2-SHA256-RSA2048 '.$sign,
            'Accept:application/json',
            'User-Agent:'.$merchant_id
        ];
        $result=$this->curl($url,'',$header,'GET');
        $result=json_decode($result,true);

        $serial_no=$result['data'][0]['serial_no'];//获取的平台证书序列号
        $encrypt_certificate=$result['data'][0]['encrypt_certificate'];
        $sign_key="JeO9MgDcxUOLOD1ZpvVXIwQaGVWyTPvu";  //APIv3密钥,商户平台API安全中获取
        $result=$this->decryptToString($encrypt_certificate['associated_data'],$encrypt_certificate['nonce'],$encrypt_certificate['ciphertext'],$sign_key);
        file_put_contents('./cert/cert.pem',$result);//获取的文件临时保存到服务器

        return $serial_no;//返回平台证书序列号
    }

    /**
    *解密方法
     */
    public function decryptToString($associatedData,$nonceStr,$ciphertext,$aesKey){
        $ciphertext=\base64_decode($ciphertext);
        if(function_exists('\sodium_crypto_aead_aes256gcm_is_available')&& \sodium_crypto_aead_aes256gcm_is_available()){
            return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext,$associatedData,$nonceStr,$aesKey);
        }
        if(PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())){
            $ctext=substr($ciphertext,0,-16);
            $authTag=substr($ciphertext,-16);
            return \openssl_decrypt(
                $ctext,
                'aes-256-gcm',
                $aesKey,
                \OPENSSL_RAW_DATA,
                $nonceStr,
                $authTag,
                $associatedData
            );
        }
        throw new \RuntimeException('php7.1');
    }

    /**
    *curl请求方法
     **/
    public function curl($url,$data=[],$header,$method='POST'){
        $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 function nonce_str()
    {
        return date('YmdHis', time()) . rand(18080,99999);
    }

    /**
    *获取商户私钥
     */
    public static function getPrivateKey($path)
    {
        return openssl_get_privatekey(file_get_contents($path));
    }

    public function sign($url,$http_method,$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_method . "\n".
            $canonical_url . "\n".
            $timestamp . "\n".
            $nonce . "\n".
            $body . "\n";
        openssl_sign($message,$raw_sign,$mch_private_key,'sha256WithRSAEncryption');
        $sign=base64_encode($raw_sign);
        $schema='WECHATPAY2-SHA256-RSA2048';
        $token=sprintf(
            'mchid="%s",nonce_str="%s",signature="%s",timestamp="%d",serial_no="%s"',
            $merchant_id,
            $nonce,
            $sign,
            $timestamp,
            $serial_no
        );
        return $token;
    }
这里我给一个进件的json示例 
{
	"business_code":"121a2w32w1q1ew22e",
	"contact_info":{
		"contact_name":"aa",
		"contact_id_number":"2807071996102200313",
		"mobile_phone":"18345851000",
		"contact_email":"123456@qq.com"
	},
	"subject_info":{
		"subject_type":"SUBJECT_TYPE_INDIVIDUAL",
		"business_license_info":{
			"license_copy":"iIY9dw0Ra_Y2JBqZFABLeZ1fmaav-d1xIRfzQ4q5ZU-aZejvaF6hNhJt7344iFF531GoMJarKs-8mv8VEBGsSQuJ7eFh3BKzvG3NWM3Y_Ss",
			"license_number":"123456789012345678",
			"merchant_name":"腾讯科技",
			"legal_person":"张三"
		},
		"identity_info":{
			"id_doc_type":"IDENTIFICATION_TYPE_IDCARD",
			"id_card_info":{
				"id_card_copy":"iIY9dw0Ra_Y2JBqZFABLeZ1fmaav-d1xIRfzQ4q5ZU-aZejvaF6hNhJt7344iFF531GoMJarKs-8mv8VEBGsSQuJ7eFh3BKzvG3NWM3Y_Ss",
				"id_card_national":"iIY9dw0Ra_Y2JBqZFABLeXAdngbRQS9zLFMxFmMRPwCvkRkk1597gkU43l3NMx8j-ICo4Ua4tCWm7evA14LtUKy1PfimEkjUGn4Vdapa4-o",
				"id_card_name":"aq",
				"id_card_number":"2807071996102200313",
				"card_period_begin":"2026-06-06",
				"card_period_end":"2026-06-06"
				
			},
		 "owner": "0"
		}
	},
	"business_info":{
		"merchant_shortname":"大开口说",
		"service_phone":"121231",
		"sales_info":{
			"sales_scenes_type":["SALES_SCENES_STORE"],
			"biz_store_info":{
				"biz_store_name":"大郎烧饼",
				"biz_address_code":"440305",
				"biz_store_address":"南山区xx大厦x层xxxx室",
				"store_entrance_pic":["iIY9dw0Ra_Y2JBqZFABLeU4jmfgvCj02z9vP_8mNKfYtFCEybjgpxeGqif6f5GqmdjNLs3v2w57_-M8G_zI98HM2WJehAS1Z6BUZxBEK2lM"],
				"indoor_pic":["iIY9dw0Ra_Y2JBqZFABLeXAdngbRQS9zLFMxFmMRPwCvkRkk1597gkU43l3NMx8j-ICo4Ua4tCWm7evA14LtUKy1PfimEkjUGn4Vdapa4-o"]
			}
		}
	},
	"settlement_info":{
		"settlement_id":"719",
		"qualification_type":"餐饮"
	}
}

注意进件接口中需要脱敏加密的字段,使用加密方法getEncryptS()进行加密处理

图片上传接口Postman示例
在这里插入图片描述
这就大功告成了 自己在完善一下代码的参数验证和逻辑判断就可以了。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
PHP微信支付接口是一种用于在网站或应用程序中实现微信支付功能的工具。它支持服务商模式,在这种模式下,开发者可以代替商户接入微信支付,为商户提供支付服务。 通过PHP微信支付接口服务商可以实现以下功能: 1. 创建子商户:服务商可以通过接口创建子商户,子商户即代表真实的商户,在微信支付平台注册账号后,获取子商户的商户号。 2. 交易支付:服务商可以通过接口发起交易支付请求,包括拉起微信支付页面、生成二维码等方式。用户在微信内完成支付后,服务商可以获取支付结果,并进行相应的业务处理。 3. 查询交易状态服务商可以查询某笔交易的支付状态,包括已支付、未支付等。 4. 退款:服务商可以通过接口进行退款操作,将交易金额退还给用户。 5. 订单查询服务商可以查询某个商户的订单列表,包括交易时间、金额、状态等信息。 6. 结算功能:服务商可以通过接口进行订单的结算操作,将商户的资金结算到指定的银行账户。 总而言之,PHP微信支付接口支持服务商模式,为服务商提供了丰富的支付功能和业务接口,方便服务商代替商户接入微信支付,进行支付和业务管理。服务商可以通过编写PHP代码,调用相应的接口实现支付功能,并根据业务需要进行支付结果查询、退款、结算等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值