支付宝支付原理与后端代码

## 支付宝支付原理

在这里插入图片描述

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

posted @ 2020-10-26 21:32  天听  阅读(574)  评论(0)    收藏  举报