*接口文档
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_0.shtml
接入之前先 做好 后台开通 H5 支付,并且 后台 配置 相关域名信息,已经 证书。
证书 在 【API 安全】那里,可以查看 到 [商户API证书序列号] 以及 下载 商户私钥KEY 的 PEM 文件。
* 开始接入 的代码
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_2.shtml
去 https://github.com/wechatpay-apiv3/wechatpay-guzzle-middleware 下载 封装好的库 ,
* 其中 该库 需 使用 composer 进行 安装 , 没有 composer 参考:https://www.runoob.com/w3cnote/composer-install-and-usage.html 安装。
然后运行命令,加载 微信支付库
composer require wechatpay/wechatpay-guzzle-mIDdleware
如果 加载不成功,则自己手动下载包,然后手动 include 相关文件。
* 另外 该库 还需用到 guzzlehttp 库。也可以使用 composer 安装
composer require guzzlehttp/guzzle
安装后 会 得到 vender 目录文件
如果 不能正常 加载 guzzle 库,则自己 手动拷贝这些文件 并 包含 autoload.PHP
* 其中 【商户API证书序列号】 在 商户后台 API 安全 那里可以看到, 【商户私钥文件】就是 商户后台下载那个。
【微信支付平台证书】就比较麻烦了。
参考 https://blog.csdn.net/ningxn/article/details/107344223
先是 获取 平台证书 及 序列号。获取的结果是 加密过的。
class GetCert{ /** * 获取平台证书内容 */ public function get_Certificates() { $merchant_ID = '10000000001';//商户号,需改成自己的 $serial_no = 'KJASDFJLK23423424321';//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); print_r(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 = './cert/apiclient_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; }} $a = new GetCert();$a->get_Certificates();
获取 如下 类似的 结果
然后 要对这些 进行 解密。 解密 参考 官方 DEMO https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/zheng-shu-he-hui-tiao-bao-wen-jie-mi
因为 官方DEMO 的 PHP 解密 需要 PHP 7.1+ 的版本,所以 使用了 JAVA 版本的 解密。
import java.io.IOException;import java.security.GeneralSecurityException;import java.security.InvalIDAlgorithmParameterException;import java.security.InvalIDKeyException;import java.security.NoSuchAlgorithmException;import java.util.Base64;import javax.crypto.Cipher;import javax.crypto.NoSuchpaddingException;import javax.crypto.spec.GCMParameterSpec;import javax.crypto.spec.SecretKeySpec;public class AesUtil { static final int KEY_LENGTH_BYTE = 32; static final int TAG_LENGTH_BIT = 128; private final byte[] aesKey; public AesUtil(byte[] key) { if (key.length != KEY_LENGTH_BYTE) { throw new IllegalArgumentException("无效的APIV3Key,长度必须为32个字节"); } this.aesKey = key; } public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext) throws GeneralSecurityException, IOException { try { Cipher cipher = Cipher.getInstance("AES/GCM/Nopadding"); SecretKeySpec key = new SecretKeySpec(aesKey, "AES"); GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce); cipher.init(Cipher.DECRYPT_MODE, key, spec); cipher.updateAAD(associatedData); return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8"); } catch (NoSuchAlgorithmException | NoSuchpaddingException e) { throw new IllegalStateException(e); } catch (InvalIDKeyException | InvalIDAlgorithmParameterException e) { throw new IllegalArgumentException(e); } }}
如果 电脑 只安装了 AndroID Studio 也可以 只允许 JAVA 调试。
参考 : https://www.jianshu.com/p/716a12a854c1
然后 将 解密 结果 写入 TXT 文件 ,并重命名 .pem 用于 【微信支付平台证书】
至此, 该准备的 准备好了。开始如下代码:
<?PHPrequire './vendor/autoload.PHP'; use Guzzlehttp\Exception\RequestException;use WechatPay\GuzzleMIDdleware\WechatPayMIDdleware;use WechatPay\GuzzleMIDdleware\Util\PemUtil;use Guzzlehttp\HandlerStack; include("./cert/Credentials.PHP");include("./cert/Signer.PHP");include("./cert/VerifIEr.PHP");include("./cert/CertificateVerifIEr.PHP");include("./cert/ValIDator.PHP");include("./cert/WechatPay2ValIDator.PHP");include("./cert/PrivateKeySigner.PHP");include("./cert/PemUtil.PHP");include("./cert/WechatPayMIDdleware.PHP");include("./cert/WechatPayMIDdlewareBuilder.PHP");include("./cert/WechatPay2Credentials.PHP");//function GetIP(){ if (getenv("http_CLIENT_IP") && strcasecmp(getenv("http_CLIENT_IP"), "unkNown")) $ip = getenv("http_CLIENT_IP"); else if (getenv("http_X_FORWARDED_FOR") && strcasecmp(getenv("http_X_FORWARDED_FOR"), "unkNown")) $ip = getenv("http_X_FORWARDED_FOR"); else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unkNown")) $ip = getenv("REMOTE_ADDR"); else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unkNown")) $ip = $_SERVER['REMOTE_ADDR']; else $ip = "unkNown"; return($ip); } // 商户相关配置,$merchantID = '16100000001'; // 商户号$merchantSerialNumber = '34KL32J4LKJ2L41234234'; // 商户API证书序列号$merchantPrivateKey = PemUtil::loadPrivateKey('./cert/apiclient_key.pem'); // 商户私钥文件路径 // 微信支付平台配置$wechatpayCertificate = PemUtil::loadCertificate('./cert/wx_cert.pem'); // 微信支付平台证书文件路径 // 构造一个WechatPayMIDdleware$wechatpayMIDdleware = WechatPayMIDdleware::builder() ->withMerchant($merchantID, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置 ->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书,参数类型为array ->build(); // 将WechatPayMIDdleware添加到Guzzle的HandlerStack中$stack = Guzzlehttp\HandlerStack::create();$stack->push($wechatpayMIDdleware, 'wechatpay'); // 创建Guzzle http ClIEnt时,将HandlerStack传入,接下来,正常使用Guzzle发起API请求,WechatPayMIDdleware会自动地处理签名和验签$clIEnt = new Guzzlehttp\ClIEnt(['handler' => $stack]); ?> <?PHP $clt_ip = GetIP();try { $resp = $clIEnt->request( 'POST', 'https://API.mch.weixin.qq.com/v3/pay/transactions/h5', //请求URL [ // JsON请求体 'Json' => [ "amount" => [ "total" => 100, "currency" => "CNY", ], "mchID" => "1002340241", "description" => "Image形象店-深圳腾大-QQ公仔", "notify_url" => "http://demo2.shijIEhuashanglianmeng.com/demo/1/pay/1.PHP", "out_Trade_no" => "1217752501201407033233361001", "goods_tag" => "WXG", "appID" => "wx234ASDFASDF234", "attach" => "自定义数据说明", "scene_info" => [ "device_ID" => "013467007045761", "payer_clIEnt_ip" => $clt_ip, "h5_info"=>[ "type"=>"AndroID" ], ] ], 'headers' => [ 'Accept' => 'application/Json' ] ] ); $statusCode = $resp->getStatusCode(); if ($statusCode == 200) { //处理成功 echo $reBody = $resp->getbody()->getContents(); $Json = Json_decode($reBody); print_r($Json); echo '<a href="'.$Json->h5_url.'" >跳转</a>'; } else if ($statusCode == 204) { //处理成功,无返回Body echo "success"; }} catch (RequestException $e) { // 进行错误处理 echo '错误应答 '."<BR><BR>"; echo $e->getMessage()."\n"; if ($e->hasResponse()) { echo "Failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getbody() . "\n"; } return;}?>
总结
以上是内存溢出为你收集整理的微信支付 H5 版本 PHP全部内容,希望文章能够帮你解决微信支付 H5 版本 PHP所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)