def get_wallet():
    dbg('get_wallet')
    reply ,status_code = {'code': 0, 'msg': ''}, 200

    user_id = current_user.id
    agent_id = current_user.agent_id
    wallet = dbapi.get_wallet(user_id=user_id, agent_id=agent_id)
    wechat_user = dbapi.get_wechat_user(admin_uid=user_id)
    nickname = ''
    if not wechat_user:
        nickname = '未绑定微信'
    else:
        nickname = wechat_user.nickname

    total_fee_sum = dbapi.get_pay_to_user(user_id=user_id, total=True)
    wallet = dbapi.get_wallet(user_id=user_id, agent_id=agent_id)
    receipt_sum = dbapi.get_agent_wallet_receipt_sum(wallet.id)

    reply['data'] = {
        'balance': int(wallet.balance),
        'withdrawable_balance': int(wallet.withdrawable_balance),
        'nickname': nickname,
        'total_fee_sum': total_fee_sum,
        'receipt_sum': receipt_sum,
    }
    return make_response(jsonify(reply), status_code)
Exemple #2
0
def get_wallet_balance():
    dbg('get_wallet_balance')
    reply, status_code = {'code': 0, 'msg': ''}, 200

    try:
        data = request.get_json()
        imei = data['imei']
    except:
        print_exception_info()
        raise ApiError('ERROR_PARAM', error.ERROR_PARAM)

    device = dbapi.get_device(imei=imei)
    if not device:
        raise ApiError('ERROR_DEVICE_NOT_FOUND', error.ERROR_DEVICE_NOT_FOUND)

    user_id = g.oauth_user.user_id
    wallet = dbapi.get_wallet(role=0,
                              user_id=user_id,
                              agent_id=device.owner_agent_id)

    agent_setting = dbapi.get_agent_setting(agent_id=device.agent_id)
    wallet_pay_enable = 1
    if agent_setting and agent_setting.wallet_pay_enable == 0:
        wallet_pay_enable = 0

    reply['data'] = {
        'balance': wallet.balance,
        'wallet_pay_enable': wallet_pay_enable
    }
    return make_response(jsonify(reply), status_code)
Exemple #3
0
def make_refund_ticheng_wallet_receipt(agent, receipt, remark):
    dbg('make_refund_ticheng_wallet_receipt')
    user_id = agent.openluat_user_id
    agent_id = agent.id
    wallet = dbapi.get_wallet(user_id=user_id, agent_id=agent_id)
    wallet_id = wallet.id
    trade_type = dbapi.WALLET_TRADE_TYPE_REFUND_TICHENG
    withdrawable_balance = wallet.withdrawable_balance
    if wallet.withdrawable_balance > wallet.balance + receipt:
        withdrawable_balance = withdrawable_balance + receipt
        withdrawable_receipt = receipt
    else:
        withdrawable_receipt = 0
    wallet_receipt = dbapi.make_new_wallet_receipt(user_id, agent_id,
                                                   wallet_id, trade_type,
                                                   receipt,
                                                   withdrawable_receipt,
                                                   remark)
    dbg(wallet_receipt)
    balance = wallet.balance + receipt
    wallet = dbapi.update_wallet(wallet,
                                 balance=balance,
                                 withdrawable_balance=withdrawable_balance)
    dbg('update wallet: %d\treceipt: %f' % (wallet.id, receipt))
    db.session.add(wallet)
Exemple #4
0
def check_refund_available(device, total_fee):
    dbg('check_refund_available')
    imei = device.imei
    rates = (device.l1, device.l2, device.l3, device.l4)
    dds = dbapi.get_device_distribution(imei=imei)
    for dd in dds:
        agent = dbapi.get_agent(id=dd.to_agent)
        if not agent:
            dbg('can not find agent: %d' % dd.to_agent)
            return False
        wallet = dbapi.get_wallet(user_id=agent.openluat_user_id,
                                  agent_id=agent.id)
        rate = rates[agent.level - 1]
        fee = total_fee * rate
        dbg((agent.id, fee, wallet.withdrawable_balance))
        if fee > wallet.withdrawable_balance:
            return False

    return True
Exemple #5
0
def ali_notify():
    dbg('ali_notify')

    reply = {"return_code": 'SUCCESS', "return_msg": ""}

    try:
        trade_no = request.form['out_trade_no']
        nofity_res = {}
        for k in request.form:
            print(k, request.form[k])
            nofity_res[k] = request.form[k]
        trade_status = request.form['trade_status']
        ali_trade_no = request.form['trade_no']
        buyer_id = request.form['buyer_id']
        buyer_logon_id = request.form['buyer_logon_id']
        cash_fee = request.form.get(
            'buyer_pay_amount') or request.form['total_amount']
    except:
        print_exception_info()
        raise ApiError('ERROR_PARAM', error.ERROR_PARAM)

    # 检查订单
    pay = dbapi.get_pay(trade_no=trade_no)
    if not pay:
        raise ApiError('can not find pay: %s' % trade_no)

    # 签名
    # sign = request.form['sign']
    # ali_config = dbapi.get_ali_config(agent_id=int(agent_id))
    # key_path   = ali_config.pub_path

    # 如果已经支付,则直接返回Ok
    if pay.status > 0:
        return make_response('success')

    if trade_status == 'TRADE_CLOSED':
        dbapi.update_pay(pay,
                         user_id=pay.user_id,
                         status=2,
                         nofity_res=json.dumps(nofity_res))
        try:
            db.session.commit()
        except:
            print_exception_info()
            db.session.rollback()
            raise ApiError('ali_notify error')

    elif trade_status == 'TRADE_SUCCESS':
        dbapi.update_pay(pay=pay,
                         user_id=pay.user_id,
                         status=1,
                         cash_fee=cash_fee,
                         nofity_res=json.dumps(nofity_res),
                         ali_trade_no=ali_trade_no)
        product = dbapi.get_product(product_id=pay.product_id)
        if product.cat == 99:
            # 钱包充值
            user_id = pay.user_id
            wallet = dbapi.get_wallet(role=0,
                                      user_id=user_id,
                                      agent_id=pay.agent_id)
            wallet_id = wallet.id
            trade_type = dbapi.WALLET_TRADE_TYPE_DEPOSIT
            receipt = product.value
            withdrawable_receipt = 0
            remark = product.title
            wallet_receipt = dbapi.make_new_wallet_receipt(
                user_id, pay.agent_id, wallet_id, trade_type, receipt,
                withdrawable_receipt, remark)

            balance = wallet.balance + receipt
            wallet = dbapi.update_wallet(wallet, balance=balance)

        wechat_pay_receipt(pay)

        try:
            db.session.commit()
        except:
            print_exception_info()
            db.session.rollback()
            raise ApiError('ali_notify error', error.ERROR_DATABASE_COMMIT)

    return make_response('success')
Exemple #6
0
def pay_notify():
    dbg('pay_notify')
    reply = {"return_code": 'SUCCESS', "return_msg": ""}

    try:
        data_info = request.data.decode('utf8')
        data = wechatpay.xml_to_dict(data_info)
        nofity_res = json.dumps(data)
        dbg('data_info: %s' % data_info)

        return_code = None
        result_code = None

        if "result_code" in data and "return_code" in data:
            return_code = data["return_code"]
            result_code = data["result_code"]

        if return_code != "SUCCESS":
            raise ApiError('wechat interface return error')

        # return_code为`SUCCESS`, 则包含out_trade_no

        # 检查订单
        trade_no = data['out_trade_no']
        pay = dbapi.get_pay(trade_no=trade_no)
        if not pay:
            raise ApiError('can not find pay: %s' % trade_no)

        # 如果已经支付,则直接返回Ok
        if pay.status > 0:
            return make_response(wechatpay.dict_to_xml(reply).encode('utf-8'))

        # 检查签名
        sign = data['sign']
        data.pop('sign')
        wechat_config = dbapi.get_wechat_config(agent_id=pay.agent_id)
        key = wechat_config.mchkey
        local_sign = wechatpay.params_sign(data, key)
        data['sign'] = sign
        dbg((sign, local_sign))
        if sign != local_sign:
            raise ApiError('sign error')

        if result_code != "SUCCESS":
            '''
                ``` 支付失败, 更新支付异常
            '''
            dbapi.update_pay(pay, status=2, nofity_res=nofity_res)

            try:
                db.session.commit()
            except:
                print_exception_info()
                db.session.rollback()
                raise ApiError('pay_notify error')

        else:
            '''
                ``` 支付成功, 并更新支付成功
            '''
            cash_fee = data['cash_fee']
            dbapi.update_pay(pay=pay,
                             status=1,
                             cash_fee=cash_fee,
                             nofity_res=nofity_res)
            product = dbapi.get_product(product_id=pay.product_id)
            if product.cat == 99:
                # 钱包充值
                user_id = pay.user_id
                wallet = dbapi.get_wallet(role=0,
                                          user_id=user_id,
                                          agent_id=pay.agent_id)
                wallet_id = wallet.id
                trade_type = dbapi.WALLET_TRADE_TYPE_DEPOSIT
                receipt = product.value
                withdrawable_receipt = 0
                remark = product.title
                wallet_receipt = dbapi.make_new_wallet_receipt(
                    user_id, pay.agent_id, wallet_id, trade_type, receipt,
                    withdrawable_receipt, remark)

                balance = wallet.balance + receipt
                wallet = dbapi.update_wallet(wallet, balance=balance)

            if product.cat == dbapi.PRODUCT_CAT_COUPON:
                # 优惠券
                coupon = dbapi.get_coupon(pay_id=pay.id)
                if coupon:
                    coupon = dbapi.update_coupon(coupon, paid=1)

            wechat_pay_receipt(pay)

            try:
                db.session.commit()
            except:
                print_exception_info()
                db.session.rollback()
                raise ApiError('wechat_pay_notify error',
                               error.ERROR_DATABASE_COMMIT)

    except ApiError as e:
        # if e.msg != 'wechat pay failed':
        print_exception_info()
        reply['return_code'] = "FAIL"
        reply['return_msg'] = e.msg
    except:
        print_exception_info()
        reply['return_code'] = "FAIL"
        reply['return_msg'] = 'server error'

    res_data = wechatpay.dict_to_xml(reply).encode('utf-8')
    print(res_data)
    return make_response(res_data)
def top_agent_get_wechat_withdraw():
    dbg('top_agent_get_wechat_withdraw')
    reply ,status_code = {'code': 0, 'msg': ''}, 200

    try:
        page  = int(request.args.get('page', 1))
        psize = int(request.args.get('psize', 10))
    except:
        print_exception_info()
        raise ApiError('ERROR_PARAM', error.ERROR_PARAM)

    agent_id = current_user.agent_id
    user_id  = current_user.id

    wechat_agent_id = get_top_wechat_agent_id(agent_id)
    if wechat_agent_id != agent_id:
        raise ApiError('ERROR_AGENT_NO_PERMISSION', error.ERROR_AGENT_NO_PERMISSION)

    agent_setting = dbapi.get_agent_setting(agent_id=wechat_agent_id)

    count, res = dbapi.get_pay_to_user(wechat_agent_id=wechat_agent_id,
        page=page, psize=psize)
    data = []
    sum_dict = {}
    if count:
        for pay_to_user in res:
            openluat_user_id = pay_to_user.openluat_user_id
            agent = dbapi.get_agent(user_id=openluat_user_id)
            if agent:
                wallet = dbapi.get_wallet(user_id=openluat_user_id, agent_id=agent_id)
                name = agent.name
                agent_id = agent.id
                if agent_id in sum_dict:
                    dbg('sum in dict')
                    total_fee_sum = sum_dict[agent_id]['total_fee_sum']
                    receipt_sum = sum_dict[agent_id]['receipt_sum']
                else:
                    total_fee_sum = dbapi.get_pay_to_user(user_id=openluat_user_id, total=True)
                    receipt_sum = dbapi.get_agent_wallet_receipt_sum(wallet.id)
                    sum_dict[agent_id] = {
                        'total_fee_sum': total_fee_sum,
                        'receipt_sum': receipt_sum
                    }
            else:
                dbg('agent not found for openluat_user_id: %s' % openluat_user_id)
                name = ''
                total_fee_sum = 0
                receipt_sum = 0

            info = {
                'time': int(pay_to_user.ctime.timestamp()),
                # 'to_nickname': pay_to_user.to_nickname,
                'payment_no': pay_to_user.payment_no,
                'name': name,
                'total_fee': pay_to_user.total_fee,
                'wechat_fee': math.ceil(pay_to_user.total_fee * agent_setting.withdraw_fee),
                'wechat_fee_rate': agent_setting.withdraw_fee,
                'fee': pay_to_user.total_fee - math.ceil(pay_to_user.total_fee * agent_setting.withdraw_fee),
                'total_fee_sum': total_fee_sum,
                'receipt_sum': receipt_sum,
                'balance': int(wallet.balance),
                'withdrawable_balance': int(wallet.withdrawable_balance),
                'status': pay_to_user.status
            }
            data.append(info)

    reply = {
        'count': count,
        'pays': data
    }

    return make_response(jsonify(reply), status_code)
def wechat_withdraw():
    dbg('wechat_withdraw')
    reply ,status_code = {'code': 0, 'msg': ''}, 200

    try:
        data    = request.get_json()
        fee     = data['fee']
        desc    = data['desc']
        remark  = data['remark']
        pswd    = data['pswd']
        assert(isinstance(fee, int))
    except:
        print_exception_info()
        raise ApiError('ERROR_PARAM', error.ERROR_PARAM)

    if not current_user.verify_password(pswd):
        raise ApiError('ERROR_WRONG_PSWD', error.ERROR_WRONG_PSWD)

    agent_id = current_user.agent_id
    agent_setting = dbapi.get_agent_setting(agent_id=agent_id)
    if fee < agent_setting.min_withdraw:
        dbg('fee: %d\tmin_withdraw: %d' % (fee, agent_setting.min_withdraw))
        raise ApiError('ERROR_WITHDRAW_FEE', error.ERROR_WITHDRAW_FEE)

    wallet = dbapi.get_wallet(user_id=current_user.id, agent_id=agent_id)
    if fee > wallet.withdrawable_balance:
        dbg('fee: %d\twithdrawable_balance: %d' % (fee, wallet.withdrawable_balance))
        raise ApiError('ERROR_WITHDRAW_FEE', error.ERROR_WITHDRAW_FEE)

    user_id = current_user.id
    wechat_user = dbapi.get_wechat_user(admin_uid=user_id)
    if not wechat_user:
        # TODO 错误类型需要优化
        raise ApiError('ERROR_NO_USER', error.ERROR_NO_USER)
    to_openid = wechat_user.openid
    to_nickname = wechat_user.nickname
    max_id  = dbapi.get_max_pay_to_user_id()
    str_max_id = '%04d' % max_id
    if len(str_max_id) > 4:
        str_max_id = str_max_id[-4:]
    trade_no = 'P' + str(int(time.time())) + str_max_id

    wechat_agent_id = get_top_wechat_agent_id(agent_id)
    if not wechat_agent_id:
        raise ApiError('ERROR_TOP_WECHAT_NOT_FOUND', error.ERROR_NO_USER)

    pay_to_user = dbapi.make_new_pay_to_user(wechat_agent_id, user_id, to_openid, to_nickname, trade_no,
        fee, desc, remark)
    db.session.commit()

    kwargs = {
        'openid': to_openid,
        'trade_no': trade_no,
        'money': fee - math.ceil(fee*agent_setting.withdraw_fee),   # 向上取整
        'desc': desc,
        'agent_id': agent_id
    }
    err, result = wechatpay.pay_to_user(**kwargs)
    if err:
        pay_to_user = dbapi.update_pay_to_user(pay_to_user, status=2,
            notify_res=str(err))
        db.session.add(pay_to_user)
        db.session.commit()
        raise ApiError('wechat withdraw error', error.ERROR_PAY_TO_USER_FAIL)

    payment_no = result['payment_no']
    pay_to_user = dbapi.update_pay_to_user(pay_to_user, status=1,
        notify_res=str(result), payment_no=payment_no)
    db.session.add(pay_to_user)

    wallet_id = wallet.id
    trade_type = dbapi.WALLET_TRADE_TYPE_WECHAT_WITHDRAW
    receipt = -fee
    withdrawable_receipt = -fee
    wallet_receipt = dbapi.make_new_wallet_receipt(user_id, agent_id, wallet_id,
        trade_type, receipt, withdrawable_receipt, remark, payment_no)

    balance = wallet.balance - fee
    withdrawable_balance = wallet.withdrawable_balance - fee
    wallet = dbapi.update_wallet(wallet, balance=balance, withdrawable_balance=withdrawable_balance)
    db.session.add(wallet)
    db.session.commit()

    return make_response(jsonify(reply), status_code)