支付宝支付原理与后端代码
## 支付宝支付原理
1.首先,需要在支付宝的沙箱环境中,创建一个应用
https://openhome.alipay.com/platform/appDaily.htm?tab=info
2.然后按照官方要求生成密钥
3.把生成的app公钥粘贴到沙箱环境的app中
之后查看沙箱环境的账号和密码
代码:
1.首先建一个keys文件夹,然后建两个文件夹,用来存放app私钥和支付宝公钥
app_private_key.pem
app私钥
-----BEGIN RSA PRIVATE KEY-----
自己的app私钥
-----END RSA PRIVATE KEY-----
alipay_public_key.pem
支付宝公钥
-----BEGIN PUBLIC KEY-----
支付宝的公钥
-----END PUBLIC KEY-----
注意,两个文件中的格式并不一样,请仔细
自己建立一个py文件来测试一下
from alipay import AliPay
# 沙箱环境中 app 私钥
app_private_key_string = open('app_private_key.pem').read()
alipay_public_key_string = open('alipay_public_key.pem').read()
def get_alipay_url():
alipay = AliPay(
appid='2016102600762844', # 沙箱appid
app_notify_url=None, #默认回调URL
app_private_key_string=app_private_key_string, # 支付宝公钥,验证支付宝回传消息使用,不是自己的公钥
alipay_public_key_string=alipay_public_key_string,
sign_type='RSA2', # RSA or RSA2
debug=True, # 默认False,因为是沙箱,所以改成True(让访问沙箱环境支付宝地址)
)
# 调用支付接口
# 电脑网站支付,需要跳转到 https://openapi.alipay.com/gateway.do? + order_string
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no='201612226', # 订单id,应该从前端获取
total_amount=str(0.01), # 订单总金额
subject='测试阿里云付款', # 付款标题信息
return_url=None, # 付款成功回调地址(可以为空)
notify_url=None, # 付款成功后异步通知地址(可以为空)
)
pay_url = "https://openapi.alipaydev.com/gateway.do?" + order_string
get_alipay_url()
SYL
项目
goods.views
中:
from rest_framework.viewsets import ModelViewSet
from . import models
from .models import Orders
from course.models import UserCourse
from .serializers import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny, IsAuthenticated
from goods.utils import get_order_id, get_pay_url, alipay
from decimal import Decimal
# 生成订单页面
class PayUrlView(APIView):
''' 生成支付链接返回给前端,生成订单表(未支付)'''
permission_classes = (IsAuthenticated,)
def post(self,request):
goods_id = request.data.get('goods_id')
goods = Goods.objects.get(id=goods_id)
user = request.user
# 2. 下定单
order_id = get_order_id()
if user.vip.vip_type == '1': # 普通会员
goods_price = goods.price * Decimal('0.80').quantize(Decimal('0.00'))
elif user.vip.vip_type == '2': # 高级会员
goods_price = goods.price * Decimal('0.60').quantize(Decimal('0.00'))
else: # 普通用户
goods_price = goods.price
goods_price = Decimal(goods_price).quantize(Decimal('0.00'))
order = Orders(user=user, goods=goods, order_id=order_id, pay_method=1, status=1, total_amount=goods_price)
print()
order.save()
print(order.total_amount, type(order.total_amount))
# 3. 根据订单 生成支付链接
subject = "实验楼订单:%s, 价格:%s" % (order.order_id, order.total_amount)
pay_url = get_pay_url(order.order_id, order.total_amount, subject)
print(pay_url)
return Response({"code": 0, "msg": "下单成功", "data": {"pay_url": pay_url}})
# 订单回调与修改支付状态
class PeymentView(APIView):
def post(self,request):
# 1. 获取了支付宝返回的数据
data = request.data
sign = data.pop('sign')
# 查询到对应的订单
order = Orders.objects.get(order_id=data['out_trade_no'])
# 添加下单和支付时间
order.trade_no = data['trade_no']
order.pay_time = data['timestamp']
# 修改状态
order.status = 2
# 提交事务
order.save()
user = order.user
course = order.goods.course
UserCourse.objects.create(user=user, course=course)
return Response({'code': 0, 'msg': '购买成功'})
自建工具py文件
goods.utils
中:
import datetime
import os
import random
from alipay import AliPay
from syl import settings
app_private_key_path = os.path.join(settings.BASE_DIR, "apps/goods/keys/app_private_key.pem")
alipay_public_key_path = os.path.join(settings.BASE_DIR, "apps/goods/keys/alipay_public_key.pem")
with open(app_private_key_path) as f:
app_private_key_string = f.read()
with open(alipay_public_key_path) as f:
alipay_public_key_string = f.read()
# 创建支付宝支付对象
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None, # 默认回调url
app_private_key_string=app_private_key_string,
alipay_public_key_string=alipay_public_key_string,
# app_private_key_path=app_private_key_path,
# alipay_public_key_path=alipay_public_key_path,
sign_type="RSA2",
debug=settings.ALIPAY_DEBUG
)
def get_pay_url(out_trade_no, total_amount, subject):
# 生成登录支付宝连接
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=out_trade_no,
total_amount=str(total_amount),
subject=subject,
return_url=settings.ALIPAY_RETURN_URL,
)
alipay_url = settings.ALIPAY_URL + "?" + order_string
# print(alipay_public_key_string)
# print(app_private_key_string)
return alipay_url
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)
rand_num = str(random.randint(10000, 99999))
return base + time_str + rand_num