*接口文档

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

java 引用如下


import java.io.IOException;
import java.security.GeneralSecurityException;public class MyClass {public static void main(String[] args) {byte[] key = "234sdfasdf234sdafsf".getBytes();byte[] associatedData = "certificate".getBytes();byte[] nonce = "2324dfsf".getBytes();String ciphertext = "s5s8QCRHGQe+lca9YtES0QrFR15t2khc=======";AesUtil as = new AesUtil(key);try {String certBack =  as.decryptToString(associatedData,nonce,ciphertext);System.out.print(certBack);} catch (GeneralSecurityException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

然后 将 解密 结果 写入 TXT 文件  ,并重命名 .pem  用于 【微信支付平台证书】

** 如果提示 unable to get local issuer certificate 。 则下载个 ca-bundle.crt

https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt

放在服务器 ,并在 php.ini 中配置路径

curl.cainfo="d:/ca-bundle.crt"

至此, 该准备的 准备好了。开始如下代码:

<?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) { //处理成功,无返回Bodyecho "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相关推荐

  1. 微信支付V3版本的 签名生成,验签,解密,统一下单的简单封装

    微信支付 V3版本的 签名生成,验签,解密,统一下单的简单封装 V3Base 获取平台证书 回调报文解密 统一下单 暂时看了文档只完成了这部分,感觉封装的不是特别完美,希望有大佬指点一下,想着封装好一 ...

  2. 2020微信支付v3版本java对接详细流程

    都0202年,我似乎翻遍了百度,都没找到最新版微信支付v3的对接相关的详细博客,我都纳闷了,只有自己摸索.还有就是竟然还有人用一些v3对接的假代码,来骗积分,我真的服了,感同身受,以下是我对接的过程, ...

  3. h5封装去底部_干货分享 | 一步一步教你在SpringBoot中集成微信支付H5支付

    一:开发文档场景介绍 H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付. 主要用于触屏版的手机浏览器请求微信支付的场景. ...

  4. 微信支付查询订单java_微信支付java版本之查询订单

    本文实例为大家分享了微信支付订单的查询接口,供大家参考,具体内容如下 1.接口简介 2.代码实现 package com.zhrd.bussinss.platform.controller.shop; ...

  5. (微信支付签名失败)微信支付v2版本踩坑-二次签名不同类型签名参数key不同

    小伙伴们在做微信支付对接的时候会遇到各种各样的坑,特别是微信支付v2版本,微信支付的二次签名官方文档没有给出明显的签名参数,导致在开发中很容易碰到微信支付的这个坑(微信支付签名失败),app签名key ...

  6. PHP实现小程序微信支付(v3版本)

    PS:本篇文章是PHP对小程序进行微信支付v3版本的实现,仅用于对支付流程的了解,具体使用方面需要大家自行调整 小程序端JS代码: getPrepayID(){var that = thiswx.ge ...

  7. 微信支付-H5网页支付开通流程

    简介  H5 支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付.主要用于触屏版的手机浏览器请求微信支付的场景.可以方便的从外 ...

  8. 微信支付v3版本对接记录

    微信支付v3版本对接记录 1.申请公众号和商户号 2.配置商户API_V3_key和商户证书 3.导入依赖 4.构建调用接口httpclient 5.调用jsapi下单示例 6.签名解释 7.回调示例 ...

  9. PHP实现小程序微信支付v3版本退款,以及对退款订单进行查询

    PS:本篇文章仅用作对小程序微信支付v3版本的退款流程以及对退款订单进行查询的流程展示,如要用于实际,还请自行修改代码 文章中调用的API_Connect.php 与API_v3Connect.php ...

  10. Java对接第三方支付渠道之微信支付APIV3版本

    提示:微信支付APIV3版本对接流程梳理,目前微信支付提供APIV3和APIV2两个版本,简而言之,V3版本的安全性比V2更高. Java对接第三方支付渠道之微信支付APIV3版本 一.接入指引 1. ...

最新文章

  1. 一位39岁程序员的困惑:知道得越多编程越慢怎么办?
  2. 瞧!老师的屏幕是如何被学生的弹幕玩坏的......
  3. python求阶乘和
  4. python open读取_python,一读取文件open()
  5. c++面向对象高级编程 学习二 带指针的类
  6. C# ASP.NET MVC 配置允许跨域访问
  7. 一年多开源没进展,我也放弃了
  8. Python3入门机器学习经典算法与应用 第3章 matplotlib基础
  9. chm转txt(chm转txt格式转换器安卓)
  10. tomcat原理详解和请求过程(涉及网卡、套接字等)
  11. 计算机网络怎么算默认网关,ip地址子网掩码计算器_默认网关怎么计算_ip 掩码 网关的关系...
  12. 虚拟机中无法使用鼠标滚轮(罗技鼠标)
  13. vmware 安装 mac os 修改序列号
  14. 电脑设置u盘启动方法
  15. 解决ubuntu无法连接网络问题
  16. html在线编辑器源代码,最完整的html在线编辑器 - WEB源码|其它源码|源代码 - 源码中国...
  17. vscode 热门插件超实用插件汇总——vscode使用必看
  18. CNPC海外操作人员英语日常用语900句
  19. SecureCRT scripting
  20. 使用AD(Altium Designer)三年的笔记(虽然很口语化,但是好记性不如烂笔头嘛~开熏)

热门文章

  1. html箭头轮播,CSS-用伪类制作小箭头(轮播图的左右切换btn)
  2. 鹅厂假前端实习鹅的实习日志
  3. aes sm1 对比_SM1,SM2,SM3,SM4刨析
  4. 计算机网络 DNS解析命令汇总
  5. 杭州电子科技大学计算机复试内容,2018年杭州电子科技大学考研复试录取办法...
  6. Linux查看系统自启动服务
  7. 雷达原理-运动目标检测与测速
  8. SpringBoot实战笔记:记一次接口406错误的解决
  9. Springboot 406错误
  10. Android 深入理解AIL语言与init.rc文件