**开发之前配置篇:**
一、登陆公众号平台(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