微信支付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 = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi'; $notify_url = url('/api/weixin/notify'); $data = []; $data['appid'] = action::config(config_wxxcx, 'app_id'); $data['mchid'] = action::config(config_wxxcx, 'mchid'); //商户号 $data['description'] = 'xxx'; //描述? $data['out_trade_no'] = $sn; //商户系统内部订单号 $data['time_expire'] = date('y-m-d') . 't' . date('h:i:s', (time() + 1800)) . '+08:00'; //订单失效时间2018-06-08t10:34:56+08:00 $data['notify_url'] = $notify_url; //异步通知接口地址 $data['amount'] = ['total' => $money * 100, 'currency' => 'cny']; //金额 $data['payer'] = ['openid' => $openid]; //用户 $re = self::wxcurl($url, $data, 'post'); if (!isset($re['prepay_id'])) { api_fail('参数获取失败'); } $result = []; $result['appid'] = action::config(config_wxxcx, 'app_id'); $result['timestamp'] = (string)time(); $result['noncestr'] = uniqid(); $result['package'] = 'prepay_id=' . $re['prepay_id']; $result['signtype'] = 'rsa'; $result['paysign'] = self::getpaysign($result); return $result; } /** * 查询订单 * @param type $sn */ public static function select($sn, $return = false) { $mchid = action::config(config_wxxcx, 'mchid'); //商户号 $url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/' . $sn . '?mchid=' . $mchid; $re = self::wxcurl($url, [], 'get'); if ($return) { return $re; } if (isset($re['trade_state']) && $re['trade_state'] == 'success') { return true; } return false; } /** * 关闭订单 * @param type $sn */ public static function close($sn) { $mchid = action::config(config_wxxcx, 'mchid'); //商户号 $url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/' . $sn . '/close'; $re = self::wxcurl($url, ['mchid'=>$mchid], 'post'); return true; } /** * 退款 * @param type $sn */ public static function refund($order_sn,$refund_sn,$total,$refund,$msg='退款') { $url='https://api.mch.weixin.qq.com/v3/refund/domestic/refunds'; $data=[]; $data['notify_url']=url('ag/weixin/notify_refund'); $data['out_trade_no']=$order_sn;//订单号 $data['out_refund_no']=$refund_sn;//退款单号 $data['reason']=$msg; $data['amount']=['refund'=>$refund*100,'total'=>$total*100,'currency'=>'cny']; $re = self::wxcurl($url, $data, 'post'); return $re; } //请求 public static function wxcurl($url, $data = [], $method = 'get') { $authorization = self::getresign($url, $data, $method); $header = [ 'content-type: application/json', 'accept: application/json', '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', 'authorization: ' . $authorization ]; $redata = $data ? json_encode($data) : ''; $res = recurl($url, $redata, $header); return $res ? json_decode($res, true) : []; } //后端请求签名 public static function getresign($url, $data, $method = 'get') { $url_parts = parse_url($url); $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : "")); $http_method = $method; $timestamp = time(); $nonce = uniqid(); $body = $data ? json_encode($data) : ''; $mchid = action::config(config_wxxcx, 'mchid'); //商户id $serial_no = action::config(config_wxxcx, 'serial_no'); //证书编号 $private_key = self::getprivatekey(base_path . 'cert/apiclient_key.pem'); //商户私钥 $message = $http_method . "\n" . $canonical_url . "\n" . $timestamp . "\n" . $nonce . "\n" . $body . "\n"; openssl_sign($message, $raw_sign, $private_key, 'sha256withrsaencryption'); $sign = base64_encode($raw_sign); $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $mchid, $nonce, $timestamp, $serial_no, $sign); return 'wechatpay2-sha256-rsa2048 ' . $token; } //前端小程序签名 public static function getpaysign($result) { $private_key = self::getprivatekey(base_path . 'cert/apiclient_key.pem'); //商户私钥 $message = $result['appid'] . "\n" . $result['timestamp'] . "\n" . $result['noncestr'] . "\n" . $result['package'] . "\n"; openssl_sign($message, $raw_sign, $private_key, 'sha256withrsaencryption'); $sign = base64_encode($raw_sign); return $sign; } //验证签名 public static function checksign() { $header = context::get('header'); $serial_no = $header['wechatpay-serial'] ''; //微信平台序列号 $timestamp = $header['wechatpay-timestamp'] ''; $nonce = $header['wechatpay-nonce'] ''; $body = context::get('raw'); $wx_sign = $header['wechatpay-signature'] ''; $wx_serial_no = action::config(config_wxxcx, 'wx_serial_no');//保存的序列号 if (!$serial_no || $wx_serial_no != $serial_no) { \sff\log::write('签名过期'); return false; } $message = $timestamp . "\n" . $nonce . "\n" . $body . "\n"; $wx_sign = base64_decode($wx_sign); $public_key = self::getpublickey(base_path . 'cert/wx_public_cert.pem'); //平台公钥 $res = openssl_verify($message, $wx_sign, $public_key, openssl_algo_sha256); if ($res == 1) { return true; } \sff\log::write('验签失败'); 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 . 'cert/wx_public_cert.pem'; //'平台证书路径'; $public_key = file_get_contents($public_key_path); $encrypted = ''; if (openssl_public_encrypt($str, $encrypted, $public_key, openssl_pkcs1_oaep_padding)) { //base64编码 $sign = base64_encode($encrypted); } else { throw new exception('encrypt failed'); } return $sign; } //解密数据 public static function decrypttostring($ciphertext, $associateddata, $noncestr) { $aeskey = action::config(config_wxxcx, 'mch_keyv3'); //商户apiv3密钥解密 $str = base64_decode($ciphertext); if (strlen($str) <= 16) { return ''; } // ext-sodium (default installed on >= php 7.2) return \sodium_crypto_aead_aes256gcm_decrypt($str, $associateddata, $noncestr, $aeskey); } //下载平台证书 public static function downcert() { $url = 'https://api.mch.weixin.qq.com/v3/certificates'; $re = self::wxcurl($url, [], 'get'); if (!isset($re['data'])) { api_fail('获取证书失败'); } $ciphertext = $re['data'][0]['encrypt_certificate']['ciphertext']; $associateddata = $re['data'][0]['encrypt_certificate']['associated_data']; $noncestr = $re['data'][0]['encrypt_certificate']['nonce']; $data = self::decrypttostring($ciphertext, $associateddata, $noncestr); if (!$data) { api_fail('获取证书解密失败'); } file_put_contents(base_path . '/cert/wx_public_cert.pem', $data); return $data; }}
以上就是分享微信支付v3版 php解密解密代码的详细内容。
