PHP 小微开户遇到的几个大坑

本文记录了微信小微商户开户过程中的技术挑战,包括使用libsodium扩展解密平台证书,处理PHP版本依赖,以及解决上传图片接口问题。分享了解决方案和代码实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最后接了个小微开户的需求,查阅相关文档发现微信并没有提供什么案例代码,心中顿时一万个草泥马在奔腾,不说了,说说过程中遇到的那些坑。
1、获取平台证书,关于这个接口我也是醉了,这个接口返回的密文需要我们用APIV3密钥解密生成相关的明文,即所谓的平台证书。解密的过程需要用到libsodium这个扩展,而这个扩展只有在php>=7.0上才有,我靠,不是吧,弄个这个还得升级php,况且php7.0和php5.6变动也太大了。这是搞死人的节奏啊,一开始没注意,后来看获取证书的接口这个密文的有效期为5年,我去,那我就调一次就行了嘛,然后搭了个临时的环境(PHP_version >= 7.0)获取密文,然后解密。
2、就是上传图片了,这个接口也挺闹心的,我们提供的参数就是要获取图片在服务器的绝对路径(例如这个路径就不行:https://jiangbowen.cn/563/ayu/w3/a.jpg),然后可以用curl_file_create() 方法获取图片的具体信息,然后再提交接口就行,返回的参数是用MD5加密的,一开始默认是HMAC-SHA256,然后调试了下发现是MD5,我也是醉了
3、贴下跑的代码

获取参数
 $data = [
            'version' => '3.0',
            'cert_sn' => $app::CERT_SN,
            'mch_id' => $app::MCH_ID,
            'nonce_str' => $app->getNonceStr(),
            'sign_type' => 'HMAC-SHA256',
            'sign' => '',
            'business_code' => $this->getBusinessCode(), // 业务申请编号
            'id_card_copy' => $app->uploadImage($params['id_card_copy']), // 身份证人像面照片  media_id
            'id_card_national' => $app->uploadImage($params['id_card_national']), // 身份证国徽面照片
            'id_card_name' => $this->getEncrypt($params['id_card_name']),
            'id_card_number' => $this->getEncrypt($params['id_card_number']),
            'id_card_valid_time' =>'["'.$id_card_valid_time[0].'"'.','.'"'.$id_card_valid_time[1].'"]',
            'account_name' => $this->getEncrypt($params['id_card_name']),
            'account_bank' => $params['account_bank'],
            'bank_address_code' =>$params['bank_address_code'],
            'account_number' => $this->getEncrypt($params['account_number']),
            'store_name' => $params['store_name'],
            'store_address_code' => $params['store_address_code'],
            'store_street' => $params['store_street'],
            'store_entrance_pic' => $app->uploadImage($params['store_entrance_pic']),
            'indoor_pic' => $app->uploadImage($params['indoor_pic']),
            'merchant_shortname' => $params['merchant_shortname'],
            'service_phone' => $params['service_phone'],
            'product_desc' => '居民生活服务',
            'contact' => $this->getEncrypt($params['contact']),
            'contact_phone' => $this->getEncrypt($params['contact_phone']),
            'contact_email' => $this->getEncrypt($params['contact_email'])
        ];
        //重点说下获取平台证书方法
         public function getCert_sn()
        {
       	 $data=[
	            'mch_id'=>self::MCH_ID,
	            'nonce_str'=>$this->getNonceStr(),
	            'sign_type' => 'HMAC-SHA256'
	       	   ];
	        $data['sign'] = $this->makeSign($data,$data['sign_type']);
	        $xml = $this->toXml($data);
	        $res = $this->httpsRequest(self::CERT_URL, $xml, [], false);
	        $responseData = $this->disposeReturn($res);
	        //生成解密文件
	        $certificates = $responseData['certificates'];
	        $certificates_arr = json_decode($certificates,true);
	        $this->decodePem($certificates_arr['encrypt_certificate']);
	        return $certificates_arr['serial_no'];
	        exit;
    	}
		
		/**
      *解密证书
      **/
    public function decodePem($data){
	        $ciphertext = $data['ciphertext'];
	        $nonce = $data['nonce'];
	        $associated_data = 'certificate';
	        $key = self::AESKEY;
	        $check_sodium_mod = extension_loaded('libsodium');
	        if($check_sodium_mod === false){
	           response( null,1,'没有安装libsodium模块');
	        }
	        $check_aes256gcm = sodium_crypto_aead_aes256gcm_is_available();
	        if($check_aes256gcm === false){
	            response( null,1,'当前不支持aes256gcm');
	        }
	        $pem = sodium_crypto_aead_aes256gcm_decrypt(base64_decode($ciphertext),$associated_data,$nonce,$key);
	        file_put_contents(trim(APPPATH,'/').'/libraries/microencode.pem',$pem);
	        var_dump($pem); //这是解密出来的证书内容,复制出来保存就行了
    }

        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值