thinkcmf+jsapi 实现微信支付

2024-04-29 02:38

本文主要是介绍thinkcmf+jsapi 实现微信支付,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先从小程序端接收订单号、金额等参数,然后后台进行统一下单,把微信支付的订单号返回,在把订单号发送给前台,前台拉起支付,返回参数后更改支付状态。。。

回调

 public function notify() {$wechat=Db::name('wechat')->where('status',1)->find();//$post = $GLOBALS['HTTP_RAW_POST_DATA']; $post = file_get_contents("php://input"); //接受POST数据XML个数// $order_over_test['openid']=$post;// Db::name('order_over')->insert($order_over_test);$post_data  = $this->xml_to_array($post);//输出订单号$order_sn = $post_data['out_trade_no'];$order_over['order_sn']=$order_sn;$order_over['money']=$post_data['total_fee'];$order_over['openid']=$post_data['openid'];$order_over['time_end']=$post_data['time_end'];$order_update['status']='1';// Db::name('order_over')->insert($order_over);$order_info=Db::name('order')->where('order_id',$order_sn)->find();if ($post_data['return_code'] == 'SUCCESS') {//判断证书是否正确// if ($postSign != $user_sign) {//     Log::write('签名不匹配');//     exit;// }if ($order_info['status'] != '1') {Db::name('order_over')->insert($order_over);$result=Db::name('order')->where('order_id', $order_sn)->update($order_update);}return 'success';} else {return 'error';//$this->error('error!');}
}public function xmlToArray($xml){$p = xml_parser_create();xml_parse_into_struct($p, $xml, $vals, $index);xml_parser_free($p);$data = "";foreach ($index as $key => $value) {if ($key == 'xml' || $key == 'XML') continue;$tag = $vals[$value[0]]['tag'];$value = $vals[$value[0]]['value'];$data[$tag] = $value;}return $data;}public function xml_to_array($xml){if(!$xml){return false;}//将XML转为array//禁止引用外部xml实体libxml_disable_entity_loader(true);$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);return $data;}public static function ToUrlParams($data){$buff = "";foreach ($data as $k => $v){if($k != "sign" && $v != "" && !is_array($v)){$buff .= $k . "=" . $v . "&";}}$buff = trim($buff, "&");return $buff;}

统一下单

 public function getwxpay($orderSn,$money)
{// $orderSn=$orderSn;$body='广告投放';//$orderSn='HB14257311281654';//$money= '1';  $money=$money*100;$wechat=Db::name('wechat')->where('status',1)->find();$order_id=$orderSn;// $money= $money;                     //充值金额 微信支付单位为分$appid  = $wechat['appid'];    //应用APPID$mch_id =$wechat['mch_id'];                  //微信支付商户号$KEY    = $wechat['key'];                 //微信商户API密钥$out_trade_no = $orderSn ;//平台内部订单号$nonce_str = $this->rand_code();//随机字符串// $openid='oM0TH0nyMtlyrP_J8cOL70oLYaCw';$openid=session('openid');//获取系统的配置//$nonce_str = $this->rand_str(12);//随机字符串$notify_url = "http://**********************t/Wxnotify/notify";  //支付完成回调地址url,不能带参数$spbill_create_ip = get_client_ip();$trade_type = 'JSAPI';//交易类型 默认JSAPI//这里是按照顺序的 因为下面的签名是按照(字典序)顺序 排序错误 肯定出错$post['appid'] = $appid;$post['body'] = $body;$post['mch_id'] = $mch_id;$post['nonce_str'] = $nonce_str;//随机字符串$post['notify_url'] = $notify_url;$post['openid'] = $openid;$post['out_trade_no'] = $out_trade_no;$post['spbill_create_ip'] = $spbill_create_ip;//服务器终端的ip$post['total_fee'] = intval($money);        //总金额 最低为一分钱 必须是整数$post['trade_type'] = $trade_type;$sign = $this->MakeSign($post, $KEY);              //签名$this->sign = $sign;$post_xml = "<xml><appid>$appid</appid> <mch_id>$mch_id</mch_id><nonce_str>$nonce_str</nonce_str><body>$body</body><notify_url>$notify_url</notify_url><openid>$openid</openid><out_trade_no>$out_trade_no</out_trade_no><spbill_create_ip>$spbill_create_ip</spbill_create_ip><total_fee>{$post["total_fee"]}</total_fee><trade_type>$trade_type</trade_type><sign>$sign</sign></xml>";//统一下单接口prepay_id$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';$xml = $this->http_request($url, $post_xml);     //POST方式请求http$array = $this->xml2array($xml);               //将【统一下单】api返回xml数据转换成数组,全要大写$array['my_sign'] = $sign;$array['post_xml'] = $post_xml;$array['source_xml'] = $xml;if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {$time = time();$tmp = '';                            //临时数组用于签名$tmp['appId'] = $appid;$tmp['nonceStr'] = $nonce_str;$tmp['package'] = 'prepay_id=' . $array['PREPAY_ID'];$tmp['signType'] = 'MD5';$tmp['timeStamp'] = "$time";// $data['state'] = 1;$data['timeStamp'] = "$time";           //时间戳$data['nonceStr'] = $nonce_str;         //随机字符串$data['signType'] = 'MD5';              //签名算法,暂支持 MD5$data['package'] = 'prepay_id='.$array['PREPAY_ID'];   //统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*$data['paySign'] = $this->MakeSign($tmp, $KEY);       //签名,具体签名方案参见微信公众号支付帮助文档;$data['prepay_id'] = $array['PREPAY_ID'];$data['out_trade_no'] = $out_trade_no;$data['order_id'] = $order_id;} else {// $data['statusCode'] = ;$data['statusMsg'] = "请求错误";$data['data']['RETURN_CODE'] = $array['RETURN_CODE'];$data['data']['RETURN_MSG'] = $array['RETURN_MSG'];}return $data;}public function postXmlCurl($xml,$url,$second = 30){$ch = curl_init();//设置超时curl_setopt($ch, CURLOPT_TIMEOUT, $second);curl_setopt($ch,CURLOPT_URL, $url);curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//设置headercurl_setopt($ch, CURLOPT_HEADER, FALSE);//要求结果为字符串且输出到屏幕上curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//post提交方式curl_setopt($ch, CURLOPT_POST, TRUE);curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);//运行curl$data = curl_exec($ch);//返回结果if($data){curl_close($ch);return $data;}else{$error = curl_errno($ch);curl_close($ch);echo "curl出错,错误码:$error"."<br>";}}//生成签名public function MakeSign($params, $KEY){//签名步骤一:按字典序排序数组参数ksort($params);$string = $this->ToUrlParams($params);  //参数进行拼接key=value&k=v//签名步骤二:在string后加入KEY$string = $string . "&key=" . $KEY;//签名步骤三:MD5加密$string = md5($string);//签名步骤四:所有字符转为大写$result = strtoupper($string);return $result;}/*** 格式化参数格式化成url参数*/public static function ToUrlParams($data){$buff = "";foreach ($data as $k => $v){if($k != "sign" && $v != "" && !is_array($v)){$buff .= $k . "=" . $v . "&";}}$buff = trim($buff, "&");return $buff;}//发送http请求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);//$zs1 = CMF_ROOT . "cert/apiclient_cert.pem";$zs2 = CMF_ROOT . "cert/apiclient_key.pem";//        curl_setopt ( $curl, CURLOPT_SSLCERT, $zs1 );//        curl_setopt ( $curl, CURLOPT_SSLKEY, $zs2 );//设置证书//使用证书:cert 与 key 分别属于两个.pem文件curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');curl_setopt($curl, CURLOPT_SSLCERT, $zs1);curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');curl_setopt($curl, CURLOPT_SSLKEY, $zs2);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;}//获取xml里面数据,转换成arraypublic function xml2array($xml){$p = xml_parser_create();xml_parse_into_struct($p, $xml, $vals, $index);xml_parser_free($p);$data = "";foreach ($index as $key => $value) {if ($key == 'xml' || $key == 'XML') continue;$tag = $vals[$value[0]]['tag'];$value = $vals[$value[0]]['value'];$data[$tag] = $value;}return $data;}//随机字符串public function rand_code($length = 16) {$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";$str = "";for ($i = 0; $i < $length; $i++) {$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);}return $str;}public function ToXml($data=array()){if(!is_array($data) || count($data) <= 0){return '数组异常';}$xml = "<xml>";foreach ($data as $key=>$val){if (is_numeric($val)){$xml.="<".$key.">".$val."</".$key.">";}else{$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";}}$xml.="</xml>";return $xml;}

前台页面拉起微信支付

<!DOCTYPE html>
<html>
<head><title>订单支付 {$site_info.site_name|default=''}</title><meta name="keywords" content="{$site_info.site_seo_keywords|default=''}"/><meta name="description" content="{$site_info.site_seo_description|default=''}"><include file="public@head"/></head>
<body >
<include file="public@top"/>
<hook name="before_head_end"/>
<!-- top --><div class="zt">
<div class="am-container"><div><div class="order_info"><h3 class="am-text-center">核实订单</h3>
</div><div class="order_money am-text-center"><table class="am-table "><tr><td>订单号</td><td class="am-text-right">{$order_info['order_id']}</td></tr><tr><td>金额</td><td class="am-text-right">{$order_info['money']}¥</td><input type="hidden" name="money" id="money_input" value=""></tr></table></div><div class="am-form-group"><button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" type="button" onclick="callpay()" >立即支付</button></div>
</div>
</div>
</div><include file="public@footer"/><!--  <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> --><script type="text/javascript">//调用微信JS api 支付function jsApiCall(){WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId":'{$wechat['appid']}',     //公众号名称,由商户传入     "timeStamp":'{$wxpay_status['timeStamp']}',       //时间戳,自1970年以来的秒数     "nonceStr":'{$wxpay_status['nonceStr']}', //随机串     "package":'{$wxpay_status['package']}',     "signType":"MD5",         //微信签名方式:     "paySign":'{$wxpay_status['paySign']}'//微信签名 }, function(res){console.log(res);WeixinJSBridge.log(res.err_msg);//alert('err_code:'+res.err_code+'err_desc:'+res.err_desc+'err_msg:'+res.err_msg);//alert(res.err_code+res.err_desc+res.err_msg);//alert(res);if(res.err_msg == "get_brand_wcpay_request:ok"){  alert("支付成功!");window.location.href="http://m.sxcrcm.com";}else if(res.err_msg == "get_brand_wcpay_request:cancel"){  alert("用户取消支付!");  }else{  alert("支付失败!");  }  });}function callpay(){if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);}else if (document.attachEvent){document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall);}}else{jsApiCall();}}</script>
</body>

这篇关于thinkcmf+jsapi 实现微信支付的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

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

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

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现