Python Django框架--添加支付宝支付功能

Python Django框架--添加支付宝支付功能

      支付宝没有提供Python SDK。生成预付订单需要使用SHA1withRSA签名,签名的生成比较麻烦容易出错。这里提供了一个简单的库,希望能够简化一些Python开发的流程。

安装 & 开发文档说明

python对接支付宝SDK安装pip install python-alipay-sdk --upgrade

python对接支付宝SDKhttps://github.com/fzlee/alipay/blob/master/README.zh-hans.md

支付宝开发文档快速接入https://docs.open.alipay.com/270/105899/

接入步骤

1.创建应用

          注册为支付宝开发者,创建应用并获取APPID 。

2. 生成应用的公钥 & 私钥

      使用下列指令,创建应用的公钥&密钥文件,把应用公钥设置到alipay中,把alipay的公钥复制到应用文件中(在pay子应用中创建keys目录,分别存放应用私钥&alipay公钥)。

openssl
# 生成应用私钥
genrsa -out app_private_key.pem   2048  
# 生成应用公钥
rsa -in app_private_key.pem -pubout -out app_public_key.pem 

3 .搭建 & 配置开发环境(测试开发使用沙箱环境) 

# 支付宝支付-配置
ALIPAY_APPID = "20160917xxx"                             # appid 
ALIPAY_URL = "https://openapi.alipaydev.com/gateway.do"  # 沙箱环境
ALIPAY_DEBUG = True                                      # DEBUG模式

# 应用私钥文件路径
APP_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'apps/pay/keys/app_private_key.pem')
# 支付宝公钥文件路径
ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR, 'apps/pay/keys/alipay_public_key.pem')

4. 根据开发文档 & 支付宝对接流程,调用接口

具体代码如下

from alipay import AliPay
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from mall import settings
from orders.models import OrderInfo
from pay.models import Payment


class AlipayView(APIView):
    """
    支付宝-支付
    接口分析:
    GET     /pay/orders/(?P<order_id>/d+)/
    请求参数: order_id
    返回值: alipay_url
    """
    permission_classes = [IsAuthenticated]

    def get(self, request, order_id):
        user = request.user
        # 1. 根据order_id, 验证订单对象是否存在
        try:
            order = OrderInfo.objects.get(pk=order_id, user=user,
                                          status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
        except OrderInfo.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 2. 创建alipay对象, 生成order_string,拼接alipay的url
        app_private_key_string = open("apps/pay/keys/app_private_key.pem").read()
        alipay_public_key_string = open("apps/pay/keys/alipay_public_key.pem").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
        )

        # 如果你是 Python 3的用户,使用默认的字符串即可
        subject = "测试订单"

        # 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,                   # order_id
            total_amount=str(order.total_amount),     # 订单总金额,需要转换成str类型,因为JSON不支持Decimal货币类型
            subject=subject,
            return_url='http://www.DJ.com:8080/pay_success.html',   # 成功回调地址
            notify_url=None  # 可选, 不填则使用默认notify url
        )

        # 拼接url
        alipay_url = settings.ALIPAY_URL + '?' + order_string

        # 返回拼接的alipay_url
        return Response({'alipay_url': alipay_url})


class AlipayStatusView(APIView):
    """
    支付宝-支付状态
    POST    /pay/payment/status/?
    思路分析:
    1. 后端接收前端发送的支付状态数据data,获取标记数据signature
    2. 创建alipay对象, 将data & signature传递过去,获取支付状态
    3. 如果支付成功,保存支付编号&订单号到数据表,修改订单的状态(未支付-未发货),返回支付编号&成功信息
    4. 如果支付未成功, 则返回错误信息
    """

    def post(self, request):
        # 后端接收前端发送的支付状态数据,转换成字典类型,获取signature
        data_dict = request.query_params.dict()
        signature = data_dict.pop('sign')

        # 创建alipay对象, 将data & signature传递过去,获取支付状态
        app_private_key_string = open("apps/pay/keys/app_private_key.pem").read()
        alipay_public_key_string = open("apps/pay/keys/alipay_public_key.pem").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
        )

        success = alipay.verify(data_dict, signature)

        if success:
            order_id = data_dict.get('out_trade_no')   # 商户订单号
            trade_id = data_dict.get('trade_no')           # 交易编号

            # 如果支付成功,保存支付编号&订单号到数据表,修改订单的状态(未支付-未发货)
            Payment.objects.create(order_id=order_id, trade_id=trade_id)

            OrderInfo.objects.filter(pk=order_id).update(
                status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
            return Response({'trade_id':trade_id}, status=status.HTTP_200_OK)
        else:
            return Response({'message':'订单支付失败'}, status=status.HTTP_400_BAD_REQUEST)



-------------------------- END ------------------------

猜你喜欢

转载自blog.csdn.net/Refrain__WG/article/details/81710777