一、支付模块
1、配置文件配置
RETURN_URL = "http://101.201.249.159/course/paysuccess"
NOTIFY_URL = "http://101.201.249.159:8000/order/success/"
2、libs文件夹
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj6hSSLaSBnC3LwjAOJYM5Gx6NqjMku1f4Ebs820VAwBigI2o0nPUXBwCf7PJEXr0dGXvjaIa3alAoumqMSJVxXI3nYWTdS/qzCfvn9Be8jsC+cbGfGDOuw7vPgWDYGwZqy99OYvo5MHAR+/Kz+6dz6vYUdg07ny8n5KiC2ww4FS+RvxlMCZCFhiizQHdvvv/JwEaoe9WR4e4beFApwGl+7+zp2qrFQUwA4oU6t0UsYcDgNVqryIFKToGvo6h8Pf4zP1GzL4R726apRp865Km69Q9GlY6QUH37cRI1yhMaZKzq0Lb07L1dq2fRWgx9iRPY2+nXpO9m/W90dcWVoAVmQIDAQAB
-----END PUBLIC KEY-----
-----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-----
from .pay import alipay,gateway
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
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()
APP_ID = '2021000116699833'
SIGN = 'RSA2'
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,]
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):
total_amount = self._check_price(attrs)
out_trade_no = self._get_out_trade_no()
user = self._get_user()
pay_url = self._get_pay_url(out_trade_no,total_amount,attrs.get('subject'))
self.context['pay_url'] = pay_url
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