Ejemplo n.º 1
0
    def get(self, request, format=None):
        """
        接收微信支付后台发送的支付结果并对订单有效性进行验证,将验证结果反馈给微信支付后台
        根据支付结果修改交易单,通知订单状态发生改变
        :param format:
        :return:
        """
        data = request.GET

        try:
            if data.get('trade_no'):
                trade = WxPaymentTradeOrder.objects.get(trade_no=data.get('trade_no'))
            elif data.get('transaction_id'):
                trade = WxPaymentTradeOrder.objects.get(transaction_id=data.get('transaction_id'))
            elif data.get('product_order_no'):
                trade = WxPaymentTradeOrder.objects.get(product_id=data.get('product_order_no'))
            else:
                return HttpResponseBadRequest('缺少必要的参数')

            if trade.uid != request.user.id:
                return HttpResponseBadRequest('没有权限')

            if not trade.order_status in (0, 2):
                return Response({'order':  trade, 'ret_status':  {'status': 0, 'msg': u'成功'}}, status=status.HTTP_200_OK)

            with transaction.atomic():
                trade = WxPaymentTradeOrder.objects.select_for_update().get(pk=trade.pk)

                self.query_and_set_order(trade)

        except WxPaymentTradeOrder.DoesNotExist as e:
            logging.exception(e)
            return HttpResponse('订单不存在')
        except ProductOrder.DoesNotExist as e:
            logging.exception(e)
            return HttpResponse(u'订单不存在')
        except Exception as e:
            logging.exception(e)
            return HttpResponse(u'查询失败', status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Ejemplo n.º 2
0
def get_prepay_short_url(product_id):
    """
    根据product_id生成是微信扫描支付模式一URL
    :param product_id: 订单号
    :return: url
    """
    #生成长地址
    long_url = WxPayApi.get_pre_pay_url(product_id)

    try:
        #获取短地址
        result = WxPayApi.get_short_url({'long_url': long_url}, time_out=3)

        if result['return_code'] == 'SUCCESS' and result['result_code'] == 'SUCCESS' and result.get('short_url'):
            return result.get('short_url')
        else:
            logging.exception('获取微信short url失败')
            logging.exception(result)
    except Exception as e:
        logging.exception(e)
    # 生成短地址失败是返回长地址
    return long_url
Ejemplo n.º 3
0
    def get(self, request, format=None):
        """
        下载对账单
        :param format:
        :return: '成功’:0;'没有权限.',1;"参数错误.",-2;4:订单不存在.
        """
        try:
            bill_date = request.GET['bill_date']
            datetime.strptime(bill_date, '%Y%m%d')
            bill_type = request.GET.get('bill_type','ALL')
            if bill_type not in ['ALL', 'SUCCESS', 'REFUND', 'REVOKE']:
                raise ValueError
        except (KeyError, ValueError):
            return HttpResponseBadRequest(u'缺少必要的参数')

        # ALL,返回当日所有订单信息,默认值
        # SUCCESS,返回当日成功支付的订单
        # REFUND,返回当日退款订单
        # REVOKED,已撤销的订单
        bill_type = 'ALL'
        if bill_type == 'ALL':
            bill_types = ['SUCCESS', 'REFUND']  # 没有REVOKED类型下载
        else:
            bill_types = [bill_type]

        try:

            bills = []
            for bill_type in bill_types:
                params = {}
                params['bill_date'] = bill_date
                params['bill_type'] = bill_type

                # 向微信查询
                r = WxNativePayApi.download_bill(params)
                if isinstance(r, dict):
                    if r.get('return_msg') == 'No Bill Exist':
                        continue
                        # return HttpResponse(u'当天没有指定类型的对账单.')
                    else:
                        logging.exception(u'下载对账单({})失败:'.format(bill_type) + str(r))
                        return HttpResponse(u'下载对账单错误.', status=status.HTTP_500_INTERNAL_SERVER_ERROR)

                content = r.decode('utf-8')

                ls = content.splitlines()
                if len(ls) >= 4:
                    ls.pop()
                    ls.pop()
                    head = ls.pop(0)
                    head = head.split()
                    col_name = []
                    for item in head:
                        if self.__BILL_HAED_COL_NAME.get(item) and hasattr(WxPaymentBill, item):
                            col_name.append(self.__BILL_HAED_COL_NAME.get(item))

                    for l in ls:
                        bill = WxPaymentBill()
                        items = dict(zip(col_name, l.split(',`')))
                        for p in items.items():
                            setattr(bill, p[0], p[1])
                        bills.append(bill)

            if bills:
                WxPaymentBill.objects.bulk_create(bills)

                return HttpResponse(u'下载成功')
            else:
                return HttpResponse(u'当天没有指定类型的对账单.')

        except Exception as e:
            logging.exception(e)
            return HttpResponse(u'下载对账单错误.', status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Ejemplo n.º 4
0
    def post(self, request, format=None):
        """
        接收微信支付后台发送的支付结果并对订单有效性进行验证,将验证结果反馈给微信支付后台
        根据支付结果修改交易单,通知订单状态发生改变
        :param format:
        :return:
        """

        try:
            logging.info(request.data)

            notify_data = self.get_notify_data(request.data)
            if isinstance(notify_data, HttpResponse):
                return notify_data

            transaction_id = notify_data.get('transaction_id')
            if not transaction_id:
                return HttpResponse('<xml><return_code><![CDATA[FAIL]]></return_code>'
                                    '<return_msg><![CDATA[支付结果中微信订单号不存在]]></return_msg></xml>')
            elif self.__query_order(transaction_id) == False:
                logging.error(u'订单查询失败' + str(notify_data))
                return HttpResponse('<xml><return_code><![CDATA[FAIL]]></return_code>'
                                    '<return_msg><![CDATA[订单查询失败]]></return_msg></xml>')

            if notify_data["return_code"] != "SUCCESS":
                data = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[通信失败]]></return_msg></xml>'
                return HttpResponse(data)

            trade_no = notify_data.get('out_trade_no')
            if not trade_no:
                logging.error(u'订单通知失败,缺少必要参数out_trade_no : ' + str(notify_data))
                return HttpResponse('<xml><return_code><![CDATA[FAIL]]></return_code>'
                                '<return_msg><![CDATA[缺少必要的参数:out_trade_no]]></return_msg></xml>')

            need_notify_order_success = False
            with transaction.atomic():
                trade = WxPaymentTradeOrder.objects.select_for_update().get(trade_no=trade_no)

                if trade.order_status not in (0, 2):
                    # 已经处理过,直接返回成功接收
                    return Response(data=self.__success_data, status=status.HTTP_200_OK)

                product_order = ProductOrder.objects.select_for_update().get(order_no=trade.product_id)
                trade.transaction_id = notify_data.get('transaction_id')
                if not trade.prepay_id and notify_data.get('prepay_id'):
                    trade.prepay_id = notify_data.get('prepay_id')
                if notify_data['result_code'] == 'SUCCESS':
                    trade.order_status = 3
                    product_order.status = 2
                    product_order.pay_type = 2
                else:
                    trade.order_status = 1
                    product_order.status = 3
                if notify_data.get('time_end'):
                    trade.end_time = datetime.strptime(notify_data['time_end'], '%Y%m%d%H%M%S')
                trade.wx_result_code = notify_data['result_code']
                trade.wx_err_code = notify_data.get('err_code', '')
                trade.wx_err_code_des = notify_data.get('err_code_des', '')
                trade.wx_response = notify_data

                if trade.order_status == 3 and trade.is_order_over is False:
                    trade.is_order_over = True
                    need_notify_order_success = True

                trade.save(force_update=True)
                product_order.save()

            if need_notify_order_success:
                # 通知订单支付成功
                notify_order_pay_success(product_order)
            content = '<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>'
            return HttpResponse(content)
        except WxPaymentTradeOrder.DoesNotExist as e:
            logging.exception(e)
            return HttpResponse('<xml><return_code><![CDATA[FAIL]]></return_code>'
                                '<return_msg><![CDATA[该订单号不存在]]></return_msg></xml>')
        except ProductOrder.DoesNotExist as e:
            logging.exception(e)
            return HttpResponse('<xml><return_code><![CDATA[FAIL]]></return_code>'
                                '<return_msg><![CDATA[该订单不存在]]></return_msg></xml>')
        except Exception as e:
            logging.exception(e)
            return HttpResponse(body='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg></return_msg></xml>', status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Ejemplo n.º 5
0
    def get(self, request, data_format=None, *args, **kwargs):
        # user = request.user
        data = request.GET
        if data_format == 'json' or data.get('data_format') == 'json':
            is_json = True
        else:
            is_json = False

        # ①不存在----记录,
        # ②已经撤单---记录   ---- 购买不能撤单
        try:
            order_no = data['order_no']
            # order_no = '123'
            if not order_no:
                raise ValueError
        except (KeyError, ValueError):
            return HttpResponseBadRequest(u'缺少订单号')

        try:

            with transaction.atomic():
                # 根据订单号取订单
                product_order = ProductOrder.objects.select_for_update().get(order_no=order_no)
                # ③已经支付---不做处理
                if self.has_payed(product_order):
                    if is_json:
                        return JsonResponse({'msg': u'订单已支付', 'code': 1,})
                    else:
                        return HttpResponseBadRequest(u'订单已支付')
                # ④支付中
                # elif self.is_paying(product_order):
                #     return HttpResponseBadRequest(u'订单支付进行中')
                # ⑤未支付----修改交易单状态,记录,通知
                # 生成交易单
                wx_trade_order = self.__get_or_create_trade(product_order,
                                                            appid=WxNativePaymentConstData.APP_ID,
                                                            mch_id=WxNativePaymentConstData.MCH_ID,
                                                            spbill_create_ip=WxNativePaymentConstData.IP)
                wx_trade_order = WxPaymentTradeOrder.objects.select_for_update().get(pk=wx_trade_order.pk)

                now = datetime.today() if wx_trade_order.time_expire.tzinfo is None else django.utils.timezone.now()
                if wx_trade_order.order_status==9 or (wx_trade_order.order_status in (0,1,4) and (not wx_trade_order.code_url or wx_trade_order.time_expire < now)):
                    try:
                        if wx_trade_order.time_expire <= now:
                            wx_trade_order.start_time = django.utils.timezone.now()
                            wx_trade_order.time_expire = wx_trade_order.start_time + timedelta(seconds=self.__REMAINING_SECONDS)
                            wx_trade_order.code_url = ''
                            wx_trade_order.save()
                        # 调用统一下单api
                        fromWxData = self.__unified_order(wx_trade_order)

                        wx_trade_order.wx_return_code = fromWxData['return_code']
                        wx_trade_order.wx_return_msg = fromWxData['return_msg']
                        wx_trade_order.wx_response = fromWxData
                        if fromWxData['return_code'] == 'SUCCESS':  #通信成功 #交易成功
                            if not fromWxData.get("appid") or not fromWxData.get("mch_id") or not fromWxData.get("code_url"):
                                raise Exception(message='统一下单失败,返回值缺少必要参数')
                            if fromWxData['result_code'] == 'SUCCESS':
                                wx_trade_order.order_status = 2
                                wx_trade_order.wx_prepay_id = fromWxData.get('prepay_id', '')
                                wx_trade_order.code_url = fromWxData.get('code_url')
                                # product_order.status = 2
                                product_order.pay_type = 2
                                product_order.save()
                            else:
                                wx_trade_order.order_status = 9

                            wx_trade_order.wx_result_code = fromWxData['result_code']
                            wx_trade_order.wx_err_code = fromWxData.get('err_code', '')
                            wx_trade_order.wx_err_code_des = fromWxData.get('err_code_des', '')
                        else:
                            wx_trade_order.order_status = 9

                        wx_trade_order.save()
                    except Exception as e:
                        print '1'
                        logging.exception(u'统一下单失败 :' + e.message)
                        wx_trade_order.comment = u'统一下单失败'
                        wx_trade_order.order_status = 9
                        wx_trade_order.save()
                        if is_json:
                            print '2'
                            return JsonResponse({'msg': u'二维码生成失败', 'code': -1,})
                        else:
                            print '3'
                            return HttpResponse(u'二维码生成失败')

                    if not wx_trade_order.code_url or wx_trade_order.order_status == 9:
                        if wx_trade_order.wx_err_code in ['ORDERPAID', 'ORDERCLOSED', 'OUT_TRADE_NO_USED']:
                            return HttpResponse(WxNativePaymentConstData.UnifiedOrderErrorCodeMsg[wx_trade_order.wx_err_code])
                        else:
                            logging.exception('统一下单失败')
                            if is_json:
                                print '4'
                                return JsonResponse({'msg': u'二维码生成失败', 'code': -1,})
                            else:
                                print '5'
                                return HttpResponse(u'二维码生成失败')
                elif wx_trade_order.order_status == 2: #预支付中,查询订单状态
                    r = WxOrderQueryPayStatusView.query_and_set_order(wx_trade_order)
                    if r:
                        wx_trade_order = r

                if wx_trade_order.order_status == 3:  # 已经支付
                    notify_order_pay_success(product_order)
                    if is_json:
                        return JsonResponse({'msg': u'已经支付', 'code': 1,})
                    else:
                        return HttpResponse(u'已经支付')

                ctx = {'msg': '', 'code': 0,}
                ctx['order_no'] = order_no
                ctx['price'] = product_order.amount
                now = datetime.today() if wx_trade_order.time_expire.tzinfo is None else django.utils.timezone.now()
                ctx['remaining_seconds'] = (wx_trade_order.time_expire-now).seconds
                if ctx['remaining_seconds']<0:
                    ctx['remaining_seconds'] = 0
                if not wx_trade_order.code_url_img_url or wx_trade_order.time_expire >= django.utils.timezone.now() or not os.path.exists(wx_trade_order.code_url_img_path):
                    prepay_url = wx_trade_order.code_url
                    wx_trade_order.code_url_img_url, wx_trade_order.code_url_img_path = generate_qrcode(prepay_url)
                    wx_trade_order.save()

            ctx['qr_code_url'] = wx_trade_order.code_url_img_url

            tpl = 'customer/finance/wx/pay/pay_home.html'

            if is_json:
                return JsonResponse(ctx)
            else:
                return render(request, tpl, ctx)
        except ProductOrder.DoesNotExist:
            if is_json:
                return JsonResponse({'msg': u'订单不存在', 'code': -2,})
            else:
                return HttpResponseBadRequest(u'订单不存在')