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用户: 缱绻淡蓝海 原创,代码具有时效性,作者会不定时对发布过的文章进行更新