0
点赞
收藏
分享

微信扫一扫

开源web框架django知识总结(二十二)

自由情感小屋 2022-05-01 阅读 93

开源web框架django知识总结(二十二)

支付

支付宝介绍

  • https://open.alipay.com/platform/home.htm
    在这里插入图片描述

1.使用手机上的支付宝扫码登录

2. 创建应用和沙箱环境

2.沙箱环境

支付宝提供给开发者的模拟支付的环境。跟真实环境是分开的。

沙箱应用:https://openhome.alipay.com/platform/appDaily.htm?tab=info
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置支付宝“应用公钥”,“支付宝公钥”
在这里插入图片描述

沙箱账号:https://openhome.alipay.com/platform/appDaily.htm?tab=account
在这里插入图片描述
在这里插入图片描述

买家账号sdkywg1362@sandbox.com
登录密码111111
支付密码111111
用户名称沙箱环境
证件类型身份证(IDENTITY_CARD)
证件号码847038195010111148
账户余额
2016215.53充值取现

3. 支付宝开发文档

  • 文档主页: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

    • SDK安装:pip install python-alipay-sdk==2.0.1
      在这里插入图片描述
  1. 电脑网站支付流程
    在这里插入图片描述

5.新建apps --> payment,注册,添加主路由,添加子urls.py

6.配置RSA2公/私钥

提示:

  • 阿尔法商城私钥加密数据,阿尔法商城公钥解密数据。
  • 支付宝私钥加密数据,支付宝公钥解密数据。

1.生成 阿尔法商城公/私钥
在这里插入图片描述

========================================================

对接支付宝系统

订单支付功能

  • 订单支付触发页面:《order_success.html》 和 《user_center_order.html》
  • 我们实现订单支付功能时,只需要向支付宝获取登录链接即可,进入到支付宝系统后就是用户向支付宝进行支付的行为。
    在这里插入图片描述
选项方案
请求方法GET
请求地址/payment/(?P<order_id>\d+)/
参数名类型是否必传说明
order_idint订单编号
字段说明
code状态码
errmsg错误信息
alipay_url支付宝登录链接

payment.views.py

from django.views import View
from django.http import JsonResponse
from django.conf import settings
from orders.models import OrderInfo
from .models import Payment
from alipay import AliPay
import os


class PaymentView(View):

    # 接口1、获取支付页面链接
    def get(self, request, order_id):
        # 1、提取参数
        # 2、校验参数
        try:
            order = OrderInfo.objects.get(pk=order_id)
        except OrderInfo.DoesNotExist as e:
            print(e)
            return JsonResponse({'code': 400, 'errmsg': '订单不存在!'}, status=404)

        # 3、获取支付页面链接  默认回调url
        alipay_url = None

        with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_private_key.pem'), "r") as f:
            app_private_key = f.read()
        with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_public_key.pem'), "r") as f:
            alipay_public_key = f.read()

        # 3.1 构建一个Alipay对象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            # 异步回调,支付成功之后,阿里后台主动请求阿尔法
            app_notify_url=None,
            # 阿尔法私钥
            app_private_key_string=app_private_key,
            # 阿里公钥
            alipay_public_key_string=alipay_public_key,
            sign_type='RSA2',
            debug=settings.ALIPAY_DEBUG
        )

        # 3.2 调用对象的方法
        # 扫码页面完整的链接是:
        # https://openapi.alipaydev.com/gateway.do?<查询字符串参数>
        # order_string = alipay.api_alipay_trade_app_pay() # 移动端
        # 网页端
        order_string = alipay.api_alipay_trade_page_pay(
            subject='阿尔法商城%s'%order_id,
            out_trade_no=order_id,
            total_amount=float(order.total_amount),
            # 支付成功之后,用户页面跳转地址
            return_url=settings.ALIPAY_RETURN_URL
        )

        # 4、构建响应返回
        alipay_url = settings.ALIPAY_URL + '?' + order_string

        return JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'alipay_url': alipay_url
        })

5.支付宝SDK配置参数

dev.py

# 阿里支付配置参数
ALIPAY_APPID = '2016102500755751'
ALIPAY_DEBUG = True
ALIPAY_URL = 'https://openapi.alipaydev.com/gateway.do'
ALIPAY_RETURN_URL = "http://127.0.0.1/pay_success.html"

=================================

保存订单支付结果

1. 支付结果数据说明

  • 用户订单支付成功后,支付宝会将用户重定向到 http://127.0.0.1:8000/payment/status/,并携带支付结果数据。
  • 参考统一收单下单并支付页面接口:https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay?scene=API002020081300013629
  1. 定义支付结果模型类
from django.db import models
from aerf_mall.utils.BaseModel import BaseModel
from orders.models import OrderInfo


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

3. 保存订单支付结果

选项方案
请求方法GET
请求地址/payment/status/

参考统一收单下单并支付页面接口中的《页面回跳参数》

3.响应结果:HTML

pay_success.html

4.后端接口定义和实现

注意:保存订单支付结果的同时,还需要修改订单的状态为待评价

class PaymentStatusView(View):

    def put(self, request):
        # 用户支付成功之后,跳转回阿尔法页面的请求
        # 校验是否支付成功

        # 1、提取查询字符串参数
        data = request.GET # QueryDict类型
        data = data.dict() # QueryDict.dict()转化成普通字典
        # 提取签名(token值)
        sign = data.pop('sign')

        with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_private_key.pem'), "r") as f:
            app_private_key = f.read()
        with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_public_key.pem'), "r") as f:
            alipay_public_key = f.read()

        # 2、根据签名验证数据是否完整
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            # 异步回调,支付成功之后,阿里后台主动请求阿尔法
            app_notify_url=None,
            # 阿尔法私钥
            app_private_key_string=app_private_key,
            # 阿里公钥
            alipay_public_key_string=alipay_public_key,
            sign_type='RSA2',
            debug=settings.ALIPAY_DEBUG
        )
        if not alipay.verify(
            data,
            signature=sign
        ):
            return JsonResponse({'code': 400, 'errmsg': '支付失败!'}, status=400)

        # 3、阿尔法订单号和支付宝流水号关联
        order_id = data.get('out_trade_no')
        trade_id = data.get('trade_no')

        try:
            Payment.objects.create(
                order_id=order_id,
                trade_id=trade_id,
            )
        except Exception as e:
            print(e)
            return JsonResponse({
                'code': 400,
                'errmsg': '支付订单保存失败!'
            })

        # 修改订单状态
        OrderInfo.objects.filter(
            order_id=order_id
        ).update(
            status=OrderInfo.ORDER_STATUS_ENUM['UNSEND']
        )

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

payment.urls.py

from django.urls import re_path
from . import views

urlpatterns = [
# 订单支付
    re_path(r'^payment/(?P<order_id>\d+)/$', views.PaymentView.as_view()),
# 订单支付状态
    re_path(r'^payment/status/$', views.PaymentStatusView.as_view()),
]
举报

相关推荐

0 条评论