首页 > 微信应用  > 

分享微信支付v3版 php解密解密代码

分享微信支付v3版 php解密解密代码
微信支付V3版本小程序支付 php签名,验签,数据解密代码分享;数据解密需要用到sodium扩展 大部分php版本需要安装,证书序列号可以在这里查看https://myssl.com/cert_decode.html。

微信支付v3版本小程序支付 php签名,验签,数据解密代码分享

微信支付v3版 php解密解密代码

数据解密需要用到sodium扩展 大部分php版本需要安装

证书序列号可以在这里查看https://myssl.com/cert_decode.html

我用的php7.4版本

直接上代码:

//微信原生支付class Wxpay{ /* * 支付(小程序支付) * @param type $sn 订单编号 * @param type $money 金额 * @param type $openid 用户小程序openid * @return type */ public static function getPayParam($sn, $money, $openid) { $url = &#39;https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi&#39;; $notify_url = url(&#39;/api/weixin/notify&#39;); $data = []; $data[&#39;appid&#39;] = Action::config(CONFIG_WXXCX, &#39;app_id&#39;); $data[&#39;mchid&#39;] = Action::config(CONFIG_WXXCX, &#39;mchid&#39;); //商户号 $data[&#39;description&#39;] = &#39;xxx&#39;; //描述? $data[&#39;out_trade_no&#39;] = $sn; //商户系统内部订单号 $data[&#39;time_expire&#39;] = date(&#39;Y-m-d&#39;) . &#39;T&#39; . date(&#39;H:i:s&#39;, (time() + 1800)) . &#39;+08:00&#39;; //订单失效时间2024-06-08T10:34:56+08:00 $data[&#39;notify_url&#39;] = $notify_url; //异步通知接口地址 $data[&#39;amount&#39;] = [&#39;total&#39; => $money * 100, &#39;currency&#39; => &#39;CNY&#39;]; //金额 $data[&#39;payer&#39;] = [&#39;openid&#39; => $openid]; //用户 $re = self::wxCurl($url, $data, &#39;POST&#39;); if (!isset($re[&#39;prepay_id&#39;])) { api_fail(&#39;参数获取失败&#39;); } $result = []; $result[&#39;appId&#39;] = Action::config(CONFIG_WXXCX, &#39;app_id&#39;); $result[&#39;timeStamp&#39;] = (string)time(); $result[&#39;nonceStr&#39;] = uniqid(); $result[&#39;package&#39;] = &#39;prepay_id=&#39; . $re[&#39;prepay_id&#39;]; $result[&#39;signType&#39;] = &#39;RSA&#39;; $result[&#39;paySign&#39;] = self::getPaySign($result); return $result; } /** * 查询订单 * @param type $sn */ public static function select($sn, $return = false) { $mchid = Action::config(CONFIG_WXXCX, &#39;mchid&#39;); //商户号 $url = &#39;https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/&#39; . $sn . &#39;?mchid=&#39; . $mchid; $re = self::wxCurl($url, [], &#39;GET&#39;); if ($return) { return $re; } if (isset($re[&#39;trade_state&#39;]) && $re[&#39;trade_state&#39;] == &#39;SUCCESS&#39;) { return true; } return false; } /** * 关闭订单 * @param type $sn */ public static function close($sn) { $mchid = Action::config(CONFIG_WXXCX, &#39;mchid&#39;); //商户号 $url = &#39;https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/&#39; . $sn . &#39;/close&#39;; $re = self::wxCurl($url, [&#39;mchid&#39;=>$mchid], &#39;POST&#39;); return true; } /** * 退款 * @param type $sn */ public static function refund($order_sn,$refund_sn,$total,$refund,$msg=&#39;退款&#39;) { $url=&#39;https://api.mch.weixin.qq.com/v3/refund/domestic/refunds&#39;; $data=[]; $data[&#39;notify_url&#39;]=url(&#39;ag/weixin/notify_refund&#39;); $data[&#39;out_trade_no&#39;]=$order_sn;//订单号 $data[&#39;out_refund_no&#39;]=$refund_sn;//退款单号 $data[&#39;reason&#39;]=$msg; $data[&#39;amount&#39;]=[&#39;refund&#39;=>$refund*100,&#39;total&#39;=>$total*100,&#39;currency&#39;=>&#39;CNY&#39;]; $re = self::wxCurl($url, $data, &#39;POST&#39;); return $re; } //请求 public static function wxCurl($url, $data = [], $method = &#39;GET&#39;) { $Authorization = self::getReSign($url, $data, $method); $header = [ &#39;Content-Type: application/json&#39;, &#39;Accept: application/json&#39;, &#39;User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.63&#39;, &#39;Authorization: &#39; . $Authorization ]; $redata = $data ? json_encode($data) : &#39;&#39;; $res = reCurl($url, $redata, $header); return $res ? json_decode($res, true) : []; } //后端请求签名 public static function getReSign($url, $data, $method = &#39;GET&#39;) { $url_parts = parse_url($url); $canonical_url = ($url_parts[&#39;path&#39;] . (!empty($url_parts[&#39;query&#39;]) ? "?${url_parts[&#39;query&#39;]}" : "")); $http_method = $method; $timestamp = time(); $nonce = uniqid(); $body = $data ? json_encode($data) : &#39;&#39;; $mchid = Action::config(CONFIG_WXXCX, &#39;mchid&#39;); //商户id $serial_no = Action::config(CONFIG_WXXCX, &#39;serial_no&#39;); //证书编号 $private_key = self::getPrivateKey(BASE_PATH . &#39;cert/apiclient_key.pem&#39;); //商户私钥 $message = $http_method . "\n" . $canonical_url . "\n" . $timestamp . "\n" . $nonce . "\n" . $body . "\n"; openssl_sign($message, $raw_sign, $private_key, &#39;sha256WithRSAEncryption&#39;); $sign = base64_encode($raw_sign); $token = sprintf(&#39;mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"&#39;, $mchid, $nonce, $timestamp, $serial_no, $sign); return &#39;WECHATPAY2-SHA256-RSA2048 &#39; . $token; } //前端小程序签名 public static function getPaySign($result) { $private_key = self::getPrivateKey(BASE_PATH . &#39;cert/apiclient_key.pem&#39;); //商户私钥 $message = $result[&#39;appId&#39;] . "\n" . $result[&#39;timeStamp&#39;] . "\n" . $result[&#39;nonceStr&#39;] . "\n" . $result[&#39;package&#39;] . "\n"; openssl_sign($message, $raw_sign, $private_key, &#39;sha256WithRSAEncryption&#39;); $sign = base64_encode($raw_sign); return $sign; } //验证签名 public static function checkSign() { $header = Context::get(&#39;header&#39;); $serial_no = $header[&#39;wechatpay-serial&#39;] ?? &#39;&#39;; //微信平台序列号 $timeStamp = $header[&#39;wechatpay-timestamp&#39;] ?? &#39;&#39;; $nonce = $header[&#39;wechatpay-nonce&#39;] ?? &#39;&#39;; $body = Context::get(&#39;raw&#39;); $wx_sign = $header[&#39;wechatpay-signature&#39;] ?? &#39;&#39;; $wx_serial_no = Action::config(CONFIG_WXXCX, &#39;wx_serial_no&#39;);//保存的序列号 if (!$serial_no || $wx_serial_no != $serial_no) { \sff\Log::write(&#39;签名过期&#39;); return false; } $message = $timeStamp . "\n" . $nonce . "\n" . $body . "\n"; $wx_sign = base64_decode($wx_sign); $public_key = self::getPublicKey(BASE_PATH . &#39;cert/wx_public_cert.pem&#39;); //平台公钥 $res = openssl_verify($message, $wx_sign, $public_key, OPENSSL_ALGO_SHA256); if ($res == 1) { return true; } \sff\Log::write(&#39;验签失败&#39;); return false; } //获取私钥 public static function getPrivateKey($filepath) { return openssl_get_privatekey(file_get_contents($filepath)); } //获取公钥 public static function getPublicKey($filepath) { return openssl_pkey_get_public(file_get_contents($filepath)); } //加密数据 public static function getEncrypt($str) {//$str是待加密字符串 $public_key_path = BASE_PATH . &#39;cert/wx_public_cert.pem&#39;; //&#39;平台证书路径&#39;; $public_key = file_get_contents($public_key_path); $encrypted = &#39;&#39;; if (openssl_public_encrypt($str, $encrypted, $public_key, OPENSSL_PKCS1_OAEP_PADDING)) { //base64编码 $sign = base64_encode($encrypted); } else { throw new Exception(&#39;encrypt failed&#39;); } return $sign; } //解密数据 public static function decryptToString($ciphertext, $associatedData, $nonceStr) { $aesKey = Action::config(CONFIG_WXXCX, &#39;mch_keyv3&#39;); //商户apiv3密钥解密 $str = base64_decode($ciphertext); if (strlen($str) <= 16) { return &#39;&#39;; } // ext-sodium (default installed on >= PHP 7.2) return \sodium_crypto_aead_aes256gcm_decrypt($str, $associatedData, $nonceStr, $aesKey); } //下载平台证书 public static function downCert() { $url = &#39;https://api.mch.weixin.qq.com/v3/certificates&#39;; $re = self::wxCurl($url, [], &#39;GET&#39;); if (!isset($re[&#39;data&#39;])) { api_fail(&#39;获取证书失败&#39;); } $ciphertext = $re[&#39;data&#39;][0][&#39;encrypt_certificate&#39;][&#39;ciphertext&#39;]; $associatedData = $re[&#39;data&#39;][0][&#39;encrypt_certificate&#39;][&#39;associated_data&#39;]; $nonceStr = $re[&#39;data&#39;][0][&#39;encrypt_certificate&#39;][&#39;nonce&#39;]; $data = self::decryptToString($ciphertext, $associatedData, $nonceStr); if (!$data) { api_fail(&#39;获取证书解密失败&#39;); } file_put_contents(BASE_PATH . &#39;/cert/wx_public_cert.pem&#39;, $data); return $data; }}

分享微信支付v3版 php解密解密代码由讯客互联微信应用栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“分享微信支付v3版 php解密解密代码