微信小程序支付中的prepay_id获取方法,以及微信支付统一签名算法闭坑

2024-05-16 09:58

本文主要是介绍微信小程序支付中的prepay_id获取方法,以及微信支付统一签名算法闭坑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

class Wechat
{//公众号的或者小程序支付参数private $appId = "*************";private $appSecret = "*************";//商家的配置信息private $mch_id = "*************";private $mch_key = "*************";//回调地址public $notify_url = '';//退款回掉地址public $refund_notify_url = '';private $request;private $nonce_str;public function __construct(){$this->request = Request::instance();$this->notify_url = base_url() . 'notice.php';$this->refund_notify_url = base_url() . 'refund.php';$this->nonce_str = md5(date('YmdHis') . time() . rand(1000, 9999));}//小程序登录/*** @param $code  获取微信支付的登录code* @return mixed*/public function wxLogin($code){$url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $this->appId . "&secret=" . $this->appSecret . "&js_code=" . $code . "&grant_type=authorization_code";return json_decode($this->execute($url), true);}/*** @param $out_trade_no  微信支付唯一订单* @param $openid 微信支付用户的openid* @param $price  订单支付的价格,(单位,元)* @param string $desc 订单描述* @return array|mixed 组装支付参数*/public function getPayParameter($out_trade_no, $openid, $price, $desc = ''){header("Content-type:text/html;charset=utf-8"); //此处进行字符集初始化,$data = array('appid' => $this->appId,'body' => $desc,'mch_id' => $this->mch_id,'nonce_str' => $this->nonce_str,               //随机字符串'notify_url' => $this->notify_url,             //异步回调地址'openid' => $openid,                           //用户登录时获取的code中含有的值'out_trade_no' => $out_trade_no,               //商家订单号'spbill_create_ip' => $this->get_real_ip(),    //APP和网页支付提交用户端ip'total_fee' => $price * 100,                   //订单总额//'total_fee' => 1,'attach' => 'order',           //确定是哪个商家进行的支付'trade_type' => 'JSAPI'           //交易类型);//将数组转化为Xml$data['sign'] = $this->makeSign($data);$abc_xml = $this->arrayToXml($data);//统一下单接口prepay_id$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';$xml = $this->execute($url, $abc_xml, 1);//将XMl转化为数组$info = $this->xml2array($xml);if (!isset($info['prepay_id'])) {return $info;}$params = array('appId' => $this->appId,'nonceStr' => $data['nonce_str'],'package' => 'prepay_id=' . $info['prepay_id'],'signType' => 'MD5','timeStamp' => '' . time(),);$_info['paySign'] = $this->makeSign($params);$_info['timeStamp'] = "" . $params['timeStamp'];$_info['nonceStr'] = $params['nonceStr'];$_info['package'] = $params['package'];$_info['signType'] = $params['signType'];$_info['notify_url'] = $this->notify_url;//请求成功后进行返回数据信息if ($info['return_code'] == 'SUCCESS' || $info['result_code'] == 'SUCCESS') {return $_info;} else {return [];}}/*** @param $openid  支付的用户的openid* @return mixed*/public function userInfo($openid){$token = $this->getWxAccessToken();$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $token . "&openid=$openid&lang=zh_CN";return json_decode($this->execute($url), true);}//获取微信的tokenpublic function getWxAccessToken(){$key = $this->appId . 'miniProgram_access_token';$accessToken = Cache::get($key);if ($accessToken) return $accessToken;$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->appId . "&secret=" . $this->appSecret;$con = json_decode($this->execute($url));Cache::set($key, $con->access_token, $con->expires_in);return $con->access_token;}/*** @param $url  请求url地址* @param string $data 请求参数* @param int $post 是否为post* @param int $cert 是否为微信的cert* @return mixed*/private function execute($url, $data = '', $post = 0, $cert = 0){if (is_array($data)) {$data = json_encode($data);}$ch = curl_init();curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);curl_setopt($ch, CURLOPT_POST, $post);if ($post)curl_setopt($ch, CURLOPT_POSTFIELDS, $data);if ($cert) {curl_setopt($ch, CURLOPT_SSLCERT, WEB_PATH . 'cert' . DS . 'apiclient_cert.pem');curl_setopt($ch, CURLOPT_SSLKEY, WEB_PATH . 'cert' . DS . 'apiclient_key.pem');}// curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);curl_setopt($ch, CURLOPT_URL, $url);$result = curl_exec($ch);curl_close($ch);return $result;}function http_post_data($url, $data_string, $header = [], $is_array = 0, $is_key_pem = false){if (is_array($data_string)) {$data_string = json_encode($data_string);}if (!$header) {$header = ["Content-Type: application/json; charset=utf-8","Content-Length: " . strlen($data_string)];} else {$header = array_merge($header, ["Content-Type: application/json; charset=utf-8","Content-Length: " . strlen($data_string)]);}$ch = curl_init();curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);curl_setopt($ch, CURLOPT_HTTPHEADER, $header);curl_setopt($ch, CURLOPT_TIMEOUT, 3);if ($is_key_pem) {$isdir = '/cert/';curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 终止从服务端进行验证curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置// curl_setopt($ch, CURLOPT_CAINFO, 'PEM');// curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem');}ob_start();curl_exec($ch);$return_content = ob_get_contents();ob_end_clean();$return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);if ($is_array) {if (!is_array($return_content)) {$return_content = json_decode($return_content, true);}}return $return_content;}// 数组转化为 xlmpublic function arrayToXml($data){$data['sign'] = $this->makeSign($data);ksort($data);//进行拼接数据$abc_xml = "<xml>";foreach ($data as $key => $val) {if (is_numeric($val)) {$abc_xml .= "<" . $key . ">" . $val . "</" . $key . ">";} else {$abc_xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";}}$abc_xml .= "</xml>";return $abc_xml;}//xlm 转化为数组public function xml2array($xml){if (empty($xml)) {return array();}//禁止引用外部xml实体libxml_disable_entity_loader(true);$xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);$val = json_decode(json_encode($xmlstring), true);return $val;}//微信进行拼接signpublic function makeSign($params){//签名步骤一:按字典序排序数组参数ksort($params);$buff1 = '';foreach ($params as $k => $v) {if ($k != "sign" && $v != "" && !is_array($v)) {$buff1 .= $k . "=" . $v . "&";}}$buff1 = trim($buff1, "&");//签名步骤二:在string后加入KEY$string = $buff1 . "&key=" . $this->mch_key;//签名步骤三:MD5加密$string = md5($string);//签名步骤四:所有字符转为大写$result = strtoupper($string);return $result;}//验证图片或者视频是否涉黄public function imgSecCheck($media_url, $media_type = 2){$url = 'https://api.weixin.qq.com/wxa/media_check_async?access_token=' . $this->getWxAccessToken();$return = $this->execute($url, ['media_url' => $media_url,'media_type' => $media_type,], 1);$return = json_decode($return, true);if ($return && $return['errcode'] == 0) {return true;}return false;}//验证发布内容是否违法以及敏感词汇public function msgSecCheck($content = ''){$url = 'https://api.weixin.qq.com/wxa/msg_sec_check?access_token=' . $this->getWxAccessToken();$return = $this->execute($url, ['content' => $content], 1);$return = json_decode($return, true);if ($return && $return['errcode'] == 0) {return true;}return false;}/*** [sendMoney 企业付款到零钱]* @param  [type] $amount     [发送的金额(分)目前发送金额不能少于1元]* @param  [type] $re_openid  [发送人的 openid]* @param  string $desc [企业付款描述信息 (必填)]* @param  string $check_name [收款用户姓名 (选填)]* @return [type]             [description]* https://www.cnblogs.com/echoppy/p/8603286.html*/public function sendMoney($amount, $re_openid){$total_amount = (100) * $amount;$data = array('mch_appid' => $this->appId,//商户账号appid'mchid' => $this->mch_id,//商户号'nonce_str' => $this->nonce_str,//随机字符串'partner_trade_no' => date('YmdHis') . rand(1000, 9999),//商户订单号'openid' => $re_openid,//用户openid'check_name' => 'NO_CHECK',//校验用户姓名选项,'amount' => $total_amount,//付款金额,单位为分'desc' => '商户提现',//企业付款描述信息'spbill_create_ip' => $this->get_real_ip(),//Ip地址);//生成签名算法$secrect_key = $this->mch_key;   ///这个就是个API密码。MD5 32位。$data = array_filter($data);ksort($data);$str = '';foreach ($data as $k => $v) {$str .= $k . '=' . $v . '&';}$str .= 'key=' . $secrect_key;$data['sign'] = md5($str);//生成签名算法$xml = $this->arraytoxml($data);$url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //调用接口//$res = $this->http_post_data($url, $xml)$res = $this->execute($url, $xml, 1, 1);$return = $this->xml2array($res);return $return;}/*** @param $amount  退款金额* @param $re_openid  退款用户的openid* @return bool  退款成功失败* 开发文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4*/public function refundUserMoney($transaction_id, $total_fee, $refund_fee, $out_refund_no){$data = array('appid' => $this->appId,//商户账号appid'mch_id' => $this->mch_id,//商户号'nonce_str' => $this->nonce_str,//随机字符串'transaction_id' => $transaction_id,//微信支付商户号'total_fee' => $total_fee * 100,//订单金额'refund_fee' => $refund_fee * 100,//退款金额'notify_url' => $this->refund_notify_url,//退款金额'out_refund_no' => $out_refund_no,//退款金额);//生成签名算法$secrect_key = $this->mch_key;   ///这个就是个API密码。MD5 32位。$data = array_filter($data);ksort($data);$str = '';foreach ($data as $k => $v) {$str .= $k . '=' . $v . '&';}$str .= 'key=' . $secrect_key;$data['sign'] = md5($str);//生成签名算法$xml = $this->arraytoxml($data);$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";$res = $this->execute($url, $xml, 1, 1);if (!$res) {return false;}//$res = $this->http_post_data($url, $xml);$return = $this->xml2array($res);if ($return['return_code'] == 'SUCCESS') {return true;}return false;}public function get_real_ip(){$ip = $_SERVER['REMOTE_ADDR'];if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {foreach ($matches[0] AS $xip) {if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {$ip = $xip;break;}}} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {$ip = $_SERVER['HTTP_CLIENT_IP'];} elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) {$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];} elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_IP'])) {$ip = $_SERVER['HTTP_X_REAL_IP'];}return $ip ? $ip : '127.0.0.1';}}

 

这篇关于微信小程序支付中的prepay_id获取方法,以及微信支付统一签名算法闭坑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/994585

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操