PHP开发微信支付小微商户V3版本 图片上传、生成签名、平台证书获取、平台证书编号、敏感信息加密
吐槽一下,看微信支付小微商户的开发文档头都大了,什么是平台证书、什么是商户API证书......
好了废话不多说下面明确几个名词:
商户API证书:是由权威CA颁发,用于有关微信支付等操作API接口使用。
平台证书:这个是通过API接口申请下来的,用于一些敏感信息加密使用。
API v3密钥:这个秘钥用于解密平台证书使用。
(API)证书序列号:用于获取平台证书时使用。
一、获取商户API证书
通过此连接获取,什么是商户API证书?如何获取商户API证书? 按照里面的操作指引进行生成和下载。下载完解压完后应该是.pem 的文件,文件内容以-----BEGIN CERTIFICATE-----开头是证书,以-----BEGIN PRIVATE KEY-----开头的是私钥,这里的文件不要动。直接放到服务器的文件夹里面即可。
二、获取和设置API v3密钥
登录微信支付官网,我这里用的是搜狗浏览器,其他的浏览器我试了兼用都有问题,且将浏览器设置为IE模式(切记),这里APIV3和API秘钥我都设置为一样的,避免后期有其他的问题。
二、查询(API)证书序列号
账户中心 -> API安全 ->查看证书,里面就有证书编号
三、开始获取平台证书、平台证书序列号
微信支付官方获取平台证书的文档
/*** 获取平台证书内容*/public function get_Certificates(){$merchant_id =$this->mch_id;//商户号$serial_no = $this->api_serial_no;//API证书序列号$sign = $this->get_Sign("https://api.mch.weixin.qq.com/v3/certificates","GET","",$this->get_Privatekey(), $merchant_id, $serial_no);//$http_method要大写$header[] = 'User-Agent:https://zh.wikipedia.org/wiki/User_agent';$header[] = 'Accept:application/json';$header[] = 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign;$back=$this->http_Request("https://api.mch.weixin.qq.com/v3/certificates",$header);dump(json_decode($back,true));}/*** 获取sign* @param $url* @param $http_method [POST GET 必读大写]* @param $body [请求报文主体(必须进行json编码)]* @param $mch_private_key [商户私钥]* @param $merchant_id [商户号]* @param $serial_no [证书编号]* @return string*/private function get_Sign($url, $http_method, $body, $mch_private_key, $merchant_id, $serial_no){$timestamp = time();//时间戳$nonce = $timestamp . rand(10000, 99999);//随机字符串$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);$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',$merchant_id, $nonce, $timestamp, $serial_no, $sign);return $token;}/*** 获取商户私钥* @return false|resource*/public function get_Privatekey(){$private_key_file = (dirname(__FILE__) . '/key/private_key.pem');//私钥文件路径 如linux服务器秘钥地址地址:/www/wwwroot/test/key/private_key.pem"$mch_private_key = openssl_get_privatekey(file_get_contents($private_key_file));//获取私钥return $mch_private_key;}/*** 数据请求* @param $url* @param array $header 获取头部* @param string $post_data POST数据,不填写默认以GET方式请求* @return bool|string*/public function http_Request($url, $header = array(), $post_data = ""){$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HTTPHEADER, $header);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 2);if ($post_data != "") {curl_setopt($ch, CURLOPT_POST, TRUE);curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); //设置post提交数据}//判断当前是不是有post数据的发$output = curl_exec($ch);if ($output === FALSE) {$output = "curl 错误信息: " . curl_error($ch);}curl_close($ch);return $output;}
通过get_Certificates()获取到的数据如下
serial_no | 平台证书序列号 |
ciphertext | 平台证书的密文 |
noce | AES GCM 的随机数 |
associated_data | 相关解密数据 |
通过平台证书的密文,获取平台证书的内容
微信支付官方解密参考文档
我这里直接用的微信支付官方PHPdemo解密的,官方demo如下:
class AesUtilController
{/*** AES key** @var string*/private $aesKey;const KEY_LENGTH_BYTE = 32;const AUTH_TAG_LENGTH_BYTE = 16;/*** Constructor*/public function __construct($aesKey){if (strlen($aesKey) != self::KEY_LENGTH_BYTE) {throw new InvalidArgumentException('无效的ApiV3Key,长度应为32个字节');}$this->aesKey = $aesKey;}/*** Decrypt AEAD_AES_256_GCM ciphertext** @param string $associatedData AES GCM additional authentication data* @param string $nonceStr AES GCM nonce* @param string $ciphertext AES GCM cipher text** @return string|bool Decrypted string on success or FALSE on failure*/public function decryptToString($associatedData, $nonceStr, $ciphertext){$ciphertext = \base64_decode($ciphertext);if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {return false;}// ext-sodium (default installed on >= PHP 7.2)if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') &&\sodium_crypto_aead_aes256gcm_is_available()) {return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey);}// ext-libsodium (need install libsodium-php 1.x via pecl)if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') &&\Sodium\crypto_aead_aes256gcm_is_available()) {return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey);}// openssl (PHP >= 7.1 support AEAD)if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {$ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);$authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);return \openssl_decrypt($ctext, 'aes-256-gcm', $this->aesKey, \OPENSSL_RAW_DATA, $nonceStr,$authTag, $associatedData);}throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');}
}
调用微信官方demo进行解密,代码如下
public function Decrypt(){$AesUtil=new AesUtilController("填写你APIV3 的秘钥");$associatedData="这是get_Certificate()获取到的associated_data";$nonceStr="这是get_Certificate()获取到的noce";$ciphertext = "这是get_Certificate()获取到的ciphertext";$back=$AesUtil->decryptToString($associatedData,$nonceStr,$ciphertext);dump($back);}
返回的内容粘贴到txt文档里面,然后将文档后缀名改为.pem格式,至此平台证书,及平台证书编号获取完成。
四、图片上传API
微信支付图片上传官方文档
protected $upload_img_api = 'https://api.mch.weixin.qq.com/v3/merchant/media/upload';//图片上传接API/*** 获取图片上传后Media(腾讯提供)信息* @param $file_path [文件的路径] 如/www/wwwroot/test/img/123.png* @param $file_name [文件名称] 如 123.png* @return bool|mixed|string*/public function get_Media_id($file_path, $file_name){$merchant_id = $this->mch_id;//商户号$mime_type = mime_content_type($file_path);//获取图片MIME类型$meta['filename'] = $file_name;//文件名称$meta['sha256'] = hash_file('sha256', $file_path);//文件生成哈希值$boundary = "abcdefg"; //分割符号 (为商户自定义的一个字符串)$sign = $this->get_Sign($this->upload_img_api, "POST", json_encode($meta), $this->get_Privatekey(), $merchant_id, $this->merchant_serial_no);//$http_method要大写$header[] = 'User-Agent:Mozilla/5.0';$header[] = 'Accept:application/json';$header[] = 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign;$header[] = 'Content-Type:multipart/form-data;boundary=' . $boundary;$boundaryStr = "--{$boundary}\r\n";$body = $boundaryStr;$body .= 'Content-Disposition: form-data; name="meta"' . "\r\n";$body .= 'Content-Type: application/json' . "\r\n";$body .= "\r\n";$body .= json_encode($meta, true) . "\r\n";$body .= $boundaryStr;$body .= 'Content-Disposition: form-data; name="file"; filename="' . $meta['filename'] . '"' . "\r\n";$body .= 'Content-Type: ' . $mime_type . ';' . "\r\n";$body .= "\r\n";$body .= (fread(fopen($file_path, 'rb'), filesize($file_path))) . "\r\n";$body .= "--{$boundary}--\r\n";$back = $this->http_Request($this->upload_img_api,$header,$body);$back = json_decode($back, true);return $back;}
五、敏感信息加密
微信支付官方敏感信息加密文档
/*** 敏感信息加密算法* @param $str* @return string*/public function getEncrypt($str){//$str是待加密字符串$public_key_path = dirname(__FILE__) . '/key/open.pem';//平台证书$public_key = file_get_contents($public_key_path);$encrypted = '';openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING);//这里 类型要设置为OPENSSL_PKCS1_OAEP_PADDING//base64编码$sign = base64_encode($encrypted);return $sign;}
这里有个坑我要说一下,
openssl_public_encrypt的padding类型必须设置为OPENSSL_PKCS1_OAEP_PADDING,否则你后期你提交资料时就会提示你解密信息错误。
如需转载请注明出处,如内容有误请及时留言,谢谢!
PHP开发微信支付小微商户V3版本 图片上传、生成签名、平台证书获取、平台证书编号、敏感信息加密相关推荐
- 微信PC版本如何打开开发版小程序进行调试,图片上传在PC版小程序上传失败,手机端和开发者工具中均正常的问题解决
1.小程序开发者工具-设置-通用设置中,将自动预览的启动PC自动预览勾选上 2.预览中选择自动预览即可,这样就可以在PC版的小程序中进行调试了哦. 3.图片上传在pc版的小程序中上传失败的解决办法:去 ...
- 微信V3接口,图片上传签名错误
||–查看的码友,在不麻烦的情况,如果文章有用,烦请点个赞.如果没用可以留言讨论哦–|| V3官方错误相关文档:https://wechatpay-api.gitbook.io/wechatpay-a ...
- IOS5开发-http get/post调用mvc4 webapi互操作(图片上传)
目前最流行的跨平台交互是采用http协议通过JSON对象进行互操作.这种方式最简单,也很高效.webservice+xml的方式似乎已经过时. 下面是我做的一个例子 webapi的代码 View Co ...
- 微信小程序多图片上传全栈实战
本篇教程技术栈:springBoot(Java后端)+ 微信小程序.完整的图片上传教程. 页面截图,点击图片右上角按钮可以删除图片. 1.图片上传需要使用wx.uploadFile(Object o ...
- python生成图片链接_python 实现图片上传接口开发 并生成可以访问的图片url
版本:python3.7 功能,开发一个用户访问的页面,支持图片上传,并将其保存在服务器. 项目结构: app.py文件内容如下: from flask import Flask, Response, ...
- 微信小程序开发-微信支付功能【WxMaService 获取openid,WxPayService建微信订单,接收微信支付异步通知回调方法,附有完整前后端代码】
前提:对小程序开发有一定的基础:小程序已发布使用,已开通微信支付,关联商户号. 微信小程序平台:小程序平台 微信开发者文档:开发者文档 微信小程序支付API 地址:微信支付文档地址 微信支付平台:微信 ...
- 小程序云开发 ——微信支付
云开发的微信支付:免鉴权.免签名计算.免 access_token,在云函数内原生调用微信支付接口.以前的实现微信支付,必须要有自己的服务器,有自己的备案域名,还有后端部分代码 云开发-微信支付,官方 ...
- 微信小程序云开发微信支付、订单查询、申请退款
微信小程序云开发微信支付 使用云开发微信支付功能的前提 统一下单 查询订单 申请退款 常见问题总结: 使用云开发微信支付功能的前提 小程序主体为企业或者工商个体户 小程序完成了微信认证 小程序接入微信 ...
- 微信小程序开发-微信支付之免密支付(自动扣费)一 小程序+java接口
微信小程序开发-微信支付之免密支付(自动扣费)一 小程序+java接口 链接: 点击进入
最新文章
- Fedora 15 安装与配置一览
- 技术感悟---主动学习
- 常用系统存储过程有:
- 网络故障解决方案之非标准子网划分【网管员必懂】
- filter的原理(转)
- 不浮躁的社会是什么样的?
- g开头的C语言编程软件,C语言函数大全(g开头)
- c语言拔河分组回溯算法,【阅读下面的文字,完成10—12题。文明的共相回溯我们历史演-查字典问答网...
- Frame - 快速创建高品质的 Web 应用原型
- java.sql.SQLException: Field 'id' doesn't have a default value解决方法
- [2020 年百度之星·程序设计大赛 - 复赛] Battle for Wosneth
- ps保存psd后图层全没了_ps保存成psd格式后,再打开就是一张图片而不显图层,怎么办啊??急!!...
- fftshift详解
- Oracle 字段 中文英文拆分
- 谷歌地图地名显示繁体字_谷歌地图卫星地图怎么取消地名还有路线
- 硬盘异响(嗑啦嗑啦)的可能原因
- 自动驾驶/机器人 SLAM算法 面经1
- 大学数据库创建与查询实战——查询
- 【深度学习】关于EMA:指数移动平均
- 【数字电路】D锁存器和D触发器的区别
热门文章
- win7计算机本地用户和组,Win7旗舰版找不到本地用户和组如何解决
- 安装pyrit qq5ed84579da89e
- 用request模块爬取拉钩招聘信息
- svelte-scrollbar: 基于svelte.js自定义滚动条组件|svelte3虚拟滚动条
- DTI数据TBSS组间统计对比设计矩阵
- Android 屏幕旋转的处理
- VS Studio和VS Code,IntelliJ IDEA的护眼背景色设置
- 在家用手机怎么赚钱?赚钱的秘密就在这里!
- DEVC++第五人格V2.0
- 那些年,年我们一起看过的大风车——HTML5风车效果