微信支付V3版本小程序支付 php簽名,驗(yàn)簽,數(shù)據(jù)解密代碼分享
微信支付v3版 php解密解密代碼
數(shù)據(jù)解密需要用到sodium擴(kuò)展 大部分php版本需要安裝
證書序列號(hào)可以在這里查看https://myssl.com/cert_decode.html
我用的php7.4版本
直接上代碼:
//微信原生支付 class Wxpay { /* * 支付(小程序支付) * @param type $sn 訂單編號(hào) * @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'); //商戶號(hào) $data['description'] = 'xxx'; //描述? $data['out_trade_no'] = $sn; //商戶系統(tǒng)內(nèi)部訂單號(hào) $data['time_expire'] = date('Y-m-d') . 'T' . date('H:i:s', (time() + 1800)) . '+08:00'; //訂單失效時(shí)間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('參數(shù)獲取失敗'); } $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'); //商戶號(hào) $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; } /** * 關(guān)閉訂單 * @param type $sn */ public static function close($sn) { $mchid = Action::config(CONFIG_WXXCX, 'mchid'); //商戶號(hào) $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;//訂單號(hào) $data['out_refund_no']=$refund_sn;//退款單號(hào) $data['reason']=$msg; $data['amount']=['refund'=>$refund*100,'total'=>$total*100,'currency'=>'CNY']; $re = self::wxCurl($url, $data, 'POST'); return $re; } //請(qǐng)求 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) : []; } //后端請(qǐng)求簽名 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'); //證書編號(hào) $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; } //驗(yàn)證簽名 public static function checkSign() { $header = Context::get('header'); $serial_no = $header['wechatpay-serial'] ?? ''; //微信平臺(tái)序列號(hào) $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');//保存的序列號(hào) if (!$serial_no || $wx_serial_no != $serial_no) { \sff\Log::write('簽名過(guò)期'); 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'); //平臺(tái)公鑰 $res = openssl_verify($message, $wx_sign, $public_key, OPENSSL_ALGO_SHA256); if ($res == 1) { return true; } \sff\Log::write('驗(yàn)簽失敗'); 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)); } //加密數(shù)據(jù) public static function getEncrypt($str) { //$str是待加密字符串 $public_key_path = BASE_PATH . 'cert/wx_public_cert.pem'; //'平臺(tái)證書路徑'; $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; } //解密數(shù)據(jù) 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); } //下載平臺(tái)證書 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; } }
Atas ialah kandungan terperinci 分享微信支付v3版 php解密解密代碼. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)
