目录
django支付宝支付
新建支付宝应用
# 访问"支付宝开发平台"登录,可以访问开发者中心
https://open.alipay.com/platform/home.htm
# 可以参考"电脑网站支付" 熟悉电脑支付整体流程
https://docs.open.alipay.com/270/105899/
创建应用(使用沙箱环境测试)
- 沙箱环境说明
- 线上环境需要创建应用,因为我们不是企业,没有资质,所以只能申请沙箱环境
- 简单来讲沙箱环境就是给开发者使用的测试环境
- 沙箱环境地址: https://openhome.alipay.com/platform/appDaily.htm?tab=info
按照官方要求生成私钥(可以上支付宝开发平台下载支付宝开发助手)
把生成的app公钥粘贴到沙箱的app中
沙箱环境地址: https://openhome.alipay.com/platform/appDaily.htm?tab=info
查看沙箱账号和密码
支付宝开发地址
支付宝开放平台: https://open.alipay.com/platform/home.htm
支付宝沙箱环境: https://openhome.alipay.com/platform/appDaily.htm?tab=info
支付宝开发者文档:https://openhome.alipay.com/developmentDocument.htm
电脑网站支付流程:https://docs.open.alipay.com/270
生成签名:https://docs.open.alipay.com/291/106103/
python-alipay-adk : https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
说明
- 阿里官方没有提供python对接支付的sdk,但是python库中有非官方的sdk包可以使用
- python-alipay-adk : https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
- 使用起来非常简单,只要传入几个必要的参数就可以完成
- 由于支付对安全要求很高,所以要理解对接支付宝安全的流程: 公钥加密、私钥解密 这八个字
在utils中封装请求支付宝扫码地址url的函数和生成订单id的函数
私钥和公钥可以放在app_private_key.pem 和 alipay_public_key.pem文件中。使用时引入
沙箱环境中 app 私钥
private_key_string= open('app_private_key.pem').read()
支付宝公钥
public_key_string = open( 'alipay_public_key.pem').read()
# -*- coding: utf-8 -*- import datetime import os import random from alipay import AliPay private_key_string = '''-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEApNZyqxPGS3xs/p6lpgffgnbvELjReMRz3y2WGhynDeY/vwODsafKy7XDvYPvE6iGXegz4vxtJINOBJprPXqamQvPJq20z/R3CZlCsOEy75Pr77ZRGZbMvzVXGkuavnLQoH40FuRbQYMXt8rLR1GnBS+5Bs5tWNfy94f4x4VroEZ80zVDnQEkzy46fmoi6lZ5r6N/7iXFo0fXdFWlvZJ0EDBF0BdSnHz7nSi6gbAix+VRU2mhyxh/C3ziF8GSuffzfolPORAKj/ws/UCLyBEio6OR0LJPPiulEEYR1cOsm784GHqCh+7C8MWoRmF1UWZ7nwVR+87Ezaq+ksxLxlKwYwIDAQABAoIBACc0RdOAgYIEltu8GcP2Lx1MnO+CNXfWqYRkEDYnqGe64mBo0pKXSLlIgsR5M4xmYYbGKkkLJl4vyId5vpXBqjFKSLt3RvDKwOEMjXsKJJYshUne/8zpO8siQZQkdSpknk/9lB/5seaT6jkxR0WwGtw17Hi88e7WdZf/w+CYT++vUNDR3thzhGSzgXvfrWppP4XMDnW75HJY+MgRo591vsbLwuQgEMTRqaroU1i5+ivDRak6KhKsiJ3QKJYUO1a+0AUTZMuoOo1Vhyn1qYiaRASYov73vK0WZDLd5/K8anBxWXKVwxj5IBivXcotrlaEQzvvcdu/HxH6+WT4VKQHq5kCgYEA9VFat/q6hGGoSgP3byl2ZbqohoEB2dGFGwgoXKGt8wO2tLhJCAGeyU4uLRAGTk6eO9qnAVr7ZsGmEQ1yaMOwRmatJLZze9yjQufkKOkInrXvVUebXdvRmeUtJ4l0NqtrmkrNcJw49HNR0pjSOhN6R9BGUd75l/P/hU3yjoFF7n0CgYEArAPz8UDYvq1ZKico2vjrWIrnsDpvDsgx8L+i73LzKrL9B3ZTimW+7wsIcWhQF1s27qMnQFPjKbEuqWOTi92TbV7BYXbAyQND0V+y0Txbfs54rGwB2A+0kVTP+sLA/x0mqnek3P2gAsl4p9A5A37rNGESgM64hLd5NOauH60S8F8CgYAixyzQRf2txNaB37wVY1BoraS0pNdpVN3E7kwijb1GZXFif3nDC8/CBDZhpxLtyRF/tMjWVVqsv6lWY4yjs5Jq+KV1PfRzS91NX+ilsBvLvEk40tUA4mf9pFLZdxAlq/muPwqO+2bLqQmheI7JMvez9J/zfWPvGeVQtbM8ZrFOVQKBgQCY+nr8V5trGGdv4ZuoAi/rcr1SMOWL0+b2ILgbE7PGiaAV/tmU/5+qn7lGgmqYGvrjiB3kS7Z+4aCJ7JDPlqMCZX692wrguhKaJe21v2Pvhlgzn2qUaINBrJe6f3F8cMRuXjE0iCrBz8OKGthZj4pF7v6xpybagQE+VtkMOrPZKQKBgDQh5Q4510y+ta+mFPb3tum4cXKBAUeRTS6+Us/0wvNVGpvnPGKzIcP+rGXlAO0Nl7O/PTBgejcIILjcS9AuyxPSfSWhlt5DjjzeQ8/J4yrgVAwQeNC28jkmnKBe5K3R+++Si++nYq4/nZ1WEyyginFf2nvQrW2G+rkzMOKvtRn/ -----END RSA PRIVATE KEY-----''' publice_key_string = '''-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApNZyqxPGS3xs/p6lpyVImg1XELjReMRz3y2WGhynDeY/vwODsafKy7XDvYPvE6iGasegz4vxtJINOBJprPXqamQvPJq20z/R3CZlCsOEy75Pr77ZRGZbMvzVXGkuavnLQoH40FuRbQYMXt8rLR1GnBS+5Bs5tWNfy94f4x4VroEZ80zVDnQEkzy46fmoi6lZ5r6N/7iXFo0fXdFWlvZJ0EDBF0BdSnHz7nSi6gbAix+VRU2mhyxh/C3ziF8GSuffzfolPORAKj/ws/UCLyBEio6OR0LJPPiulEEYR1cOsm784GHqCh+7C8MWoRmF1UWZ7nwVR+87Ezaq+ksxLxlKwYwIDAQAB -----END PUBLIC KEY-----''' # udbble1952@sandbox.com ## 获取支付宝url def get_alipay_url(order_id, order_amount, subject): alipay = AliPay( appid="888888888888", # 沙箱appid app_notify_url=None, # 默认回调url app_private_key_string=private_key_string, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, alipay_public_key_string=publice_key_string, sign_type="RSA2", # RSA 或者 RSA2 debug=True, # 默认False,我们是沙箱,所以改成True(让访问沙箱环境支付宝地址) ) # 调用支付接口 # 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string order_string = alipay.api_alipay_trade_page_pay( out_trade_no=order_id, # 订单id,应该从前端获取生成链接地址如下 total_amount=str(order_amount), # 订单总金额 subject=subject, # 付款标题信息 return_url='http://127.0.0.1:8888/payment/callback/', # 付款成功回调地址(可以为空) notify_url=None # 付款成功后异步通知地址(可以为空) ) pay_url = "https://openapi.alipaydev.com/gateway.do?" + order_string return pay_url # 将这个url复制到浏览器,就会打开支付宝支付页面 # 获取订单唯一id def get_order_id(): """ SYL202008241212121200005/24 生成订单号: 格式: SYL + 年月日时分秒 + 5位随机数 :return: """ d = datetime.datetime.now() base = 'SYL' time_str = '%04d%02d%02d%02d%02d%02d' % (d.year, d.month, d.day, d.hour, d.minute, d.second) # 1.4 syl/setings.py中配置支付相关参数 # 2.测试 # 请求地址 # 携带参数 # 返回数据 rand_num = str(random.randint(10000, 99999)) return base + time_str + rand_num
在model.py中定义表
from django.db import models from utils.MyBaseModel import Base # Create your models here. # 商品表 class Goods(Base): GOODS_TYPE = ( ("1", "vip"), ("2", "Course") ) CHANNEL_TYPE = ( ("1", "普通"), ("2", "促销") ) course = models.OneToOneField('course.Course', on_delete=models.PROTECT) goods_type = models.CharField("商品种类", choices=GOODS_TYPE, max_length=8) product_id = models.CharField("产品id", max_length=8) title = models.CharField("商品名称", max_length=24) price = models.DecimalField("商品价格", max_digits=8, decimal_places=2) channel_type = models.CharField("购买渠道", choices=CHANNEL_TYPE, max_length=8) period = models.IntegerField("有效期", default=365) is_launched = models.BooleanField("是否上架", default=True) class Meta: db_table = "tb_goods" def __str__(self): return self.title # 订单表 class Orders(Base): PAY_METHOD = ( ("1", "支付宝"), ) ORDER_STATUS = ( ("1", "待支付"), ("2", "已支付"), ("3", "已取消") ) user = models.ForeignKey('user.User', on_delete=models.PROTECT, verbose_name="下单用户") goods = models.ForeignKey(Goods, on_delete=models.PROTECT) order_id = models.CharField("订单号", max_length=24) trade_no = models.CharField("支付订单号", max_length=32, null=True) pay_time = models.DateTimeField("支付时间", null=True) pay_method = models.CharField("支付方式", choices=PAY_METHOD, default=1, max_length=8) status = models.CharField("支付状态", choices=ORDER_STATUS, default=1, max_length=8) total_amout = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="商品总金额") class Meta: db_table = "tb_orders" def __str__(self): return self.order_id # 用户购买课程表 class UserCourse(Base): user = models.ForeignKey('user.User', on_delete=models.CASCADE) course = models.ForeignKey('course.Course', on_delete=models.CASCADE) class Meta: db_table = "usercourse" def __str__(self): return "用户%s购买的%s" % (self.user, self.course)
在views.py中获取支付宝支付的url的接口和回调接口
from decimal import Decimal from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from .models import Goods, Orders, UserCourse from .serializers import GoodsModelSer, OrdersModelSer from .util import get_order_id, get_alipay_url from course.models import Course # 获取支付宝扫码页面的url class Get_Pay_url(APIView): def post(self,request): # 根据前端发送的商品id获取对应的商品信息 goods_id = request.data.get("goods_id") goods_obj = Goods.objects.get(pk=goods_id) # 获取用户信息 user = request.user # 判断用户的身份对应进行打折 if user.vip.vip_type == "3": goods_price = (goods_obj.price * Decimal('0.60')).quantize(Decimal('0.00')) elif user.vip.vip_type == "2": goods_price = (goods_obj.price * Decimal('0.80')).quantize(Decimal('0.00')) else: goods_price = goods_obj.price # 存入数据库 order = Orders( user= user, goods= goods_obj, order_id= get_order_id(), # 调用在util.py中写的函数获取商品订单id pay_method= 1, status= 1, total_amout= goods_price, ) order.save() subject = "实验楼订单:%s,价格:%s" % (order.order_id, goods_price) # 调用util中的获取支付宝路由的函数并把自己生成的订单id pay_url = get_alipay_url(order_id=order.order_id, order_amount=order.total_amout, subject=subject) return Response({"code":200, "msg": "成功", "data": {"pay_url": pay_url}}) """ # 前端回调返回的数据 { "charset": "utf-8", "out_trade_no": "SYL2020101508522512986", # 我们自己生成的订单id "method": "alipay.trade.page.pay.return", "total_amount": "100.00", # 支付价格 "sign": "HFfe2xBFw/jY8XaJdzuUnqWg9+wPS/PdH7GGigNRScVhfxF94lm2id1eURP/TdvWs4F2HRukJ0Rf/UNzrz4QG18EKiT68ChGrZvIiZHaONY2ok/ix5r68IkQM/7yCB+YF4NrkHDuw92Iy7mLrdKNkOan3+uLgocNuWDTNWo4hT5gCFTxOPPrrWDSJmanX3RPI6HrLsOWUpTcZjhQafAKK0S6Y+bl+MtgfLPV7+hcMesItb/pvsHDRPD1j63VkGuP2mXwW3eDCns3LCn1YfWqjwmutXGqbLEK0HG9NgOKFBL9N6+lBE2lJqfdSo79vMY9cv7287ZvC1b07cygLXMVDA==", "trade_no": "2020101522001458970501542142", # 支付宝的支付id "auth_app_id": "2016103000778269", "version": "1.0", "app_id": "2016103000778269", "sign_type": "RSA2", "seller_id": "2088102181451641", "timestamp": "2020-10-15 16:52:56" # 支付时间 } """ # 支付宝回调地址 class PeyMent(APIView): def post(self, request): # 获取前端发送的数据 order_id = request.data.get("out_trade_no") # 自己生成的订单id trade_no = request.data.get("trade_no") # 支付宝返回的支付宝订单id pay_time = request.data.get("timestamp") # 创建时间 # 根据订单id获取到对应的订单信息 orders = Orders.objects.get(order_id=order_id) # 修改订单状态,支付时间,支付宝的订单id orders.trade_no = trade_no orders.pay_time = pay_time orders.status = 2 orders.save() # 根据订单获取到对应的商品然后获取到对应的课程 course_obj = Course.objects.get(pk=orders.goods.course_id) # 存到用户购买课程表中 user = UserCourse(user=request.user, course=course_obj) user.save() return Response({"code":200, "msg": "支付成功"})
前端vue
生成订单, 获取支付链接
// 生成订单, 获取支付链接 pay() { // goods_id: 课程id payurl_post({ goods_id: this.goods.id }).then((resp) => { console.log(resp) let pay_url = resp.data.pay_url // debugger window.location = pay_url }) },
回调页面
<template> <div> 这里是支付回调地址, 把数据发送给后端 参数是: {{query}} <p> 支付结果是: {{msg}} </p> </div> </template> <script> import { payment_post } from './axios_api/api'; export default { data() { return { query: '', msg: '', //支付结果 } }, mounted() { this.query = this.$route.query payment_post(this.query).then((resp) => { // ({"code": 999, "msg": "非法请求"}) this.msg = resp.msg }) }, } </script>
POJ 1061 青蛙的约会(拓展欧几里得)
How Many Zeroes? LightOJ
HDU
A
mysql中函数cast使用
Django基础08篇 filter&tag
Django基础07篇 ORM操作
Django基础06篇 分页
Django 基础05篇 上下文管理和前端代码复用
Copyright © 2011-2022 走看看