华为云服务器+Nginx+Python3.7+Django2.2+支付宝支付接入部署

本次分享内容共分四个主要部署步骤
1.Django框架项目搭建部署
2.本地内网穿透测试
3.阿里支付宝支付接口部署
4.华为云服务器部署(弹性云服务器ECS)

一,搭建django项目基本结构

1.创建当前项目的虚拟环境

python3 -m venv venv

2.安装依赖环境

pip install -r requirement.txt

Django==2.2.6
Pillow==6.2.0
pkg-resources==0.0.0
pycrypto==2.6.1
pycryptodomex==3.7.2
python-alipay-sdk==1.10.1
pytz==2019.3
sqlparse==0.3.0

3.完成项目基本结构开发(略…)

按照基本模型和路由参考,完成以下基本项目功能:
1.商品列表页:需要完成数据的查询及模板中的数据展示
2.商品下单: 在商品列表页可以对商品进行下单购买,及对应的订单数据入库操作
3.订单列表: 可以查看到当前所有订单及订单的支付状态
4.完成发起支付请求,支付回调地址的视图函数定义(代码可以暂时不写)

模型 models.py

from django.db import models
from django.utils.html import format_html
# Create your models here.
# 书籍模型
class Books(models.Model):# 书名name = models.CharField(max_length=30)# 价格price = models.FloatField()# 数量num = models.IntegerField(default=5)# 封面img_url = models.ImageField(upload_to="./static/uploads/",null=True)def loadimg(self):return format_html('<img src="%s" height="64" width="64" />' %(self.img_url,))class Order(models.Model):# 订单号ordercode = models.IntegerField()# 下单用户iduser = models.CharField(max_length=5,default='测试用户')# 购买产品idbookid = models.IntegerField()# 产品名称bookname = models.CharField(max_length=50)# 应付金额monery = models.FloatField()# 支付方式 0 支付宝paytype = models.IntegerField(default=0)# 支付状态 0未支付  1 已支付 paystatus = models.IntegerField(default=0)# 订单创建时间ordertime = models.DateTimeField(auto_now_add=True)# 订单支付时间paytime = models.DateTimeField(null=True)

路由及对应视图函数 urls.py

# 商品列表
path('',views.index),
# 创建订单
path('order/create', views.create_order,name="createOrder"),
# 发起支付请求
path('order/pay', views.order_pay_request,name="orderpay"),
# 支付宝回调地址
path('order/pay_result', views.order_pay_result,name="order_pay_result"),
# 订单列表,支付成功后的跳转页面
path('order/list', views.orderlist,name="orderlist"),
# 订单删除
path('order/delete', views.orderdel,name="orderdel"),

二,使用ngrok|花生壳内网穿透

推荐使用花生壳进行内网穿透测试
http://service.oray.com/question/1664.html

三,支付宝接入

1.登陆支付宝开放平台创建支付宝沙箱环境

支付宝开放平台 https://openhome.alipay.com/platform/appDaily.htm?tab=info
支付文档 https://docs.open.alipay.com/200/105311

2.创建密钥

1.生成应用公钥和秘钥
2.把应用公钥赋值并配置到当前的沙箱环境中
3.配置完公钥后,沙箱环境配置会给一个支付宝公钥,复制并保存
4.在项目根目录中创建keys文件目录,存储应用私钥(rsa_private_key.txt)和支付宝公钥(rsa_public_key.txt)

ubuntu生成密钥和公钥

#打开终端输入 openssl
# 输入以下命令创建密钥
genrsa -out rsa_private_key.txt 2048
# 输入以下命令创建公钥
rsa -in rsa_private_key.txt -pubout -out rsa_public_key.txt
#输入 exit  推出 openssl
# ls 查看当前目录下创建的密钥和公钥
rsa_private_key.txt  rsa_public_key.txt

windows10 可以安装支付宝开放平台助手,创建密钥

https://docs.open.alipay.com/291/105971

注意:在项目中配置 keys应用 私钥和支付宝公钥 放进来

    1,在项目中 创建 keys 目录 里面放入 秘钥文件2,创建 rsa_private_key.txt 放入秘钥,加开始和结束的标记-----BEGIN RSA PRIVATE KEY-----.....-----END RSA PRIVATE KEY-----3,创建 rsa_public_key.txt 放入秘钥,加开始和结束的标记-----BEGIN PUBLIC KEY-----....-----END PUBLIC KEY-----

3. 项目中支付宝接口的配置 settings.py

1.参考以下配置在项目中进行支付宝相关配置

# 支付宝相关配置
# APPID
# 沙箱APPID,生产环境须更改为应用APPID。
ALIPAY_APPID = "0000000000011111100"# 网关
# 沙箱网关,生产环境须更改为正式网关。
ALIPAY_URL = "https://openapi.alipaydev.com/gateway.do"
# 正式网关,开发环境勿使用。
# ALIPAY_URL = "https://openapi.alipay.com/gateway.do"# 回调通知地址
ALIPAY_NOTIFY_URL = "http://mv23102380.imwork.net/order/pay_result"# 支付后的跳转地址
ALIPAY_RETURN_URL = 'http://mv23102380.imwork.net/order/pay_result'# 应用私钥
APP_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'keys/rsa_private_key.txt')
# 支付宝公钥
ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR, 'keys/rsa_public_key.txt')

4.发起支付请求

  1. 完成支付请求前基本开发
# 首页
def index(request):data = Books.objects.all()return render(request,'index.html',{'data':data})# 创建订单,发起支付请求
def create_order(request):# 接受表单数据id = request.POST.get('id')# 获取对象obj = Books.objects.get(id=id)# 检测库存if obj.num <= 0:return JsonResponse({'code':1,'msg':'当前商品已经售空'})# 创建订单# 订单号,购买产品id,应付金额data = {'ordercode':int(time.time())+random.randint(10000,99999),'bookid':obj.id,'bookname':obj.name,'monery':obj.price}orderobj = Order(**data)orderobj.save()print(f'订单创建成功,\r\n订单信息:{data}')# return HttpResponse('创建订单,发起支付请求')return order_pay_request(orderobj)# 支付成功后的跳转页面
def orderlist(request):# 获取所有的订单数据data = Order.objects.all()for i in data:i.img = Books.objects.get(id=i.bookid).img_urlreturn render(request,'orderlist.html',{'data':data})# 订单删除
def orderdel(request):oid = request.GET.get('oid')obj = Order.objects.get(id=oid)obj.delete()return HttpResponseRedirect(reverse('orderlist'))
  1. 导入支付宝支付接口类

在项目根目录创建utils包文件夹,创建pay.py模块写入支付接口类
web\utils\pay.py

from datetime import datetime
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from urllib.parse import quote_plus
from urllib.parse import urlparse, parse_qs
from base64 import decodebytes, encodebytes
import jsonclass AliPay(object):"""支付宝支付接口(PC端支付接口)"""def __init__(self, appid, app_notify_url, app_private_key_path,alipay_public_key_path, return_url, debug=False):self.appid = appidself.app_notify_url = app_notify_urlself.app_private_key_path = app_private_key_pathself.app_private_key = Noneself.return_url = return_urlwith open(self.app_private_key_path) as fp:self.app_private_key = RSA.importKey(fp.read())self.alipay_public_key_path = alipay_public_key_pathwith open(self.alipay_public_key_path) as fp:self.alipay_public_key = RSA.importKey(fp.read())if debug is True:self.__gateway = "https://openapi.alipaydev.com/gateway.do"else:self.__gateway = "https://openapi.alipay.com/gateway.do"def direct_pay(self, subject, out_trade_no, total_amount, return_url=None, **kwargs):biz_content = {"subject": subject,"out_trade_no": out_trade_no,"total_amount": total_amount,"product_code": "FAST_INSTANT_TRADE_PAY",# "qr_pay_mode":4}biz_content.update(kwargs)data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url)return self.sign_data(data)def build_body(self, method, biz_content, return_url=None):data = {"app_id": self.appid,"method": method,"charset": "utf-8","sign_type": "RSA2","timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),"version": "1.0","biz_content": biz_content}if return_url is not None:data["notify_url"] = self.app_notify_urldata["return_url"] = self.return_urlreturn datadef sign_data(self, data):data.pop("sign", None)# 排序后的字符串unsigned_items = self.ordered_data(data)unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items)sign = self.sign(unsigned_string.encode("utf-8"))# ordered_items = self.ordered_data(data)quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items)# 获得最终的订单信息字符串signed_string = quoted_string + "&sign=" + quote_plus(sign)return signed_stringdef ordered_data(self, data):complex_keys = []for key, value in data.items():if isinstance(value, dict):complex_keys.append(key)# 将字典类型的数据dump出来for key in complex_keys:data[key] = json.dumps(data[key], separators=(',', ':'))return sorted([(k, v) for k, v in data.items()])def sign(self, unsigned_string):# 开始计算签名key = self.app_private_keysigner = PKCS1_v1_5.new(key)signature = signer.sign(SHA256.new(unsigned_string))# base64 编码,转换为unicode表示并移除回车sign = encodebytes(signature).decode("utf8").replace("\n", "")return signdef _verify(self, raw_content, signature):# 开始计算签名key = self.alipay_public_keysigner = PKCS1_v1_5.new(key)digest = SHA256.new()digest.update(raw_content.encode("utf8"))if signer.verify(digest, decodebytes(signature.encode("utf8"))):return Truereturn Falsedef verify(self, data, signature):if "sign_type" in data:sign_type = data.pop("sign_type")# 排序后的字符串unsigned_items = self.ordered_data(data)message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items)return self._verify(message, signature)
  1. 支付请求及回调函数封装
# 发起支付请求
def order_pay_request(orderobj):# 获取支付对象alipay = Get_AliPay_Object()# 生成支付的urlquery_params = alipay.direct_pay(subject=orderobj.bookname,  # 商品简单描述out_trade_no = orderobj.ordercode,# 用户购买的商品订单号total_amount = orderobj.monery,  # 交易金额(单位: 元 保留俩位小数))# 支付宝网关地址(沙箱应用)pay_url = settings.ALIPAY_URL+"?{0}".format(query_params)  print('正在发起支付请求...')# 页面重定向到支付页面return HttpResponseRedirect(pay_url)# 支付宝回调地址
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def order_pay_result(request):# 获取对象alipay = Get_AliPay_Object()if request.method == "POST":# 检测是否支付成功# 去请求体中获取所有返回的数据:状态/订单号from urllib.parse import parse_qs# name&age=123....body_str = request.body.decode('utf-8')post_data = parse_qs(body_str)post_dict = {}for k, v in post_data.items():post_dict[k] = v[0]sign = post_dict.pop('sign', None)status = alipay.verify(post_dict, sign)print('------------------开始------------------')print('POST验证', status)print(post_dict)out_trade_no = post_dict['out_trade_no']# 修改订单状态ass = {'paystatus':1,'paytime':post_dict['gmt_payment']}print(ass)Order.objects.filter(ordercode=out_trade_no).update(**ass)print('------------------结束------------------')# 修改订单状态:获取订单号return HttpResponse('success')else:params = request.GET.dict()sign = params.pop('sign', None)status = alipay.verify(params, sign)print('==================开始==================')print('GET验证', status)print('==================结束==================')return HttpResponse('<script>alert("支付成功");location.href="/order/list"</script>')# 支付宝对象创建方法
from web import settings
from utils.pay import AliPay# AliPay 对象实例化
def Get_AliPay_Object():alipay = AliPay(appid=settings.ALIPAY_APPID,# APPID (沙箱应用)app_notify_url=settings.ALIPAY_NOTIFY_URL, # 回调通知地址return_url=settings.ALIPAY_RETURN_URL,# 支付完成后的跳转地址app_private_key_path=settings.APP_PRIVATE_KEY_PATH, # 应用私钥alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,  # 支付宝公钥debug=True,  # 默认False,)return alipay

四.上线华为云服务器部署(弹性云服务器ECS)

环境配置:
ubuntu 18.04
Python 3.6.8(python3.7亦可)
nginx version: nginx/1.14.0 (Ubuntu)

1. 购买华为云服务器

文档 https://support.huaweicloud.com/ecs/index.html

2. 上传到华为云服务器,安装依赖环境,启动项目测试

3. 搭建uwsgi启动项目测试

1.安装uwsgi
sudo pip3 install uwsgi --upgrade2.安装完成后使用命令测试
先进入项目目录,启动命令
uwsgi --http :80 --chdir /home/alipay/web  --module web.wsgi --home /home/alipay/venv/bin# --home 指定virtualenv 路径,如果没有可以去掉。web.wsgi 指的是 web/wsgi.py 文件3.访问测试,启动成功后
127.0.0.1:8080

4. 配置uwsgi文件启动项目

第一步:创建一个uwsgi.ini文件第二步:在django项目同级目录创建script目录,用于存放配置脚本等等
/home/alipay/web/script/  web/ db.sqlite3 manage.py uwsgi.ini第三步:编辑uwsgi.ini文件内容如下: 目录参考个人目录进行修改
# uwsig使用配置文件启动
[uwsgi]
# 项目目录
chdir=/home/alipay/web/
# 指定项目的application
module=web.wsgi:application
# 指定sock的文件路径
socket=/home/alipay/web/script/uwsgi.sock
# 进程个数
workers=5
pidfile=/home/alipay/web/script/uwsgi.pid
# 指定IP端口
http=0.0.0.0:8000
# 指定静态文件
#static-map=/static=/home/alipay/web/static/
# 启动uwsgi的用户名和用户组
uid=www-data
gid=www-data
# 启用主进程
master=true
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=30
# 设置缓冲
post-buffering=4096
# 设置日志目录
daemonize=/home/alipay/web/script/uwsgi.log
# 权限
chmod-socket = 666
chown-socket = www-data

5.执行命令,启动项目测试

uwsgi --ini uwsgi.ini
在浏览器访问127.0.0.1:8000

6,安装nginx

1.安装nginx
sudo apt-get install python-dev nginx

2.安装完成后,可以使用通过浏览器访问公网IP测试

3.创建项目的配置文件,或者直接修改原nginx配置文件都可以
vim /etc/nginx/sites-available/webtest.conf

server {listen      80;server_name localtion;charset     utf-8;client_max_body_size 75M;location / {uwsgi_pass  unix:///home/alipay/web/script/uwsgi.sock;include     /etc/nginx/uwsgi_params;}#location /media  {#    alias /path/to/project/media;#}location /static {alias /home/alipay/web/static/;}}

4.创建完配置文件后创建软连接
sudo ln -s /etc/nginx/sites-available/webtest.conf /etc/nginx/sites-enabled/webtest.conf

5.启动nginx,重新加载配置文件
nginx -s reload

注意:

1.给当前项目设置访问权限。www-data

2.注意在nginx的配置中uwsgi_pass这一项
uwsgi_pass unix:///home/yc/web/script/uwsgi.sock;
它需要找到你在启动uwsgi后的sock文件,并且要注意权限

3.在使用uwsgi --ini uwsgi.ini启动后会创建 .sock文件
那么在后面更新代码时不需要把 script目录下的文件都删除
只需要重启即可
uwsgi --reload xxx.pid

华为云服务器+Nginx+Python3.7+Django2.2+支付宝支付接入部署相关推荐

  1. docker+nginx+tomcat*3在华为云服务器上的负载均衡

    具体包括: 1,要求部署一台Nginx和三台Tomcat服务器 2,Ngnix需要实现三种策略: 轮询: 权重,三台服务器的权重为1,3,5: IP Hash. 最终实现的效果是,本地电脑通过网页访问 ...

  2. 华为服务器修改root密码,华为云服务器root权限设置密码

    华为云服务器root权限设置密码 内容精选 换一换 如果您需要对购买的ECS资源,给企业中的员工设置不同的访问权限,以达到不同员工之间的权限隔离,您可以使用统一身份认证服务(Identity and ...

  3. 记录一次使用华为云服务器(从零搭建环境)

    系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 华为云服务器使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录 前言 一.购 ...

  4. 华为云服务器使用之搭建极简服务器

    华为云服务器之搭建极简服务器 今天在牛客网看到了华为云服务器的优惠活动,真的是非常优惠,本人正好也想学习一些web开发方面的内容,于是立马下单了. 服务器系统版本:Ubuntu16.04 服务器配值: ...

  5. 部署Django项目到华为云服务器教程

    Ubuntu 20.04 + Python3.7 + mysql5.7 + Django4.1.3 + 宝塔Linux面板 文章目录 1.连接华为云服务器 2.安装宝塔linux面板 3.安装项目对应 ...

  6. 在华为云服务器上部署的web项目,外网不能访问处理方法

    解决方法: 在服务器ping外网可以ping通 外网ping服务器无法ping通,可以判断是网络问题. 在华为云服务器的安全组添加出入站,点默认的default安全组进入编辑页面 分别在入方向规则和出 ...

  7. 华为云服务器linux切换账号,华为云Windows服务器如何切换为Linux系统?

    目前大多数建站程序都跟 Linux 系统比较契合,效率最高,所以老古一直都建议各位站长想要购买云服务器建站就首选 Linux(CentOS)系统,然后安装一个宝塔 Linux 面板就可以轻松简单管理云 ...

  8. 华为云服务器初探二(完结)

    在上一篇<华为云服务器初探> 中介绍了在使用华为云服务器部署时的一些关键点,本篇继续,内容涉及如下: 中间件的部署问题解决 NAT 网关使用 数据库服务的访问 dotNET Core 程序 ...

  9. syslog 华为 服务器_删除华为云服务器自带的探针

    不喜欢服务器上跑着不明的进程,年初入了几个华为云耀云服务器,这一篇记录如何卸载华为云服务器自带的系统探针,系统为Debian 10. 首先我们来看一下服务器有哪些进程: pstree -a 可以查到与 ...

最新文章

  1. CLR Via C# 3rd 阅读摘要 -- Chapter 24 – Runtime Serialization
  2. 关于flock文件锁的阻塞与非阻塞
  3. 关于完美拖拽的问题三
  4. 微软向Chromium贡献代码以优化浏览器滚动体验
  5. 训练日志 2019.3.10
  6. 判断一棵树是否是一颗完全二叉树☆
  7. UIImage 剪裁的方法
  8. 教你10分钟内在Windows上完成Rails开发环境的安装和配置
  9. 从零实现 SPI_flash(W25Q256)
  10. 中文论文检索证明怎么开_作者如何拿到论文检索证明
  11. 介绍一种AI的抠图方法
  12. python反素数_可逆素数-随心随性无为而为-51CTO博客
  13. c++ 中关于引用(1)
  14. Java学习路线·进阶
  15. Win10 WSL初体验
  16. 全球与中国制冷压缩机润滑油市场深度研究分析报告
  17. 微信小程序(6)——使用音频功能
  18. Unity3D屏幕划线附带物理碰撞效果
  19. 设计模式之过滤器模式(摘自菜鸟驿站)
  20. 矩形障碍算例(附Fortran计算代码及MATLAB后处理代码)

热门文章

  1. CSS知识点总结(一)
  2. PHP正则中的i,m,s,x,e分别表示什么
  3. c语言中 float delta,比较float和double值与delta吗?
  4. QT应用编程: 编写MQTT客户端登录OnetNet服务器完成主题订阅与发布
  5. Excel----考勤表制作自动更新日期
  6. bigquant量化平台笔记
  7. 气动调节阀的用途安装知识
  8. 张小龙演讲全文:如何把产品做简单
  9. 实战6:基于OpenCV的人脸口罩识别检测详细教程
  10. 佳德智诚电商:拼多多货物拒收后要如何退款?