拍爱

views.py 7.1KB

    # -*- coding: utf-8 -*- from django.conf import settings from django.db import transaction from django.http import JsonResponse from django.shortcuts import HttpResponse from pay.models import OrderInfo from utils.page_utils import pagination from utils.error.errno_utils import OrderStatusCode from utils.error.response_utils import response from logit import logit from TimeConvert import TimeConvert as tc from wechatpy import WeChatPay, WeChatPayException import xmltodict WECHAT = settings.WECHAT @logit @transaction.atomic def wx_order_create_api(request): """ 订单创建 :param request: :return: """ from_uid = request.POST.get('from_uid', '') to_lid = request.POST.get('to_lid', '') to_uid = request.POST.get('to_uid', '') body = request.POST.get('body', '') # 商品描述 total_fee = int(request.POST.get('total_fee', 0)) # 总金额,单位分 # JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里 trade_type = request.POST.get('trade_type', '') # 根据 trade_type 获取 wechat 配置 wechat = WECHAT.get(trade_type, {}) # WeChatPay 初始化 wxpay = WeChatPay(wechat.get('appID'), wechat.get('apiKey'), wechat.get('mchID')) # 生成订单 order = OrderInfo.objects.create( from_uid=from_uid, to_lid=to_lid, to_uid=to_uid, total_fee=total_fee, trade_type=trade_type, ) try: prepay_data = wxpay.order.create( body=body, notify_url=settings.API_DOMAIN + '/wx/notify_url', out_trade_no=order.order_id, total_fee=total_fee, trade_type=trade_type, # user_id=None, # 可选,用户在商户appid下的唯一标识。trade_type=JSAPI,此参数必传 ) except WeChatPayException: return response(OrderStatusCode.WX_UNIFIED_ORDER_FAIL) prepay_id = prepay_data.get('prepay_id', '') if trade_type == 'JSAPI': wxpay_params = wxpay.jsapi.get_jsapi_params(prepay_id) elif trade_type == 'APP': wxpay_params = wxpay.order.get_appapi_params(prepay_id) return JsonResponse({ 'status': 200, 'message': 'Order Create Success', 'description': u'订单创建成功', 'data': { 'order_id': order.order_id, 'prepay_id': prepay_id, 'wxpay_params': wxpay_params, } }) def order_paid_success(order): if order.pay_status == OrderInfo.PAID: return order.pay_status = OrderInfo.PAID order.paid_at = tc.utc_datetime() order.save() def order_paid_fail(order): if order.pay_status == OrderInfo.FAIL: return order.pay_status = OrderInfo.FAIL order.save() @logit @transaction.atomic def wx_order_query_api(request): """ 订单查询 :param request: :return: """ order_id = request.POST.get('order_id', '') transaction_id = request.POST.get('transaction_id', '') try: order = OrderInfo.objects.get(order_id=order_id) except OrderInfo.DoesNotExist: return response(OrderStatusCode.WX_ORDER_NOT_FOUND) if order.pay_status == OrderInfo.PAID: return JsonResponse({ 'status': 200, 'message': 'Order Pay Success', 'description': u'订单支付成功', 'data': { } }) elif order.pay_status == OrderInfo.FAIL: return response(OrderStatusCode.WX_ORDER_PAY_FAIL) # 根据 trade_type 获取 wechat 配置 wechat = WECHAT.get(order.trade_type, {}) # WeChatPay 初始化 wxpay = WeChatPay(wechat.get('appID'), wechat.get('apiKey'), wechat.get('mchID')) # 订单查询 query_data = wxpay.order.query(transaction_id, order_id) # 签名校验 if not wxpay.check_signature(query_data): return response(OrderStatusCode.SIGN_CHECK_FAIL) # 交易状态 trade_state = query_data.get('trade_state') # 订单状态判断更新 if trade_state == 'SUCCESS': # 订单支付成功 order_paid_success(order) return JsonResponse({ 'status': 200, 'message': 'Order Pay Success', 'description': u'订单支付成功', 'data': { } }) elif trade_state == 'NOTPAY': # 订单未支付 return response(OrderStatusCode.WX_ORDER_NOT_PAY) elif trade_state == 'USERPAYING': # 订单支付中 return response(OrderStatusCode.WX_ORDER_PAYING) else: # 订单支付失败 order_paid_fail(order) return response(OrderStatusCode.WX_ORDER_PAY_FAIL) @logit @transaction.atomic def wx_order_list_api(request): """ 订单列表 :param request: :return: """ user_id = request.POST.get('user_id', '') page = int(request.POST.get('page', 1)) num = int(request.POST.get('num', settings.ORDER_NUM_PER_PAGE)) orders = OrderInfo.objects.filter(from_uid=user_id).order_by('-pk') orders, left = pagination(orders, page, num) orders = [order.data for order in orders] return JsonResponse({ 'status': 200, 'message': u'获取订单列表成功', 'data': { 'orders': orders, 'left': left, }, }) @logit @transaction.atomic def wx_order_detail_api(request): """ 订单详情 :param request: :return: """ user_id = request.POST.get('user_id', '') order_id = request.POST.get('order_id', '') try: order = OrderInfo.objects.get(order_id=order_id) except OrderInfo.DoesNotExist: return response(OrderStatusCode.WX_ORDER_NOT_FOUND) if user_id not in [order.from_uid, order.to_lid, order.to_uid]: return response(OrderStatusCode.NO_DETAIL_PERMISSION) return JsonResponse({ 'status': 200, 'message': u'获取订单详情成功', 'data': { 'order': order.data, }, }) @logit @transaction.atomic def wx_notify_url_api(request): """ 支付异步通知回调地址 :param request: :return: """ try: data = xmltodict.parse(request.body)['xml'] except xmltodict.ParsingInterrupted: # 解析 XML 失败 return HttpResponse(settings.WXPAY_NOTIFY_FAIL) trade_type = data.get('trade_type', '') # 根据 trade_type 获取 wechat 配置 wechat = WECHAT.get(trade_type, {}) # WeChatPay 初始化 wxpay = WeChatPay(wechat.get('appID'), wechat.get('apiKey'), wechat.get('mchID')) # 签名校验 if not wxpay.check_signature(data): return response(OrderStatusCode.SIGN_CHECK_FAIL) out_trade_no = data.get('out_trade_no', '') return_code = data.get('return_code', '') result_code = data.get('result_code', '') if return_code != 'SUCCESS' or result_code != 'SUCCESS': return HttpResponse(settings.WXPAY_NOTIFY_FAIL) try: order = OrderInfo.objects.get(order_id=out_trade_no) except OrderInfo.DoesNotExist: return response(OrderStatusCode.WX_ORDER_NOT_FOUND) order_paid_success(order) return HttpResponse(settings.WXPAY_NOTIFY_SUCCESS)