商城第九天
商城难点重点
- 构造数组结构(看业务场景,查看数据表现形式)
rbac获取所有的权限—》两个技巧
商品详情页单选属性—》通过attr_id分组
购物车列表 –》加两个下标 goodsInfo attrInfo
后台商品添加动态拼接商品类型属性–》动态属性入库(表单name拼接[])
完成订单数据入库
订单数据入库的顺序
订单商品入库的顺序:
第一步:先把订单基本数据入库到订单表sh_order
第二步:订单表数据入库成功之后才能把订单商品入库到订单商品表中sh_order_goods中
如果保证上面两步执行过程中都没有问题呢,这里需要借助到mysql的事务,可以保持数据的一致性。当发生异常的时候,会自动回滚。
注意:只有表的引擎是innodb引擎才支持事务操作。
TP5中有关事务操作的相关方法:
启动事务:Db::startTrans()
提交事务:Db::commit()
事务回滚:Db::rollback()
手册示例:
订单商品入库的顺序:
第一步:先把订单基本数据入库到订单表sh_order
第二步:订单表数据入库成功之后才能把订单商品入库到订单商品表中sh_order_goods中
如果保证上面两步执行过程中都没有问题呢,这里需要借助到mysql的事务,可以保持数据的一致性。当发生异常的时候,会自动回滚。
注意:只有表的引擎是innodb引擎才支持事务操作。
订单表(sh_order)和订单商品表(sh_order_goods)的关系:
TP5中有关事务操作的相关方法:
启动事务:Db::startTrans()
提交事务:Db::commit()
事务回滚:Db::rollback()
手册示例:
注:只要在try{}中抛出出一个异常throw new \Exception(‘失败信息’) ,就会执行catch中的回滚操作,$e->getMessage(失败信息);
订单表和订单商品表的数据入库
入库流程图:
- 在订单结算页面,设置好表单的name字段,或收货人的基本信息(收货地址、电话、邮编)
给提交按钮,绑定单击事件,让上面的表单进行提交:
注:表单跳转还是跳转到当前控制器方法,属于post方式提交(method=post)
- 在方法_writeOrder中,开启事务,保证订单商品入库成功
- 在try{}中进行订单表的数据入库,和订单商品表数据的入库
注:上面的代码需要引入Db类
同时建立订单表和订单商品表的模型:
二、支付技术介绍
1、早期网站支付
早期的电商都是送货上门,邮政汇款,这样的话,商家会承担很大的风险。
后面的时候有部分网站和银行进行签约,使用网银、手机银行等。
再往后,就是支付宝、微信。
早期的公司如果想申请网银需要直接去找银行申请相关的支付接口,而且现在银行这么多公司不可能去每家银行申请支付接口,这样未免也太麻烦了。
如果有的网站的资金流动比较少的话,有的银行都不会和这些小公司进行合作,因为从中赚不到什么利润。所以就有了第三方支付平台(微信、支付宝、京东钱包、qq财付通、百度钱包)来解决这些问题。
2、现在的网站支付
为了解决早期网站支付的问题,避免了商家繁琐的去每家银行获取支付接口。现在有些公司专门集合了所有银行的支付接口,这些公司进而在提供支付接口给我们企业或开发者使用,这些公司就是第三方支付平台。
常见的第三方支付平台:微信、支付宝、京东钱包、qq财付通、百度钱包等
有了这些第三方支付平台,我们企业或开发者就不需要独自跑去银行去申请支付接口了,直接利用第三方支付平台,在参考他们的支付接口文档即可完成我们的支付了!
三、支付宝支付
注意一点:现在的支付宝支付需要企业或个体工商户可申请才,个人是没法申请的。
企业或个体工商户申请的条件如下:
1. 提供真实有效的营业执照,且支付宝账户名称需与营业执照主体一致;
2. 网站能正常访问且页面信息有完整商品内容;
3. 网站必须通过ICP备案,个体户备案需与账户主体一致。
(团购类网站不支持个体工商户签约)
不过好处的个人开发者我们可以使用支付宝提供的沙箱环境进行模拟支付。
那么什么是沙箱环境?
答:就是支付宝提供给我们开发者一个虚拟的支付环境。其中的操作和真实支付环境是完全一样的。买家账号和卖家账号沙箱环境都给我们提供好了。
后面的沙箱环境支付,支付宝会提供一个商家账户和个人买家账户给我们,我们在配合支付接口文档即可完成支付。
企业或个体工商户申请支付
申请的网址:https://b.alipay.com/ (b: business企业)
点击下面的电脑网站支付的接入按钮:
这里支付宝提供了5种支付方式给我们使用,网站就要使用电脑网站支付。
早期支付宝只有两种支付方式:
即时到帐:我们上面看到的5个支付方式都是这个衍生出来的 ,一旦付款,立马到账。
担保支付: 7天担保,早期淘宝网,买家买东西的钱先到了淘宝的帐号呆够7天,商家才收到款,担保支付支付宝已经取消了。
企业或个体户点击上面电脑网站支付,需要以下申请条件:
上面的申请条件,以后去企业上班,公司都会帮我们申请好的。
上面是企业或个体工商户申请的基本步骤,我们个人没法申请,所以这里我们只能使用沙箱环境进行支付测试。
申请沙箱应用
首页,登陆支付宝开放平台,进入到如下的开发者中心
https://openhome.alipay.com/platform/developerIndex.htm
点击开发者中心->研发服务,进入如下的沙箱环境:
去创建沙箱应用,如下是已经创建的沙箱环境:
沙箱中的提供两个测试账户:商家账户 和 买家账户,其账户余额都是虚拟的
成功付款的时候,钱会从买家账户打到商家账户
商家账号:
买家账号:
特别注意一点:
3、下载支付宝支付的开发包SDK&Demo
下载地址:https://docs.open.alipay.com/270/106291
下载回来的压缩包如下:
解压下来如下所示:
aop:包含支付宝核心的支付文件。
lotusphp_runtime: 这是一个国外的PHP框架,这里是支付宝默认使用的。
pagepay:具体的实现支付接口的代码文件
config.php:配置文件,填写应用配置APPID、应用密钥、支付宝、支付网关的文件
notify_url.php:支付成功以后支付宝post方式异步跳转的地址,获取支付结果的地址
return_url.php:支付成功以后支付宝get方式同步跳转的地址,获取支付结果的地址
注:支付宝接口对我们的PHP版本有要求,必须在PHP5.5以上,可以使用phpStudy集成环境进行切换。且需要开启对应php版本的php.ini配置文件中的openssl扩展,去掉前面的分号,并重启apache服务器:
四、集成支付宝到项目中
1、引入支付宝到项目中
1、把下载下来的压缩包进行解压,把所有的文件复制到/public/alipay/目录下面
支付前的相关参数配置
几个重要的配置参数:
- APPID:可以从支付宝的沙箱应用中获取到
- 支付宝支付网关
沙箱环境:https://openapi.alipaydev.com/gateway.do
正式环境:https://openapi.alipay.com/gateway.do
提示:以后去公司做支付宝支付时,上线要使用正式环境的支付网关
- 应用私钥
- 应用公钥
其中应用私钥和公钥可通过支付宝提供的相关工具生成。
- 支付宝公钥
我们直接运行RSA签名验签工具
签名:说白了就是加密
验签:说白了判断加密是否正确,
例如:
我们注册会员的时候,会给会员密码加密,你可以理解,我们给会员的密码进行签名,
会员会在网站登录,我们直接从数据库找出密码的加密串 和 会员注册时的密码加密后进行判断,这个动作可以理解为验签
我们使用RSA签名验签工具生成应用的私钥和公钥:
商户的私钥:复制到config.php中。
商户的公钥:复制到支付宝网站中,再获取支付宝的公钥复制到config.php中
应用私钥和应用公钥,支付宝公钥说明:
修改config.php文件:
配置好之后,进行访问,如果能够出现一个支付宝的支付页面,说明配置参数成功:
之后通过沙箱中的买家账号和密码进行支付即可。
分析如何唤起支付宝支付页面
支付流程图解:
当单击支付按钮的时候,跳转到pagepay/pagepay.php文件中进行支付,此页面才是跳转到支付宝的真正支付页面。
文件如下:
即,后面只要在支付的时候,引入上面的pagepay/pagepay.php文件即可完成支付。
实现商城订单的支付
1、上面配置没有问题的话,且可以出现支付页面,我们就可以把/public/alipay目录复制到extend/目录下面:
- 当订单数据入库成功之后,需要引入上面的pagepay/pagepay.php文件进行支付,这里我们封装在一个支付的方法_payMoney()中。方便后面支付调用
同时需要把pagepay.php文件中的原本是$_POST的变量改为我们上面定义的$payData变量。
之所以要更改是因为后面个人订单支付也可以采用get方式进行传参支付。这样支付就更加灵活。
测试下商品加入购物车进行订单支付,如果下面付款的总金额一致,说明集成项目中成功
支付成功修改订单状态
在上面的支付宝页面进行支付成功之后,会跳转到我们在config.php中设置好的return_url配置项的同步回调地址。
只要支付宝支付成功之后,就会往同步地址和异步地址进行跳转:
同步通知和异步通知的区别:
同步和异步通知携带的支付参数没有本质的区别:
同步通知:支付成功后返回到指定callback回调域,同时携带支付状态的get参数,让自己的网站用于验证(更新支付的状态)。
异步通知:其实是双保险机制,主要是防止意外情况。因为交易涉及到钱的问题,支付宝考虑到如果同步通知的过程中,用户不小心关闭浏览器或者浏览器卡死的情况,这样就无法实现同步通知,从而也就无法更新用户的支付状态(用户支付成功,但显示未付款)。而支付宝服务器会在一段时间内持续的往我们的服务器发送异步通知。直到返回给支付宝success即可,这个一段时间在1-2天内通知8次左右。
- 在config.php中设置好同步的回调地址
- 建立一个同步回调的方法returnurl,打印get方法带来的支付成功参数
打印get携带的支付成功的参数如下:
两个重要的参数:
out_trade_no :自己网站的订单号
trade_no:支付宝那么支付成功返回来的订单号
这里我们可以通过out_trade_no订单号进行修改订单的支付状态,把支付状态的字段pay_status改为1.
- 修改订单的支付状态:
更改用户的支付状态和支付宝返回的订单号:
注:如果是线上环境,支付宝还会以post方式进行异步通知我们在config.php设置的异步回调地址。
异步代码也是更新订单的支付状态,只是把get接收方式改为post,且最后支付成功一定要echo一个success字符串给支付宝那边,否则支付宝在一段时间会一直通知,这个一段时间在1-2天内通知8次左右。
6、订单数据入库验证补充
- 定义Order验证器即规则
- 写入订单数据的时候进行验证
查看个人订单
- 修改模板(nav.html)我的订单的链接地址
- 在前台的home的order控制器,建立一个selfOrder方法,查询个人的所有订单,并分配到模板中。
- 把前台模板order.html复制到/home/view/order/目录下面,并改名为selforder.html
b、selfOrder方法
我们可以把用户的付款状态和发货状态对应的文本值定义在配置文件中,这样非常方便后期状态的维护。
- 模板selfOrder.html遍历订单数据
效果:
完成订单付款
- 给去付款按钮设置一个链接地址
- 在payMoney的方法中,完成付款的操作
修改支付成功的get同步回调的方法returnurl,支付成功,跳转到用户的订单列表
七、后台订单管理
1、订单列表无刷新分页
分析:
无属性分页只需要发送ajax请求,只需获取需要的数据返回来进行替换即可。
- 给分页的超练级a标签绑定单击事件,需要获取到其href属性值,并且阻止默认行为,用ajax请求地址即可,获取所需要的上面两部分数据,进行替换即可
- 为了获取独立的分页主体数据,我们可以抽离到一个html模板中
3、在index方法判断是否是ajax请求,返回所需要的数据即可。
核心利用fetch方法:此方法其实做了3件事件;
- 获取到模板内容 2.把分配到此模板中的变量进行替换 3.把替换好的模板内返回
注:由于无刷新分页的页码是ajax动态返回来的,要给动态增加元素绑定事件只能是用委托方式去绑定:
父选择器.on(事件名,子选择器,callback)