python-django-对接支付宝步骤

文章目录

      • 接入步骤
      • 支付宝流程步骤如下

我们再web开发中,经常会遇到接入QQ登录,微信登录,支付宝支付,微信登录等等需求,以下针对python接入支付宝的流程进行总结。

接入步骤

  • 目前支付宝的官方文档中,暂不支持python版本(凭什么?)
    python-django-对接支付宝步骤_第1张图片

  • github上有大神写出了python对接支付宝的教程,大家可以参考https://github.com/fzlee/alipay/blob/master/README.zh-hans.md

  • # 安装python-alipay-sdk
    pip install python-alipay-sdk --upgrade
    # 对于python2, 请安装2.0以下版本: pip install python-alipay-sdk==1.1
    

支付宝流程步骤如下

python-django-对接支付宝步骤_第2张图片

  • 这里面有两对密钥对

    • 支付宝维护一对, 在我们的支付宝沙箱环境中能拿到支付宝的公钥,我们先拿着支付宝的公钥对我们的订单进行签名,支付宝那边接受到请求拿着自己的私钥进行验签,这样可以避免别人的恶意请求,因为公钥和私钥是配对的,别人拿不到支付宝的公钥。
    • 我们也要把我们应用的公钥给支付宝,在我们完成支付的时候支付宝会拿着我们应用公钥对支付订单,支付流水号等进行签名,然后我们后端就得拿着我们自己应用私钥进行验签。
    • 这两队签名和验签步骤都可以参考上面支付宝流程图
  • 生成密钥的两种方式

    • openssl # openssl 是Linux自带的 在终端即可执行
      OpenSSL> genrsa -out app_private_key.pem   2048  # 私钥
      OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 导出公钥
      OpenSSL> exit   # 注意这个生成的密钥会在当前路径下 
      

python-django-对接支付宝步骤_第3张图片

  • 点击下载 这是一个app,安装好后会生成密钥对
    python-django-对接支付宝步骤_第4张图片

  • 支付宝的私钥支付宝自己保存了,我们需要将我们的公钥交给我们的沙箱
    python-django-对接支付宝步骤_第5张图片
    支付宝公钥我们复制,保存起来,因为等一下参数要用到。
    python-django-对接支付宝步骤_第6张图片
    因为我们在沙箱环境中已经设置了应用公钥,所以这里没有必要将应用公钥放进来
    python-django-对接支付宝步骤_第7张图片

  • 注意,还需要在公钥文件中补充开始与结束标志

    -----BEGIN PUBLIC KEY-----
    此处是公钥内容
    -----END PUBLIC KEY-----
    

这一步做完了之后配置就完成啦,当我们创建完订单选择支付宝付款后,我们后端就需要请求支付宝,支付宝接收我的订单拼接url用户尽心登录,输入密码,确认支付

app_private_key_str = open(r'/home/python/Desktop/2020jxsz_teach/student_items/selfblog/SelfBlog/order/keys/app_private_key.pem').read()
alipay_public_key_str = open(r'/home/python/Desktop/2020jxsz_teach/student_items/selfblog/SelfBlog/order/keys/alipay_public_key.pem').read()
class AliPayView(APIView):
    def get(self, request, order_id):
        # 向支付宝发起请求,获取支付链接参数
        print("订单号为:", order_id)

        alipay_client = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string = app_private_key_str,
            alipay_public_key_string=alipay_public_key_str,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False  是否是沙箱环境 True 代表沙箱
        )
        try:
            order = OrderInfo.objects.get(order_id=order_id)
        except OrderInfo.DoesNotExist:
            return Response({"msg":"非法请求,不存在此订单"}, status= status.HTTP_400_BAD_REQUEST)
        # 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay_client.api_alipay_trade_page_pay(
            out_trade_no=order_id,  # 订单编号
            total_amount=str(order.total_amount),  # 总金额
            subject='昆仑的数据展示:%s' % order_id,
            return_url="http://127.0.0.1:8000/order/success/",
            notify_url=None  # 可选, 不填则使用默认notify url
        )

        # 拼接支付链接网址
        alipay_url = settings.ALIPAY_URL + '?' + order_string
        return Response({"alipay_url":alipay_url, "msg":"SUCCESS"}, status = 200)

完成支付后,支付宝会返回回调url,回调url由我们调用支付宝接口时传递的return_url参数指定,支付宝返回给我们的签名,支付宝付款流水等信息拼接在该url后面

我们在支付完成后也需要完成后端逻辑,比如既然完成了支付,我们的商品状态就应该由为支付改为已支付,销量+1等,但记住,在执行这些逻辑之前必须得先用应用公钥进行验签,不然可能会被人冒用支付宝而篡改我们订单。

class OrderSuccessView(APIView):
    def get(self, request):
        # 接收参数
        # 校验
        alipay_req_data = request.query_params  # QueryDict
        if not alipay_req_data:
            return Response({'message': "缺少参数"}, status=status.HTTP_400_BAD_REQUEST)

        alipay_req_dict = alipay_req_data.dict()
        sign = alipay_req_dict.pop('sign')
        alipay_client = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string=app_private_key_str,
            alipay_public_key_string=alipay_public_key_str,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False  是否是沙箱环境
        )

        # 返回验证结果,True False
        result = alipay_client.verify(alipay_req_dict, sign) # 验签
        print(alipay_req_dict)
        print(result,"result")
        if  result:
            order_id = alipay_req_dict.get('out_trade_no')
            trade_id = alipay_req_dict.get('trade_no')
            # 保存数据
            #   保存支付结果数据Payment
            Payment.objects.create(
                order_id=order_id,
                trade_id=trade_id
            )
            #  修改订单状态
            OrderInfo.objects.filter(order_id=order_id).update(status=5)
            return Response({'trade_id': trade_id})
        else:
            return Response({'message': '参数有误'}, status=status.HTTP_400_BAD_REQUEST)

alipay_client.verify(alipay_req_dict, sign) 进行验签,结果为True代表验证通过。那么就表示时支付宝发送过来的请求。

下面贴出我的一些执行流程,界面比较丑,见谅。
python-django-对接支付宝步骤_第8张图片
首页,想做个博客,还没成功,后续会慢慢更新。
python-django-对接支付宝步骤_第9张图片
提交订单
python-django-对接支付宝步骤_第10张图片
订单支付页面
python-django-对接支付宝步骤_第11张图片
进行支付,不过这里的账号不是你真正的支付宝的账号,而是要你支付宝沙箱环境里面拿

点这里: https://openhome.alipay.com/platform/appDaily.htm?tab=account
python-django-对接支付宝步骤_第12张图片
python-django-对接支付宝步骤_第13张图片
以上是我的测试数据。

python-django-对接支付宝步骤_第14张图片
沙箱环境,想充多少就充多少。

以上,希望大家一同交流

项目git地址:https://gitee.com/hanzhou521/selfblog.git

你可能感兴趣的:(dajngo,python)