產品開會提出了這樣的需求:一個二維碼可以微信支付也可以支付寶支付

經過自己的鑽研以及詢問技術高人(本人程式碼一般般)和網上搜索 最終實現其功能  我用微信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就結束了   下一篇講支付寶的流程以及程式碼操作