后台:(只写接口)
商品列表:
public static function goodsList($goodsInfo){
try {
$page = $goodsInfo['page']?:1;
// $list_rows = $goodsInfo['list_rows']?:5;
$redis = Cache::store('redis');
$goodsList = $redis->get('goods-list-page-'.$page)?:null;
// 如果缓存内不为空就讲redis缓存数据返回前端
if (!empty($goodsList)){
return success(200,'商品列表',[
'goods'=>$goodsList,
]);
}
// 如果缓存没有 我们需要先获取 然后存入redis
$goodsList = \app\home\model\Goods::page($page,6)->select();
$redis->set('goods-list-page'.$page,$goodsList,3600);
return success(200,'成功',[
'goods'=>$goodsList,
]);
}catch (\Exception $exception){
return fail(2001,$exception->getMessage(),[]);
}
}
商品详情:
public static function goodsDetail($id){
try {
$goods = \app\home\model\Goods::find($id);
if ($goods['goods_status'] == 0){
throw new Exception('商品已售罄');
}
return success(200,'商品详情获取成功',[
'goods'=>$goods,
]);
}catch (\Exception $exception){
return fail(2001,$exception->getMessage(),[]);
}
}
创建订单:
public static function getOrder($data){
try {
$id = $data['id'];
$number = $data['number'];
$user_id = get_user_id();
if (connection_status() != 0){
throw new \Exception('网络中断,请检查网络');
}
if (!is_numeric($id)){
throw new \Exception('商品参数id不合法');
}
if (!is_numeric($number)){
throw new \Exception('商品参数购买数量不合法');
}
$goods = \app\home\model\Goods::find($id);
Db::startTrans();
$order_sn = 'pdd'.md5(time().uniqid(1000,9999));
Order::create([
'user_id'=>get_user_id(),
'order_sn'=> $order_sn,
'order_status'=>0,
'order_freight'=>0,
'order_consume'=>$number*$goods['goods_price'],
'create_time'=>time(),
]);
$order_id = Order::getLastInsID();
GoodsOrder::create([
'order_id'=>$order_id,
'goods_id'=>$id,
'goods_number'=>$number,
'goods_price'=>$goods['goods_price'],
'goods_consume'=>$number*$goods['goods_price'],
'create_time'=>time(),
]);
Db::commit();
return success(200,'下单成功',[
'order_sn'=> $order_sn,
'total'=>number_format($number*$goods['goods_price'],2),
]);
}catch (\Exception $exception){
Db::rollback();
return fail(2001,$exception->getMessage(),[]);
}
}
支付:
public static function pay($data){
try {
$order_sn = $data['order_sn'];
$order = Order::where('order_sn','=',$order_sn)->find();
if (empty($order)){
throw new \Exception('订单不存在,请重新下单');
}
if (time()- strtotime($order['create_time']) >= 900){
throw new \Exception('订单超时,请重新下单');
}
// 防止重复请求
$is_handle = \cache('order-id-'.$order['id'])?:0;
if ($is_handle == 1){
throw new \Exception('订单正在处理中');
}
// 第一次请求 存入缓存 避免重复支付
\cache('order-id-'.$order['id'],1);
// Cache::delete('order-id-'.$order['id']);
// 支付
$goodsOrder = GoodsOrder::where('order_id','=',$order['id'])->find();
$total = $goodsOrder['goods_number']*$goodsOrder['goods_price'];
require_once public_path().'/static/home/alipay/config.php';
require_once public_path().'/static/home/alipay/pagepay/service/AlipayTradeService.php';
require_once public_path().'/static/home/alipay/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';
$goods = \app\home\model\Goods::find($goodsOrder['goods_id']);
$body = substr_replace(mb_substr($goods['goods_name'],0,10),'...',30,5);
$subject = $order_sn;
$total_amount = $total;
$out_trade_no = $order_sn;
//构造参数
// $payRequestBuilder = new AlipayTradePagePayContentBuilder();
$payRequestBuilder = new \AlipayTradePagePayContentBuilder();
$payRequestBuilder->setBody($body);
$payRequestBuilder->setSubject($subject);
$payRequestBuilder->setTotalAmount($total_amount);
$payRequestBuilder->setOutTradeNo($out_trade_no);
$aop = new \AlipayTradeService($config);
/**
* pagePay 电脑网站支付请求
* @param $builder 业务参数,使用buildmodel中的对象生成。
* @param $return_url 同步跳转地址,公网可以访问
* @param $notify_url 异步通知地址,公网可以访问
* @return $response 支付宝返回的信息
*/
$response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
//输出表单
var_dump($response);
}catch (\Exception $exception){
return fail(2001,$exception->getMessage(),[]);
}
}
同步和异步回掉:
public static function aliSync($arr)
{
try {
require_once public_path() . '/static/home/alipay/pagepay/service/AlipayTradeService.php';
$config = config('account');
$alipaySevice = new \AlipayTradeService($config);
$result = $alipaySevice->check($arr);
//验证成功
if ($result) {
//商户订单号
$out_trade_no = htmlspecialchars($arr['out_trade_no']);
// 支付金额
$total_amount = $arr['total_amount'];
// 条件
$where = [
['order_sn', '=', $out_trade_no],
['order_consume', '=', $total_amount],
];
$order = Order::where($where)->select();
if (!$order) {
throw new Exception('支付失败');
}
return redirect('http://www.chaishao.com/month/pay_success.html');
}
}catch (\Exception $exception){
return redirect('http://www.chaishao.com/month/pay_fail.html');
}
}
public static function aliAsyn($arr){
try {
$out_trade_no = $arr['out_trade_no'];
$trade_status = $arr['trade_status'];
$order = Order::where('order_sn','=',$out_trade_no)->find();
if (!$order){
echo 'fail';
die();
}
if ($order['order_status'] == 1){
// 订单已经做过处理 防止重复提交
echo 'success';
die();
}
if ($trade_status == 'TRADE_SUCCESS'){
// 判断该笔订单是否再商户网站中做过处理
Db::startTrans();
Order::where('order_sn','=',$out_trade_no)->update([
'order_status'=>1,
'pay_time'=>time(),
]);
PayLog::create([
'order_sn'=>$out_trade_no,
'json'=>json_encode($arr),
'create_time'=>time(),
]);
Log::write(json_encode($arr));
Db::commit();
echo 'success';
die();
}else{
echo 'fail';
die();
}
}catch (\Exception $exception){
Db::rollback();
echo 'fail';
die();
}
}
订单列表和订单详情:
public static function orderList($data){
try {
$page = $data['page'];
if (empty($page)){
throw new \Exception('页码参数为空');
}
if (!is_numeric($page) || $page<=0){
throw new \Exception('页码参数不正确');
}
$where = [];
$where[] =['user_id','=',get_user_id()];
if (!array_key_exists('order_status',$data)){
throw new \Exception('订单状态参数缺少');
}
if ($data['order_status'] != 1 && $data['order_status'] != 0 && $data['order_status'] != ''){
throw new \Exception('订单状态参数错误');
}
if ($data['order_status'] || $data['order_status'] == 0){
$order_status = $data['order_status'];
$where[] = ['order_status','=',"$order_status"];
}
$redis = Cache::store('redis');
$order = $redis->get('order-list-page-'.$page.'-status-'.$data['order_status'])?:'';
if ($order){
return success(200,'列表获取成功',[
'order'=>json_decode($order),
]);
}
$order = \app\home\model\Order::where($where)->page($page,6)->select();
$orderList = json_encode($order);
$redis->set('order-list-page-'.$page.'-status-'.$data['order_status'],$orderList,3600);
return success(200,'订单列表获取成功',[
'order'=>$order,
]);
}catch (\Exception $exception){
return fail(2001,$exception->getMessage(),[]);
}
}
public static function orderDetail($data){
try {
$orderId = $data['id'];
if (!is_numeric($orderId)){
throw new \Exception('订单id参数不合法');
}
$order = \app\home\model\Order::with('goodsOrder')->find($orderId);
if (empty($order)){
throw new \Exception('订单不存在');
}
return success(200,'订单详情',[
'order_detail'=>$order,
]);
}catch (\Exception $exception){
return fail(2001,$exception->getMessage(),[]);
}
}
中间件验证签名和token以及时间戳:
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
* 中间件验证
*/
public function handle($request, \Closure $next)
{
try {
$this->checkTime();
$this->checkSign();
$this->checkToken();
// 验证全部通过 方行
return $next($request);
}catch (\Exception $exception){
return fail(2001,$exception->getMessage(),[]);
}
}
/**
* @throws \Exception
* 验证时间戳参数合法与否
* 以及请求时长是否超时
*/
public function checkTime(){
$client_time = request()->get('timestamp')?:request()->post('timestamp');
if (!is_numeric($client_time)){
throw new \Exception('时间格式不正确');
}
if (time()-$client_time > 60){
throw new \Exception('请求超时');
}
}
/**
* @throws \Exception
* 验证签名
*/
public function checkSign(){
$client_sign = request()->get('sign')?:request()->all('sign');
#判断是否有签名
if (!$client_sign){
throw new \Exception('签名不存在');
}
#判断签名是否正确
$server_sign = $this->getSign();
if ($server_sign != $client_sign){
throw new \Exception('签名不正确');
}
}
/**
* @return string
* 获取签名
*/
public function getSign(){
#获取所有参数
$params = request()->all();
#签名规则
#第一步 参与签名的参数不包括签名本身 不包括token
unset($params['token']);
unset($params['sign']);
#第二步 按照ASCLL排序
ksort($params);
$wait_sign = '';
foreach($params as $key => $value){
$wait_sign .= $key.'='.$value.'&';
}
$wait_sign = rtrim($wait_sign,'&');
return md5($wait_sign);
}
/**
* @throws Exception
* token验证
*/
public function checkToken(){
$token = JWTAuth::token();
if ($token == null){
throw new Exception('token不存在-请先登录');
}
$token = $token->get();
$payload = JWTAuth::auth();
$user_id = $payload['user_id']->getValue();
if (empty($user_id) || !is_numeric($user_id)){
throw new \Exception('用户id参数不合法-非法请求');
}
$delete_token = cache('delete_token')?:[];
if (in_array($token,$delete_token)){
throw new \Exception('token已失效,请重新登录');
}
}
支付时:如果报错 缺少记录日志的文件 则:
define("AOP_SDK_WORK_DIR", dirname(__FILE__)."/tmp/");