支付流程

一、支付模块

1、配置文件配置

# 配置文件
RETURN_URL = "http://101.201.249.159/course/paysuccess"  # 前端地址
NOTIFY_URL = "http://101.201.249.159:8000/order/success/"  # 公网

2、libs文件夹

# 先写一个ali_pay的包,pem文件夹
# pem文件夹
# alipay_public_key.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6hSSLaSBnC3LwjAOJYM5Gx6NqjMku1f4Ebs820VAwBigI2o0nPUXBwCf7PJEXr0dGXvjaIa3alAoumqMSJVxXI3nYWTdS/qzCfvn9Be8jsC+cbGfGDOuw7vPgWDYGwZqy99OYvo5MHAR+/Kz+6dz6vYUdg07ny8n5KiC2ww4FS+RvxlMCZCFhiizQHdvvv/JwEaoe9WR4e4beFApwGl+7+zp2qrFQUwA4oU6t0UsYcDgNVqryIFKToGvo6h8Pf4zP1GzL4R726apRp865Km69Q9GlY6QUH37cRI1yhMaZKzq0Lb07L1dq2fRWgx9iRPY2+nXpO9m/W90dcWVoAVmQIDAQAB
-----END PUBLIC KEY-----
# app_private_key.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAiwbZqOE7slfuqyamxsawtiAYDtjL3x68fZeKPGjEJlWIvDDqCjhvbNXjJnTZZA66/Mzt4aVUgQMQT+29NaY1aTFRY0DZ5d3EIkWi3U1QL8PObB+Wun0sSubjrF1lXbg+3PD3bSu8ax7K083ckVMqSO55u7yEjykb5FO/kiyRpnvss4jTi7rosU0u2AApsfhrJcT/IPleJ6d3N4L9nBc5rTIerreiq6HMMS8nzHRZ4fwCpDSgziVQVtTDTk61vtRtX8Abh44Y4tDxT3vg6qCopTxzv0O6idabJCaL6ub0LDY5f2/L+zNJk8co9aMUgUvazDpIej28tdZO3KE5pgB8vQIDAQABAoIBAAywElssOwN6rOhnvZ60cVodsbRhKrHxHyijFNWQhh4tfi4WlLVcEycume1fiptsELqThT4rlXu0qN9yhesIgSVZf+D8ASbOR2ENU+C4dpH1X7hUZbAdTlaDndGUMHUOJIaLYzlOXYK1K7OKvQ9yNJC1Wty8Rqi+CrKaxgf0E1LLJs2quZUio9YYbR5j1FUrtEdJBMeFMhWRIOYKqd8eyML50vOh2Uxc9e+nsPULwTnoZQfa2zPiYRfDnpAX1ctENZJOuffROHZwdv2MxVJAAE26jF659DkD5ZtooaNA709tM1tqikafXvdHueu2wdfcujpd7O50bkT29vXYn9mmeE0CgYEA9ug5AdeZ2b9Gnouva1meqYXMAQjL74SuICMghoEE+L7VazNMWLqCAkfJwtZiyz66p2XZSAEMBs1hCgRtVQGxKpPMxcqjW0jh+o9WfvflyOZoFUA/L3RMwJzUkxIyADW6hASDLVbjf0j+ASzbkrFhkKnxMqAm+4gdZ+VVyqoEJm8CgYEAkCWPHOnAMr1INoy8JWmvFbBaaFlouuuZqESkNpG71042yAzpju4S+mFYA438Zre7IZ8CUNnfKa+Z46zScdr4giolOwGQSZ8zg72LmYweiWHToyOfBMWqGZAriJ/BYmCGdiY5HtPWVcypLG5PKo4EpuHckamUF12FtsdfvBolxZMCgYEA4EHaDW9LAPh3ZueOo91Ze7XXrhTUTi9fjDb7gs9Kubdy1pRYQrrb/MBBZCMexmWqWQLr0DeLOd5uxg9xUmVgCkEGG5xKtU3EWrS4Jkh4v/luDec1vJ9QWx3XAeHj4kbqqqACmTqzFNgyRNT+dgWAjUmdlpLZ9VoTA1vMiW/UpycCgYBIMgeTu59/yj241JQHSP9gJYuiZ+WEeSvkkzyL+EHUfGADojP4WlU3AjpKzXp1F+Cp3jISvIyBHGo/Fffw/nMo/mLXQtk5hnsOqIiaxwskU9LkCptCkJ25X/Pt4dXBqAawdkR1pDPdlTvF/Rm5fpfl3YnTitOZQEYQXZsdYxs38QKBgQCS1u0UpTOD+isj/vqp5i4ZjWVXI7lillLU+E75yIMkD6fSYnUsBp1Eu2MRZxNF7TRuM2QTmHqzrhbUgaRd8PXB6kVxVCEoDX2+bdjoxS18RCw1r+HMkN7FbsX31Oy97lFKqefsZ+mgPkXJY/LLN+6aPKTuQZv4EkQtRHeaEiYJiQ==
-----END RSA PRIVATE KEY-----

# __init__.py
from .pay import alipay,gateway

# pay.py
from alipay import AliPay
from . import settings
# 支付对象
alipay = AliPay(
	appid = settings.APP_ID,
    app_notify_url = None,
    app_private_key_string = settings.APP_PRIVATE_KEY_STRING,
    alipay_public_key_string = settings.ALIPAY_PUBLIC_KEY_STRING,
    sign_type = settings.SIGN,
    debug = settings.DEBUG
)
# 支付网关
gateway = settings.GATEWAY

# settings.py
import os
# 应用私钥
APP_PRIVATE_KEY_STRING = open(os.path.join(os.path.dirname(os.path.abspath(__file__)),'pem','app_private_key.pem')).read()
# 支付宝公钥
ALIPAY_PUBLIC_KEY_STRING = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pem', 'alipay_public_key.pem')).read()
# 应用id
APP_ID = '2021000116699833'
# 加密方式
SIGN = 'RSA2'
# 是否是支付宝测试环境(沙箱环境),如果采用真是支付宝环境,配置False
DEBUG = True
# 支付网关
GATEWAY = 'https://openapi.alipaydev.com/gateway.do?' if DEBUG else 'https://openapi.alipay.com/gateway.do?'

3、视图中

from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin
from .models import Order
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated
class PayView(GenericViewSet,CreateModelMixin):
    queryset = Order.objects.all()
    serializer_class = PaySerializer
    # 认证类需要搭配一个权限类,保证必须登陆才能用
    authentication_classes = [JSONWebTokenAuthentication,]
    permission_classes = [IsAuthenticated,]
    # 重写create方法,返回数据(支付链接)
    def create(self,request,*args,**kwargs):
        ser = self.get_serializer(data = request.data,context = {'request':request})
        if ser.is_valid():
            self.perform_create(ser)
            pay_url = ser.context.get('pay_url')
            return APIResponse(msg = '订单创建成功',pay_url = pay_url)
        else:
            return APIResponse(status = 1,msg = '失败')
logger = get_logger('pay')
class PaySuccessView(APIView):
    def get(self,request,*args,**kwargs):
        out_trade_no = request.GET.get('out_trade_no')
        order = Order.objects.filter(out_trade_no=out_trade_no,order_status=1).first()
        if order:
            return APIResponse(msg='支付成功')
        else:
            return APIResponse(status=1,msg='暂未支付成功')
    def post(self,request,*args,**kwargs):
        try:
            result_data = request.data.dict()
            out_trade_no = result_data.get('out_trade_no')
            signature = result_data.pop('sign')
            result = ali_pay.alipay.verify(result_data, signature)
            if result and result_data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):               			 	Order.objects.filter(out_trade_no=out_trade_no).update(order_status=1)
                logger.warning('%s订单支付成功' % out_trade_no)
                return Response('success')
            else:
                logger.error('%s订单支付失败' % out_trade_no)
        except:
            pass
        return Response('fail')

4、序列化中

class PaySerializer(serializers.ModelSerializer):
    courses = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all(),many=True,write_only=True)
    class Meta:
        model = Order
        fields = ['subject','pay_type','total_amount','courses']
        extra_kwargs = {
            'total_amount':{'required':True},
            'pay_type':{'required':True}
        }
    def _check_price(self,attrs):
        courses = attrs.get('courses')
        total_amount = attrs.get('total_amount')
        total = 0
        for course in courses:
            total += course.price
    	if not total == total_amount:
            raise MyException('钱数不合法')
    def _get_out_trade_no(self):
        out_trade_no = str(uuid.uuid4())
        return out_trade_no.replace('-'.'')
    def _get_user(self):
        user = self.context.get('request').user
        return user
        def _gen_pay_url(self, attrs, out_trade_no):
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=out_trade_no,
            total_amount=float(attrs.get('total_amount')),  # 转成浮点型
            subject=attrs.get('subject'),
            # 写在配置文件中
            return_url=settings.RETURN_URL,
            notify_url=settings.NOTIFY_URL
        )
        return gateway + order_string
        def _before_create(self,attrs,user,out_trade_no):  # 入库前两个表的信息准备,用户,订单号,订单状态
            attrs['user'] = user
            attrs['out_trade_no'] = out_trade_no
            attrs['order_status'] = 0
        def validate(self, attrs):
            # 1)订单总价校验
            total_amount = self._check_price(attrs)
            # 2)生成订单号
            out_trade_no = self._get_out_trade_no()
            # 3)支付用户:request.user
            user = self._get_user()
            # 4)支付链接生成
            pay_url = self._get_pay_url(out_trade_no,total_amount,attrs.get('subject'))
            self.context['pay_url'] = pay_url  # 传给视图
            # 5)入库(两个表)的信息准备
            self._before_create(attrs,user,out_trade_no)
            return attrs
        # 代表该校验方法通过,进入入库操作
        def create(self, validated_data):  # 重写的目的,完成订单和订单详情两个表的入库操作
            courses = validated_data.pop('courses')
            order = Order.objects.create(**validated_data)
            for course in courses:
            	OrderDetail.objects.create(course=course,order=order,price=course.price,real_price=course.price)
            return order
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值