微信支付 H5 版本 PHP

微信支付 H5 版本 PHP,第1张

概述*接口文档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_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所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1000649.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存