作者 lihan
1 个管道 的构建 通过 耗费 0 秒

微信接入自动部署

# 定义 stages
stages:
- pull
# 定义 job
job1:
stage: pull
script:
- cd /alidata/www/w/sami
- git pull
\ No newline at end of file
... ...
... ... @@ -157,8 +157,13 @@ class OrderController extends HomeBaseController
//首次下单状态改变
Db::name('user')->update(['id' => session('user.id'), 'is_first' => 0]);
if ($data['payment'] == 1) {
echo json_encode(['msg' => '微信支付']);
exit();
$info = [
'attach' => $oid,
'openid' => session('openid'),
'body' => '萨米户外',
'total_fee' => $final_price
];
$this->success('微信支付', url('user/Center/orderDetail', ['oid' => $oid]), $this->wxPay($info));
} elseif ($data['payment'] == 2) {
} elseif ($data['payment'] == 0) {
... ... @@ -214,7 +219,7 @@ class OrderController extends HomeBaseController
echo json_encode(['msg' => '未知错误', 'code' => 40000]);
exit();
}
//再次支付的支付方式
//再次支付的支付方式,先更新支付方式
$payment = $request->param('payment');
Db::name('order_info')->update(['id' => $oid, 'payment' => $payment]);
if ($payment == 0) {
... ... @@ -222,7 +227,7 @@ class OrderController extends HomeBaseController
if ($model->orderCallBack($oid, $order_amount)) {
//如果是有定金订单,则需要更新order_log
if ($info['order_type'] == 1) {
Db::name('order_log')->where(['oid' => $oid])->update(['type' => 0, 'order_amount' => $order_amount]);
Db::name('order_log')->where(['oid' => $oid])->update(['order_amount' => $order_amount]);
}
echo json_encode(['msg' => '支付成功', 'code' => 20000]);
exit();
... ... @@ -231,9 +236,15 @@ class OrderController extends HomeBaseController
exit();
}
} elseif ($payment == 1) {
$data = [
'attach' => $oid,
'openid' => session('openid'),
'body' => '萨米户外',
'total_fee' => $order_amount
];
$this->success('微信支付', url('user/Center/orderDetail', ['oid' => $oid]), $this->wxPay($data));
} elseif ($payment == 2) {
echo json_encode(['msg' => '支付宝支付', 'code' => 20000]);
} else {
echo json_encode(['msg' => '未知错误', 'code' => 40000]);
exit();
... ... @@ -290,7 +301,7 @@ class OrderController extends HomeBaseController
*/
private function checkOrder($scheduleId, $payment = 0, $escort, $num, $finalPrice)
{
if($scheduleId == null) {
if ($scheduleId == null) {
echo json_encode(['msg' => '请选择活动批次', 'code' => 40000]);
exit();
}
... ... @@ -317,4 +328,12 @@ class OrderController extends HomeBaseController
}
}
//微信支付
private function wxPay($info)
{
require_once EXTEND_PATH . '/Payment.php';
$pay = new \Payment($info['oid'], session('openid'), $info['body'], $info['total_fee']);
$pay->pay();
}
}
\ No newline at end of file
... ...
... ... @@ -51,7 +51,7 @@ class OrderModel extends Model
Db::startTrans();
$go = 'rollback';
if ($orderInfo['payment'] == 0) {
$amount = ($order_amount == null) ? $order_amount['order_amount'] : $order_amount;
$amount = ($order_amount == null) ? $orderInfo['order_amount'] : $order_amount;
if (Db::name('user')->where(['id' => $orderInfo['user_id']])->setDec('balance', $amount)) {
$wallet = [
'user_id' => $orderInfo['user_id'],
... ...
... ... @@ -22,6 +22,43 @@ class IndexController extends HomeBaseController
function _initialize()
{
parent::_initialize(); // TODO: Change the autogenerated stub
if (cmf_is_wechat()) {
if (empty(session('user.id'))) {
require_once EXTEND_PATH . '/WeChatCommon.php';
$wx = new \WeChatCommon();
if (request()->param('code') == NULL) {
$wx->code();
} else {
$code = request()->param('code');
$info = $wx->getOpenid($code);
if(Db::name('user')->where(['openid'=>$info['openid']])->count() == 0) {
//注册新用户
//拉去用户信息
$return = $wx->getUserInfo($info);
$data = [
'user_type' => 2,
'create_time' => time(),
'user_nickname' => $return['nickname'],
'sex' => $return['sex'],
'avatar' => $return['headimgurl'],
'openid' => $info['openid']
];
if(Db::name('user')->insert($data)) {
$userId = Db::name('user')->getLastInsID();
session('user.id', $userId);
session('user.openid', $info['openid']);
}
}else {
$userId = Db::name('user')->where(['openid'=>$info['openid']])->value('id');
session('user.id', $userId);
session('user.openid', $info['openid']);
}
}
}
}else {
$this->error('请从微信浏览器打开');
}
session('user.id', 2);
}
... ...
... ... @@ -262,7 +262,7 @@
</div>
</div>
<div>
<i class='iconfont icon-xuanzhong2'></i>
<i class='iconfont icon-xuanzhong2' data-var="0"></i>
</div>
</div>
<div class="shang1 shan1">
... ... @@ -276,7 +276,7 @@
</div>
</div>
<div>
<i class='iconfont'></i>
<i class='iconfont' data-var="1"></i>
</div>
</div>
<div class="shang1 shan1">
... ... @@ -290,7 +290,7 @@
</div>
</div>
<div>
<i class='iconfont'></i>
<i class='iconfont' data-var="2"></i>
</div>
</div>
<div class="agreepay">
... ... @@ -758,7 +758,7 @@
schedule_id:schedule_id,
num:$("#quantity").html(),
escort:escort_id,
payment:1,
payment:$(".icon-xuanzhong2").attr('data-var'),
discount_coupon_id:money_id,
desc:$('.dian_text').val(),
room:$('.xuandan').html()
... ...
... ... @@ -136,7 +136,7 @@
</div>
</div>
<div>
<i class='iconfont icon-xuanzhong2'></i>
<i class='iconfont icon-xuanzhong2' data-var="0"></i>
</div>
</div>
<div class="shang1 shan1">
... ... @@ -150,7 +150,7 @@
</div>
</div>
<div>
<i class='iconfont'></i>
<i class='iconfont' data-var="1"></i>
</div>
</div>
<div class="shang1 shan1">
... ... @@ -164,7 +164,7 @@
</div>
</div>
<div>
<i class='iconfont'></i>
<i class='iconfont' data-var="2"></i>
</div>
</div>
... ... @@ -293,7 +293,7 @@
url:"{:url('order/Order/done2')}",
data:{
oid:'{$data.baseInfo.oid}',
payment:0
payment:$(".icon-xuanzhong2").attr('data-var')
},
type:"POST",
dataType:"JSON",
... ...
<?php
class Payment {
protected $attach;
protected $openid;
protected $body;
protected $total_fee;
function __construct($attach=null, $openid=null, $body=null, $total_fee=null) {
$this->attach = $attach;
$this->openid = $openid;
$this->body = $body;
$this->total_fee = $total_fee;
}
/**
* 对外暴露的支付接口
* @return array
*/
public function pay() {
return $this->weixinPay();
}
private function weixinPay() {
//统一下单接口
$unifiedorder = $this->unifiedorder();
$parameters = array(
'appId' => config('AppID'),
'timeStamp' => '' . time() . '', //时间戳
'nonceStr' => $this->createNoncestr(), //随机串
'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //数据包
'signType' => 'MD5'//签名方式
);
//签名
$parameters['paySign'] = $this->getSign($parameters);
return $parameters;
}
//统一下单接口
private function unifiedorder() {
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$parameters = array(
'appid' => config('AppID'),
'mch_id' => config('MchId'),
'nonce_str' => $this->createNoncestr(),
'body' => $this->body,
'out_trade_no' => config('MchId').time(),
'total_fee' => $this->total_fee,
'spbill_create_ip' => '114.215.223.17', //终端IP
'notify_url' => 'http://integral.w.bronet.cn/pay/Pay/notify',
'openid' => $this->openid,
'trade_type' => 'JSAPI',//交易类型
'attach' => $this->attach
);
//统一下单签名
$parameters['sign'] = $this->getSign($parameters);
$xmlData = $this->arrayToXml($parameters);
$return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60));
return $return;
}
//作用:生成签名
private function getSign($Obj) {
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//签名步骤二:在string后加入KEY
$String = $String . "&key=" . config('Key');
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
private static function postXmlCurl($xml, $url, $second = 30) {
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
//运行curl
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出错,错误码:$error");
}
}
//数组转换成xml
private function arrayToXml($arr) {
$xml = "<root>";
foreach ($arr as $key => $val) {
if (is_array($val)) {
$xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
} else {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
}
}
$xml .= "</root>";
return $xml;
}
//xml转换成数组
private function xmlToArray($xml) {
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring), true);
return $val;
}
//作用:产生随机字符串,不长于32位
private 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;
}
///作用:格式化参数,签名过程需要使用
private function formatBizQueryParaMap($paraMap, $urlencode) {
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
$reqPar='';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
public function handleNotify() {
//$postXml = $GLOBALS["HTTP_RAW_POST_DATA"]; //接收微信参数
$postXml=file_get_contents("php://input");
cache('xml', $postXml);
if (empty($postXml)) {
return false;
}else {
$data = $this->xmlToArray($postXml);
if($data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS') {
$data = (array)simplexml_load_string($postXml, 'SimpleXMLElement', LIBXML_NOCDATA);
$signA = "appid=".$data['appid']."&attach=".$data['attach']."&bank_type=".$data['bank_type']."&cash_fee=".$data['cash_fee']."&fee_type=".$data['fee_type']."&is_subscribe=".$data['is_subscribe']."&mch_id=".$data['mch_id']."&nonce_str=".$data['nonce_str']."&openid=". $data['openid']."&out_trade_no=".$data['out_trade_no']."&result_code=".$data['result_code']."&return_code=".$data['return_code']."&time_end=".$data['time_end']."&total_fee=".$data['total_fee']."&trade_type=".$data['trade_type']."&transaction_id=".$data['transaction_id']."&key=".config('Key');
$sign = strtoupper(MD5($signA));
if($sign == $data['sign']) {
return $data;
}else {
return false;
}
}else {
return false;
}
}
}
}
\ No newline at end of file
... ...
<?php
class WeChatCommon
{
/**
* 判断是否已关注公众号
*/
public function isAuth()
{
$access_token = $this->getAccessToken();
$subscribe_msg = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $access_token . "&openid=" . session('openid');
$subscribe = json_decode(file_get_contents($subscribe_msg));
$gzxx = $subscribe->subscribe;
if ($gzxx === 1) {
return true;
} else {
return false;
}
}
/**
* 获取code
*/
public function code()
{
$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . config('AppID') . "&redirect_uri=http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
header('location:' . $url);
}
/**
* 获取openid
* @param $code
* @return mixed
*/
public function getOpenid($code)
{
$get_token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . config('AppID') . '&secret=' . config('AppSecret') . '&code=' . $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $get_token_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$res = curl_exec($ch);
curl_close($ch);
$json_obj = json_decode($res, true);
return $json_obj;
}
/**
* 获取access_token,全局缓存7200s
* @return mixed
*/
public function getAccessToken()
{
$data = cache('Vendor/access_token');
if (!empty($data) && ((time() - $data['time']) < 7000)) {
return $data['access_token'];
} else {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . config('AppID') . "&secret=" . config('AppSecret') . "";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$jsoninfo = json_decode($output, true);
$access_token = $jsoninfo["access_token"];
$time = time();
$data = array(
'access_token' => $access_token,
'time' => $time
);
cache('Vendor/access_token', $data);
return $access_token;
}
}
/**
* 获取用户信息(头像、昵称等)
* @return array
*/
public function getUserInfo($info)
{
$url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $info['access_token'] . '&openid=' . $info['openid'] . '&lang=zh_CN';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$jsoninfo = json_decode($output, true);
return $jsoninfo;
}
/**
* 下载网址内容,配合getUserInfo使用
* @param $url
* @param $filename
* @return mixed
*/
public function curl_file_get_contents($url, $filename)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);
curl_setopt($ch, CURLOPT_REFERER, _REFERER_);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$r = curl_exec($ch);
curl_close($ch);
file_put_contents('data/upload/headimg/' . $filename, $r);
return $filename;
}
/**
* 获取js-sdkp票据,全局缓存7200s
* @return mixed
*/
public function get_jsapi_ticket()
{
$ticket = cache('Vendor/ticket');
if (!empty($ticket) && ((time() - $ticket['time']) < 7000)) {
return $ticket['ticket'];
} else {
$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $this->getAccessToken() . '&type=jsapi';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$res = curl_exec($ch);
curl_close($ch);
$json_obj = json_decode($res, true);
$jsapi_ticket = $json_obj['ticket'];
$time = time();
$data = array(
'ticket' => $jsapi_ticket,
'time' => $time
);
cache('Vendor/ticket', $data);
return $jsapi_ticket;
}
}
/**
* JS_SDK
* @return array
*/
public function js_sdk()
{
$timestamp = time();
$string = 'jsapi_ticket=' . $this->get_jsapi_ticket() . '&noncestr=je9omv03bc5ryqz1&timestamp=' . $timestamp . '&url=' . 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$signature = sha1($string);
return array(
'appId' => config('AppId'),
'timestamp' => $timestamp,
'nonceStr' => 'je9omv03bc5ryqz1',
'signature' => $signature,
);
}
/**
* 创建菜单
* @return mixed|string
*/
public function creatMenu()
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" . $this->getAccessToken());
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->menuItem());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tmpInfo = curl_exec($ch);
if (curl_errno($ch)) {
return curl_error($ch);
}
curl_close($ch);
return $tmpInfo;
}
/**
* 菜单内容JSON
* @return string
*/
public function menuItem()
{
$data = '{
"button":[{
"type":"view",
"name":"登录/注册",
"url":"http://hospital.wx.bronet.cn/index.php/UserCenter/login"
}],
"button":[{
"type":"view",
"name":"医生预约",
"url":"http://hospital.wx.bronet.cn/index.php/DoctorAppointment/index"
}],
"button":[{
"type":"view",
"name":"个人中心",
"url":"http://hospital.wx.bronet.cn/index.php/UserCenter/index"
}]
}';
return $data;
}
/**
* 上传永久素材
*/
public function eternalMaterial()
{
$file_info = array('filename' => '/public/images/soul_of_cinder.png', //国片相对于网站根目录的路径
'content-type' => 'image/jpg/png', //文件类型
'filelength' => '71' //图文大小
);
$url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=" . $this->getAccessToken() . "&type=png";
$ch1 = curl_init();
$timeout = 5;
$real_path = "{$_SERVER['DOCUMENT_ROOT']}{$file_info['filename']}";
//$real_path=str_replace("/", "//", $real_path);
$data = array("media" => "@{$real_path}", 'form-data' => $file_info);
curl_setopt($ch1, CURLOPT_URL, $url);
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch1, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch1);
curl_close($ch1);
if (curl_errno() == 0) {
$result = json_decode($result, true);
var_dump($result);
return $result['media_id'];
} else {
return false;
}
}
}
\ No newline at end of file
... ...