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

news/2024/10/18 5:38:14/

PS:本篇文章是PHP对小程序进行微信支付v3版本的实现,仅用于对支付流程的了解,具体使用方面需要大家自行调整

小程序端JS代码:

getPrepayID(){var that = thiswx.getStorage({key:'openid',success(res){that.setData({'openid':res.data})}})wx.getStorage({key:'username',success(res){that.setData({'username':res.data})}})//console.log(that.data.openid)wx.request({url: 'http://127.0.0.1:2908/wxPayV3/v3GetPrepayId.php', //此处填写你的PHP文件url地址method:'POST',header:{'content-type':'application/x-www-form-urlencoded'},data:{  //发送的数据,大家根据需要自行调整'description':'0.38mm.pen',  //商品描述,自行调整'openid':that.data.openid,  //用户openid,此处是从缓存中获取到的'total':1,                  //订单总金额,单位为分,实际使用请乘100改为以元为单位'username':that.data.username,  //用户的昵称,此处从缓存中获取,用于后续存放于数据库中'goods_id':1                //商品编号,数据库使用},success(res){//console.log(res)// that.setData({//   'nonceStr':res.data.nonceStr,//   'package':res.data.package,//   'paySign':res.data.paySign,//   'timeStamp':res.data.timeStamp,//   'signType':res.data.signType// })console.log(res.data)wx.requestPayment({nonceStr: res.data.nonceStr,package: res.data.package,paySign: res.data.paySign,timeStamp: res.data.timeStamp,signType: 'RSA',success(res){//自行书写成功调用的逻辑,本篇仅为了实现成功支付}})}})},

PHP类的相关代码:

<?php
require_once('../config/appConfig.php');  //读取相关配置,主要是appid,mch_id,serial_no,APIv3class API_v3Connect
{/*** 获取相关配置*/public function __construct(){$appid = appid;$mch_id = mchID;$serial_no = serial_no;$APIv3 = APIv3;$this->appid = $appid;$this->mch_id = $mch_id;$this->serial_no = $serial_no;$this->APIv3 = $APIv3;}/*** 用于生成请求报文的主体,最终返回json格式数据* @param $description :商品描述* @param $out_trade_no :商户订单号* @param $total :订单总金额* @param $openid :小程序微信用户身份唯一标识符* @return false|string*/public function requestBody($description, $out_trade_no, $total, $openid){$data = array('appid' => $this->appid,'mchid' => $this->mch_id,'description' => $description,'out_trade_no' => $out_trade_no,'notify_url' => 'http://001.chutest.xyz/v3Result.php','amount' => ['total' => $total,],'payer' => ['openid' => $openid]);return json_encode($data);}/*** 用于生成签名数据主体* @param $disposeUrl :此处的url是接口地址去除域名后的url* @param $nonce_str :32位随机字符串* @param $requestBody :请求报文的主体* @return string*/public function signBody($disposeUrl, $time, $nonce_str, $requestBody){$data = array('POST', $disposeUrl, $time, $nonce_str, $requestBody, '');return join("\n", $data);}/*** 用于生成签名值* @param $data :用于签名的数据* @return string*/public function getSignature($data){$private = file_get_contents('./certificate/apiclient_key.pem');$key = openssl_pkey_get_private($private);openssl_sign($data, $signature, $key, 'sha256WithRSAEncryption');return base64_encode($signature);}/*** @param $nonce_str :32位随机字符串,与上方的随机字符串保持一致* @param $signature :上方生成的签名值* @return string[]*/public function getHeader($nonce_str, $signature){$token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%s",signature="%s"', $this->mch_id, $this->serial_no, $nonce_str, time(), $signature);$data = array('Accept: application/json','Content-Type: application/json','User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71',"Authorization: WECHATPAY2-SHA256-RSA2048 $token",);return $data;}/*** 使用curl完成对接口的请求* @param $url :接口的url地址* @param string $type :传输类型,若为POST需要提供$data与$header* @param string $data :当type = POST时需要提供,为请求主体数据* @param array $header :当type = POST时需要提供,为请求头* @return bool|string*/public function curlRequest($url, string $type = '', string $data = '', array $header = []){$action = curl_init();curl_setopt($action, CURLOPT_URL, $url);curl_setopt($action, CURLOPT_CONNECTTIMEOUT, 60);curl_setopt($action, CURLOPT_RETURNTRANSFER, 1);curl_setopt($action, CURLOPT_HEADER, 0);curl_setopt($action, CURLOPT_SSL_VERIFYPEER, 0);curl_setopt($action, CURLOPT_SSL_VERIFYHOST, 0);if ($type == 'POST') {curl_setopt($action, CURLOPT_POST, 1);curl_setopt($action, CURLOPT_POSTFIELDS, $data);curl_setopt($action, CURLOPT_HTTPHEADER, $header);}$result = curl_exec($action);curl_close($action);return $result;}/*** 构造对prepay_id再次签名的签名数据主体* @param $time :时间戳* @param $nonceStr :32位随机字符串* @param $prepay_id :预支付参数* @return string*/public function paySignBody($time, $nonceStr, $prepay_id){$data = array($this->appid, $time, $nonceStr, "prepay_id=$prepay_id", '');return join("\n", $data);}/*** 构造返回给小程序段的数据,json数据* @param $nonce_str :32位随机字符串* @param $prepay_id :预支付参数* @param $paySign :签名值* @param $time :时间戳* @param $out_trade_no :商户订单号* @return false|string*/public function requestPayData($nonce_str, $prepay_id, $paySign, $time, $out_trade_no){$data = array('nonceStr' => $nonce_str,'package' => 'prepay_id=' . $prepay_id,'paySign' => $paySign,'timeStamp' => $time,'signType' => 'RSA','out_trade_no' => $out_trade_no);return json_encode($data);}
}

PHP调用方法的代码:

<?php
require_once('./API_v3Connect.php');
require_once('../wxPayV2/API_Connect.php'); //此处调用v2是为了省去再次写一遍获取随机字符串与商户订单号的麻烦
require_once('../database/getDatabase.php'); //此处调用数据库,将该订单的相关信息加入数据库中$description = $_POST['description'];  //接收商品描述
$openid = $_POST['openid'];  //接收用户的openid
$total = $_POST['total'];  //接收订单总金额
$total = (int)$total;  //将订单总金额转化为int类型,此处接收到的数据默认是string类型
$time = time();$getPartData = new v2Connect;
$nonce_str = $getPartData->nonce_str();  //获取32位随机字符串
$out_trade_no = $getPartData->out_trade_no();  //获取商户订单号$getData = new API_v3Connect;$requestBody = $getData->requestBody($description, $out_trade_no, $total, $openid);  //获取请求主体的json数据$disposeUrl = '/v3/pay/transactions/jsapi';  //处理过后的url地址 注:去掉前方的域名即可
$signBody = $getData->signBody($disposeUrl, $time, $nonce_str, $requestBody);  //获取参与签名的主体数据$signature = $getData->getSignature($signBody);  //获取签名值$header = $getData->getHeader($nonce_str, $signature);  //获取请求头$url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';  //接口的url地址
$prepay_id = $getData->curlRequest($url, 'POST', $requestBody, $header);  //获取预支付参数
$disposePrepayId = json_decode($prepay_id, true);   //将返回的数据转化为数组
$prepay_id = $disposePrepayId['prepay_id'];  //从转化的数组中获取prepay_id$paySignBody = $getData->paySignBody($time, $nonce_str, $prepay_id);  //构造生成支付签名的签名主体数据$paySign = $getData->getSignature($paySignBody); //对构造好的签名数据主体进行签名$time = (string)$time; //将时间戳由int转化为string类型
$getPayData = $getData->requestPayData($nonce_str, $prepay_id, $paySign, $time, $out_trade_no); //获取返回给小程序段的数据
echo $getPayData;

支付成功后微信回调发送的数据:

{"id": "2dd87d80-2478-5ab0-852c-6d20084f8175","create_time": "2022-07-26T17:07:28+08:00","resource_type": "encrypt-resource","event_type": "TRANSACTION.SUCCESS","summary": "支付成功","resource": {"original_type": "transaction","algorithm": "AEAD_AES_256_GCM","ciphertext": "此处显示密文,需要经过解密显示","associated_data": "transaction","nonce": "8oAAd7fCPvpO"}
}

PS:微信会掉返回的内容中部分数据是进过加密的,需要进过解密之后才会显示


本文由CSDN用户: 缱绻淡蓝海 原创,代码具有时效性,作者会不定时对发布过的文章进行更新


http://www.ppmy.cn/news/239590.html

相关文章

oppoa57计算机有存储功能吗,虽是入门级产品,但OPPO A57这两个功能值得称赞

原标题&#xff1a;虽是入门级产品&#xff0c;但OPPO A57这两个功能值得称赞 一向低调的OPPO随着R11s新机的预热再次走到了消费者的视野中&#xff0c;作为其首款全面屏旗舰&#xff0c;该机无疑成为了用户新的追求对象。当然&#xff0c;如果你是实用主义者觉得该机价格较高&…

中兴f660有没有千兆_电信F660是不是千兆光纤猫?200兆光宽带能不能用电信中兴F660光纤猫?...

展开全部 F660光纤猫可用于千兆光纤宽带,自带无线路由器,但只有lan1口支持32313133353236313431303231363533e59b9ee7ad9431333365633934千兆输出,其余的只能支持百兆输出。 中国电信集团公司是我国特大型国有通信企业、上海世博会全球合作伙伴&#xff0c;连续多年入选"世…

phpexcel 在php7中出现500错误

PHPExcel在PHP7中&#xff0c;Writer->save出现ERR_INVALID_RESPONSE错误的解决方法 这个Writer->save错误可能由于很多原因导致&#xff0c;其中有一部分是因为header和缓冲区的错误导致的。 这部分具体讨论可以看这里 http://stackoverflow.com/questions/8566196/php…

一代机皇Redmi K20 Pro销量破500万 Redmi K30 Pro即将正式发布

2020年2月24日&#xff0c;Redmi通过官方微博宣布&#xff0c;深受500多万用户喜爱的Redmi K20 Pro谢幕。Redmi K20 Pro于2019年5月28日发布&#xff0c;全球持续热销&#xff0c;总销量突破500万。受行业5G转型大环境的影响&#xff0c;过去一年4G旗舰市场竞争尤其激烈&#x…

移动光猫试玩

移动自带光猫中移物联吉比特GM620&#xff0c;网上查不到这个型号&#xff0c;还好CMCCAdmin密码网上查的到&#xff0c;登录进去看看&#xff0c;改掉TR069连接的VLAN ID和RMS上报URL。 这光猫配置还行&#xff0c;实际是ZTE ZX279128&#xff0c;双核1.5G&#xff0c;512M R…

500、1000

上周日&#xff0c;是我参加工作整整 1000 天&#xff0c;确实没想到&#xff0c;我都已经混迹职场这么久了。 周一呢&#xff0c;也是距离我写第一篇公众号文章的第 500 天&#xff0c;确实也没想到写这么久了。 两个相比较来说&#xff0c;工作的收获稍大一些。 公众号基本…

电信光猫F660 4台限制破解

首先说明几点&#xff1a; 1. xml 当然是要明文的。没有明文的&#xff0c;只能丢失配置完全重新写一份。 2. tr69 远程控制必须去掉&#xff0c;因为限制会被重新加上使破解失效。 最简明的方法是把服务器 URL 改掉&#xff1a; 比如 http://devacs.edatahome... 那个&#…

中兴光纤猫 F460 V3.0破解

电信最近不断在推免费的光纤猫&#xff0c;疯狂的要把原有基于电话线ADSL都升级掉。怎不知电信要免费给你做什么什么了&#xff0c;基本上就没什么好事情了。果然&#xff0c;电信所谓的免费升级就是换回来一个中兴的ZXA10 F460 V3.0光纤猫。性能真的是不怎么样&#xff0c;无线…