diff --git a/core/routers/pay/routes.py b/core/routers/pay/routes.py index f8889e9..6041e05 100644 --- a/core/routers/pay/routes.py +++ b/core/routers/pay/routes.py @@ -9,7 +9,7 @@ from xml.parsers.expat import ExpatError import xmltodict from asyncer import asyncify -from fastapi import APIRouter, Request, HTTPException, status, Depends +from fastapi import APIRouter, Request, HTTPException, status, Depends, Response from sqlalchemy.ext.asyncio import AsyncSession from core.base import schema as base_schema @@ -93,11 +93,20 @@ async def create_order( return {'data': {'payment_params': payment_params, 'order_id': order.order_id}} -@pay_router.post('/wechat/notify', summary='处理支付结果通知', response_model=base_schema.BaseResponse) +@pay_router.post('/wechat/notify', summary='处理支付结果通知') async def wechat_notify( request: Request, db_session: AsyncSession = Depends(get_async_session) ): + def generate_response(): + xml_response = """ + + + + + """ + return Response(content=xml_response.strip(), media_type="application/xml") + body = await request.body() logger.debug(body.decode()) try: @@ -113,34 +122,35 @@ async def wechat_notify( local_sign = wechat_pay_api.generate_sign(params) if sign != local_sign: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail='签名验证失败' - ) + return generate_response() # 处理支付结果 db_crud = CRUD(db_session, Order) - record = { - 'order_id': params['out_trade_no'], - 'transaction_id': params['transaction_id'] - } - if params['return_code'] == 'SUCCESS' and params['result_code'] == 'SUCCESS': - record.update({ - 'notify_total_fee': params['total_fee'], - 'status': base_schema.OrderStatusType.PAID - }) - result = {'status': 200, 'message': 'OK'} - await asyncify(add_task)( - actions_after_payment, - notify_params=params, - task_id=record['order_id'], + order = await db_crud.get(filters={'order_id': params['out_trade_no']}) + if order and order.status.value not in ['ok', 'fail']: + record = { + 'order_id': params['out_trade_no'], + 'transaction_id': params['transaction_id'] + } + if params['return_code'] == 'SUCCESS' and params['result_code'] == 'SUCCESS': + record.update({ + 'notify_total_fee': params['total_fee'], + 'status': base_schema.OrderStatusType.PAID + }) + await asyncify(add_task)( + actions_after_payment, + notify_params=params, + task_id=record['order_id'], + ) + else: + record.update({ + 'status': base_schema.OrderStatusType.FAIL, + }) + + await db_crud.update( + data=record, + filters={ + 'order_id': record['order_id'], 'status': base_schema.OrderStatusType.WAIT_PAYMENT + } ) - else: - result = {'status': 400, 'message': '支付失败'} - record.update({ - 'status': base_schema.OrderStatusType.FAIL, - }) - - await db_crud.update(data=record, filters={'order_id': record['order_id']}) - - return result + return generate_response() diff --git a/requirements.txt b/requirements.txt index 6a17e0d..64b75be 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,7 +24,7 @@ pycryptodome xmltodict fastapi-limiter asyncer - +apscheduler