Blogger Information
Blog 62
fans 7
comment 2
visits 58227
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
laravel 商城支付宝支付对接
我是郭富城
Original
1557 people have browsed it

1. 功能演示

http://pay.aoebbs.cn/shop/detail?proid=1

2. 支付宝官方设置

2.1 开通对应的支付功能

2.2 获取支付宝公钥和商户私钥

https://openhome.alipay.com/dev/workspace/key-manage

3. 商城控制器源码

  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Support\Facades\DB;
  5. use Illuminate\Support\Facades\Auth;
  6. class Shop extends Controller
  7. {
  8. //商城首页
  9. public function index() {
  10. $member = Auth::guard('member')->user();
  11. $data['member'] = $member;
  12. $data['lists'] = DB::table('product')->where('status',1)->lists();
  13. return view('shop/index',$data);
  14. }
  15. // 商城列表页
  16. public function lists() {
  17. return view('shop/lists');
  18. }
  19. // 商城详情页
  20. public function detail(Request $request) {
  21. $member = Auth::guard('member')->user();
  22. // echo '<pre>';
  23. // var_dump($member);
  24. // exit();
  25. $proid=(int)$request->proid;
  26. $data['item'] = DB::table('product')->where('id',$proid)->item();
  27. $data['detail'] = DB::table('product_detail')->where('proid',$proid)->item();
  28. $data['member'] = $member;
  29. if(!$data['item']) {
  30. return view('shop/page404');
  31. }
  32. return view('shop/detail',$data);
  33. }
  34. // 用户下单(微信下单)
  35. public function create_order(Request $request) {
  36. $member = Auth::guard('member')->user();
  37. $pro_id = (int)$request->pro_id;
  38. $product = DB::table('product')->where('id',$pro_id)->where('status',1)->item();
  39. if (!$product) {
  40. exit(json_encode(['code'=>1,'msg'=>'该商品不存在或未上架']));
  41. }
  42. if ($product['stock'] <= 0) {
  43. exit(json_encode(['code'=>1,'msg'=>'库存不足']));
  44. }
  45. if ($product['stock'] < (int)$request->buy_count) {
  46. exit(json_encode(['code'=>1,'msg'=>'库存不足']));
  47. }
  48. // 确定用户是否已经登录,自定义登录验证中间件
  49. $data['ord_no'] = time().$member->id.rand(1,555); //订单号
  50. $data['member_id'] = (int)$member->id; //交易商品id
  51. $data['pro_id'] = $pro_id; //交易商品id
  52. $data['count'] = (int)$request->buy_count; //数量
  53. $data['money'] = $request->buy_count * $product['price']; //金额
  54. $data['add_time'] = time(); //交易时间
  55. // 添加订单信息
  56. DB::table('orders')->insert($data);
  57. // 减库存
  58. DB::table('product')->where('id',$pro_id)->decrement('stock',$request->buy_count);
  59. exit(json_encode(['code'=>0,'msg'=>'下单成功','ord_no'=>$data['ord_no']]));
  60. }
  61. // 支付(支付宝支付)
  62. public function alipay(Request $request) {
  63. $alipay_path = __DIR__ . '/../../../vendor/alipay/';
  64. require_once $alipay_path.'config.php';
  65. require_once $alipay_path.'pagepay/service/AlipayTradeService.php';
  66. require_once $alipay_path.'pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';
  67. $ord_no = $request->ord_no;
  68. //商户订单号,商户网站订单系统中唯一订单号,必填
  69. $out_trade_no = $ord_no;
  70. //订单名称,必填
  71. $subject = '支付宝测试商品名称';
  72. //付款金额,必填
  73. $total_amount = '1';
  74. //商品描述,可空
  75. $body = '测试商品描述';
  76. //构造参数
  77. $payRequestBuilder = new \AlipayTradePagePayContentBuilder();
  78. $payRequestBuilder->setBody($body);
  79. $payRequestBuilder->setSubject($subject);
  80. $payRequestBuilder->setTotalAmount($total_amount);
  81. $payRequestBuilder->setOutTradeNo($out_trade_no);
  82. $aop = new \AlipayTradeService($config);
  83. /**
  84. * pagePay 电脑网站支付请求
  85. * @param $builder 业务参数,使用buildmodel中的对象生成。
  86. * @param $return_url 同步跳转地址,公网可以访问
  87. * @param $notify_url 异步通知地址,公网可以访问
  88. * @return $response 支付宝返回的信息
  89. */
  90. $response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
  91. //输出表单
  92. var_dump($response);
  93. }
  94. // 支付(微信支付)
  95. public function pay(Request $request) {
  96. // 生成二维码
  97. // echo __DIR__;
  98. // D:\laravel\app\Http\Controllers
  99. // exit;
  100. $wx_pay_path = __DIR__ . '/../../../vendor/wx_pay/';
  101. require_once $wx_pay_path . "lib/WxPay.Api.php";
  102. require_once $wx_pay_path . "example/WxPay.NativePay.php";
  103. // require_once 'log.php';
  104. $notify = new \NativePay();
  105. $input = new \WxPayUnifiedOrder();
  106. // 获取订单号
  107. $ord_no = $request->ord_no;
  108. $input->SetBody("test");
  109. $input->SetAttach("test");
  110. $input->SetOut_trade_no($ord_no);
  111. $input->SetTotal_fee("1");
  112. $input->SetTime_start(date("YmdHis"));
  113. $input->SetTime_expire(date("YmdHis", time() + 600));
  114. $input->SetGoods_tag("test");
  115. $input->SetNotify_url("http://pay.aoebbs.cn/shop/notify");
  116. $input->SetTrade_type("NATIVE");
  117. $input->SetProduct_id("123456789");
  118. $result = $notify->GetPayUrl($input);
  119. $data['url2'] = $result["code_url"];
  120. $data['ord_no'] = $ord_no;
  121. // echo '<pre>';
  122. // var_dump($result);
  123. return view('shop/pay',$data);
  124. }
  125. public function creatqrcode() {
  126. $wx_pay_path = __DIR__ . '/../../../vendor/wx_pay/';
  127. require_once $wx_pay_path . 'example/phpqrcode/phpqrcode.php';
  128. $url = urldecode($_GET["data"]);
  129. if(substr($url, 0, 6) == "weixin"){
  130. \QRcode::png($url);
  131. }else{
  132. header('HTTP/1.1 404 Not Found');
  133. }
  134. }
  135. // 异步通知
  136. public function notify() {
  137. // $xml = "aaaa";
  138. $xml = file_get_contents('php://input');
  139. $obj = simplexml_load_string($xml,"SimpleXMLElement", LIBXML_NOCDATA);
  140. $arr = json_decode(json_encode($obj),true);
  141. // 检查订单是否已付款
  142. $order = DB::table('orders')->where('ord_no',$arr['out_trade_no'])->item();
  143. if (!$order) {
  144. return '<xml>
  145. <return_code><![CDATA[SUCCESS]]></return_code>
  146. <return_msg><![CDATA[OK]]></return_msg>
  147. </xml>';
  148. }
  149. // 订单已经付款
  150. if ($order['status'] === 1) {
  151. return '<xml>
  152. <return_code><![CDATA[SUCCESS]]></return_code>
  153. <return_msg><![CDATA[OK]]></return_msg>
  154. </xml>';
  155. }
  156. // 订单未付款
  157. if ($order['status'] === 0) {
  158. // 设置订单支付状态为已支付
  159. DB::table('orders')->where('ord_no',$arr['out_trade_no'])->update(['status'=>1]);
  160. DB::table('orders')->where('ord_no',$arr['out_trade_no'])->update(['trance_id'=>$arr['transaction_id']]);
  161. return '<xml>
  162. <return_code><![CDATA[SUCCESS]]></return_code>
  163. <return_msg><![CDATA[OK]]></return_msg>
  164. </xml>';
  165. }
  166. file_put_contents('xml.txt', $xml);
  167. }
  168. // 支付宝异步通知
  169. public function alipay_notify() {
  170. $trade_no = $_POST['trade_no']; //支付宝交易号
  171. $out_trade_no = $_POST['out_trade_no']; //商户订单号
  172. $TRADE_SUCCESS = isset($_POST['TRADE_SUCCESS'])?$_POST['TRADE_SUCCESS']:'';
  173. // 检查订单是否已付款
  174. $order = DB::table('orders')->where('ord_no',$out_trade_no)->item();
  175. if (!$order) {
  176. return 'success';
  177. }
  178. // 订单已经付款
  179. if ($order['status'] === 1) {
  180. return 'success';
  181. }
  182. // 订单未付款
  183. if ($order['status'] === 0) {
  184. // 设置订单支付状态为已支付
  185. DB::table('orders')->where('ord_no',$out_trade_no)->update(['status'=>1]);
  186. DB::table('orders')->where('ord_no',$out_trade_no)->update(['trance_id'=>$trade_no]);
  187. return 'success';
  188. }
  189. }
  190. // 检查订单支付状态
  191. public function check_order_status(Request $request) {
  192. $ord_no = $request->ord_no;
  193. $order = DB::table('orders')->where('ord_no',$ord_no)->item();
  194. if ($order['status'] >= 1) {
  195. # code...
  196. exit(json_encode(['code'=>0,'msg'=>'支付成功']));
  197. }
  198. exit(json_encode(['code'=>1,'msg'=>'not pay']));
  199. }
  200. // 选择支付方式
  201. public function selectpay(Request $request) {
  202. $data['ord_no'] = $request->ord_no;
  203. return view('shop/selectpay',$data);
  204. }
  205. }

4. 商城路由

  1. // 商城
  2. Route::get('/shop/index','Shop@index');//商城首页
  3. Route::get('/shop/lists','Shop@lists');//商城列表
  4. Route::get('/shop/detail','Shop@detail');//商品详情
  5. Route::post('/shop/create_order','Shop@create_order')->middleware('automember');//商城订单
  6. Route::get('/shop/pay','Shop@pay')->middleware('automember');//商品微信付款二维码
  7. Route::get('/shop/creatqrcode','Shop@creatqrcode');//生成二维码
  8. Route::post('/shop/notify','Shop@notify');//微信异步通知
  9. Route::get('/shop/check_order_status','Shop@check_order_status');//检查订单支付状态
  10. Route::get('/shop/alipay','Shop@alipay')->middleware('automember');//支付宝支付
  11. Route::post('/shop/alipay_notify','Shop@alipay_notify');//支付宝异步通知
  12. Route::get('/shop/selectpay','Shop@selectpay')->middleware('automember');//选择支付方式

5. 商城详情页

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <!-- 当前文档要用到阿里字体图标-->
  6. <link rel="stylesheet" href="/static/font/iconfont.css">
  7. <link rel="stylesheet" href="/static/css/shop_detail.css">
  8. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  9. <script src="/static/plugins/layui/layui.js"></script>
  10. <title>{{$item['title']}}</title>
  11. </head>
  12. <body>
  13. @include('shop/public/header')
  14. <!--主体全部放在main元素中-->
  15. <main>
  16. <!-- 商城公共头部-->
  17. @include('shop/public/header_search')
  18. <!--为商品详情区块单独创建一个包含块,方便用网格布局-->
  19. <div class="detail">
  20. @csrf
  21. <!--商城详情页上部购买组件-->
  22. <div class="shop-detail-bug">
  23. <!--头部面包屑导航-->
  24. <nav>
  25. <a href="">首页&nbsp;&gt;&nbsp;</a>
  26. <a href="">图片写真&nbsp;&gt;&nbsp;</a>
  27. <a href="">日本&nbsp;&gt;&nbsp;</a>
  28. <a href="">颖宝宝</a>
  29. </nav>
  30. <article>
  31. <input type="hidden" name="pro_id" value="{{$item['id']}}">
  32. <!-- <input type="hidden" name="price" value="{{$item['price']}}"> -->
  33. <span><img src="{{$item['thumb']}}" alt=""></span>
  34. <div>
  35. <!--商品标题-->
  36. <h3>{{$item['title']}}</h3>
  37. <!--商品价格-->
  38. <div class="price">
  39. <span>本站特惠:</span>
  40. <span>&yen;{{$item['price']}}</span>
  41. </div>
  42. <!--基本描述-->
  43. <div class="desc">
  44. 销量: <span>13</span>&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
  45. 累积评价: <span>3</span>&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
  46. 好评率: <span>199%</span>
  47. </div>
  48. <!-- 购买数量-->
  49. <div class="buy-num">
  50. <label for="num">购买数量:</label><input type="number" id="num" value="1">
  51. </div>
  52. <!--购买按钮-->
  53. <div class="buy-btn">
  54. <button onclick="buy()">立即购买</button>
  55. <button><i class="iconfont icon-icon_tianjia"></i>加入购物车</button>
  56. </div>
  57. <!--售后承诺-->
  58. <div class="promise">
  59. <span><i class="iconfont icon-zhanghaoquanxianguanli"></i>本站保障</span>
  60. <span><i class="iconfont icon-icon_safety"></i>企业认证</span>
  61. <span><i class="iconfont icon-tianshenpi"></i>退款承诺</span>
  62. <span><i class="iconfont icon-kuaisubianpai"></i>免费换货</span>
  63. </div>
  64. </div>
  65. </article>
  66. </div>
  67. <!--商城详情页左下推荐商品列表-->
  68. <div class="shop-detail-recommend">
  69. <h3>推荐商品</h3>
  70. <div>
  71. <a href="">
  72. <img src="/static/images/shop/shop1.jpg" alt="">
  73. </a>
  74. <a href="">韩国美女最新海报促销美妆写真图集</a>
  75. <div class="hot">
  76. <span>热销:</span><span>8976</span>
  77. <span>价格:</span><span>&yen;99</span>
  78. </div>
  79. </div>
  80. <div>
  81. <a href="">
  82. <img src="/static/images/shop/shop2.jpg" alt="">
  83. </a>
  84. <a href="">韩国美女最新海报促销美妆写真图集</a>
  85. <div class="hot">
  86. <span>热销:</span><span>324</span>
  87. <span>价格:</span><span>&yen;798</span>
  88. </div>
  89. </div>
  90. <div>
  91. <a href="">
  92. <img src="/static/images/shop/shop3.jpg" alt="">
  93. </a>
  94. <a href="">韩国美女最新海报促销美妆写真图集</a>
  95. <div class="hot">
  96. <span>热销:</span><span>678</span>
  97. <span>价格:</span><span>&yen;630</span>
  98. </div>
  99. </div>
  100. <div>
  101. <a href="">
  102. <img src="/static/images/shop/shop4.jpg" alt="">
  103. </a>
  104. <a href="">韩国美女最新海报促销美妆写真图集</a>
  105. <div class="hot">
  106. <span>热销:</span><span>12</span>
  107. <span>价格:</span><span>&yen;980</span>
  108. </div>
  109. </div>
  110. </div>
  111. <!--商城详情页右下详情选项卡-->
  112. <div class="shop-detail-tab">
  113. <div class="tab">
  114. <span class="active">商品详情</span>
  115. <span>案例/演示</span>
  116. <span>常见问题</span>
  117. <span>累计评价</span>
  118. <span>产品咨询</span>
  119. </div>
  120. <div class="content">
  121. {!!$detail['contents']!!}
  122. </div>
  123. </div>
  124. <!--评论与回复-->
  125. <div class="public-comment-reply">
  126. <!-- 评论区-->
  127. <div class="comment">
  128. <h3>我要评论</h3>
  129. <div>
  130. <label for="comment"><img src="/static/images/user.png" alt=""></label>
  131. <textarea name="" id="comment"></textarea>
  132. </div>
  133. <button>发表评论</button>
  134. </div>
  135. <!-- 回复区-->
  136. <div class="reply">
  137. <h3>最新回复</h3>
  138. <div>
  139. <img src="/static/images/user.png" alt="">
  140. <div class="detail">
  141. <span>用户昵称</span>
  142. <span>留言内容: php中文网,是一个有温度,有思想的学习平台</span>
  143. <div>
  144. <span>2019-12-12 15:34:23发表</span>
  145. <span><i class="iconfont icon-dianzan"></i>回复</span>
  146. </div>
  147. </div>
  148. </div>
  149. <div>
  150. <img src="/static/images/user.png" alt="">
  151. <div class="detail">
  152. <span>用户昵称</span>
  153. <span>留言内容: php中文网,是一个有温度,有思想的学习平台</span>
  154. <div>
  155. <span>2019-12-12 15:34:23发表</span>
  156. <span><i class="iconfont icon-dianzan"></i>回复</span>
  157. </div>
  158. </div>
  159. </div>
  160. <div>
  161. <img src="/static/images/user.png" alt="">
  162. <div class="detail">
  163. <span>用户昵称</span>
  164. <span>留言内容: php中文网,是一个有温度,有思想的学习平台</span>
  165. <div>
  166. <span>2019-12-12 15:34:23发表</span>
  167. <span><i class="iconfont icon-dianzan"></i>回复</span>
  168. </div>
  169. </div>
  170. </div>
  171. <div>
  172. <img src="/static/images/user.png" alt="">
  173. <div class="detail">
  174. <span>用户昵称</span>
  175. <span>留言内容: php中文网,是一个有温度,有思想的学习平台</span>
  176. <div>
  177. <span>2019-12-12 15:34:23发表</span>
  178. <span><i class="iconfont icon-dianzan"></i>回复</span>
  179. </div>
  180. </div>
  181. </div>
  182. </div>
  183. </div>
  184. </div>
  185. </main>
  186. <!--公共页脚-->
  187. @include('shop/public/footer')
  188. </body>
  189. </html>
  190. <script>
  191. layui.use('layer', function(){
  192. $ = layui.jquery;
  193. var layer = layui.layer;
  194. });
  195. // 购买
  196. function buy() {
  197. var pro_id = parseInt($('input[name="pro_id"]').val());
  198. var buy_count = parseInt($('#num').val());
  199. if (isNaN(pro_id) || pro_id === 0) {
  200. return layer.alert('商品参数错误',{icon:2});
  201. }
  202. if (isNaN(buy_count) || buy_count === 0) {
  203. return layer.alert('购买数量错误',{icon:2});
  204. }
  205. // 下订单
  206. var _token = $('input[name="_token"]').val();
  207. // var price = $('input[name="price"]').val();
  208. $.post('/shop/create_order',{pro_id:pro_id,_token:_token,buy_count:buy_count},function (res) {
  209. // 未登录
  210. if (res.code === 401) {
  211. //iframe层
  212. layer.open({
  213. type: 2,
  214. title: '用户登录',
  215. shadeClose: true,
  216. shade: 0.8,
  217. area: ['400px', '300px'],
  218. content: '/account/login' //iframe的url
  219. });
  220. return;
  221. }
  222. if (res.code > 0) {
  223. return layer.alert(res.msg,{icon:2});
  224. }
  225. // 选择何种支付方式
  226. layer.open({
  227. type: 2,
  228. title: '选择付款方式',
  229. shadeClose: true,
  230. shade: 0.2,
  231. area: ['400px', '300px'],
  232. content: '/shop/selectpay?ord_no='+ res.ord_no //iframe的url
  233. });
  234. // 跳转到支付宝
  235. // window.location.href="/shop/alipay?ord_no=" + res.ord_no;
  236. // 下面是微信的哦
  237. // layer.msg(res.msg);
  238. // layer.open({
  239. // type: 2,
  240. // title: '付款二维码',
  241. // shadeClose: true,
  242. // shade: 0.2,
  243. // area: ['400px', '300px'],
  244. // content: '/shop/pay?ord_no='+res.ord_no //iframe的url
  245. // });
  246. },'json');
  247. }
  248. </script>

6. 付款方式选择页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <link rel="stylesheet" href="/static/plugins/layui/css/layui.css">
  6. <script src="/static/plugins/layui/layui.js"></script>
  7. <title>支付方式选择</title>
  8. <style>
  9. body {
  10. height: 80vh;
  11. display: flex;
  12. flex-flow: row nowrap;
  13. justify-content: center;
  14. align-items: center;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <button type="button" class="layui-btn" onclick="wxpay()">微信支付</button>
  20. <button type="button" class="layui-btn layui-btn-normal" onclick="alipay()">支付宝支付</button>
  21. </body>
  22. </html>
  23. <script>
  24. // 微信支付
  25. function wxpay() {
  26. window.location.href="/shop/pay?ord_no=" + {{$ord_no}};
  27. }
  28. // <!-- 支付宝支付 -->
  29. function alipay() {
  30. window.open("/shop/alipay?ord_no=" + {{$ord_no}});
  31. }
  32. </script>

7. 效果图

8. 修改冲突

  1. Cannot redeclare Encrypt() (previously declared in .../vendor/laravel/lumen-framework/src/helpers.php:126)
  2. //或:
  3. Cannot redeclare Decrypt() (previously declared in .../vendor/laravel/lumen-framework/src/helpers.php:126)

这是因为Laravel 5使用Alipay SDK时,Laravel内带的加密解密函数Encrypt()/Decrypt()函数和Alipay SDK中的加密解密函数Encrypt()/Decrypt()函数命名冲突

解决方法:只需修改Alipay SDK中定义的函数名称,修改引用的函数名称。

9. 总结

虽然官方的说明已经够详细了,但是真正入手去做还是有很多坑,此次对接过程中学习很多,其中尤其要注意的是因为官方的关系。

Correcting teacher:GuanhuiGuanhui

Correction status:qualified

Teacher's comments:Javascript代码不要写在html标签外,尽量写在body标签底部。
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post