zoukankan      html  css  js  c++  java
  • 支付宝接口参数

    支付宝支付

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    # 1、在沙箱环境下实名认证:https://openhome.alipay.com/platform/appDaily.htm?tab=info
    # 2、电脑网站支付API:https://docs.open.alipay.com/270/105898/
    # 3、完成RSA密钥生成:https://docs.open.alipay.com/291/105971
    # 4、在开发中心的沙箱应用下设置应用公钥:填入生成的公钥文件中的内容
    # 5、Python支付宝开源框架:https://github.com/fzlee/alipay
    # >: pip install python-alipay-sdk --upgrade
    # 7、公钥私钥设置
    """
    # alipay_public_key.pem
    -----BEGIN PUBLIC KEY-----
    支付宝公钥
    -----END PUBLIC KEY-----
    # app_private_key.pem
    -----BEGIN RSA PRIVATE KEY-----
    用户私钥
    -----END RSA PRIVATE KEY-----
    """
    # 8、支付宝链接
    """
    开发:https://openapi.alipay.com/gateway.do
    沙箱:https://openapi.alipaydev.com/gateway.do
    """

    1

     2

     3

     4

     5

    支付流程

     

    aliapy二次封装包

    依赖
    1
    >: pip install python-alipay-sdk

      

    结构
    1
    2
    3
    4
    5
    6
    7
    libs
        ├── iPay                            # aliapy二次封装包
        │   ├── __init__.py                 # 包文件
        │   ├── keys                        # 密钥文件夹
        │   │   ├── alipay_public_key.pem   # 支付宝公钥
        │   │   └── app_private_key.pem     # 应用私钥
        └── └── settings.py                 # 应用配置 

      

    setting.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import os
    # 支付宝应用id
    APP_ID = '2016093000631831'
    # 默认异步回调的地址,通常设置None就行
    APP_NOTIFY_URL = None
    # 应用私钥文件路径
    APP_PRIVATE_KEY_PATH = os.path.join(os.path.dirname(__file__), 'keys', 'app_private_key.pem')
    # 支付宝公钥文件路径
    ALIPAY_PUBLIC_KEY_PATH = os.path.join(os.path.dirname(__file__), 'keys', 'alipay_public_key.pem')
    # 签名方式
    SIGN_TYPE = 'RSA2'
    # 是否是测试环境 - 是否是支付宝沙箱
    DEBUG = True
    # 支付连接
    DEV_PAY_URL = 'https://openapi.alipaydev.com/gateway.do?'
    PROD_PAY_URL = 'https://openapi.alipay.com/gateway.do?'

      

    __init__.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from alipay import AliPay
    from .settings import *
    # 对外提供支付对象
    alipay = AliPay(
        appid=APP_ID,
        app_notify_url=APP_NOTIFY_URL,
        app_private_key_path=APP_PRIVATE_KEY_PATH,
        alipay_public_key_path=ALIPAY_PUBLIC_KEY_PATH,
        sign_type=SIGN_TYPE,
        debug=DEBUG
    )
    # 对外提供的支付链接前缀
    pay_url = DEV_PAY_URL if DEBUG else PROD_PAY_URL

      


    alipay_public_key.pem
    1
    2
    3
    -----BEGIN PUBLIC KEY-----
    支付宝公钥
    -----END PUBLIC KEY-----<br># 在支付宝生成秘钥的软件中,通过应用公钥换取支付宝公钥

      

    app_private_key.pem
    1
    2
    3
    -----BEGIN RSA PRIVATE KEY-----
    应用私钥
    -----END RSA PRIVATE KEY-----

      

    补充:dev.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 前后台base_url
    UP_BASE_URL = 'http://127.0.0.1:8080'
    END_BASE_URL = 'http://127.0.0.1:8000'
    # alipay回调接口配置
    # 上线后必须换成官网地址
    # 同步回调的接口(get),前后台分离时一般设置前台页面url
    RETURN_URL = UP_BASE_URL + '/pay/success'
    # 异步回调的接口(post),一定设置为后台服务器接口
    NOTIFY_URL = END_BASE_URL + '/order/success/'

      

     

     

     

    支付模块

    order/models.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    from django.db import models
    # 订单表:
    from django.db import models
    from utils.model import BaseModel
    from user.models import User
    from course.models import Course
    class Order(models.Model):
        """订单模型"""
        status_choices = (
            (0, '未支付'),
            (1, '已支付'),
            (2, '已取消'),
            (3, '超时取消'),
        )
        pay_choices = (
            (1, '支付宝'),
            (2, '微信支付'),
        )
        subject = models.CharField(max_length=150, verbose_name="订单标题")
        total_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="订单总价", default=0)
        out_trade_no = models.CharField(max_length=64, verbose_name="订单号", unique=True)
        trade_no = models.CharField(max_length=64, null=True, verbose_name="流水号")
        order_status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="订单状态")
        pay_type = models.SmallIntegerField(choices=pay_choices, default=1, verbose_name="支付方式")
        pay_time = models.DateTimeField(null=True, verbose_name="支付时间")
        user = models.ForeignKey(User, related_name='user_orders', on_delete=models.DO_NOTHING, db_constraint=False,
                                 verbose_name="下单用户")
        class Meta:
            db_table = "luffy_order"
            verbose_name = "订单记录"
            verbose_name_plural = "订单记录"
        def __str__(self):
            return "%s - ¥%s" % (self.subject, self.total_amount)
        @property
        def courses(self):
            data_list = []
            for item in self.order_courses.all():
                data_list.append({
                    "id": item.id,
                    "course_name": item.course.name,
                    "real_price": item.real_price,
                })
            return data_list
    class OrderDetail(BaseModel):
        """订单详情"""
        order = models.ForeignKey(Order, related_name='order_courses', on_delete=models.CASCADE, db_constraint=False,
                                  verbose_name="订单")
        course = models.ForeignKey(Course, related_name='course_orders', on_delete=models.CASCADE, db_constraint=False,
                                   verbose_name="课程")
        price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程原价")
        real_price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程实价")
        class Meta:
            db_table = "luffy_order_detail"
            verbose_name = "订单详情"
            verbose_name_plural = "订单详情"
        def __str__(self):
            return "%s订单(%s)" % (self.course.name, self.order.out_trade_no)

      

     

     

    支付接口生成支付链接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    import time
    from rest_framework.views import APIView
    from utils.response import APIResponse
    from libs.iPay import alipay
    from . import authentications, serializers
    from rest_framework.permissions import IsAuthenticated
    from django.conf import settings
    # 获取前台 商品名、价格,产生 订单、支付链接
    class PayAPIView(APIView):
        authentication_classes = [authentications.JWTAuthentication]
        permission_classes = [IsAuthenticated]
        def post(self, request, *args, **kwargs):
            # 前台提供:商品名、总价、支付方式
            request_data = request.data
            # 后台产生:订单号、用户
            out_trade_no = '%d' % time.time() * 2
            request_data['out_trade_no'] = out_trade_no
            request_data['user'] = request.user.id
            # 反序列化数据,用于订单生成前的校验
            order_ser = serializers.OrderModelSerializer(data=request_data)
            if order_ser.is_valid():
                # 生成订单,订单默认状态为:未支付
                order = order_ser.save()
                # 支付链接的参数
                order_string = alipay.api_alipay_trade_page_pay(
                    subject=order.subject,
                    out_trade_no=order.out_trade_no,
                    total_amount='%.2f' % order.total_amount,
                    return_url=settings.RETURN_URL,
                    notify_url=settings.NOTIFY_URL
                )
                # 形成支付链接:alipay._gateway根据字符环境DEBUG配置信息,决定是沙箱还是真实支付环境
                pay_url = '%s?%s' % (alipay._gateway, order_string)
                return APIResponse(0, 'ok', pay_url=pay_url)
            return APIResponse(1, 'no ok', results=order_ser.errors)

      

     

     

     

     

     

    支付完成订单校验的接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    from . import models
    from utils.logging import logger
    from rest_framework.response import Response
    class SuccessAPIView(APIView):
        # 不能认证,别人支付宝异步回调就进不来了
        # authentication_classes = [authentications.JWTAuthentication]
        # permission_classes = [IsAuthenticated]
        def patch(self, request, *args, **kwargs):
            # 默认是QueryDict类型,不能使用pop方法
            request_data = request.query_params.dict()
            # 必须将 sign、sign_type(内部有安全处理) 从数据中取出,拿sign与剩下的数据进行校验
            sign = request_data.pop('sign')
            result = alipay.verify(request_data, sign)
            if result:  # 同步回调:修改订单状态
                try:
                    out_trade_no = request_data.get('out_trade_no')
                    order = models.Order.objects.get(out_trade_no=out_trade_no)
                    if order.order_status != 1:
                        order.order_status = 1
                        order.save()
                except:
                    pass
                return APIResponse(0, '支付成功')
            return APIResponse(1, '支付失败')
        # 支付宝异步回调
        def post(self, request, *args, **kwargs):
            # 默认是QueryDict类型,不能使用pop方法
            request_data = request.data.dict()
            # 必须将 sign、sign_type(内部有安全处理) 从数据中取出,拿sign与剩下的数据进行校验
            sign = request_data.pop('sign')
            result = alipay.verify(request_data, sign)
            # 异步回调:修改订单状态
            if result and request_data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED" ):
                out_trade_no = request_data.get('out_trade_no')
                logger.critical('%s支付成功' % out_trade_no)
                try:
                    order = models.Order.objects.get(out_trade_no=out_trade_no)
                    if order.order_status != 1:
                        order.order_status = 1
                        order.save()
                except:
                    pass
                # 支付宝八次异步通知,订单成功一定要返回 success
                return Response('success')
            return Response('failed')
  • 相关阅读:
    六.初识Mybatis
    python中文资源大全
    阅读《乌云回忆录一》后的一点感慨
    SSH无法连上CentOS7的问题
    [转]sqlmap使用教程
    [转]11种常见sqlmap使用方法详解
    ZVulDrill渗透环境搭建及部分题目writeup
    渗透资源大全-整理
    【洛谷5934】[清华集训2012] 最小生成树(最小割)
    【洛谷3974】[TJOI2015] 组合数学(模拟最大流)
  • 原文地址:https://www.cnblogs.com/yangxinpython/p/11938310.html
Copyright © 2011-2022 走看看