feat: add recharge callback processing
This commit is contained in:
+80
-1
@@ -1,3 +1,8 @@
|
||||
import logging
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from rest_framework.exceptions import AuthenticationFailed
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
@@ -15,7 +20,22 @@ from apps.api.serializers import (
|
||||
GenerateImageRequestSerializer,
|
||||
GenerateTitleRequestSerializer,
|
||||
)
|
||||
from apps.billing.services import get_balance_snapshot
|
||||
from apps.billing.payment_gateways import (
|
||||
PaymentVerificationError,
|
||||
verify_alipay_callback,
|
||||
verify_wechat_callback,
|
||||
)
|
||||
from apps.billing.services import (
|
||||
InvalidRechargeOrderStateError,
|
||||
RechargeAmountMismatchError,
|
||||
RechargeCallbackError,
|
||||
RechargeOrderNotFoundError,
|
||||
RechargePayMethodMismatchError,
|
||||
apply_recharge_payment,
|
||||
get_balance_snapshot,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ExternalApiView(APIView):
|
||||
@@ -77,3 +97,62 @@ class BalanceView(ExternalApiView):
|
||||
},
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
|
||||
|
||||
class RechargeCallbackView(APIView):
|
||||
authentication_classes = ()
|
||||
permission_classes = ()
|
||||
|
||||
@staticmethod
|
||||
def _error_response(exc: Exception):
|
||||
if isinstance(exc, PaymentVerificationError):
|
||||
return (
|
||||
api_error("signature_invalid", "支付回调验签失败"),
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
if isinstance(exc, RechargeAmountMismatchError):
|
||||
return (
|
||||
api_error("amount_mismatch", "支付回调金额与本地订单金额不一致"),
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
if isinstance(exc, RechargeCallbackError):
|
||||
return api_error(exc.code, "支付回调处理失败"), status.HTTP_400_BAD_REQUEST
|
||||
return api_error("bad_request", "支付回调处理失败"), status.HTTP_400_BAD_REQUEST
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class WechatRechargeCallbackView(RechargeCallbackView):
|
||||
def post(self, request):
|
||||
try:
|
||||
payment = verify_wechat_callback(request.headers, request.body)
|
||||
apply_recharge_payment(payment)
|
||||
except (
|
||||
PaymentVerificationError,
|
||||
RechargeAmountMismatchError,
|
||||
InvalidRechargeOrderStateError,
|
||||
RechargeOrderNotFoundError,
|
||||
RechargePayMethodMismatchError,
|
||||
) as exc:
|
||||
logger.warning("Rejected WeChat recharge callback: %s", exc.__class__.__name__)
|
||||
data, http_status = self._error_response(exc)
|
||||
return Response(data, status=http_status)
|
||||
return Response({"code": "SUCCESS", "message": "成功"}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class AlipayRechargeCallbackView(RechargeCallbackView):
|
||||
def post(self, request):
|
||||
try:
|
||||
payload = request.data.dict() if hasattr(request.data, "dict") else dict(request.data)
|
||||
payment = verify_alipay_callback(payload)
|
||||
apply_recharge_payment(payment)
|
||||
except (
|
||||
PaymentVerificationError,
|
||||
RechargeAmountMismatchError,
|
||||
InvalidRechargeOrderStateError,
|
||||
RechargeOrderNotFoundError,
|
||||
RechargePayMethodMismatchError,
|
||||
) as exc:
|
||||
logger.warning("Rejected Alipay recharge callback: %s", exc.__class__.__name__)
|
||||
return HttpResponse("fail", status=status.HTTP_400_BAD_REQUEST)
|
||||
return HttpResponse("success", content_type="text/plain", status=status.HTTP_200_OK)
|
||||
|
||||
Reference in New Issue
Block a user