Django实现支付宝支付(沙箱环境)

python编程快速上手(持续更新中…)

python实战项目(Django技术点)


1. 创建应用和沙箱环境

沙箱应用:https://openhome.alipay.com/platform/appDaily.htm?tab=info

扫码注册
在这里插入图片描述
在这里插入图片描述

沙箱账号:https://openhome.alipay.com/platform/appDaily.htm?tab=account

额度可以自行修改
在这里插入图片描述

2. 支付宝开发文档

文档主页: https://openhome.alipay.com/developmentDocument.htm
电脑网站支付产品介绍: https://docs.open.alipay.com/270
电脑网站支付快速接入: https://docs.open.alipay.com/270/105899/
API列表: https://docs.open.alipay.com/270/105900/
SDK文档: https://docs.open.alipay.com/270/106291/
Python支付宝SDK: https://github.com/fzlee/alipay/blob/master/README.zh-hans.md

3. 电脑网站支付流程

在这里插入图片描述

4. 配置RSA2公私钥

提示:

美多商城私钥加密数据,美多商城公钥解密数据。
支付宝私钥加密数据,支付宝公钥解密数据。
在这里插入图片描述

生成RSA2密钥

1.Linux中生成公私钥

$ openssl
$ OpenSSL> genrsa -out app_private_key.pem 2048 # 制作私钥RSA2
$ OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥

$ OpenSSL> exit

2.配置美多商城公私钥

配置美多商城私钥

a.新建子应用pay,在该子应用下新建文件夹keys用于存储公私钥
将制作的美多商城私钥app_private_key.pem拷贝到keys文件夹中。
在这里插入图片描述

b.将payment.keys.app_public_key.pem文件中内容上传到支付宝。
在这里插入图片描述
在这里插入图片描述
3.配置支付宝公钥
将支付宝公钥内容拷贝到应用key文件夹下:payment.keys.alipay_public_key.pem文件中。

-----BEGIN PUBLIC KEY-----
支付宝公钥内容
-----END PUBLIC KEY-----

在这里插入图片描述

5.订单支付功能

提示:

订单支付触发页面:《order_success.html》 和 《user_center_order.html》

我们实现订单支付功能时,只需要向支付宝获取登录链接即可,进入到支付宝系统后就是用户向支付宝进行支付的行为。

1.请求方式

选项方案
请求方法GET
请求地址/payment/(?P<order_id>\d+)/

2.请求参数:路径参数

参数名类型是否必传说明
order_idint订单编号

3.响应结果:JSON

字段说明
code状态码
errmsg错误信息
alipay_url支付宝登录链接

4.后端接口定义和实现

A.创建子应用

django-admin startapp pay

B.添加模块

INSTALLED_APPS = [
‘apps.pay’,
]

C.配置路由

urlpatterns = [
path(‘payment/<order_id>/’,PayUrlView.as_view()),
]

urlpatterns = [
path(’’,include(‘apps.pay.urls’)),
]

D.业务逻辑

"""
需求:
    当用户点击去支付按钮的时候,要后端生成一个跳转的连接

前端:
        axios 请求. 携带 订单id
后端:

    请求:             获取订单id
    业务逻辑:          生成支付宝链接(读取文档)
                    读取应用私钥和支付宝公钥
                    创建支付宝实例,调用支付宝的方法
                    拼接连接
    响应:
    路由:     GET    payment/order_id/ 
    步骤:
        1. 获取订单id
        2. 验证订单id (根据订单id查询订单信息)
        3. 读取应用私钥和支付宝公钥
        4. 创建支付宝实例
        5. 调用支付宝的支付方法
        6.  拼接连接
        7. 返回响应

"""
from django.views import View
from apps.orders.models import OrderInfo
from utils.views import LoginRequiredJSONMixin
from django.http import JsonResponse
from meiduo_mall import settings
from alipay import AliPay, AliPayConfig


class PayUrlView(LoginRequiredJSONMixin, View):

    def get(self, request, order_id):
        user = request.user
        # 1. 获取订单id
        # 2. 验证订单id (根据订单id查询订单信息)
        try:
            # 为了业务逻辑的准确性,
            # 查询待支付的订单
            order = OrderInfo.objects.get(order_id=order_id,
                                          status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'],
                                          user=user)
        except OrderInfo.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': '没有此订单'})
        # 3. 读取应用私钥和支付宝公钥

        app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
        alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()
        # 4. 创建支付宝实例
        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,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG,  # 默认False
            config=AliPayConfig(timeout=15)  # 可选, 请求超时时间
        )
        # 5. 调用支付宝的支付方法
        # 如果你是 Python 3的用户,使用默认的字符串即可
        subject = "多多商城测试订单"

        # 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        # https://openapi.alipay.com/gateway.do 这个是线上的
        # 'https://openapi.alipaydev.com/gateway.do' 这个是沙箱的
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,
            total_amount=str(order.total_amount),  # 一定要进行类型转换,因为decimal不是基本数据类型
            subject=subject,
            return_url=settings.ALIPAY_RETURN_URL,  # 支付成功之后,跳转的页面
            notify_url="https://example.com/notify"  # 可选, 不填则使用默认notify url
        )
        # 6.  拼接连接
        pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string
        # 7. 返回响应
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'alipay_url': pay_url})

E.我的测试
在这里插入图片描述
在这里插入图片描述

异常:Crtl+Shift+delete,清空浏览器缓存
在这里插入图片描述

5.添加交易记录

添加模型

# Create your models here.
from django.db import models
from apps.orders.models import OrderInfo
from utils.models import BaseModel

class Payment(BaseModel):
    """支付信息"""
    order = models.ForeignKey(OrderInfo, on_delete=models.CASCADE, verbose_name='订单')
    trade_id = models.CharField(max_length=100, unique=True, null=True, blank=True, verbose_name="支付编号")

    class Meta:
        db_table = 'tb_payment'
        verbose_name = '支付信息'
        verbose_name_plural = verbose_name

代码实现

"""
前端:
        当用户支付完成之后,会跳转到 指定商品页面
        页面中的请求 查询字符串中有 支付相关信息
        前端把这些数据提交给后端就可以了
后端:
    请求:         接收数据
    业务逻辑:       查询字符串转换为字典,验证数据,验证没有问题获取支付宝交易流水号
                  改变订单状态
    响应: 
    路由:     PUT     payment/status/
    步骤:
        1. 接收数据
        2. 查询字符串转换为字典 验证数据
        3. 验证没有问题获取支付宝交易流水号
        4. 改变订单状态
        5. 返回响应


买家账号eghulw5253@sandbox.com
登录密码111111
支付密码111111
"""
from apps.pay.models import Payment


class PaymentStatusView(View):

    def put(self, request):
        # 1. 接收数据
        data = request.GET
        # 2. 查询字符串转换为字典 验证数据
        data = data.dict()

        # 3. 验证没有问题获取支付宝交易流水号
        signature = data.pop("sign")

        app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
        alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).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,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG,  # 默认False
            config=AliPayConfig(timeout=15)  # 可选, 请求超时时间
        )
        success = alipay.verify(data, signature)
        if success:
            # 获取 trade_no	String	必填	64	支付宝交易号
            trade_no = data.get('trade_no')
            order_id = data.get('out_trade_no')
            Payment.objects.create(
                trade_id=trade_no,
                order_id=order_id
            )
            # 4. 改变订单状态

            OrderInfo.objects.filter(order_id=order_id).update(status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])

            return JsonResponse({'code': 0, 'errmsg': 'ok', 'trade_id': trade_no})
        else:

            return JsonResponse({'code': 400, 'errmsg': '请到个人中心的订单中查询订单状态'})

展示鲜果

在这里插入图片描述

  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值