- 业务流程
- 小程序登录获取code,wx.login()
- code appid secret获取openid
- 开发者服务器生成token
- 开发者自己业务token获取数据交互
- 时序图
小程序登录时序图
小程序端pay.wxml
<import src="http://img.studyofnet.com../../common/head.wxml" />
<import src="http://img.studyofnet.com../../common/foot.wxml" />
<view hidden='{{!isShow}}'>
<view class="modal">
<view class='modal-content'>
<view class='modal-top'>
<view class='header'>关闭</view>
</view>
<view class='modal-body'>
<text>需要微信登录才能支付 </text>
</view>
<view class='modal-footer'>
<button lang="zh_CN" type="primary" bindgetuserinfo="onGotUserInfo" open-type="getUserInfo">微信登录</button>
</view>
</view>
</view>
</view>
<view class="container">
<template is="head" data="{{title: '支付体验'}}"/>
<view class="page-body">
<form catchsubmit="formSubmit" catchreset="formReset">
<view class="page-section">
<view class="weui-cells weui-cells_after-title">
<view class="weui-cell weui-cell_input">
<view class="weui-cell__bd">
<input class="weui-input" name="amount" placeholder="请输入金额" />
</view>
</view>
</view>
</view>
<view class="page-section">
<view class="weui-cells weui-cells_after-title">
<view class="weui-cell weui-cell_input">
<view class="weui-cell__bd">
<input class="weui-input" name="desc" placeholder="请输入备注信息" />
</view>
</view>
</view>
</view>
<view class="btn-area">
<button type="warn" formType="submit">支付充值体验</button>
</view>
</form>
</view>
<template is="foot" />
</view>
小程序端pay.js
// pages/pay/pay.js
var app = getApp();
var md5 = require('../../md5/md5.js');
Page({
/**
* 页面的初始数据
*/
data: {
isShow: true,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
onGotUserInfo: function (e) {
var userInfo = e.detail.userInfo
console.log(userInfo)
this.setData({
userInfo: userInfo,
isShow: false
})
app.getUserInfo(function (red) {
console.log(red)
}, userInfo)
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
formSubmit(e) {
var data = e.detail.value;
if(data.amount<=0){
wx.showToast({
title: '金额必须大于0',
icon:'loading'
})
}
var appId = '';
//支付
var sysUserInfo = wx.getStorageSync('userInfo');
console.log(sysUserInfo)
wx.request({
url: app.globalData.domain '/api/wxpay/payorder',
data: {
amount: data.amount,
openid: sysUserInfo.openid
},
method: "post",
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: function (resoder) {
if (resoder.data.return_code == "SUCCESS") {
var timeStamp = (Date.parse(new Date()) / 1000).toString();
var pkg = 'prepay_id=' resoder.data.prepay_id;
var nonceStr = resoder.data.nonce_str;
var paySign = md5.hexMD5('appId=' 'appid' '&nonceStr=' nonceStr '&package=' pkg '&signType=MD5&timeStamp=' timeStamp "&key=key").toUpperCase();//此处用到hexMD5插件
//发起支付
wx.requestPayment({
'timeStamp': timeStamp,
'nonceStr': nonceStr,
'package': pkg,
'signType': 'MD5',
'paySign': paySign, //此处用到hexMD5插件
'success': function (res) {
console.log(res)
},
'fail': function (res) {
console.log(res)
}
})
}
}
})
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
小程序端app.js
/**
* 运行时全局变量
*/
let _globalData = {
userInfo:null,
toname:'',
wishes:'',
// in case
// 在更多页面中选则某条祝福话后,直接覆盖上面的wishes字段,而用户却在自定义页面选择了取消或返回
tempwishes:'',
temptoname:'',
tempnickname:''
}
//app.js
App({
onLaunch: function () {
//调用API从本地缓存中获取数据
/*var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)*/
/*wx.clearStorage()*/
},
globalData: {
appid: '',
secret: '',
version: '0.0.1',
domain: '',
},
/**
* 读取与修改运行时全局变量的方法
*/
getUserInfo:function(cb,userInfo){
console.log(userInfo.nickName)
var that = this
var sysUserInfo = wx.getStorageSync('userInfo')
if(sysUserInfo){
_globalData.userInfo = sysUserInfo
}
if(_globalData.userInfo){
typeof cb == "function" && cb(_globalData.userInfo)
}else{
//调用登录接口
wx.login({
success: function (res) {
_globalData.userInfo = userInfo
wx.request({
url: '/login',
data: {
code: res.code,
appid:'' ,
secret: '',
nickname: userInfo.nickName,
gender: userInfo.gender,
city: userInfo.city,
province: userInfo.province,
avatarurl: userInfo.avatarUrl
},
success: function (resRutern) {
if (resRutern.data.status) {
userInfo.utoken = resRutern.data.utoken;
userInfo.openid = resRutern.data.openid;
wx.setStorageSync('userInfo', userInfo);
} else {
console.log('登录失败');
return false;
}
}
})
}
})
}
},
setUserInfo:function(userInfo){
var that = this;
if (_globalData.userInfo){
_globalData.userInfo = userInfo;
return;
}
that.getUserInfo();
},
getTempNickName : function(){
return _globalData.tempnickname
},
setTempNickName : function(nickname){
_globalData.tempnickname = nickname;
},
clearTempNickName :function(){
_globalData.tempnickname = '';
},
getToName : function(isTemp){
if (isTemp){
return _globalData.temptoname
}else{
return _globalData.toname;
}
},
setToName : function(toname,isTemp){
if (isTemp){
_globalData.temptoname = toname;
}else{
_globalData.toname = toname;
}
},
clearTempToName: function(){
_globalData.temptoname = '';
},
setWishes : function(content,isTemp){
if (isTemp){
_globalData.tempwishes = content;
}else{
_globalData.wishes = content;
}
},
getWishes : function(isTemp){
if (isTemp){
return _globalData.tempwishes;
}
return _globalData.wishes;
},
clearWishes: function(isTemp){
if (isTemp){
_globalData.tempwishes = '';
}else{
_globalData.wishes = '';
}
}
})
login.php代码
<?php namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\DB; class Login extends Controller { // private function isLogin($utoken){ $str = api_decode($utoken); $userauth = explode('|',$str); return $userauth[0]; } public function doLogin(Request $request){ $returnData['msg'] = ''; $returnData['status'] = 0; $returnData['data'] = []; $appid = $request->input('appid','wxc80b043c76106d6f'); $secret =$request->input('secret','3297d7fc08408df43c0f8fcc243fdf27'); $data = $request->all(); if(!isset($data['code'])){ dd('code非法'); } $code = $data['code']; $data['userInfo'] = json_decode($data['userInfo'],true); //以code换取 openid $url='https://api.weixin.qq.com/sns/jscode2session?appid='.$appid.'&secret='.$secret.'&js_code='.$code.'&grant_type=authorization_code'; $weixin = file_get_contents($url); $weixin = json_decode($weixin,true); if(!$weixin){ dd('获取openid失败'); } $userInfo = DB::table('user')->where('openid',$weixin['openid'])->first(); $openid = ''; if($userInfo){ $SaveData['nickName']= $data['userInfo']['nickName']; $SaveData['avatarUrl']= $data['userInfo']['avatarUrl']; $SaveData['appid'] = $appid ; $SaveData['update_at'] = time(); DB::table('user')->where('openid',$weixin['openid'])->update($SaveData); $openid = $userInfo->openid; $auth =[ 'id' => $userInfo->id, 'openid'=>$openid , 'last_login_at' => $userInfo->last_login_at ]; }else{ $data['userInfo']['appid'] = $appid ; $data['userInfo']['openid'] = $weixin['openid']; $data['userInfo']['session_key'] = $weixin['session_key']; $data['userInfo']['create_at'] = $data['userInfo']['update_at'] = $data['userInfo']['last_login_at'] =time(); $id = DB::table('user')->insertGetId($data['userInfo']); $openid = $weixin['openid']; $auth =[ 'id' => $id, 'openid'=> $openid, 'last_login_at' => $data['userInfo']['last_login_at'] ]; } $returnData['status'] = 1; $returnData['msg'] = '登录成功'; $token = api_encode(implode('|', $auth)); $returnData['utoken'] = $token; $returnData['openid'] = $openid; $returnData['csrf_token'] = csrf_token(); return $returnData; } public function detail(Request $request){ $utoken = $request->input('utoken'); $uid = $this->isLogin($utoken); return $uid; } }
,