最近在实现微信企业向用户银行卡付款时遇到了一些问题,发现官方文档说的太笼统,走了不少弯路,想要在此记录,希望可以帮到大家。

案例:企业付款到银行卡

     微信接口链接:https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank

在传参时发现需要一些特殊参数,正文开始。

详解一:签名(sign)

微信企业向用户银行卡付款API开发详解(PHP)-LMLPHP

注意:此处的签名必须是接口请求字段参与的签名,通俗的来讲就是要调用某个接口,需要传入签名字段(sign)时,此签名字段的值必须由其他请求字段按官方文档“MD5签名生成算法”生成,若在签名过程中遗漏某个请求字段(不参与签名),则在接口调用时会报签名错误异常(SIGNERROR)。

例如:假设请求需要商户号、APPID及签名(sign),则需要商户号和APPID参与签名生成签名(sign),然后一起作为请求参数调用接口API,此时的请求参数个数为3;

   若请求只需要商户号及签名(sign),只需要商户号参与签名生成签名(sign),然后再一起作为请求参数调用接口API,此时请求参数个数为2。

详解二:特殊请求参数(保密参数)

微信企业向用户银行卡付款API开发详解(PHP)-LMLPHP

我们发现,在调用接口时需要传入“采用标准RSA算法”加密的字段,在根据官方“获取RSA加密公钥API”时发现其将RSA算法使用分为五步:

在开发过程中,使用PHP内置函数openssl_public_encrypt()对明文进行加密时提示如下错误:

[2]  in 

openssl_public_encrypt(): key parameter is not a valid public key

  1. * @param $pubRSAPath 加密公钥路径
  2. * @return string 密文(base64)
  3. * @throws \Exception
  4. */
  5. public function RSAEncryptByPub($plainText, $pubRSAPath) {
  6. try {
  7. //读取公钥内容
  8. $pub_key = openssl_pkey_get_public(file_get_contents($pubRSAPath));
  9. //转换为openssl格式密钥
  10. if (!openssl_public_encrypt($plainText, $cipherText, $pub_key, OPENSSL_PKCS1_OAEP_PADDING)) {
  11. throw new \Exception('加密错误,请重试!');
  12. }
  13. return base64_encode($cipherText);
  14. } catch (\Exception $e) {
  15. throw $e;
  16. }

解决方案如下:

步骤一、找到生成的RSA公钥文件,查看内容,发现其为PKCS#1格式,效果如下:

步骤二、安装OpenSSL工具,将其手动转为PKCS#8格式,效果如下:

RSA公钥格式PKCS#1,PKCS#8互转说明

步骤三、替换RSA公钥文件内容并保存,异常消失,问题解决。

问题原因:公钥格式错误导致加密失败。

04-26 17:33
查看更多