900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 微信小程序支付 退款 订单查询 退款查询

微信小程序支付 退款 订单查询 退款查询

时间:2023-10-03 23:50:21

相关推荐

微信小程序支付 退款 订单查询 退款查询

基于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(); //商户订单号//注意 订单号为自己创建的订单 和支付没有任何关系 商户订单号是支付单号 用来支付的 每当订单号发起支付 就会有新的商户订单号 商户订单号是不重复的 发起一次支付就要生成新的商户订单号 要保存下来 订单表要有对应的支付订单表 而订单号与商户订单号是一对多的关系 订单表最终保存的商户订单号是支付成功的那个 也可以 没调起支付就根据订单号去修改订单表的商户订单号 只有商户订单号才能发起退款 相当于商户订单号统计记录到订单表里面 退款查询等操作 商户订单号 其实订单生成就不会改数据了 也可以用订单号改为商户订单号 这样支付 取消 在支付 也可以的(out_trade_no)//组装支付数据$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./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 = '420000071220274705432240';$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./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 = '420000071220274705432240';//微信订单号// 当前时间$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./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 = '420000071220274705432240';//微信订单号// 当前时间$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./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配置

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。