php + h5 微信支付,h5调用微信支付并提交数据

50 篇文章 0 订阅
2 篇文章 0 订阅

思路:表单页—中间页(支付)—数据提交的后台页—返回表单页

单位需要做推广页面的支付,微信浏览器里面调用支付比较好弄,官方有详细的demo,这次需要增加一个h5页面调用微信支付,头一次写,按照自己的逻辑来的,反正是成功了。我的数据提交页面是一个纯html页面,里面有表单,然后表单action带着我的输入框的参数一起提交到支付页面,支付页面把表单参数接收了,值就跟着支付完的返回地址一起跳转到数据写入数据库的后台程序页面,程序页面完成数据写入之后再用header跳转到最开始的表单页(这时候的跳转url记得带个参数,这样可以提示用户刚刚的数据提交成功了的)

表单页

<!-- 这个是用来抓取页面数据写入数据库后返回来的url,取特定参数,提醒用户数据写入成功 -->
<script type="text/javascript">
    (function($){
		$.getUrlParam = function(name){
			var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
			var r = window.location.search.substr(1).match(reg);
			if (r!=null) return unescape(r[2]); return null;
		}
     })(jQuery);

	 var iszx = $.getUrlParam('zx');
	 if(iszx == 'zx'){
         alert('您已经预约成功,请注意接收短信!');
     }    	
</script>


<!-- 这里只有关键代码,样式那些就不粘贴了 -->
<script>                          
     $("#myform").submit(function(e){
		  //这里是表单提交前的相关验证,某某值不能为空,手机号对不对之类的	
     });
</script>

<!-- https://xxxxxx.com/tjy/payh5.php  这个就是支付页面 -->
<form action="https://xxxxxx.com/tjy/payh5.php" method="post" id="myform">            
    <input type="text" name="name" id="name" placeholder="请输入患者姓名">
    <input type="number" name="age" id="age" placeholder="请输入患者年龄">
    <input type="text" name="hometel" id="hometel" placeholder="请输入联系电话">
    <!-- ……这里还有些参数,我就不写了 -->
    <input type="submit" class="zzghtj" value="提交预约"/>  
</form>

重点,中间页,支付功能 payh5.php

<?php
//接收表单参数
$name = $_POST['name'];
$sex = $_POST['sex'];
$tel = $_POST['hometel'];
$url = $_POST['url']; //这个是刚刚那个html页面的网址

//微信h5支付
$param['appid'] = "wxxxxxxxxxxxxxxxxx";//微信支付的appid
$param['body'] = "挂号";//微信支付的商品描述
$param['mch_id'] = "xxxxxxxxxxxx";//微信支付的mch_id
$param['nonce_str'] = createNoncestr();  //随机字符串
$param['notify_url'] = "http://paysdk.weixin.qq.com/notify.php";  //回调地址 这个地址需要微信支付后台配置白名单 上限貌似是五个
$param['out_trade_no'] = "xxxxxxxxxxxx".date("YmdHis");//商户订单号
$param['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];//终端ip
$param['total_fee'] = 100; //价格 100 等于 1元钱 单位分
$param['trade_type'] = "MWEB"; //交易类型 h5支付的交易类型必须为MWEB
$param['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "https://xxxx.com","wap_name": "单位名称"}}';  //场景信息 https://xxxx.com 单位官网


//按照微信规则生成签名
$key  = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";  //微信商户API密钥
$sign = wxqmzxy($param,$key);   //key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

//拼接xml数据
$send = "<xml>
            <appid>{$param['appid']}</appid>
            <attach>{$param['attach']}</attach>
            <body>{$param['body']}</body>
            <mch_id>{$param['mch_id']}</mch_id>
            <nonce_str>{$param['nonce_str']}</nonce_str>
            <notify_url>{$param['notify_url']}</notify_url>
            <out_trade_no>{$param['out_trade_no']}</out_trade_no>
            <spbill_create_ip>{$param['spbill_create_ip']}</spbill_create_ip>
            <total_fee>{$param['total_fee']}</total_fee>
            <trade_type>{$param['trade_type']}</trade_type>
            <scene_info>{$param['scene_info']}</scene_info>
            <sign>{$sign}</sign>
        </xml>";
                
                
//向微信发送请求
$result = postXmlCurl($send,"https://api.mch.weixin.qq.com/pay/unifiedorder");

//随机字符串
function createNoncestr($length = 32){
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str ="";
    for ( $i = 0; $i < $length; $i++ )  {
        $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return $str;
}

//微信支付签名生成函数
function wxqmzxy($arr,$key){

    ksort($arr);
    $str='';
    foreach($arr as $k=>$v){
        $str.=$k.'='.$v.'&';
    }

    $str.='key='.$key;

    return strtoupper(md5($str));

}

//给微信发送请求函数
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,TRUE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
    //设置header
    curl_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);
        die("curl出错,错误码:$error");
    }
}

function xml_to_array($xml){
    //禁止引用外部xml实体
    libxml_disable_entity_loader(true);
    $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $values;
}

$return_arr = xml_to_array($result);

//设置支付成功跳转地址 数据写入数据库的后台地址,域名和中间页要同一个,不然会报错
$urlstr = "https://xxxxxx.com/tjy/yuyue_pich5.php?name=".$name."&hometel=".$tel."&sex=".$sex."&url=".$url;
$return_url = urlencode($urlstr);   //支付完成后你要跳转的地址 getenv("HTTP_REFERER") 是原封不动的跳回去

//跳转此链接拉起微信支付
header("location:".$return_arr['mweb_url']."&redirect_url={$return_url}");  //拉起微信支付链接(并且附上$return_url)
exit;

//我这里为了方便,这个查单的流程要单独写函数哈
//补充,如果用户取消支付,需要去查询当前生成的订单有没有付款,微信这个接口需要支付后2-3s再进行查询验证,需要写一个弹窗或者什么中间页来引导用户去触发这个
//构造请求微信接口的参数 查询订单支付状态
$param = [
    'appid' => "填你的appid",// APP ID
    'mch_id' => "填你的mch_id",// 商户号
    'out_trade_no' => $info['orderId'],  //订单号 就是上面的单号
    'nonce_str' => $this->createNoncestr(),
    'sign_type' => 'MD5',
];
        
//按照微信规则生成签名
$key  = "填你的key";  //微信商户API密钥
$sign = $this->wxqmzxy($param,$key);   //key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
//拼接xml数据
$send = "<xml>
            <appid>{$param['appid']}</appid>
            <mch_id>{$param['mch_id']}</mch_id>
            <nonce_str>{$param['nonce_str']}</nonce_str>
            <out_trade_no>{$param['out_trade_no']}</out_trade_no>
            <sign_type>{$param['sign_type']}</sign_type>
            <sign>{$sign}</sign>
         </xml>";
//向微信发送请求
$result = $this->postXmlCurl($send,"https://api.mch.weixin.qq.com/pay/orderquery");
        
$jsonArray = $this->xml_to_array($result);

//$jsonArray['trade_state']  //支付状态
//官方 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_2&index=2


?>

数据提交的后台页 yuyue_pich5.php,因为我的后台是在织梦站点下加的数据提交程序页,插入数据库的写法是织梦的,这个可以按照自己实际的写法来就是,只要数据插入即可

<?php
header('Content-Type:text/html; charset=UTF-8');
require_once("../include/common.inc.php");
require_once 'string.func.php';
require_once 'upload.func.php';
require_once "Smtp.class.php";
header('Access-Control-Allow-Origin: *');

$DATATABLE='#@__yuyue_app';
$PICTABLE="#@__yuyue_app_pics";

$name = $_GET['name'];
$sex = $_GET['sex'];
$tel = $_GET['hometel'];
$url = $_GET['url'];
$ispay = '已支付';

//验证电话号码 
checkPhoneNumber($tel);

$inQuery = "INSERT INTO `$DATATABLE` (`name`, `sex`, `tel`, `url`,`ispay`) VALUES ('$name', '$sex', '$tel', '$url', '$ispay')";

$respay = executeQueryAndCheckErr($inQuery,'数据');

//支付完需要跳回去的网址  zx=zx 就是html头部用来提醒用户数据提交成功的关键字
$urlzxy = $url.'?zx=zx'; 

//****** 下面是发送通知有人缴费成功的通知邮件 *****
//下面就不写

//******** 发送短信,发给缴费人 ********
//下面就不写了

header("location:".$urlzxy);  //带着参数返回原地址
die;

?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值