产品开会提出了这样的需求:一个二维码可以微信支付也可以支付宝支付

经过自己的钻研以及询问技术高人(本人代码一般般)和网上搜索 最终实现其功能  我用微信jsapi 和 支付宝网页支付

其实并不怎么难:

  1.微信jsapi支付流程(微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

  2.支付宝支付流程

好了废话不多说 开始开发 代码上(Tp5开发)

首先 需要生成一个二维码这个想必大家都会吧!!! phpqrcode(下载地址:https://sourceforge.net/projects/phpqrcode/ )

 1         require_once ROOT_PATH.'/phpqrcode/phpqrcode.php';
2 $value='http://'.$_SERVER['HTTP_HOST'].'/admin.php/pay/wx_zfb; //二维码链接 (这个是重中之重!!!)
3 $errorCorrectionLevel = 'H';//容错级别
4 $matrixPointSize = 6;//生成图片大小
5 //生成二维码图片
6 QRcode::png($value, 'code/1.png', $errorCorrectionLevel, $matrixPointSize, 2);
7 $logo = 'code/kunchuan.png';//准备好的logo图片
8 $QR = 'code/1.png';//已经生成的原始二维码图
9 if ($logo !== FALSE) {
10 $QR = imagecreatefromstring(file_get_contents($QR));
11 $logo = imagecreatefromstring(file_get_contents($logo));
12 /* $QR = imagecreatefrompng($QR);
13 $logo = imagecreatefrompng($logo);*/
14 if (imageistruecolor($logo))
15 {
16 imagetruecolortopalette($logo, false, 65535);//添加这行代码来解决颜色失真问题
17 }
18
19 $QR_width = imagesx($QR);//二维码图片宽度
20 $QR_height = imagesy($QR);//二维码图片高度
21 $logo_width = imagesx($logo);//logo图片宽度
22 $logo_height = imagesy($logo);//logo图片高度
23 $logo_qr_width = $QR_width / 5;
24 $scale = $logo_width/$logo_qr_width;
25 $logo_qr_height = $logo_height/$scale;
26 $from_width = ($QR_width - $logo_qr_width) / 2;
27 //重新组合图片并调整大小
28 imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,
29 $logo_qr_height, $logo_width, $logo_height);
30 }
31
32 $lujing = 'code/merge1'.png';
33
34 //输出图片
35 imagepng($QR,$lujing);
36 return '<img src="http://'.$_SERVER['HTTP_HOST'].'/'.$lujing.'" alt="使用微信或者支付宝扫描支付">';

ok我们就生成一个二维码  因为个人隐私 我就生成了一个百度的二维码

通过扫描二维码 我们跳转到 wx_zfb方法:

 public function wx_zfb()
{
      //根据自己的需求 链接上边有参数就接值 没有就不做判断
  // if($this->request->isGet())
     // {
          //在PHP中HTTP_USER_AGENT是用来获取用户的相关信息的,包括用户使用的浏览器,操作系统等信息,
  $http_user_agent = $_SERVER['HTTP_USER_AGENT'];
  if (strpos($http_user_agent, 'MicroMessenger'))
       {
         $url="code”;//处理微信支付的方法
header("location:{$url}");
exit;
}elseif (strpos($http_user_agent, 'AlipayClient')) {
//支付宝链接  
         $url="aliyun”;//处理微信支付的方法
         header("location:{$url}"); exit
        
}else{
$this->assign('error_data','请使用微信或者支付宝扫码哦!');
return $this->view->fetch('pay/error'); } // }else{
// $this->assign('error_data','暂时没有哦');
// return $this->view->fetch('pay/error');
//}
}

接下来精彩的代码即将上线(微信jsapi支付)

  damo下载:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

  首先我们要了解微信jsapi的开发流程

  

好了这些你们就了解一下就可以了

public function code()
{
$appid = '*******';//微信的appid
$appKey = '******';//APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置), 请妥善保管, 避免密钥泄露获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
$mchid='*******';//商户平台的id
$apiKey='*******';//KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置), 请妥善保管, 避免密钥泄露设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
$wxPay = new WxpayService($mchid,$appid,$appKey,$apiKey);
$openid = $wxPay->GetOpenid();
if($openid){
Session::set("openid", $openid);
}else{
$openid=session('openid');
}
  //公众号中的话可以授权-获取用户信息
// $wxPays=new WxPayUser($appid,$appKey);
// $data = $wxPays->GetOpenid();
// $user = $WxPayUser->getUserInfo($data['openid'],$data['access_token']);
$this->assign('openid',$openid);
$this->assign('ip_user',$ip_user);
return $this->view->fetch(); }
WxpayService.php

<?php
namespace addons\epay\library;
use fast\Http; class WxpayService
{
protected $mchid;
protected $appid;
protected $appKey;
protected $apiKey;
public $data = null;
public function __construct($mchid, $appid, $appKey,$key)
{
$this->mchid = $mchid; //https://pay.weixin.qq.com 产品中心-开发配置-商户号
$this->appid = $appid; //微信支付申请对应的公众号的APPID
$this->appKey = $appKey; //微信支付申请对应的公众号的APP Key
$this->apiKey = $key; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
}
/**
* 通过跳转获取用户的openid,跳转流程如下:
* 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
* 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
* @return 用户的openid
*/
public function GetOpenid()
{
//通过code获得openid
if (!isset($_GET['code'])){
//触发微信返回code码
$_SERVER['HTTPS']=isset($_SERVER['HTTPS'])?$_SERVER['HTTPS']:'';
$scheme = $_SERVER['HTTPS']=='on' ? 'https://' : 'http://';
$uri = $_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING'];
if($_SERVER['REQUEST_URI']) $uri = $_SERVER['REQUEST_URI'];
$baseUrl = urlencode($scheme.$_SERVER['HTTP_HOST'].$uri);
$url = $this->__CreateOauthUrlForCode($baseUrl);
Header("Location: $url");
exit();
} else {
//获取code码,以获取openid
$code = $_GET['code'];
$openid = $this->getOpenidFromMp($code);
return $openid;
}
}
/**
* 通过code从工作平台获取openid机器access_token
* @param string $code 微信跳转回来带上的code
* @return openid
*/
public function GetOpenidFromMp($code)
{
$url = $this->__CreateOauthUrlForOpenid($code);
$res = self::curlGet($url);
//取出openid
$data = json_decode($res,true);
$this->data = $data;
$data['openid']=isset($data['openid'])?$data['openid']:'';
$openid = $data['openid'];
return $openid;
}
/**
* 构造获取open和access_toke的url地址
* @param string $code,微信跳转带回的code
* @return 请求的url
*/
private function __CreateOauthUrlForOpenid($code)
{
$urlObj["appid"] = $this->appid;
$urlObj["secret"] = $this->appKey;
$urlObj["code"] = $code;
$urlObj["grant_type"] = "authorization_code";
$bizString = $this->ToUrlParams($urlObj);
return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
}
/**
* 构造获取code的url连接
* @param string $redirectUrl 微信服务器回跳的url,需要url编码
* @return 返回构造好的url
*/
private function __CreateOauthUrlForCode($redirectUrl)
{
$urlObj["appid"] = $this->appid;
$urlObj["redirect_uri"] = "$redirectUrl";
$urlObj["response_type"] = "code";
$urlObj["scope"] = "snsapi_base";
$urlObj["state"] = "STATE"."#wechat_redirect";
$bizString = $this->ToUrlParams($urlObj);
return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
}
/**
* 拼接签名字符串
* @param array $urlObj
* @return 返回已经拼接好的字符串
*/
private function ToUrlParams($urlObj)
{
$buff = "";
foreach ($urlObj as $k => $v)
{
if($k != "sign") $buff .= $k . "=" . $v . "&";
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 统一下单
* @param string $openid 调用【网页授权获取用户信息】接口获取到用户在该公众号下的Openid
* @param float $totalFee 收款总费用 单位元
* @param string $outTradeNo 唯一的订单号
* @param string $orderName 订单名称
* @param string $notifyUrl 支付结果通知url 不要有问号
* @param string $timestamp 支付时间
* @return string
*/
public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp)
{
$config = array(
'mch_id' => $this->mchid,
'appid' => $this->appid,
'key' => $this->apiKey,
);
// $orderName = iconv('GBK','UTF-8',$orderName);
$unified = array(
'appid' => $config['appid'],
'attach' => 'pay', //商家数据包,原样返回,如果填写中文,请注意转换为utf-8
'body' => $orderName,
'mch_id' => $config['mch_id'],
'nonce_str' => self::createNonceStr(),
'notify_url' => $notifyUrl,
'openid' => $openid, //rade_type=JSAPI,此参数必传
'out_trade_no' => $outTradeNo,
'spbill_create_ip' => '127.0.0.1',
'total_fee' => floatval($totalFee) * 100, //单位 转为分
'trade_type' => 'JSAPI',
);
$unified['sign'] = self::getSign($unified, $config['key']); $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified)); //禁止引用外部xml实体
libxml_disable_entity_loader(true);
$unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);
if ($unifiedOrder === false) {
die('parse xml error');
}
if ($unifiedOrder->return_code != 'SUCCESS') {
die($unifiedOrder->return_msg);
}
if ($unifiedOrder->result_code != 'SUCCESS') {
die($unifiedOrder->err_code);
}
$arr = array(
"appId" => $config['appid'],
"timeStamp" => "$timestamp", //这里是字符串的时间戳,不是int,所以需加引号
"nonceStr" => self::createNonceStr(),
"package" => "prepay_id=" . $unifiedOrder->prepay_id,
"signType" => 'MD5',
);
$arr['paySign'] = self::getSign($arr, $config['key']);
return $arr;
}
public static function curlGet($url = '', $options = array())
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
if (!empty($options)) {
curl_setopt_array($ch, $options);
}
//https请求 不验证证书和host
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
public static function curlPost($url = '', $postData = '', $options = array())
{
if (is_array($postData)) {
$postData = http_build_query($postData);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
if (!empty($options)) {
curl_setopt_array($ch, $options);
}
//https请求 不验证证书和host
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
public static function createNonceStr($length = 16)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
public static function arrayToXml($arr)
{
$xml = "<xml>";
foreach ($arr as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
$xml .= "</xml>";
return $xml;
}
public function notify()
{
$config = array(
'mch_id' => $this->mchid,
'appid' => $this->appid,
'key' => $this->apiKey,
);
$postStr = file_get_contents('php://input');
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$result_1 = json_encode(simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA));
file_put_contents("1.txt",$result_1, FILE_APPEND); $arr = (array)$postObj;
return $arr;
} public static function getSign($params, $key)
{
ksort($params, SORT_STRING);
$unSignParaString = self::formatQueryParaMap($params, false);
$signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
return $signStr;
}
protected static function formatQueryParaMap($paraMap, $urlEncode = false)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if (null != $v && "null" != $v) {
if ($urlEncode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
} }

code.html

<html>

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>微信支付</title>
<style>
* {margin:0;padding:0;}
body {font-size:12px;font-family:"Microsoft YaHei","微软雅黑",sans-serif;color:#333;background-color:#f7f7f7;width:100%;}
.clearfix:after { content: "."; display: block; font-size: 0; height: 0; clear: both; visibility: hidden; }
.clearfix { display: inline-table;}
*html .clearfix { height: 1%; }
.clearfix { display: block; }
*+html .clearfix { min-height: 1%; }
ul,li{ list-style:none;border:0; box-sizing:border-box; }
.main {margin:0 auto;width:100%;max-width:750px;min-width:320px;background-color:#f7f7f7;}
.btnpay {margin:0.8rem auto 0;width:100%;}
.btnpay span {display:block;margin:0 auto;width:6.74rem;height:0.8rem;line-height:0.8rem;background-color:#80D983;border-radius:0.1rem;color:#fff;font-size:0.34rem;letter-spacing:0.06rem;text-align:center;} .xinxi{ margin:0 auto; width: 90%; line-height: 46px; display: flex; flex-direction: row; font-size: 0.32rem; border-bottom: #ccc solid 1px; color: #333;}
.moneychose{ margin:0 auto; width: 90%;}
.moneychose p {font-size:16px;color:#8D8D8F; line-height: 42px;}
.moneychose .list{ display: flex; }
.moneychose .list li{ width: 45%; margin-right:5%; border: #ccc solid 1px; background-color: #fff; border-radius:3px; text-align: center; padding:10px 0;}
.moneychose .list li span{ font-size: 0.32rem;display: block;}
.moneychose .list li.active{border: #e56d33 solid 1px; color:#e56d33;}
.tipbox{ margin:10px auto 0; width: 90%;}
.tipbox a{ text-decoration:none; color: #999; font-size:0.28rem;} .tkbox .mask,.tkknowbox .mask{margin:0 auto;width:100%;height:100%;position:fixed;left:0px;top:0px;opacity:0.85;z-index:9998;background-color:rgb(0,0,0);}
.tkbox .mymodel,.tkknowbox .mytk{width:6.2rem; padding: 0.25rem 0 0.25rem 0; position:fixed;z-index:10000;display:block;border-radius:5px;background-color:#FFFFFF;}
.mymodel .inputblock{ margin:0 auto 0.3rem; width:5.6rem;}
.mymodel .inputs {width:100%;height:0.8rem;line-height:0.8rem;font-size:0.32rem;border:1px solid #CFCFCF;text-indent:0.2rem;outline:none;white-space:pre;overflow-x:scroll;}
.frminput {margin:0.3rem auto 0;display:flex;flex-direction:row;}
.frminput input {margin-left:0.3rem;width:2.4rem;height:0.8rem;line-height:0.8rem;font-size:0.30rem;padding-left:0.2rem;border:1px solid #CFCFCF; outline:none; }
.frminput .sendCodeBtn {margin-left:0.3rem;width:2rem;height:0.8rem;line-height:0.8rem;background-color:#e56d33;border-radius:5upx;color:#fff;text-align:center;font-size:0.26rem;}
.btnconfrm {margin:0.5rem auto 0;width:5rem;}
.btnconfrm span {display:block;margin:0 auto;width:100%;height:0.8rem;line-height:0.8rem;background-color:#80D983;border-radius:0.1rem;color:#fff;font-size:0.34rem;letter-spacing:0.06rem;text-align:center;}
.topcar{ width: 100%; display: flex; flex-direction: row; margin-bottom: 0.15rem;}
.topcar .cartip{ font-size: 0.32rem;width:1.1rem;height:0.6rem; line-height:0.6rem; padding-left: 0.3rem;}
.che_tit{ text-align:center; padding:20px;}
.ul_pro{ background-color:#CED3D9; text-align:center; padding:4px 2px; font-size:0.32rem;}
.ul_pro li{ float:left; width:11.11%; padding:2px;box-sizing: border-box;}
.ul_pro .li_close{ float:right; width:22.22%;}
.ul_pro .li_close span{ background-color:#ACB3BB;}
.ul_pro .li_clean{ float:right; width:22.22%;}
.ul_pro li span{ display:block; background-color:#fff; border-radius:4px;line-height:32px; padding-top:2px; }
.ul_pro li span:active{ background-color:#4DA9F2; color:#fff;}
.ul_input{ width:4.6rem; margin:0 auto; }
.ul_input li{ float:left; width:14%; padding:0.02rem;text-align:center; }
.ul_input li span{ display:block; background-color:#fff; border:1px solid #ccc; border-radius:4px; width:0.5rem; margin:0 auto; height:0.5rem; line-height:0.5rem;font-size: 0.36rem;}
.ul_keybord{ background-color:#CED3D9; text-align:center; padding:4px 2px; font-size:14px;}
.ul_keybord li{ float:left; width:10%; padding:2px;box-sizing: border-box;}
.ul_keybord .ikey20{ margin-left:5%;}
.ul_keybord .li_w{ width:11.11%; }
.ul_keybord .li_close{ float:right; width:22.22%;}
.ul_keybord .li_close span{ background-color:#ACB3BB;}
.ul_keybord .li_clean{ float:right; width:22.22%;}
.ul_keybord li span{ display:block; background-color:#fff; border-radius:4px; box-shadow: 2px 2px 2px #888888;line-height:32px; padding-top:2px; }
.ul_keybord li span:active{ background-color:#4DA9F2; color:#fff;} .tkknowbox .closetk{ width: 0.58rem; height: 0.58rem; position: absolute; top:-39px;right:-9px;z-index: 10001;}
.tkknowbox .closetk .icon{width: 0.58rem; height: 0.58rem;}
.tkknowbox .knowmain{ padding:5px 5% 0; font-size: 0.28rem; color: #666; line-height:24px;}
.tkknowbox .knowmain .tit{ font-size: 0.30rem;}
</style>
<script type="text/javascript">
//调用微信JS api 支付
function jsApiCall(msg) {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
msg,
function (res) {
WeixinJSBridge.log(res.err_msg);
if (res.err_msg == 'get_brand_wcpay_request:ok') {
window.location.href="www.baidu.com";
// alert('支付成功!');
} else if(res.err_msg=='get_brand_wcpay_request:cancel') {
layer.msg('支付取消');
}else{
layer.msg('支付失败');
// alert('支付失败:' + res.err_code + res.err_desc + res.err_msg);
}
}
);
}
function callpay(msg) {
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(msg);
}
}
</script>
</head> <body>
<section class="main">
<section class="xinxi">
<span>手机号:</span>
<span id="phones"></span>
</section>
<section class="moneychose">
<p>选择套餐</p>
<ul class="list">
<li class="active" data-type='1'><span>12次洗车次卡</span><span>300元</span></li>
<li data-type='2'><span>25次洗车次卡</span><span>588元</span></li>
</ul>
<input type="hidden" name="openid" id='openid' value="<?php echo $openid;?>">
<input type="hidden" name="car_num_id" id='car_num_id' value="">
</section>
<section class="tipbox" id="tipbox"><span>《支付须知》</span></section>
<div class="btnpay" onclick="telypay()"><span>立即支付</span></div>
</section>
<!-- 弹框开始 -->
<section class="tkbox" >
<section class="mask"></section>
<section class="mymodel">
<section class="tipinput">
<section class="topcar">
<div class="cartip">车牌号:</div>
<div class="car_input">
<ul class="clearfix ul_input">
<li class="input_pro"><span></span></li>
<li class="input_pp input_zim"><span></span></li>
<li class="input_pp"><span></span></li>
<li class="input_pp"><span></span></li>
<li class="input_pp"><span></span></li>
<li class="input_pp"><span></span></li>
<li class="input_pp"><span></span></li>
</ul>
</div>
</section>
<div class="inputblock"><input id="phone" type="number" maxlength="11" autocomplete="off" class="inputs" placeholder="请输入手机号" onfocus="closePro()" ></div>
<section class="frminput">
<input type="number" id="code" class="inputcode" onfocus="closePro()" placeholder="请输入验证码" />
<section class="sendCodeBtn" datamark="0" id="sendCodeBtn">发送验证码</section>
</section>
</section>
<section class="btnconfrm" id="btnconfrm"><span>确定</span></section>
</section>
</section> <!-- 须知弹窗 -->
<section class="tkknowbox" style="display:none;">
<section class="mask"></section>
<section class="mytk">
<section class="closetk" onclick="$('.tkknowbox').hide();" ><img src="/code/iconclose.png" alt="关闭须知弹框" class="icon" /></section>
<section class="knowmain">
<p><span class="tit" >1)次卡:</span><br>
<span style="font-weight: bold;">轿车</span>:300元套餐(内含12次洗车服务);588元套餐(内含25次洗车服务且赠送一次打蜡)<br>
<span style="font-weight: bold;">SUV</span>: 350元套餐(内含12次洗车服务);688元套餐(内含25次洗车服务且赠送一次打蜡)<br> </p> <p><span class="tit" >2)次卡升级为年卡:</span><br>将剩余次卡数折合为钱数,并支付所差金额;即可升级为年卡且次卡剩余次数清空;<br></p>
<p>3)其他问题,请联系客服热线 ********** 咨询</p>
</section>
</section>
</section>
<!-- 弹框结束 -->
<script type="text/javascript" src="/assets/js/jquery.min.js"></script>
<script src="/assets/js/shop.js" ></script> <script type="text/javascript">
var isClick = true;
function telypay() {
if(!isClick){
return false;
}
// 这里可以写你onclick事件需要获取传到后台的值
var openid = $('#openid').val();
var price;
$(".list li").each(function(){
if($(this).hasClass('active')){
console.log($(this).attr("data-type"));
price = $(this).attr("data-type");
}
}); $.ajax({
type: 'post',
url: "/admin.php/pay/sub_pay",
data: { 'price': price, 'openid': openid},
dataType: 'json',
success: function (msg) {
isClick = true;
callpay(msg);
}
});
}
$(function () {
//隐藏弹框
var is_user=<?php echo $is_user;?>;
var car_num_id=<?php echo $car_num_id;?>;
var phone=<?php echo $phone;?>;
if(is_user - 1 == 0){
$("#car_num_id").val(car_num_id);
$('#phones').text(phone);
$(".tkbox").hide();
} var W = $('.mymodel').width();
var H = $('.mymodel').height();
var winWid = $(window).width() / 2 - W / 2;
var winHig = $(window).height() / 2 - H / 2;
$(".mymodel").css({ 'left': winWid, 'top': winHig }); $(".list li").click(function(){
$(".list li").removeClass('active');
$(this).addClass('active');
console.log($(this).attr("data-type")); }); //发送验证码
$("#sendCodeBtn").click(function(){
var datamark = $(this).attr('datamark');
//console.log(datamark);
if(datamark - 1 == 0){
return false;
}
var phone = $("#phone").val();
if(!phone){
layer.msg('请填写您的手机号');
return false;
}
var myreg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
if (!myreg.test(phone)) {
layer.msg('请填写正确的手机号');
return false;
}
$.ajax({
type: 'post',
url: "/admin.php/pay/send_code",
data: { 'phone': phone},
dataType: 'json',
success: function (msg) {
if(msg.code < 0){
layer.msg(msg.msg);
}else if(msg.code > 0){
settime($("#sendCodeBtn"));
layer.msg('发送验证码成功');
}
return false;
}
});
//settime($("#sendCodeBtn")); //此处请求接口,成功后下面 });
var countdown = 60;
function settime(obj)
{
if (countdown == 0) {
$(obj).attr("datamark", "0");
$(obj).html("获取验证码");
countdown = 60;
return;
} else {
$(obj).attr("datamark", "1");
$(obj).html(countdown + "s后重新获取");
countdown--;
}
setTimeout(function () { settime(obj) }, 1000);
} //确定按钮点击
$("#btnconfrm").click(function () { var carnum = $(".car_input").attr("data-pai");
if(carnum == undefined){
layer.msg('请填写您的车牌号');
return false;
}
carnum = carnum.replace(/[\r\n]/g,"").replace(/\s*/g,"");
// console.log(carnum);
if(carnum.length - 7 < 0){
layer.msg('请填写您的车牌号');
return false;
}
var phone = $("#phone").val();
var code = $("#code").val();
if(!phone){
layer.msg('请填写您的手机号');
return false;
}
var myreg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
if (!myreg.test(phone)) {
layer.msg('请填写正确的手机号');
return false;
}
if(!code){
layer.msg('请填写您的验证码');
return false;
}
$('#pro').remove(); $.ajax({
type: 'post',
url: "/admin.php/pay/car_num",
data: { 'carnum': carnum, 'phone': phone, 'code': code},
dataType: 'json',
success: function (message) { msgs=JSON.parse(message);
if(msgs.status=='0'){
layer.msg(msgs.msg);
return false;
}else{
$("#car_num_id").val(msgs.id);
$('#phones').text(msgs.phone);
$(".tkbox").hide();
layer.msg('提交成功');
// console.log(msg.id +"手机号"+"验证码"+msg.phone);
return true;
} }
}); //console.log(carnum +"手机号"+phone+"验证码"+code);
return false; }); $("#tipbox").click(function(){
$(".tkknowbox").show();
var W1 = $('.mytk').width();
var H1 = $('.mytk').height();
var winWid1 = $(window).width() / 2 - W1 / 2;
var winHig1 = $(window).height() / 2 - H1 / 2;
$(".mytk").css({ 'left': winWid1, 'top': winHig1 });
}); }); (function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth >= 750) {
docEl.style.fontSize = '100px';
} else {
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
</body>
</html>

(个人的需求 你们可以删除手机短信的验证 send_code 和car_num 的入库)

你们只用sub_pay方法

 public function sub_pay()
{
$openid=$this->request->post('openid');
$price=$this->request->post('price');
$price=0.01;//测试金额
// $outTradeNo = uniqid(); //你自己的商品订单号
//今日日期+时间戳后五位+毫秒从第三位到第八位+
$outTradeNo = date('Ymd').substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(1000, 9999));
$orderName = '支付测试'; //订单标题
$notifyUrl = 'http://'.$_SERVER['HTTP_HOST'].'/admin.php/Pay/callback'; //付款成功后的回调地址(不要有问号)
$payTime = time(); //提交时间
$order_price=$price*100; //测试
$sql="INSERT INTO order(`pay_type`,`order_status`,`order_num`,`shop_id`,`pay_status`,`order_price`,`create_time`) VALUES('2','0','$outTradeNo','$ip_user','0','$order_price','$payTime')";
Db::execute($sql);
//处理一下数据
     $conf = $this->payconfig($orderName,$openid,$outTradeNo,$order_price,$orderName,$notifyUrl);
    
$jsApiObj["appId"] =$conf['appid'];
$timeStamp = time();
$jsApiObj["timeStamp"] = "$timeStamp";
$jsApiObj["nonceStr"] = $this->createNoncestr();
$jsApiObj["package"] ="prepay_id=".$conf['prepay_id'];
$jsApiObj["signType"] = "MD5";
$jsApiObj["paySign"] = $this->MakeSign($jsApiObj,'KunLunqifuWangRUIHua162588080619');
echo json_encode($jsApiObj);
}
payconfig方法
#微信JS支付参数获取-注意下面是支付方法可以不需要管!!!#
protected function payconfig($title,$openid,$no, $fee, $body,$notifyUrl)
{
$config = array(
'mch_id' => '********',
'appid' => '*******',
'key' => '**************',
);
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$data['appid'] =$config['appid'];
$data['mch_id'] =$config['mch_id']; //商户号
$data['device_info'] ='WEB';
$data['body'] = $body;
$data['out_trade_no'] =$no; //订单号
$data['total_fee'] = $fee; //金额
$data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];
$data['notify_url'] =$notifyUrl;
$data['trade_type'] = 'JSAPI';
$data['openid'] = $openid; //获取openid
$data['nonce_str'] = $this->createNoncestr();
$data['sign'] = $this->MakeSign($data,$config['key']); //print_r($data);
$xml = $this->ToXml($data);
$curl = curl_init(); // 启动一个CURL会话
curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
//设置header
// curl_setopt($curl, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_POST, TRUE); //发送一个常规的Post请求
curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); // Post提交的数据包
curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
$tmpInfo = curl_exec($curl); // 执行操作
curl_close($curl); //关闭CURL会话
$arr = $this->FromXml($tmpInfo);
return $arr;
}

/**
     * 异步回调通知
     * 说明:需要在支付文件中(如native.php或者jsapi.php)的填写回调地址。例如:http://www.xxx.com/wx/notify.php
     * 付款成功后,微信服务器会将付款结果通知到该页面 我的是 callback方法
     */

 

 public function callback()
{ $xml = file_get_contents("php://input");
$log = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
$log_1=json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));
file_put_contents('1.txt',$log_1,FILE_APPEND);//只有返回参数写进文件中才可以打印 切记切记切记
      3.1根据返回的信息在生成签名防止数据泄漏导致出现“假通知”,造成资金损失。
     $apiKey="*******";
        $newSign = $this->verifySign($log,$apiKey);
     //判断数据库金额和支付金额是否一致 判断签名是否一致
     if (($yorder_data['order_price']) == (int)$trade['total_fee']&& $newSign == $trade["sign"] ) //
            {
        直接写你的操作数据库逻辑就ok了

     }
     //必须加这个!!!!
     $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';  
        echo $str;
}
/* $log=array (
'appid' => 'wx3c3f93ddce1e7845',
'bank_type' => 'OTHERS',
'cash_fee' => '1',
'device_info' => 'WEB',
'fee_type' => 'CNY',
'is_subscribe' => 'Y',
'mch_id' => '1602777325',
'nonce_str' => 'oz5dzyotw0qyz2a8x2elenbki268cyt5',
'openid' => 'os2J15vmqW1KXHLZAL4IwBtP7hL8',
'out_trade_no' => '2021070824865563665180',
'result_code' => 'SUCCESS',
'return_code' => 'SUCCESS',
'sign' => '02B66C17D8A31D0F943448979357DDEB',
'time_end' => '20210708141109',
'total_fee' => '1',
'trade_type' => 'JSAPI',
'transaction_id' => '4200001181202107085997485076',
);*/

相关的方法

  /**
* 作用:产生随机字符串,不长于32位
*/
public 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;
} /**
* 作用:产生随机字符串,不长于32位
*/
public function randomkeys($length)
{
$pattern = '1234567890123456789012345678905678901234';
$key = null;
for ($i = 0; $i < $length; $i++) {
$key .= $pattern{mt_rand(0, 30)}; //生成php随机数
}
return $key;
}
/**
* 将xml转为array
* @param string $xml
* @throws WxPayException
*/
public function FromXml($xml)
{
//将XML转为array
return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)),true);
}
/**
* 输出xml字符
* @throws WxPayException
**/
public function ToXml($arr)
{
$xml = "<xml>";
foreach ($arr as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
/**
* 生成签名
* @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
protected function MakeSign($arr,$key)
{
ksort($arr);
$string = $this->ToUrlParams($arr);
//签名步骤二:在string后加入KEY
$string = $string."&key=$key"; //key秘钥
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 格式化参数格式化成url参数
*/
protected function ToUrlParams($arr)
{
$buff = "";
foreach ($arr as $k => $v){
if ($k != "sign" && $v != "" && !is_array($v)) {
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
// 判断返回的签名和根据数据生成的数据判断是否相同,防止数据泄漏导致出现“假通知”,造成资金损失。
function verifySign($params, $apikey)
{
ksort($params);
$string = "";
foreach ($params as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) {
$string .= $k . "=" . $v . "&";
}
}
$string = $string . "key=" . $apikey;
$string = md5($string);
$result = strtoupper($string);
return $result;
}

到这里 微信jsapi就结束了   下一篇讲支付宝的流程以及代码操作

php微信jsapi支付 支付宝支付 两码合一的更多相关文章

  1. Android 微信支付&支付宝支付

    由于项目需求,加入这2个功能记录一些需要注意的地方 一.微信支付 微信支付在2016年4月份左右稍微调整了一下支付过程,但是文档却没怎么更新,这也是百度上为什么那么多开发者都说微信是个大坑. 身为一个 ...

  2. Android支付——支付宝支付总结

    摘要:分享牛系列.分享牛转载.第三方支付,java第三方支付.android第三方支付. 原文地址:http://blog.csdn.net/zwl5670/article/details/51219 ...

  3. 微信公众号中的支付宝支付与微信支付 && 支付宝支付问题(微信bug)

    一般,在微信公众号中的商城都是需要支持微信支付和支付宝支付的,当然,较大的公司对于鹅厂和阿里的站队就不说了,所以这里简单记录一下支付宝支付和微信支付的主要流程.说是简单介绍,这是因为确实不难,因为前端 ...

  4. 微信JSAPI 公众号支付 H5支付以及APP支付 WEBAPI接口开发测试

    统一下单入口 调用该方法入口: public void WxPayAPI() { //string PayPrice ="99.9"; ////订单号 //string Payor ...

  5. iOS三方支付--微信支付/支付宝支付

    一.微信支付 1.注册账号并申请app支付功能 公司需要到微信开放品台进行申请app支付功能 , 获得appid和微信支付商户号(mch_id)和API秘钥(key) . Appsecret(secr ...

  6. 微信支付/支付宝支付/银联支付,对比加总结(Java服务端)

    今天来讲讲支付. 工作到现在,接入过好几个项目的支付,其中涉及到了微信支付.支付宝支付.银联支付. 三种支付的对接感受其实整体上大同小异.都遵循同一个流程: 1).商户APP向商户服务器请求生成订单 ...

  7. iOS移动支付——支付宝支付

    这篇博客总结得很好,我只对在iOS上集成支付宝做简洁的步骤总结. http://www.it165.net/pro/html/201402/9376.html iOS集成支付宝支付的步骤: 准备工作的 ...

  8. 微信支付支付宝支付生成二维码的方法(php生成二维码的三种方法)

    如果图简单,可以用在线生成 http://pan.baidu.com/share/qrcode?w=150&h=150&url=http://www.xinzhenkj.com 最简单 ...

  9. Android H5调起原生微信或支付宝支付

    Android H5调起原生微信或支付宝支付 WebView调用原生微信或支付宝回调:其原理就是在shouldOverrideUrlLoading(final WebView view, String ...

随机推荐

  1. JavaScript正则表达式(深度)(Day_14)

    忘不掉的是回忆,继续的是生活,错过的,就当是路过. 简介 正则表达式是用于匹配字符串中字符组合的模式.在 JavaScript中,正则表达式也是对象. 这些模式被用于 RegExp 的 exec 和  ...

  2. Docker之tomcat安装与部署项目

    docker安装tomcat  docker pull tomcat:8.5 等待... (1)正常的方式启动tomcat  docker run -d --name tomcat -p 80:808 ...

  3. 给powershell增加类似于linux的alias功能

    给powershell增加类似于快捷方式的功能(类似于linux的alias) 首先执行 set-executionpolicy remotesigned 允许powershell执行脚本 然后执行e ...

  4. THINKPHP_(1)_修改TP源码,支持对中文字符串按拼音进行排序。

    问题:TP从服务器数据中取出的collection数据,当进一步在网页中进行分页显示时,需要调用order函数,实现类似如下图的排序. 当点击页面中的相关内容时,实现对服务器数据进行重排,就要调用TP ...

  5. Mobileye独创性创新

    Mobileye独创性创新 尽管存在相似之处,但Nvidia的SFF无法与Mobileye的RSS相匹配,后者是领先的AV安全模型 迈向无人驾驶的未来,Mobileye继续以新的创新引领行业,不仅将使 ...

  6. YOLOV4各个创新功能模块技术分析(三)

    YOLOV4各个创新功能模块技术分析(三)  八.数据增强相关-Stylized-ImageNet 论文名称:ImageNet-trained cnns are biased towards text ...

  7. YOLOv5目标检测源码重磅发布了!

    YOLOv5目标检测源码重磅发布了! https://github.com/ultralytics/yolov5 该存储库代表了对未来对象检测方法的超解析开源研究,并结合了在使用之前的YOLO存储库在 ...

  8. postgresql无序uuid性能测试

    无序uuid对数据库的影响 由于最近在做超大表的性能测试,在该过程中发现了无序uuid做主键对表插入性能有一定影响.结合实际情况发现当表的数据量越大,对表插入性能的影响也就越大. 测试环境 Postg ...

  9. 【Azure 应用服务】Azure Web App的服务(基于Windows 操作系统部署)在被安全漏洞扫描时发现了TCP timestamps漏洞

    问题背景 什么是TCP timestamps(TCP 时间戳)? The remote host implements TCP Timestamps, as defined by RFC1323 (h ...

  10. Linux芯片驱动之SPI Controller

    针对一款新的芯片,芯片厂商如何基于Linux编写对应的 SPI controller 驱动? 我们先看看 Linux SPI 的整体框架: 可以看到,最底层是硬件层,对应芯片内部 SPI contro ...