基于thinkphp5框架实现微信小程序支付 退款 订单查询 退款查询操作


Posted in PHP onAugust 17, 2020

微信小程序或微信支付相关操作支付退款订单查询退款查询支付成功,进行回调退款成功 进行回调用到的方法

支付

/**
 * 预支付请求接口(POST)
 * @param string $openid openid
 * @param string $body 商品简单描述
 * @param string $order_sn 订单编号
 * @param string $total_fee 金额
 * @return json的数据
 */
 public function prepay()
 {
 tp_log('预支付请求数据===>' . json_encode($_POST), 'prepay', request()->controller());
 $goods_user = db('tf_goods_user')->where(array('order_no' => $_POST['order_no']))->find();
 $goods = db('tf_goods')->where(array('id' => $goods_user['goods_id']))->find();
 //判断产品的数量
 if (($goods['sales_initial'] - $goods['sales_actual']) <= 0) {
 $return['status'] = 0;
 $return['info'] = '此产品已售完';
 exit(json_encode($return));
 }

 $order_no = $_POST['order_no']; //订单号
 $is_sale = $_POST['is_sale'];
 $openid = $_POST['openid'];
 $goods_name = $_POST['goods_name'];
 $pay_price = $_POST['price'];
 $attach['is_sale'] = $_POST['is_sale'];
 $attach['sale_id'] = $_POST['sale_id'];
 $nonce_str = $this->nonce_str();//随机字符串


 $order_no_ssh = $this->get_orderssh(); //商户订单号
 //组装支付数据
 $data = [
 'appid' => config('pay.APPID'),
 'mch_id' => config('pay.MCHID'),
 'nonce_str' => $nonce_str,
 'body' => $goods_name, //商品名称组合
 'attach' => json_encode($attach),
 'out_trade_no' => $order_no_ssh,//$order_no, //订单号 商户订单号
 'total_fee' => intval($pay_price * 100),
 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
 'notify_url' => config('pay.NOTIFY_URL'),
 'trade_type' => 'JSAPI',
 'openid' => $openid
 ];

 //订单支付表创建订单支付数据
 $p_o_data['createtime'] = time();
 $p_o_data['order_no'] = $order_no;
 $p_o_data['order_no_ssh'] = $order_no_ssh;
 $p_o_data['ready'] = json_encode($data);
 $p_o_return = db('tf_pay_order')->insert($p_o_data);
 if(!$p_o_return){
 //失败
 $return['status'] = -1;
 $return['info'] = $p_o_data;
 exit(json_encode($return));
 }

 // 获取签名
 $sign = $this->makeSign($data);
 $data['sign'] = $sign;
 $xml = $this->toXml($data);
 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //发起支付接口链接
 //发起预支付请求
 $prepay_return_reslut_xml = $this->http_request($url, $xml);
 $xml_to_arr = $this->fromXml($prepay_return_reslut_xml);
 $return_result = json_encode($xml_to_arr, true);
 tp_log('预支付请求返回数据array===>' .$return_result , 'prepay', request()->controller());
 //记录预支付返回信息
 db('tf_goods_order')->where(array('order_no' => $order_no))
 ->update(array(
 'go_pay' => $return_result,
 'updatetime' => time(),
 'updateuser' => $openid
 ));
 if($xml_to_arr['return_code'] == 'SUCCESS' && $xml_to_arr['result_code'] == 'SUCCESS'){
 //成功

 $time = time();
 //临时数组用于签名
 $tmp = [
 'appId' => config('pay.APPID'),
 'nonceStr' => $nonce_str,
 'package' => 'prepay_id='.$xml_to_arr['prepay_id'],
 'signType' => 'MD5',
 'timeStamp' => "$time",
 ];
 $data['timeStamp'] = "$time";//时间戳
 $data['nonceStr'] = $nonce_str;//随机字符串
 $data['signType'] = 'MD5';//签名算法,暂支持 MD5
 $data['package'] = 'prepay_id='.$xml_to_arr['prepay_id'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
 $data['paySign'] = $this->makeSign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;$data['out_trade_no'] = $out_trade_no;


 $return['status'] = 1;
 $return['info'] = $data;
 }else{
 //失败
 $return['status'] = -1;
 $return['info'] = $xml_to_arr;
 }
 exit(json_encode($return));
 }

 //curl请求
 public function http_request($url, $data = null, $headers = array())
 {
 $curl = curl_init();
 if (count($headers) >= 1) {
 curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
 }
 curl_setopt($curl, CURLOPT_URL, $url);


 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);


 if (!empty($data)) {
 curl_setopt($curl, CURLOPT_POST, 1);
 curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
 }
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 $output = curl_exec($curl);
 curl_close($curl);
 return $output;
 }

退款

/**
 * 申请退款API
 * @param $transaction_id
 * @param double $total_fee 账单总金额
 * @param double $refund_fee 退款金额
 * @return bool
 * @throws BaseException
 */
 public function refund()
 {

 $transaction_id = '4200000712202007274705432240';
 $total_fee = '0.01';
 $refund_fee = '0.01';
 // 当前时间
 $time = time();
 // 生成随机字符串
 $nonceStr = md5($time . $transaction_id . $total_fee . $refund_fee);
 // API参数
 $params = [
 'appid' => config('pay.APPID'),
 'mch_id' => config('pay.MCHID'),
 'nonce_str' => $nonceStr,
 'transaction_id' => $transaction_id,
 'out_refund_no' => $time,
 'total_fee' => $total_fee * 100,
 'refund_fee' => $refund_fee * 100,
 'notify_url' => config('pay.NOTIFY_URL_REFUND'),//退款回调地址
 ];
 // 生成签名
 $params['sign'] = $this->makeSign($params);

 tp_log('退款请求数据===>' . json_encode($params), 'refund', request()->controller());

 // 请求API
 $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
 $result = $this->post($url, $this->toXml($params), true, $this->getCertPem());
 $prepay = $this->fromXml($result);
 // 请求失败
 if (empty($result)) {
 throw new BaseException(['msg' => '微信退款api请求失败']);
 }
 // 格式化返回结果
 $prepay = $this->fromXml($result);
 tp_log('退款返回数据===>' . json_encode($prepay), 'refund', request()->controller());
 // 请求失败
// if ($prepay['return_code'] === 'FAIL') {
// throw new BaseException(['msg' => 'return_msg: ' . $prepay['return_msg']]);
// }
// if ($prepay['result_code'] === 'FAIL') {
// throw new BaseException(['msg' => 'err_code_des: ' . $prepay['err_code_des']]);
// }
 return true;
 }
 /**
 * 模拟POST请求
 * @param $url
 * @param array $data
 * @param bool $useCert
 * @param array $sslCert
 * @return mixed
 */
 public function post($url, $data = [], $useCert = false, $sslCert = [])
 {
 $header = [
 'Content-type: application/json;'
 ];
 $curl = curl_init();
 //如果有配置代理这里就设置代理
// if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
// && WxPayConfig::CURL_PROXY_PORT != 0){
// curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);
// curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);
// }

 curl_setopt($curl, CURLOPT_URL, $url);
 curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
 curl_setopt($curl, CURLOPT_HEADER, false);
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
 curl_setopt($curl, CURLOPT_POST, TRUE);
 curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
 if ($useCert == true) {
 // 设置证书:cert 与 key 分别属于两个.pem文件
 curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
 curl_setopt($curl, CURLOPT_SSLCERT, $sslCert['certPem']);
 curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
 curl_setopt($curl, CURLOPT_SSLKEY, $sslCert['keyPem']);
 }
 $result = curl_exec($curl);
 curl_close($curl);
 return $result;
 }

订单查询

/**
 * 订单查询
 * @param $out_trade_no
 * @return mixed
 * @throws BaseException
 */
 public function orderquery()
 {
 $transaction_id = '4200000712202007274705432240';//微信订单号
 // 当前时间
 $time = time();
 // 生成随机字符串
 $nonce_str = md5($time . mt_rand(00000,99999));
 //API参数
 $params = [
 'appid' => config('pay.APPID'), //公众号ID
 'mch_id' => config('pay.MCHID'), //商户号
 'transaction_id' => $transaction_id, //商户订单号
 'nonce_str' => $nonce_str, // 随机字符串
 ];
 //生成签名
 $params['sign'] = $this->makeSign($params);
 //请求API
 $url = 'https://api.mch.weixin.qq.com/pay/orderquery';
 $result = $this->post($url, $this->toXml($params));
 $prepay = $this->fromXml($result);
 // 请求失败
 if ($prepay['return_code'] === 'FAIL') {
 throw new BaseException(['msg' => $prepay['return_msg'], 'code' => 0]);
 }
 if ($prepay['result_code'] === 'FAIL') {
 throw new BaseException(['msg' => $prepay['err_code_des'], 'code' => 0]);
 }
 return $prepay;
 }

退款查询

/**
 * 退款查询
 * @param $out_trade_no
 * @return mixed
 * @throws BaseException
 */
 public function refundquery()
 {
 $transaction_id = '4200000712202007274705432240';//微信订单号
 // 当前时间
 $time = time();
 // 生成随机字符串
 $nonce_str = md5($time . mt_rand(00000,99999));
 //API参数
 $params = [
 'appid' => config('pay.APPID'), //公众号ID
 'mch_id' => config('pay.MCHID'), //商户号
 'transaction_id' => $transaction_id, //商户订单号
 'nonce_str' => $nonce_str, // 随机字符串
 ];
 //生成签名
 $params['sign'] = $this->makeSign($params);
 //请求API
 $url = 'https://api.mch.weixin.qq.com/pay/refundquery';
 $result = $this->post($url, $this->toXml($params));
 $prepay = $this->fromXml($result);
 dump($prepay);die;
 // 请求失败
 if ($prepay['return_code'] === 'FAIL') {
 throw new BaseException(['msg' => $prepay['return_msg'], 'code' => 0]);
 }
 if ($prepay['result_code'] === 'FAIL') {
 throw new BaseException(['msg' => $prepay['err_code_des'], 'code' => 0]);
 }
 return $prepay;
 }

支付成功,进行回调

public function index()
 {
 $data = file_get_contents('php://input');
 $data = $this->FromXml($data);
 tp_log('支付回调数据===>' . json_encode($data), 'index', request()->controller());
 // 保存微信服务器返回的签名sign
 $data_sign = $data['sign'];
 // sign不参与签名算法
 unset($data['sign']);
 $sign = $this->makeSign($data);//回调验证签名

 $str_success = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
 $str_error = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';

 if (($sign === $data_sign) && ($data['return_code'] == 'SUCCESS') && ($data['result_code'] == 'SUCCESS')) {
 // 支付成功 进行你的逻辑处理
 }
echo $str_success;//str_error 告知微信 你已的逻辑处理完毕 不用再推送或再次推送你结果
 }

退款成功 进行回调

/*
 * 小程序 退款结果通知
 */
 public function refund(){

 $data = file_get_contents('php://input');
 $data = $this->FromXml($data);
 tp_log('退款回调数据===>' . json_encode($data), 'refund', request()->controller());

 //对加密的字符串解密
 $req_info_xml = openssl_decrypt(base64_decode($data['req_info']), 'aes-256-ecb', md5(config('pay.KEY')),OPENSSL_RAW_DATA);
 $req_info = $this->FromXml($req_info_xml);

// // 保存微信服务器返回的签名sign
// $data_sign = $data['sign'];
// // sign不参与签名算法
// unset($data['sign']);
// $sign = $this->makeSign($data);//回调验证签名
//
// $str_success = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
// $str_error = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
//
//
//
// if (($sign === $data_sign) && ($data['return_code'] == 'SUCCESS') && ($data['result_code'] == 'SUCCESS')) {
// tp_log('退款成功===>', 'refund', request()->controller());
// //去修改订单的状态 和支付回调的一样 修改成功 告知微信 不在推送
// }
 }

用到的方法

/**
 * 生成签名
 * @param $values
 * @return string 本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
 */
 private function makeSign($values)
 {
 //签名步骤一:按字典序排序参数
 ksort($values);
 $string = $this->toUrlParams($values);
 //签名步骤二:在string后加入KEY
 $string = $string . '&key=' . config('pay.KEY');
 //签名步骤三:MD5加密
 $string = md5($string);
 //签名步骤四:所有字符转为大写
 $result = strtoupper($string);
 return $result;
 }
 private function ToUrlParams($array)
 {
 $buff = "";
 foreach ($array as $k => $v) {
 if ($k != "sign" && $v != "" && !is_array($v)) {
 $buff .= $k . "=" . $v . "&";
 }
 }
 $buff = trim($buff, "&");
 return $buff;
 }

 /**
 * 输出xml字符
 * @param $values
 * @return bool|string
 */
 private function toXml($values)
 {
 if (!is_array($values)
 || count($values) <= 0
 ) {
 return false;
 }
 $xml = "<xml>";
 foreach ($values as $key => $val) {
 if (is_numeric($val)) {
 $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
 } else {
 $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
 }
 }
 $xml .= "</xml>";
 return $xml;
 }

 /**
 * 将xml转为array
 * @param $xml
 * @return mixed
 */
 private function fromXml($xml)
 {
 // 禁止引用外部xml实体
 libxml_disable_entity_loader(true);
 return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
 }

 /**
 * 获取cert证书文件
 * @return array
 * @throws BaseException
 */
 private function getCertPem()
 {
// if (empty($this->config['cert_pem']) || empty($this->config['key_pem'])) {
// throw new BaseException(['msg' => '请先到后台小程序设置填写微信支付证书文件']);
// }
 // cert目录
 $filePath = EXTEND_PATH.'wxpay/cert/';
 return [
 'certPem' => $filePath . 'apiclient_cert.pem',
 'keyPem' => $filePath . 'apiclient_key.pem'
 ];
 }
/**
 * 生成商户订单号
 */
 public function get_orderssh()
 {
 return date("YmdHis") . mt_rand(10000000, 99999999);
 }

证书路径

基于thinkphp5框架实现微信小程序支付 退款 订单查询 退款查询操作

config配置

基于thinkphp5框架实现微信小程序支付 退款 订单查询 退款查询操作

总结

到此这篇关于基于thinkphp5框架实现微信小程序支付 退款 订单查询 退款查询的文章就介绍到这了,更多相关微信小程序支付 退款 订单查询 退款查询内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

PHP 相关文章推荐
Uncaught exception com_exception with message Failed to create COM object
Jan 11 PHP
Function eregi is deprecated (解决方法)
Jun 21 PHP
php实现删除指定目录下相关文件的方法
Oct 20 PHP
PHP输出两个数字中间有多少个回文数的方法
Mar 23 PHP
php实现将wav文件转换成图像文件并在页面中显示的方法
Apr 21 PHP
php实现的RSS生成类实例
Apr 23 PHP
在Laravel框架里实现发送邮件实例(邮箱验证)
May 20 PHP
mac下多个php版本快速切换的方法
Oct 09 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
Nov 13 PHP
PHP折半(二分)查找算法实例分析
May 12 PHP
php面试实现反射注入的详细方法
Sep 30 PHP
php多进程并发编程防止出现僵尸进程的方法分析
Feb 28 PHP
PhpStorm2020.1 安装 debug - Postman 调用的详细教程
Aug 17 #PHP
php开发最强大的IDE编辑的phpstorm 2020.2配置Xdebug调试的详细教程
Aug 17 #PHP
PHP unset函数原理及使用方法解析
Aug 14 #PHP
PHP常量及变量区别原理详解
Aug 14 #PHP
PHP获取当前时间不准确问题解决方案
Aug 14 #PHP
PHP语言对接抖音快手小红书视频/图片去水印API接口源码
Aug 11 #PHP
php实现微信和支付宝支付的示例代码
Aug 11 #PHP
You might like
77A一级收信机修理记
2021/03/02 无线电
PHP实现MySQL更新记录的代码
2008/06/07 PHP
PHP实现适用于自定义的验证码类
2016/06/15 PHP
Laravel日志用法详解
2016/10/09 PHP
ThinkPHP3.2框架自定义配置和加载用法示例
2018/06/14 PHP
PHP htmlspecialchars() 函数实例代码及用法大全
2018/09/18 PHP
PHP删除数组中特定元素的两种方法
2019/02/28 PHP
PHP实现简单日历类编写
2020/08/28 PHP
默认让页面的第一个控件选中的javascript代码
2009/12/26 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
jquery的map与get方法详解
2013/11/04 Javascript
全面解析Bootstrap表单使用方法(表单样式)
2015/11/24 Javascript
轻松实现jquery手风琴效果
2016/01/14 Javascript
JS实现简单的二维矩阵乘积运算
2016/01/26 Javascript
js中class的点击事件没有效果的解决方法
2016/10/13 Javascript
jQuery EasyUI 为Combo,Combobox添加清除值功能的实例
2017/04/13 jQuery
Angular实现的简单定时器功能示例
2017/12/28 Javascript
Java设计中的Builder模式的介绍
2018/03/22 Javascript
Vue中的无限加载vue-infinite-loading的方法
2018/04/08 Javascript
Vue实现按钮旋转和移动位置的实例代码
2018/08/09 Javascript
微信小程序后台持续定位功能使用详解
2019/08/23 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
antd-DatePicker组件获取时间值,及相关设置方式
2020/10/27 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
Python升级导致yum、pip报错的解决方法
2017/09/06 Python
在unittest中使用 logging 模块记录测试数据的方法
2018/11/30 Python
Python3 翻转二叉树的实现
2019/09/30 Python
Python TCPServer 多线程多客户端通信的实现
2019/12/31 Python
pytorch加载语音类自定义数据集的方法教程
2020/11/10 Python
通过canvas转换颜色为RGBA格式及性能问题的解决
2019/11/22 HTML / CSS
Gtech官方网站:地毯清洁器、吸尘器及园艺设备
2018/05/23 全球购物
工业学校毕业生自荐信范文
2014/01/03 职场文书
公司年会搞笑主持词
2014/03/24 职场文书
先进单位事迹材料
2014/12/25 职场文书
青年干部培训班学习心得体会
2016/01/06 职场文书
小学语文教学反思范文
2016/03/03 职场文书