python Django drf pc端支付宝支付

  1. 支付宝支付其实就是两步,首先,前端向后端请求订单(预付单),然后拿到订单之后请求后端去支付,后端自己去配置一些参数,然后将一个url返回给前端,前端拿到url去请求,就会返回一个支付宝二维码,用户扫码成功之后,会向请求后端的一个接口去返回支付接口,如果后端验签成功,修改订单状态即可(注意,支付宝支付还需要 支付宝公钥 用于验签 app私钥 用于加密)
  2. 支付宝公钥在你后端的文件名称:alipay_public_key.pem 打开文件之后把甲方给你的公钥放在这中间-----BEGIN PUBLIC KEY----- -----END PUBLIC KEY----- app私钥:app_private_key.pem -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- app公钥(其实这个不用配置,只是单纯的写出来):app_public_key.pem -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY-----
  3. 参考:支付宝开发文档 支付宝第三方sdk 支付宝转账旧版本

class PaymentView(CreateAPIView, UpdateAPIView):
    """订单支付"""

    permission_classes = [IsAuthenticated]
    serializer_class = PaymentSerializer

    def get(self, request):
        """订单管理去支付接口"""

        order_id = request.query_params.get('order_id',None)
        if not order_id:
            return APIResponse.fail(message='请求参数错误')

        order = OrderInfo.objects.filter(order_id=order_id,is_delete=False).first()
        if not order:
            return APIResponse.fail(message='该订单已被删除')

        address = Address.objects.filter(id=order.address_id).select_related('user','province','city','district').first()
        address_serializer = UserAddressSerializer(address)

        response = {
            'order_id':order.order_id,
            # 商品总数
            'total_count':order.total_count,
            # 订单总金额
            'total_amount':order.total_amount,
            # 订单实付金额
            'actual_amount':order.actual_amount,
            # 运费
            'freight':order.freight,
            'store_name':order.seller,
            'store_id':order.seller_id,
            # 使用优惠券名称
            'use_coupon_name':order.use_coupon_name,
            'address':address_serializer.data
        }

        if order.order_type == 1:
            # 面料商品
            goods = OrderGoods.objects.filter(order=order,goods_type=1,status=1)
            for fabric in goods:
                sku = FabricSKU.objects.filter(id=fabric.sku_id).first()
                fabric.image = sku.fabrics.default_image_url if sku else ''

        else:
            # 款式商品
            goods = OrderGoods.objects.filter(order=order,goods_type=2,status=1)
            for product in goods:
                sku = StylistProduct.objects.filter(id=product.sku_id).first()
                product.image = sku.cover if sku else ''

        response['goods'] = OrderGoodsSerializer(goods, many=True).data
        return APIResponse.success(data=response, message='OK')


    def create(self, request, *args, **kwargs):
        """此接口的支付为app pc端共同接口 app支付接口要多携带一个参数为pay_type:app"""
        data = request.data
        pay_type = data.pop('pay_type', None)

        serializer = self.get_serializer(data=data)
        if not serializer.is_valid():
            message = ','.join(
                serializer.errors[key] for key in serializer.errors if isinstance(serializer.errors[key], str))
            if not message:
                message = ','.join(
                    serializer.errors[key][0] for key in serializer.errors if isinstance(serializer.errors[key], list))
            return APIResponse.fail(message=message)

        user = request.user
        total_amount = Decimal(0)
        # 实付金额
        actual_amount = Decimal(0)
        data = serializer.validated_data

        order_list = data['orders']

        pay_method = data['pay_method']
        order_id_list = data['order_list']

        for order in order_list:
            total_amount += order.total_amount
            actual_amount += order.actual_amount

        pay_order_id = generate_order_id(user.id)
        # 更新订单的支付方式
        OrderInfo.objects.filter(order_id__in=order_id_list).update(pay_method=pay_method)

        # 支付宝支付
        if pay_method == 2:

            alipay = AliPayUtils(pay_order_id, actual_amount, 'order')
            alipay_url = alipay.get_pay_url()

            # 添加第三方支付记录
            PayOrder.objects.create(id=pay_order_id,pay_method=1,amount=actual_amount,orders=order_id_list)
            response = {
                "alipay_url": alipay_url,
                'order_id': pay_order_id
            }
            return APIResponse.success(data=response,message='OK')

```python

import os
from alipay import AliPay  # 下载的sdk
from django.conf import settings



def get_alipay():

    app_private_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem")
    alipay_public_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem")
    # 配置接入支付宝的公共参数
    alipay = AliPay(
        appid=settings.ALIPAY_APPID,
        app_notify_url=None,  # 默认回调url
        app_private_key_string=open(app_private_path).read(),
        # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
        alipay_public_key_string=open(alipay_public_path).read(),
        sign_type="RSA2",  # RSA 或者 RSA2
        debug=settings.ALIPAY_DEBUG  # 默认False
    )
    return alipay


class AliPayUtils(object):
    """支付宝支付工具"""

    def __init__(self,order_id,price,type='order'):

        self.order_id = order_id
        self.price = price
        self.type = type

    def get_pay_url(self):

        if self.type == 'order':
            notify_url = settings.ALIPAY_ORDER_NOTIFY_URL
        elif self.type == 'balance':
            notify_url = settings.ALIPAY_BALANCE_NOTIFY_URL
        else:
            notify_url = settings.ALIPAY_RECHARGE_NOTIFY_URL

        alipay = get_alipay()
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=self.order_id,  # 订单号
            # 订单总金额
            total_amount=str(self.price),
            subject='one_fashion订单%s' % self.order_id,  # 标题
            return_url=settings.ALIPAY_RETURN_URL,  # 支付成功后的回调地址(前端支付成功的页面)
            notify_url=notify_url  # 支付异步通知的后端url
        )
        return settings.ALIPAY_URL + '?' + order_string
# 支付宝接入参数
ALIPAY_APPID = ""
ALIPAY_URL = "https://openapi.alipay.com/gateway.do"
ALIPAY_DEBUG = False  # 沙箱环境为True 正式的为Fasle
ALIPAY_ORDER_NOTIFY_URL = 'https://www.XXXXX.com/alipay/order/result/' # 支付宝回调接口
ALIPAY_RETURN_URL = 'https://www.XXX.com/mall/payCode' # 支付宝支付成功前端页面

支付宝回调后端接口:

class ALiPayOrderResultView(APIView):
    """接受商品订单支付宝异步支付结果"""

    def post(self, request):

        data = request.data.copy()

        data = data.dict()
        signature = data.pop("sign")
        alipay = get_alipay()

        # verification
        success = alipay.verify(data, signature)  # 至于支付宝官网里面的什么验签的排序什么的skd已经帮我们做好了

        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):

            # 取出支付宝流水号
            trade_id = data['trade_no']
            # 取出订单号
            out_trade_no = data['out_trade_no']

            pay_order = PayOrder.objects.filter(id=out_trade_no).first()
            if pay_order:
                try:
                    order_id_list = eval(pay_order.orders)
                except:
                    order_id_list = []
                if order_id_list:
                    orders = OrderInfo.objects.filter(order_id__in=order_id_list)
                    # 更新订单状态,发送短信通知
                    send_updat_order_status_sms(orders)
                pay_order.trade_id = trade_id
                pay_order.save()


            return Response({'return_code': 'SUCCESS', 'return_msg': 'OK'})
        return Response({'return_code': 'FAIL', 'return_msg': 'SIGNERROR'})

这样整个流程就可以了,至于支付宝异步返回的几个参数都是代表的什么,大家就去看官网吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值