**開發之前配置篇:**
一、登陸公眾號平臺(https://mp.weixin.qq.com),點擊設置-》公眾號設置-》功能設置-》JS接口安全域名 (這里設置你網站的根域名),主意要將下載的文件放到你的網絡根域名設置的路徑下,不然會提示設置不成功。
二、登陸公眾號平臺(https://mp.weixin.qq.com),點擊設置-》公眾號設置-》功能設置-》網頁授權域名 (這里設置你網站的根域名),作用是為了獲取微信服務器的code,說明白一點就是微信的驗證。
三、登陸公眾號平臺(https://mp.weixin.qq.com),點擊微信支付-》開發配置-》支付授權目錄(這里面要設置到你要訪問具體方法的那個控制器,并且以反斜杠結束,如果是做分享,這步可以跳過)。
四、設置Api密匙:登陸商戶平臺(https://pay.weixin.qq.com/),賬戶中心-》API安全(這里要下載安裝操作證書,才可以設置Api密匙)
四、
**開發之前獲取參數篇:**
一、獲取原始Id:登陸公眾號平臺(https://mp.weixin.qq.com),點擊設置-》公眾號設置-》賬號詳情,拉到底就見這個值。
二、獲取商戶號:登陸公眾號平臺(https://mp.weixin.qq.com),點擊微信支付-》商戶信息,這里就可見這個值。
三、應用Id:登陸公眾號平臺(https://mp.weixin.qq.com),點擊開發-》基本配置,即可看見這個值
四、應用密匙:登陸公眾號平臺(https://mp.weixin.qq.com),點擊開發-》基本配置,即可看見這個值(需要短信驗證和授權)
五、Api密匙:登陸商戶平臺(https://pay.weixin.qq.com/),賬戶中心-》API安全(這里要下載安裝操作證書,才可以查看Api密匙,同時還要下載這里面的操作證書到你的網站中,文件夾名稱一般為cert)
**準備之后開發微信分享后臺代碼篇**
只需調用getSignPackage傳入公眾號配置信息,和緩存的信息即可。
這里特別要主要分享的頁面必須是和我們現在當前頁面的URL是一致的,不然簽名會出現錯誤
public function getSignPackage($config,$weixinConfig) {
$jsapiTicket = $this->getJsApiTicket($config,$weixinConfig);
// 注意 URL 一定要動態獲取,不能 hardcode.
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
// $url = $_GET['url'];
$timestamp = time();
$nonceStr = $this->createNonceStr();
// 這里參數的順序要按照 key 值 ASCII 碼升序排序
$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
$signature = sha1($string);
$signPackage = array(
"appId" => $config['appId'],
"nonceStr" => $nonceStr,
"timestamp" => $timestamp,
"url" => $url,
"signature" => $signature,
"rawString" => $string
);
return $signPackage;
}
private 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;
}
private function getJsApiTicket($config,$weixinConfig) {
// jsapi_ticket 應該全局存儲與更新,以下代碼以寫入到數據庫中做示例
// https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
//return 'sM4AOVdWfPE4DxkXGEs8VMSQstUYjbUtfFD4m78lNEyU_NEJkjLLJlzrfdKU-x_JPDdAS-jbru9EmpFHy2Omvw';
$access_token = $this->getAccessToken($config,$weixinConfig);
if (UTC_TIME + 1800 < $weixinConfig['jsapi_ticket_expired']) {
$jsapi_ticket = $weixinConfig['jsapi_ticket'];
} else {
$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi';
$jsapi_json = Http::get($url);
$jsapi_json = empty($jsapi_json) ? false : @json_decode($jsapi_json, true);
if(!$jsapi_json || empty($jsapi_json['ticket'])){
return false;
}
$jsapi_ticket = $jsapi_json['ticket'];
SystemConfigService::updateConfig('jsapi_ticket', $jsapi_ticket);
SystemConfigService::updateConfig('jsapi_ticket_expired', UTC_TIME + (int)$jsapi_json['expires_in']);
}
return $jsapi_ticket;
}
private function getAccessToken($config,$weixinConfig)
{
if (UTC_TIME + 1800 < $weixinConfig['access_token_expired']) {
$access_token = $weixinConfig['access_token'];
} else {
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' .
$config['appId'] . '&secret=' .$config['appSecret'];
$token_json = Http::get($url);
$token_json = empty($token_json) ? false : @json_decode($token_json, true);
if(!$token_json || empty($token_json['access_token'])){
return false;
}
$access_token = $token_json['access_token'];
SystemConfigService::updateConfig('access_token', $access_token);
SystemConfigService::updateConfig('access_token_expired', UTC_TIME + (int)$token_json['expires_in']);
}
return $access_token;
}
** 準備之后開發微信分享前端代碼篇:**
<script type="text/javascript" src="{{ asset('wap/community/newclient/js/jweixin-1.0.0.js') }}"></script>
<script type="text/javascript">
//初始化微信配置
wx.config({
debug: false, // 關閉調試模式
appId: "{{ $data['appId'] }}", // 必填,公眾號的唯一標識
timestamp: "{{ $data['timestamp'] }}", // 必填,生成簽名的時間戳
nonceStr: "{{ $data['nonceStr'] }}", // 必填,生成簽名的隨機串
signature: "{{ $data['signature'] }}",// 必填,簽名
jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表
});
wx.ready(function(){
$(".sha-frame").click(function(){
$(this).addClass('none');
});
// 分享給朋友
wx.onMenuShareAppMessage({
title: "{{ $share['share_title'] }}", // 分享標題
desc:"{{ $share['share_conten'] }}", // 分享描述
link: location.href, // 分享鏈接
imgUrl: 'img.png', // 分享圖標
type: 'link', // 分享類型,music、video或link,不填默認為link
dataUrl: '', // 如果type是music或video,則要提供數據鏈接,默認為空
success: function () {
// 用戶確認分享后執行的回調函數
},
cancel: function () {
// 用戶取消分享后執行的回調函數
}
});
// 分享到朋友圈
wx.onMenuShareTimeline({
title: "{{ $share['share_title'] }}", // 分享標題
desc:"{{ $share['share_conten'] }}", // 分享描述
link: location.href, // 分享鏈接
imgUrl: 'img.png', // 分享圖標
success: function () {
// 用戶確認分享后執行的回調函數
},
cancel: function () {
// 用戶取消分享后執行的回調函數
}
});
});
</script>
**準備之后微信支付后臺代碼篇:**
首先判斷wxpay_open_id是否存在(wxpay_open_id存在session中),沒有存在就去請求微信接口,獲取回來。然后調用staffweixinJsPay,傳入必要參數,調用后的結果集綁定到前端頁面中。
<?php namespace YiZan\Http\Controllers\Wap;
use Session, Redirect;
/**
* 微信控制器
*/
class WeixinController extends BaseController {
public function authorize(){
$url = urldecode($_REQUEST['url']);
// file_put_contents(storage_path().DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'zhifu.log',date('Y-m-d H:i:s',time())."\n"."2"."\n",FILE_APPEND);
$flage = $_REQUEST['flage'];
if(!$flage){
if (empty($url)) {
return $this->error('參數錯誤');
}
}
$result = $this->requestApi('config.getpayment',['code' => 'weixinJs']);
if (!$result || $result['code'] != 0) {
return $this->error('獲取微信配置信息失敗', $url);
}
$payment = $result['data'];
$config = $payment['config'];
Session::set('authorize_return_url', $url);
Session::save();
$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$config['appId'].
'&redirect_uri='.urlencode(u('Weixin/accesstoken',['flage'=>$flage]))
.'&response_type=code&scope=snsapi_base&state=YZ#wechat_redirect';
// file_put_contents('/mnt/www/fanwewb8/storage/logs/ceshi.log',date('Y-m-d H:i:s',time()).$url."\n",FILE_APPEND);
return Redirect::to($url);
}
public function accesstoken() {
$code = $_REQUEST['code'];
// file_put_contents(storage_path().DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'zhifu.log',date('Y-m-d H:i:s',time())."\n"."3 $code"."\n",FILE_APPEND);
$flage = $_REQUEST['flage'];
if($flage){
$url = "http://staff.wai8.fanwe.net/Weixin/accesstoken?code={$code}";
Header("Location: $url");
exit();
}
$url = Session::get('authorize_return_url');
if (empty($code)) {
return $this->error('授權失敗', $url);
}
$result = $this->requestApi('config.getpayment',['code' => 'weixinJs']);
if (!$result || $result['code'] != 0) {
return $this->error('獲取微信配置信息失敗', $url);
}
$payment = $result['data'];
$config = $payment['config'];
$wxurl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$config['appId'].
'&secret='.$config['appSecret'].'&code='.$code.'&grant_type=authorization_code';
$result = @file_get_contents($wxurl);
$result = empty($result) ? false : @json_decode($result, true);
if (!$result) {
return $this->error('授權失敗', $url);
} elseif (isset($result['errcode']) && $result['errcode'] != 0) {
return $this->error('授權失敗:'.$result['errmsg'], $url);
}
$openid = $result['openid'];
$url = $url.'&openId='.$openid;
return Redirect::to($url);
}
}
//商戶微信JS支付
public function staffweixinJsPay($userPayLog, $payment, $extend ) {
//$payment = array('appId','partnerId','partnerKey');
//$userPayLog= array('content','sn','money')
//$extend=array('openId')
// var_dump($userPayLog,$payment,$extend);die;
$config = $payment;
$money = $userPayLog['money'];
//$sellerId, $money, $sn
if(!$this->createSellerPayLog1($extend['seller_id'],$money,$userPayLog['sn'])){
return false;
}
// return $config;
$order_data = array(
'appid' => $config['appId'],//
'body' => $userPayLog['content'],//
'mch_id' => $config['partnerId'],//
'nonce_str' => md5(String::randString(16)),
'notify_url' => Config::get('app.callback_url').'Payment/StaffWeixin/jsnotify',
'openid' => $extend['openId'],//
'out_trade_no' => $userPayLog['sn'],//
'spbill_create_ip' => CLIENT_IP,
'total_fee' => round($money * 100),//
'trade_type' => 'JSAPI'
);
// return array($money,$order_data['total_fee']);
$xml = '<xml>';
$sign = '';
foreach ($order_data as $key => $data) {
if ($key == 'body') {
$xml .= "\n<{$key}><![CDATA[{$data}]]></{$key}>";
} else {
$xml .= "\n<{$key}>{$data}</{$key}>";
}
$sign .= "{$key}={$data}&";
}
$sign = strtoupper(md5("{$sign}key={$config['partnerKey']}"));
$xml .= "\n<sign>{$sign}</sign>\n</xml>";
file_put_contents(storage_path().DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'zhifu.log',date('Y-m-d H:i:s',time())."\n".$xml."\n",FILE_APPEND);
// return $xml;
$response = Http::post('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml);//統一下單
// file_put_contents(storage_path().DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'zhifu.log',date('Y-m-d H:i:s',time())."\n".$response."\n",FILE_APPEND);
// return $response;
if (empty($response)) {
return false;
}
$response = @simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA);
if (!$response || !isset($response->return_code) || $response->return_code != 'SUCCESS') {
return false;
}
$weixinConfig = SystemConfigService::getConfigByGroup('weixin');
if (UTC_TIME + 1800 < $weixinConfig['access_token_expired']) {
$access_token = $weixinConfig['access_token'];
} else {
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' .
$config['appId'] . '&secret=' .$config['appSecret'];
$token_json = Http::get($url);
$token_json = empty($token_json) ? false : @json_decode($token_json, true);
if(!$token_json || empty($token_json['access_token'])){
return false;
}
$access_token = $token_json['access_token'];
SystemConfigService::updateConfig('access_token', $access_token);
SystemConfigService::updateConfig('access_token_expired', UTC_TIME + (int)$token_json['expires_in']);
}
if (UTC_TIME + 1800 < $weixinConfig['jsapi_ticket_expired']) {
$jsapi_ticket = $weixinConfig['jsapi_ticket'];
} else {
$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi';
$jsapi_json = Http::get($url);
$jsapi_json = empty($jsapi_json) ? false : @json_decode($jsapi_json, true);
if(!$jsapi_json || empty($jsapi_json['ticket'])){
return false;
}
$jsapi_ticket = $jsapi_json['ticket'];
SystemConfigService::updateConfig('jsapi_ticket', $jsapi_ticket);
SystemConfigService::updateConfig('jsapi_ticket_expired', UTC_TIME + (int)$jsapi_json['expires_in']);
}
//js-sdk接口配置信息
$jsapi_request = array(
'jsapi_ticket' => $jsapi_ticket,
'noncestr' => md5(String::randString(16)),
'timestamp' => UTC_TIME,
'url' => $extend['url']
);
$jsapi_request['signature'] = self::weixinSign($jsapi_request, '', 'sha1');
$jsapi_request['appId'] = $config['appId'];
//支付配置
$pay_request = [
'appId' => $config['appId'],
'nonceStr' => md5(String::randString(16)),
'package' => 'prepay_id='.$response->prepay_id,
'signType' => 'MD5',
'timeStamp' => UTC_TIME + date('Z')
];
$pay_request['paySign'] = strtoupper(self::weixinSign($pay_request, $config['partnerKey']));
$pay_request['jsapi'] = $jsapi_request;
return $pay_request;
}
** 準備之后微信支付前端篇:**
<script type="text/javascript" src="{{ asset('staff/js/jweixin-1.0.0.js') }}"></script>
<script type="text/javascript">
//微信分享配置文件
wx.config({
debug: false, // 調試模式
appId: "{{$pay['appId']}}", // 公眾號的唯一標識
timestamp: "{{$pay['jsapi']['timestamp']}}", // 生成簽名的時間戳
nonceStr: "{{$pay['jsapi']['noncestr']}}", // 生成簽名的隨機串
signature: "{{$pay['jsapi']['signature']}}",// 簽名
jsApiList: ['checkJsApi','chooseWXPay'] // 需要使用的JS接口列表
});
function callpay()
{
wx.chooseWXPay({
timestamp: "{{$pay['timeStamp']}}", // 支付簽名時間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。但最新版的支付后臺生成簽名使用的timeStamp字段名需大寫其中的S字符
nonceStr: "{{$pay['nonceStr']}}", // 支付簽名隨機串,不長于 32 位
package: "{{$pay['package']}}", // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=***)
signType: "{{$pay['signType']}}", // 簽名方式,默認為'SHA1',使用新版支付需傳入'MD5'
paySign: "{{$pay['paySign']}}", // 支付簽名
success: function (res) {
alert('支付成功');
location.href = "{{ u('Mine/index') }}";
},
cancel: function (res) {
alert('取消支付');
location.href = "{{ u('Mine/index') }}";
},
fail: function (res) {
alert('支付失敗');
location.href = "{{ u('Mine/index') }}";
}
});
}
</script>
- 環境搭建
- centos6.5 lnmp環境搭建
- svn環境搭建
- centos lamp安裝配置
- mysql
- mysql常用命令
- mysql技術內幕
- 1.1mysql體系結構
- 1.2mysql存儲引擎
- 1.3mysql連接
- linux
- linux-常用命令
- linux下vim命令
- 第三方平臺開發
- 微信開發之旅
- php
- php框架
- lavarel常用命令
- thinkPhp常用命令
- yii2.0.8
- 安裝
- yii常用
- yii配置
- yii常用2
- php源碼積累
- php字符串截取
- php圖片處理(gd)
- 二維數組保持索引排序(高低)
- 獲取一個月首尾天數
- 時間函數
- php內置函數
- html
- js
- 基本命令
- js案例
- js去空格
- css
- 基本樣式
- 案例
- ul li 橫向水平居中自適應案例
- 固定底部導航欄并自適應
- 購物車帶角標
- display的兼容解決
- 前端框架
- boostrap
- 常用類
- git
- 上傳項目到遠程倉庫GitHub