您现在的位置是: 网站首页 >Django >Vue+Django REST framework前后端分离生鲜电商 Django

【Vue+DRF生鲜电商】29.线上服务支付宝接口和Vue联调,Django代理Vue运行

admin2019年8月10日 21:18 Django | Python | Vue 1512人已围观

Vue+Django REST framework前后端分离生鲜电商简介 Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。 Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ; Django版本:2.2、djangorestframework:3.9.2。 前端Vue模板可以直接联系我拿。

### 修改Vue指向线上地址 由于需要调试支付宝的相关功能,将Vue项目指向线上的接口,修改 src/api/api.js 中的`local_host` ```javascript //let local_host = 'http://localhost:8000'; let local_host = 'http://xx.ip.ip.xx:8000'; ``` 然后记得启动Django的线上服务,而不是运行在本地了,重启Vue服务器,再访问 http://127.0.0.1:8080 看下是否能够正常加载接口的数据。 用户在购物车中点击去结算,会进入`OrderInfoViewSet`逻辑,就会创建一个订单,然后将当前用户购物车中的商品取出来,放在该订单对应的商品列表中。 ### OrderInfoSerializer序列化时生成支付url 在官方文档 https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield 中有一个字段是`SerializerMethodField`, 这是一个只读字段。它通过序列化类中的方法,来获取其值。它可以用来向对象的序列化表示添加任何类型的数据。 序列化器方法应该接受单个参数(除了`self`),该参数`obj`是被序列化的对象。它应该返回想要包含在对象序列化表示中的任何内容。 修改 apps/trade/serializers.py ,在`OrderInfoSerializer`添加一个`alipay_url`字段 ```python from utils.alipay import AliPay, get_server_ip from DjangoOnlineFreshSupermarket.settings import app_id, alipay_debug, alipay_public_key_path, app_private_key_path class OrderInfoSerializer(serializers.ModelSerializer): user = serializers.HiddenField( default=serializers.CurrentUserDefault() # 表示user为隐藏字段,默认为获取当前登录用户 ) order_sn = serializers.CharField(read_only=True) # 只能读,不能显示给用户修改,只能后台去修改 trade_no = serializers.CharField(read_only=True) # 只读 pay_status = serializers.CharField(read_only=True) # 只读 pay_time = serializers.DateTimeField(read_only=True) # 只读 alipay_url = serializers.SerializerMethodField() # 生成支付宝url def generate_order_sn(self): # 当前时间+userid+随机数 import time from random import randint order_sn = '{time_str}{user_id}{random_str}'.format(time_str=time.strftime('%Y%m%d%H%M%S'), user_id=self.context['request'].user.id, random_str=randint(10, 99)) return order_sn def validate(self, attrs): # 数据验证成功后,生成一个订单号 attrs['order_sn'] = self.generate_order_sn() return attrs def get_alipay_url(self, obj): # 方法命名规则为:get_<field_name> server_ip = get_server_ip() alipay = AliPay( app_id=app_id, # 自己支付宝沙箱 APP ID notify_url="http://{}:8000/alipay/return/".format(server_ip), app_private_key_path=app_private_key_path, # 可以使用相对路径那个 alipay_public_key_path=alipay_public_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, debug=alipay_debug, # 默认False, return_url="http://{}:8000/alipay/return/".format(server_ip) ) # 创建订单 order_sn = obj.order_sn order_amount = obj.order_amount url = alipay.direct_pay( subject="生鲜超市-{}".format(order_sn), out_trade_no=order_sn, total_amount=order_amount, # return_url="http://{}:8000/alipay/return/".format(server_ip) # 支付完成后自动跳回该url,可以不填了,因为初始化已经加上了 ) re_url = "https://openapi.alipaydev.com/gateway.do?{data}".format(data=url) return re_url class Meta: model = OrderInfo fields = "__all__" ``` 该字段用于订单创建时,生成支付宝的支付url 在 alipay.py 文件中 ```python if return_url is None: data["notify_url"] = self.notify_url data["return_url"] = self.return_url ``` 没有指定`return_url`时,直接使用初始化的`return_url` 修改完成后把代码上传到服务器,**每次修改代码后都需要Upload to服务器,避免出错,然后重启Debug** 接下来访问 http://xx.ip.ip.xx:8000/ 看API是否正常 接下来访问 http://xx.ip.ip.xx:8000/orderinfo/ 测试创建新订单 ![BLOG_20190810_212214_25](/media/blog/images/2019/08/BLOG_20190810_212214_25.png "博客图集BLOG_20190810_212214_25.png") POST完成后,可以看到返回的值 ![BLOG_20190810_212208_21](/media/blog/images/2019/08/BLOG_20190810_212208_21.png "博客图集BLOG_20190810_212208_21.png") 可以拿到`alipay_url`去浏览器访问,看下是否正常 ![BLOG_20190810_212201_69](/media/blog/images/2019/08/BLOG_20190810_212201_69.png "博客图集BLOG_20190810_212201_69.png") ![BLOG_20190810_212153_88](/media/blog/images/2019/08/BLOG_20190810_212153_88.png "博客图集BLOG_20190810_212153_88.png") 接下来会跳转到`return_url`配置的页面。这样说明生成的`alipay_url`是正确的了。 ### OrderInfoDetailSerializer订单详情显示alipay_url 如果订单未按时间倒序显示,在`OrderInfo`的`Meta`中配置`ordering = ['-add_time']` ![BLOG_20190810_212146_37](/media/blog/images/2019/08/BLOG_20190810_212146_37.png "博客图集BLOG_20190810_212146_37.png") 第一条为支付成功的,状态已变为已支付。 在 http://xx.ip.ip.xx:8000/orderinfo/ 中POST创建一条新的订单,不支付 ![BLOG_20190810_212138_71](/media/blog/images/2019/08/BLOG_20190810_212138_71.png "博客图集BLOG_20190810_212138_71.png") 前端Vue中也可以看到该订单为待支付状态 ![BLOG_20190810_212131_20](/media/blog/images/2019/08/BLOG_20190810_212131_20.png "博客图集BLOG_20190810_212131_20.png") 点击该待支付订单,进入详情 ![BLOG_20190810_212119_61](/media/blog/images/2019/08/BLOG_20190810_212119_61.png "博客图集BLOG_20190810_212119_61.png") 这儿有个功能是 立即使用支付宝支付 ,点击是无效的,因为没有从后端返回支付url。 那么就需要获取到支付url,用户可以直接通过该url去支付。 所以需要实现在详情页也能显示支付url,修改 apps/trade/serializers.py 中的`OrderInfoDetailSerializer`,添加`alipay_url`字段 ```python # 订单详情序列化 class OrderInfoDetailSerializer(serializers.ModelSerializer): order_goods = OrderGoodsSerializer(many=True) # 为OrderGoods中外键关联名称 alipay_url = serializers.SerializerMethodField() # 生成支付宝url def get_alipay_url(self, obj): # 方法命名规则为:get_<field_name> server_ip = get_server_ip() alipay = AliPay( app_id=app_id, # 自己支付宝沙箱 APP ID notify_url="http://{}:8000/alipay/return/".format(server_ip), app_private_key_path=app_private_key_path, # 可以使用相对路径那个 alipay_public_key_path=alipay_public_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, debug=alipay_debug, # 默认False, return_url="http://{}:8000/alipay/return/".format(server_ip) ) # 创建订单 order_sn = obj.order_sn order_amount = obj.order_amount url = alipay.direct_pay( subject="生鲜超市-{}".format(order_sn), out_trade_no=order_sn, total_amount=order_amount, # return_url="http://{}:8000/alipay/return/".format(server_ip) # 支付完成后自动跳回该url,可以不填了,因为初始化已经加上了 ) re_url = "https://openapi.alipaydev.com/gateway.do?{data}".format(data=url) return re_url class Meta: model = OrderInfo fields = "__all__" ``` 接下来可以指定id通过DRF查看订单详情 http://xx.ip.ip.xx:8000/orderinfo/6/ ![BLOG_20190810_212102_59](/media/blog/images/2019/08/BLOG_20190810_212102_59.png "博客图集BLOG_20190810_212102_59.png") 在前端页面 http://127.0.0.1:8080/#/app/home/member/orderDetail/6 可以点击 立即使用支付宝支付 就能跳转到支付宝的支付页面。 ### Vue中购物车结算跳转支付宝url 在购物车 src/views/cart/cart.vue 中,有一个结算函数,当创建订单后,可以跳转到`alipay_url` ```JavaScript balanceCount() { // 结算 if (this.addrInfo.length == 0) { alert("请选择收货地址") } else { createOrder( { post_script: this.post_script, address: this.address, signer_name: this.signer_name, signer_mobile: this.signer_mobile, order_amount: this.totalPrice } ).then((response) => { alert('订单创建成功'); window.location.href = response.data.alipay_url; }).catch(function (error) { console.log(error); }); } }, ``` 在Vue前端中,假如一些商品,然后点击 去结算 ![BLOG_20190810_212053_18](/media/blog/images/2019/08/BLOG_20190810_212053_18.png "博客图集BLOG_20190810_212053_18.png") 之后自定跳转到支付宝支付页面 ![BLOG_20190810_212045_71](/media/blog/images/2019/08/BLOG_20190810_212045_71.png "博客图集BLOG_20190810_212045_71.png") ### 支付成功如何跳回Vue页面 在这个页面中,用户支付成功后,并不能跳回Vue的页面,而是返回了后端的接口。 如何能让支付成功就跳转到Vue页面? - 第一种方法,可以在Vue中显示支付宝返回的二维码图片,然后进行扫码支付,支付成功后,Vue跳转到其他页面; - 第二种方法相对简单一点的,原来的前端页面 运行在:8080端口,是使用 node.js 来访问的,我们可以使用Django来代理该访问,类似于渲染模板。 下面将使用第二种方法实现:将Vue模板使用Django渲染。Vue有两种开发模式,第一种是dev,第二种是build,直接使用`cnpm run build`,这样就可以生成静态文件,这些静态文件可以放在Django的Templates中就可以访问了。 直接进入Vue项目文件夹,运行 ```bash \VueOnlineFreshSupermarket> cnpm run build ``` **如可以正常打包,则跳过下一节** 正常打包后,在项目的文件夹下生成**dist**目录,结构如下: ``` │ index.entry.js │ index.html │ └─static ├─fonts │ iconfont.60cf513.ttf │ iconfont.fcaaa27.eot │ └─images loginBg1.23c7104.jpg ``` #### 运行cnpm run build报错问题 运行出错,有以下提示: ``` > online-store@1.0.0 build C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket > webpack --progress --profile --colors --config webpack.prod.js C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\_webpack-cli@3.3.6@webpack-cli\bin\cli.js:93 throw err; Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead. at Object.get [as UglifyJsPlugin] (C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\webpack\lib\webpack.js:185:10) at Object.<anonymous> (C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\webpack.prod.js:30:30) ``` 首先全局安装`webpack`,不确定是否有效,重新运行`cnpm run build`,还是报同样的错误 ```bash >npm install -g webpack --registry=https://registry.npm.taobao.org >npm install -g webpack-cli --registry=https://registry.npm.taobao.org ``` 根据提示`webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.`进行百度,参照 https://blog.csdn.net/cominglately/article/details/89525175 修改 修改压缩代码配置: ![BLOG_20190810_212027_13](/media/blog/images/2019/08/BLOG_20190810_212027_13.png "博客图集BLOG_20190810_212027_13.png") 运行`cnpm run build`进入打包过程,但又出现了下面错误 ``` WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/ ERROR in ./src/views/head/head.vue (./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"optionsId":"0","vue":true,"id":"data-v-53f64758","scoped":true,"sourceMap":false}!./node_modules/sass-loader/lib/loader.js!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/views/head/head.vue) Module build failed (from ./node_modules/sass-loader/lib/loader.js): Error: Missing binding C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass\vendor\win32-x64-64\binding.node Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 10.x Found bindings for the following environments: - Windows 64-bit with Node.js 10.x This usually happens because your environment has changed since running `npm install`. Run `npm rebuild node-sass` to download the binding for your current environment. at module.exports (C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass\lib\binding.js:15:13) at Object.<anonymous> (C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass\lib\index.js:14:35) ``` 百度了一下,将 ```config "scripts": { "dev": "webpack-dev-server --host 0.0.0.0 --mode development --inline --progress --profile --colors", "build": "webpack --progress --profile --colors --config webpack.prod.js", "server": "node server.js" }, ``` 修改为 ```config "scripts": { "dev": "webpack-dev-server --host 0.0.0.0 --mode development --inline --progress --profile --colors", "build": "webpack --mode development --progress --profile --colors --config webpack.prod.js", "server": "node server.js" }, ``` 其实解决到这一步,Vue项目目录下就已经生成了`dist` ![BLOG_20190810_212017_75](/media/blog/images/2019/08/BLOG_20190810_212017_75.png "博客图集BLOG_20190810_212017_75.png") 仍有报错,让我们一步一步把问题解决下去 ``` ERROR in ./src/views/head/head.vue (./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"optionsId":"0","vue":true,"id":"data-v-53f64758","scoped":true,"sourceMap":false}!./node_modules/sass-loader/lib/loader.js!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/views/head/head.vue) Module build failed (from ./node_modules/sass-loader/lib/loader.js): Error: Missing binding C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass\vendor\win32-x64-64\binding.node Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 10.x Found bindings for the following environments: - Windows 64-bit with Node.js 10.x This usually happens because your environment has changed since running `npm install`. Run `npm rebuild node-sass` to download the binding for your current environment. at module.exports (C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass\lib\binding.js:15:13) ``` 按照他的提示,运行`cnpm rebuild node-sass`解决该问下,从github下载很慢,耐心等待。 ```bash \VueOnlineFreshSupermarket> cnpm rebuild node-sass > node-sass@4.10.0 install C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass > node scripts/install.js Downloading binary from https://github.com/sass/node-sass/releases/download/v4.10.0/win32-x64-64_binding.node Download complete ] - : Binary saved to C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass\vendor\win32-x64-64\binding.node Caching binary to C:\Users\StarMeow\AppData\Roaming\npm-cache\node-sass\4.10.0\win32-x64-64_binding.node > node-sass@4.10.0 postinstall C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass > node scripts/build.js Binary found at C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass\vendor\win32-x64-64\binding.node Testing binary Binary is fine node-sass@4.10.0 C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket\node_modules\node-sass ``` 完美,不再报错了 ```bash \VueOnlineFreshSupermarket> cnpm run build > VueOnlineFreshSupermarket@1.0.0 build C:\Users\StarMeow\Desktop\VueOnlineFreshSupermarket > webpack --mode development --progress --profile --colors --config webpack.prod.js 7399ms building 3ms finish module graph 1ms sealing 0ms basic dependencies optimization 0ms dependencies optimization 0ms advanced dependencies optimization 1ms after dependencies optimization 3ms chunk graph 0ms after chunk graph 0ms optimizing 0ms basic module optimization 0ms module optimization 1ms advanced module optimization 0ms after module optimization 0ms basic chunk optimization 1ms chunk optimization 4ms advanced chunk optimization 0ms after chunk optimization 0ms module and chunk tree optimization 0ms after module and chunk tree optimization 1ms basic chunk modules optimization 0ms chunk modules optimization 0ms advanced chunk modules optimization 0ms after chunk modules optimization 0ms module reviving 0ms module order optimization 1ms advanced module order optimization 3ms before module ids 1ms module ids 2ms module id optimization 0ms chunk reviving 0ms chunk order optimization 0ms before chunk ids 1ms chunk id optimization 0ms after chunk id optimization 1ms record modules 0ms record chunks 7ms hashing 0ms content hashing 1ms after hashing 0ms record hash 0ms module assets processing 39ms chunk assets processing 1ms additional chunk assets processing 0ms recording 0ms additional asset processing 0ms chunk asset optimization 0ms after chunk asset optimization 0ms asset optimization 1ms after asset optimization 0ms after seal 66ms emitting 1ms after emitting Hash: 57ae548d90f979292ef7 Version: webpack 4.26.1 Time: 7559ms Built at: 2019-08-08 10:48:45 PM Asset Size Chunks Chunk Names index.entry.js 2.49 MiB index [emitted] index index.html 181 bytes [emitted] static/fonts/iconfont.60cf513.ttf 11.3 KiB [emitted] static/fonts/iconfont.fcaaa27.eot 11.6 KiB [emitted] static/images/loginBg1.23c7104.jpg 464 KiB [emitted] Entrypoint index = index.entry.js [./mock/mock.js] 9.05 KiB {index} [built] [./src/main.js] 614ms -> factory:592ms building:4868ms dependencies:368ms = 6442ms [./mock/mock/banner.js] 309 bytes {index} [built] [./src/main.js] 614ms -> [./mock/mock.js] 5460ms -> factory:590ms building:5626ms dependencies:0ms = 12290ms [./mock/mock/hotSearch.js] 184 bytes {index} [built] [./src/main.js] 614ms -> [./mock/mock.js] 5460ms -> factory:590ms building:5626ms dependencies:0ms = 12290ms [./mock/mock/login.js] 93 bytes {index} [built] [./src/main.js] 614ms -> [./mock/mock.js] 5460ms -> factory:590ms building:5626ms dependencies:0ms = 12290ms [./mock/mock/menu.js] 6.57 KiB {index} [built] [./src/main.js] 614ms -> [./mock/mock.js] 5460ms -> factory:590ms building:5626ms dependencies:0ms = 12290ms [./mock/mock/newOpro.js] 851 bytes {index} [built] [./src/main.js] 614ms -> [./mock/mock.js] 5460ms -> factory:590ms building:5626ms dependencies:0ms = 12290ms [./mock/mock/seriesList.js] 6.42 KiB {index} [built] [./src/main.js] 614ms -> [./mock/mock.js] 5460ms -> factory:590ms building:5626ms dependencies:0ms = 12290ms [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/styles/common.scss] ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/styles/common.scss 2.19 KiB {index} [built] [./src/main.js] 614ms -> [./src/styles/common.scss] 5460ms -> factory:368ms building:76ms dependencies:62ms = 6580ms [./src/App.vue] 1.68 KiB {index} [built] [./src/main.js] 614ms -> factory:592ms building:4868ms dependencies:368ms = 6442ms [./src/axios/index.js] 1.06 KiB {index} [built] [./src/main.js] 614ms -> factory:592ms building:4868ms dependencies:368ms = 6442ms [./src/main.js] 721 bytes {index} [built] factory:46ms building:568ms = 614ms [./src/router/index.js] 10.1 KiB {index} [built] [./src/main.js] 614ms -> factory:592ms building:4868ms dependencies:368ms = 6442ms [./src/store/store.js] 844 bytes {index} [built] [./src/main.js] 614ms -> factory:592ms building:4868ms dependencies:368ms = 6442ms [./src/styles/common.scss] 1.03 KiB {index} [built] [./src/main.js] 614ms -> factory:592ms building:4868ms dependencies:368ms = 6442ms [./src/styles/fonts/iconfont.css] 932 bytes {index} [built] [./src/main.js] 614ms -> factory:592ms building:4868ms dependencies:368ms = 6442ms + 257 hidden modules Child HtmlWebpackCompiler: 1 asset Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0 [./node_modules/html-webpack-plugin/lib/loader.js!./template.html] 346 bytes {HtmlWebpackPlugin_0} [built] factory:33ms building:14ms = 47ms [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 791 bytes {HtmlWebpackPlugin_0} [built] [./node_modules/html-webpack-plugin/lib/loader.js!./template.html] 47ms -> [./node_modules/lodash/lodash.js] 2939ms -> factory:1919ms building:720ms = 5625ms [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 506 bytes {HtmlWebpackPlugin_0} [built] [./node_modules/html-webpack-plugin/lib/loader.js!./template.html] 47ms -> [./node_modules/lodash/lodash.js] 2939ms -> factory:1919ms building:720ms = 5625ms + 1 hidden module ``` #### 打包的Vue项目运行配置 Vue项目生成 index.html 、index.entry.js 、static 文件后, 1. 把 index.html 复制到Django项目根目录 templates 文件夹下 2. Django项目根目录创建 static 文件夹,把 index.entry.js 复制到该文件夹下 3. 把Vue项目打包后 static目录下的 fonts和images文件夹移动到 static 下 修改 DjangoOnlineFreshSupermarket/settings.py 添加静态文件配置 ```python STATIC_URL = '/static/' # 配置静态文件 STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), # 逗号不能少 ) ``` 修改完之后,将所有修改过的文件上传到服务器 ### Django代理运行Vue模板功能 将 templates/index.html ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>首页</title> </head> <body> <div id="app"></div> <script src="index.entry.js"></script></body> </html> ``` 进行修改 ```html <!DOCTYPE html> {% load static %} <html> <head> <meta charset="utf-8"> <title>首页</title> </head> <body> <div id="app"></div> <script src="{% static 'index.entry.js' %}"></script></body> </html> ``` 在项目主url中 DjangoOnlineFreshSupermarket/urls.py 创建一个路由,用来渲染该模板 ```python from django.views.generic import TemplateView urlpatterns = [ # ... # 使用Django原生的TemplateView渲染index模板 path('index/', TemplateView.as_view(template_name='index.html'), name='index'), # ... ] ``` 修改完上传这两个文件到服务器,然后重启下Debug 之后访问线上服务器的地址 http://xx.ip.ip.xx:8000/index/ ,该地址会自动跳转到 http://xx.ip.ip.xx:8000/index/#/app/home/index ,原Vue模板正常显示,数据也能正常显示出来。 ![BLOG_20190810_211953_21](/media/blog/images/2019/08/BLOG_20190810_211953_21.png "博客图集BLOG_20190810_211953_21.png") ### 支付成功后返回主页 #### 支付成功后Django进行跳转 修改 apps/trade/views.py 中的`AliPayView`类,当用户支付成功后,会进入到`get`逻辑,可以在这控制它跳转到Django打理的视图模板`index` ```python from django.shortcuts import redirect, reverse class AliPayView(APIView): def get(self, request): """ 处理支付宝return_url返回 :param request: :return: """ processed_dict = {} for key, value in request.GET.items(): # GET逻辑和POST基本一样 processed_dict[key] = value print('request.GET的值:', processed_dict) sign = processed_dict.pop('sign', None) # 直接就是字符串了 server_ip = get_server_ip() alipay = AliPay( app_id=app_id, # 自己支付宝沙箱 APP ID notify_url="http://{}:8000/alipay/return/".format(server_ip), app_private_key_path=app_private_key_path, # 可以使用相对路径那个 alipay_public_key_path=alipay_public_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, debug=alipay_debug, # 默认False, return_url="http://{}:8000/alipay/return/".format(server_ip) ) verify_result = alipay.verify(processed_dict, sign) # 验证签名,如果成功返回True if verify_result: # POST中已经修改数据库订单状态,无需再GET中修改,且,GET中也得不到支付状态值 # 给支付宝返回一个消息,证明已收到异步通知 # return Response('success') # 修改为跳转到Vue页面 response = redirect(reverse('index')) response.set_cookie('nextPath', 'pay', max_age=2) # max_age设置为2s,让其快速过期,用一次就好了。 # 跳转回Vue中时,直接跳转到Vue的pay的页面,后台无法配置,只能让Vue实现跳转。 return response else: # 验证不通过直接跳转回首页就行,不设置cookie return redirect(reverse('index')) def post(self, request): # ...... ``` #### Vue中获取nextPath分析 在Vue项目 src/router/index.js 中,有一个逻辑 ```JavaScript //进行路由判断 router.beforeEach((to, from, next) => { var nextPath = cookie.getCookie('nextPath'); // console.log(nextPath) if (nextPath == "pay") { next({ path: '/app/home/member/order', }); } else { if (to != undefined) { if (to.meta.need_log) { //console.log(to.meta.need_log) if (!store.state.userInfo.token) { next({ path: '/app/login', }); } else { next(); } } else { if (to.path === '/') { next({ path: '/app/home/index', }); } else { next(); } } } else { if (to.path === '/') { next({ path: '/app/home/index', }); } else { next(); } } } }); ``` 进入路由时,将从cookie中获取`nextPath`的值,如果它的值为`pay`就跳转到`/app/home/member/order` 接下来讲修改过的文件上传到服务器,重启Debug 直接访问Django代理的Vue测试, http://xx.ip.ip.xx:8000/index/#/app/home/index 登录后选择一些商品添加到购物车,结算 ![BLOG_20190810_211941_69](/media/blog/images/2019/08/BLOG_20190810_211941_69.png "博客图集BLOG_20190810_211941_69.png") 点击确定后会自动跳转到支付宝的支付页面 ![BLOG_20190810_211934_49](/media/blog/images/2019/08/BLOG_20190810_211934_49.png "博客图集BLOG_20190810_211934_49.png") 利用沙箱账号进行支付,支付成功后会跳转到Django逻辑,可以打上断点 ![BLOG_20190810_211928_99](/media/blog/images/2019/08/BLOG_20190810_211928_99.png "博客图集BLOG_20190810_211928_99.png") 测试能跳转到 http://xx.ip.ip.xx:8000/index/#/ 不能自动跳转到Vue订单列表页,cookie中也有值,不知道是1C1U的服务器卡还是怎么回事,暂不调试了。 支付成功后,会跳转到,以下类似页面 ``` http://xx.ip.ip.xx:8000/alipay/return/?charset=utf-8&out_trade_no=20190809200932132&method=alipay.trade.page.pay.return&total_amount=99.00&sign=fj9Qd3vZj%2B0nMTPGCXpAGKO7mY2pLhjs%2BtXrpWY5Lho4Cg0KvcAxEJaO1rxFy7EOIJoS07id9Eo8iupEXEwtO7eLYun%2FD73%2BWRvzErlQB8wjYjBGGEDXgBJOVYqGTwp2f6w0aYk9n9WnuyXIRhc4jDpkz2wEq%2BdqqzXjPrNXI2k9vgrQ85Yjyu6MQJU7cdNR6epG0l60BcZRd9lSrTbSGGES1avLBhhVX1SuVuRxmJ7jQgBqdMzDuGztDwHEy1BOf5uI0in%2F9RqXVs20RJfnCrxvTjYjhU3fl7QKK5G2sBrY2GF1vLv4Q0hChS9nHvNNsnY4U%2BkP%2BMdw9nAL28fmtA%3D%3D&trade_no=2019080922001421571000035374&auth_app_id=2016100900646609&version=1.0&app_id=2016100900646609&sign_type=RSA2&seller_id=2088102178762103&timestamp=2019-08-09+20%3A10%3A17 ``` 可以直接使用该页面进行调试 为了方便,可以将Django项目运行到本地来测试该url ``` http://127.0.0.1:8000/alipay/return/?charset=utf-8&out_trade_no=20190809200932132&method=alipay.trade.page.pay.return&total_amount=99.00&sign=fj9Qd3vZj%2B0nMTPGCXpAGKO7mY2pLhjs%2BtXrpWY5Lho4Cg0KvcAxEJaO1rxFy7EOIJoS07id9Eo8iupEXEwtO7eLYun%2FD73%2BWRvzErlQB8wjYjBGGEDXgBJOVYqGTwp2f6w0aYk9n9WnuyXIRhc4jDpkz2wEq%2BdqqzXjPrNXI2k9vgrQ85Yjyu6MQJU7cdNR6epG0l60BcZRd9lSrTbSGGES1avLBhhVX1SuVuRxmJ7jQgBqdMzDuGztDwHEy1BOf5uI0in%2F9RqXVs20RJfnCrxvTjYjhU3fl7QKK5G2sBrY2GF1vLv4Q0hChS9nHvNNsnY4U%2BkP%2BMdw9nAL28fmtA%3D%3D&trade_no=2019080922001421571000035374&auth_app_id=2016100900646609&version=1.0&app_id=2016100900646609&sign_type=RSA2&seller_id=2088102178762103&timestamp=2019-08-09+20%3A10%3A17 ```

很赞哦! (1)

文章交流

  • emoji
4人参与,3条评论
瓦片 2019年8月11日 11:15
你好朋友,无意中在网上看到你电商的教程,我最近在慕课学习发现你的教程和老师的有所不同,对一些细节进行了优化,能否发一个前端的代码给我,按照慕课老师的做是错的,我现在卡在面包削这里,谢谢啦
吾星喵 @ 瓦片 2019年8月11日 11:22
朋友,我在QQ上收到你的留言啦,直接在网站联系下我的QQ吧,我发你
瓦片 2019年8月11日 11:15
你好朋友,无意中在网上看到你电商的教程,我最近在慕课学习发现你的教程和老师的有所不同,对一些细节进行了优化,能否发一个前端的代码给我,按照慕课老师的做是错的,我现在卡在面包削这里,谢谢啦
瓦片 2019年8月11日 11:15
你好朋友,无意中在网上看到你电商的教程,我最近在慕课学习发现你的教程和老师的有所不同,对一些细节进行了优化,能否发一个前端的代码给我,按照慕课老师的做是错的,我现在卡在面包削这里,谢谢啦

当前用户

未登录,点击   登录

站点信息

  • 建站时间:网站已运行2285天
  • 系统信息:Linux
  • 后台程序:Python: 3.8.10
  • 网站框架:Django: 3.2.6
  • 文章统计:257 篇
  • 文章评论:63 条
  • 腾讯分析网站概况-腾讯分析
  • 百度统计网站概况-百度统计
  • 公众号:微信扫描二维码,关注我们
  • QQ群:QQ加群,下载网站的学习源码
返回
顶部
标题 换行 登录
网站