如何基于ThinkPHP5框架实现微信小程序支付、退款、订单查询?

2026-03-27 06:441阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1784个文字,预计阅读时间需要8分钟。

如何基于ThinkPHP5框架实现微信小程序支付、退款、订单查询?

微信小程序或微信支付相关操作,包括订单退款查询、支付成功回调、退款成功回调等方法。支持微信支付请求接口(POST),参数包括:openid(用户标识),body(订单信息)。

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

如何基于ThinkPHP5框架实现微信小程序支付、退款、订单查询?

支付

/** * 预支付请求接口(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 = 'api.mch.weixin.qq.com/pay/unifiedorder'; //发起支付接口链接 //发起预支付请求 $prepay_return_reslut_xml = $this->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 = '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 = '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); }

证书路径

config配置

总结

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

标签:框架

本文共计1784个文字,预计阅读时间需要8分钟。

如何基于ThinkPHP5框架实现微信小程序支付、退款、订单查询?

微信小程序或微信支付相关操作,包括订单退款查询、支付成功回调、退款成功回调等方法。支持微信支付请求接口(POST),参数包括:openid(用户标识),body(订单信息)。

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

如何基于ThinkPHP5框架实现微信小程序支付、退款、订单查询?

支付

/** * 预支付请求接口(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 = 'api.mch.weixin.qq.com/pay/unifiedorder'; //发起支付接口链接 //发起预支付请求 $prepay_return_reslut_xml = $this->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 = '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 = '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); }

证书路径

config配置

总结

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

标签:框架