Example #1
0
    def doCancelOrder(cls, path):
        ''' 用于客户端支付失败后取消订单
            reason 0: user cancel the order for client sdk (e.g. ydmm/ltw) failed
                   1: user cancel the order in the first place
                   2: user cancel the order on sms send fail
                   3: user cancel the order on sms send timeout
        '''
        mi = TyContext.RunHttp.convertToMsgPack()
        platformOrderId = mi.getParamStr('platformOrderId', 'na')
        productOrderId = mi.getParamStr('productOrderId', 'na')
        shortId = 'na'
        if ShortOrderIdMap.is_short_order_id_format(platformOrderId):
            shortId, platformOrderId = platformOrderId, ShortOrderIdMap.get_long_order_id(
                platformOrderId)
        appId = mi.getParamInt('appId', 'na')
        userId = mi.getParamInt('userId', 'na')
        clientId = mi.getParamStr('clientId', 'na')
        paytype = mi.getParamStr('payType', 'na')
        errinfo = mi.getParamStr('errInfo', 'na')
        reason = mi.getParamStr('reason', 'na')

        Order.log(platformOrderId,
                  Order.CLIENT_CANCELED,
                  userId,
                  appId,
                  clientId,
                  shortId=shortId,
                  prodOrderId=productOrderId,
                  paytype=paytype,
                  subevent=reason,
                  info=errinfo if errinfo else 'na')
        mo = TyContext.Cls_MsgPack()
        mo.setCmd('cancelorder')
        mo = mo.packJson()
        return mo
Example #2
0
    def reportBi(cls, eventId, params, infomation='na'):
        platformOrderId = params['app_orderid']
        chargeKey = 'sdk.charge:' + platformOrderId
        chargeInfo = TyContext.RedisPayData.execute('HGET', chargeKey,
                                                    'charge')
        if chargeInfo == None:
            chargeInfo = {}
            appId, clientId = TyContext.RedisUser.execute(
                params['userid'], 'HMGET', 'user:'******'userid']),
                'bugYouyifuVipAppid', 'bugYouyifuVipClientid')
        else:
            chargeInfo = TyContext.strutil.loads(chargeInfo, decodeutf8=True)
            appId = chargeInfo.get('appId', 9999)
            clientId = chargeInfo.get('clientId', '')

        if clientId == None or clientId == '':
            # TyContext.ftlog.error('TuYouPayYi->doYiPayCallback Get appId and clientId ERROR.')
            # return False
            clientId = 'Android_3.73_360,tyGuest.360,yisdkpay4.0-hall6.360.dj'

        Order.log(platformOrderId,
                  eventId,
                  chargeInfo.get('uid', params['userid']),
                  str(appId),
                  clientId,
                  info=infomation,
                  paytype=chargeInfo.get('chargeType', 'na'),
                  diamondid=chargeInfo.get('diamondId', 'na'),
                  charge_price=chargeInfo.get('chargeTotal', 'na'),
                  succ_price=chargeInfo.get('chargeTotal', 'na'),
                  prod_price=chargeInfo.get('chargeTotal', 'na'),
                  sub_paytype=params.get('sub_paytype', 'na'),
                  mobile=params.get('mobileId', 'na'))
Example #3
0
 def reportBi(cls, eventId, params, infomation='na'):
     Order.log(params['platformOrderId'],
               eventId,
               params['userId'],
               params['appId'],
               params['clientId'],
               info=infomation,
               paytype=params['payType'],
               diamondid=params['productId'],
               mobile=params['mobile'])
Example #4
0
    def doCancelOrder(cls, path):
        ''' 用于客户端支付失败后取消订单
            reason 0: user cancel the order for client sdk (e.g. ydmm/ltw) failed
                   1: user cancel the order in the first place
                   2: user cancel the order on sms send fail
                   3: user cancel the order on sms send timeout
        '''
        mi = TyContext.RunHttp.convertToMsgPack()
        platformOrderId = mi.getParamStr('platformOrderId', 'na')
        productOrderId = mi.getParamStr('productOrderId', 'na')
        shortId = 'na'
        if ShortOrderIdMap.is_short_order_id_format(platformOrderId):
            shortId, platformOrderId = platformOrderId, ShortOrderIdMap.get_long_order_id(platformOrderId)
        appId = mi.getParamInt('appId', 'na')
        userId = mi.getParamInt('userId', 'na')
        clientId = mi.getParamStr('clientId', 'na')
        paytype = mi.getParamStr('payType', 'na')
        errinfo = mi.getParamStr('errInfo', 'na')
        reason = mi.getParamStr('reason', 'na')

        chargeKey = 'sdk.charge:' + platformOrderId
        chargeInfo = TyContext.RedisPayData.execute('HGET', chargeKey, 'charge')
        if chargeInfo == None:
            chargeInfo = {}
        else:
            chargeInfo = TyContext.strutil.loads(chargeInfo, decodeutf8=True)

        Order.log(platformOrderId, Order.CLIENT_CANCELED, userId, appId, clientId,
                  shortId=shortId, prodOrderId=productOrderId, paytype=paytype,
                  prodid=chargeInfo.get('prodId', 'na'),
                  diamondid=chargeInfo.get('diamondId', 'na'),
                  charge_price=chargeInfo.get('chargeTotal', 'na'),
                  subevent=reason, info=errinfo if errinfo else 'na')
        mo = TyContext.Cls_MsgPack()
        mo.setCmd('cancelorder')
        mo = mo.packJson()
        return mo
Example #5
0
 def is_orderId_valid(orderId, rparam, amount):
     chargeKey = 'sdk.charge:' + platformOrderId
     oldState, chargeInfo, consumeInfo = TyContext.RedisPayData.execute(
         'HMGET', chargeKey, 'state', 'charge', 'consume')
     if oldState != PayConst.CHARGE_STATE_ERROR_CALLBACK:
         return True
     else:
         chargeInfo = TyContext.strutil.loads(chargeInfo,
                                              decodeutf8=True)
         paytype = rparam.get('chargeType',
                              chargeInfo.get('chargeType', 'na'))
         Order.log(
             platformOrderId,
             Order.INTERNAL_ERR,
             chargeInfo['uid'],
             chargeInfo['appId'],
             chargeInfo['clientId'],
             paytype=paytype,
             prodid=chargeInfo.get('prodId', 'na'),
             diamondid=chargeInfo['diamondId'],
             charge_price=chargeInfo['chargeTotal'],
             succ_price=amount,
             sub_paytype=rparam.get('sub_paytype', 'na'),
             third_prodid=rparam.get('third_prodid', 'na'),
             third_orderid=rparam.get('third_orderid', 'na'),
             third_provid=rparam.get('third_provid', 'na'),
             third_userid=rparam.get('third_userid', 'na'),
             pay_appid=rparam.get('pay_appid', 'na'),
             info='order state charged',
         )
         TyContext.ftlog.info('callback platformOrderId=',
                              platformOrderId,
                              'old state is done, oldState=', oldState,
                              'newState=',
                              PayConst.CHARGE_STATE_CALLBACK_OK)
         return False
Example #6
0
    def request(cls, mi):
        TyContext.ftlog.debug('---request---mi', mi)
        userId = mi.getParamInt('userId')
        chargeType = mi.getParamStr('chargeType')
        appId = mi.getParamInt('appId', 'na')
        clientId = mi.getParamStr('clientId', 'na')
        platformOrderId = mi.getParamStr('platformOrderId')
        shortId = 'na'
        if ShortOrderIdMap.is_short_order_id_format(platformOrderId):
            shortId, platformOrderId = platformOrderId, ShortOrderIdMap.get_long_order_id(platformOrderId)

        mo = TyContext.Cls_MsgPack()
        mo.setCmd('request')

        chargeKey = 'sdk.charge:' + platformOrderId
        state, chargeInfo = TyContext.RedisPayData.execute('HMGET', chargeKey, 'state', 'charge')
        TyContext.ftlog.debug('TuyouPayRequest request: order', platformOrderId,
                              'state', state, 'charge', chargeInfo)
        if state is None or not chargeInfo:
            mo.setError(1, '充值错误,请关闭界面重试')
            return mo

        if state >= PayConst.CHARGE_STATE_ERROR_REQUEST:
            mo.setError(1, '充值失败,请关闭界面重试')
            return mo

        chargeInfo = json.loads(chargeInfo)
        if chargeInfo['uid'] != userId:
            mo.setError(1, '充值事务错误')
            return mo

        if 'chargeType' not in chargeInfo or chargeInfo['chargeType'] != chargeType:
            chargeInfo['chargeType'] = chargeType
            TyContext.RedisPayData.execute('HMSET', chargeKey, 'charge', json.dumps(chargeInfo))

        state = cls.__request__(chargeType, chargeInfo, mi, mo)
        if state == PayConst.CHARGE_STATE_REQUEST:
            TyContext.RedisPayData.execute('HSET', chargeKey, 'state', state)
            Order.log(platformOrderId, Order.REQUEST_OK, userId,
                      appId, clientId,
                      diamondid=chargeInfo.get('diamondId', 'na'),
                      charge_price=chargeInfo.get('chargeTotal', 'na'),
                      paytype=chargeType)
        elif state == PayConst.CHARGE_STATE_ERROR_REQUEST:
            # mo.setError(1, '充值请求失败')
            errInfo = mo.getErrorInfo()
            TyContext.RedisPayData.execute('HMSET', chargeKey, 'state', state,
                                           'errorInfo', errInfo)
            Order.log(platformOrderId, Order.REQUEST_ERROR, userId, appId,
                      clientId, info=errInfo,
                      diamondid=chargeInfo.get('diamondId', 'na'),
                      charge_price=chargeInfo.get('chargeTotal', 'na'),
                      paytype=chargeType)
        elif state == PayConst.CHARGE_STATE_REQUEST_RETRY \
                or state == PayConst.CHARGE_STATE_REQUEST_IGNORE:
            Order.log(platformOrderId, Order.REQUEST_RETRY, userId,
                      appId, clientId,
                      diamondid=chargeInfo.get('diamondId', 'na'),
                      charge_price=chargeInfo.get('chargeTotal', 'na'),
                      paytype=chargeType)
        else:
            raise Exception('not known state ' + state)
        mo.setResult('status', state)
        return mo
Example #7
0
    def status(cls, mi):

        platformOrderId = mi.getParamStr('platformOrderId')
        platformOrderId = ShortOrderIdMap.get_long_order_id(platformOrderId)
        querynums = mi.getParamInt('querynums')
        appId = mi.getParamInt('appId')
        userId = mi.getParamInt('userId')
        clientId = mi.getParamStr('clientId', 'na')
        paytype = mi.getParamStr('payType', 'na')

        mo = TyContext.Cls_MsgPack()
        mo.setCmd('status')

        chargeKey = 'sdk.charge:' + platformOrderId
        state, chargeInfo, consumemo, errorInfo = TyContext.RedisPayData.execute('HMGET', chargeKey, 'state', 'charge',
                                                                                 'consume:mo', 'errorInfo')
        if state == None or chargeInfo == None:
            mo.setError(1, 'platformOrderId参数错误')
            return mo

        chargeInfo = json.loads(chargeInfo)
        if paytype != 'na':
            chargeInfo['chargeType'] = paytype
        isOK = cls.__query_ext_status__(chargeInfo)
        if isOK:
            state, consumemo, errorInfo = TyContext.RedisPayData.execute('HMGET', chargeKey, 'state', 'consume:mo',
                                                                         'errorInfo')

        if state < PayConst.CHARGE_STATE_CLIENT_PAY_DONE:
            TyContext.RedisPayData.execute('HMSET', chargeKey, 'state', PayConst.CHARGE_STATE_CLIENT_PAY_DONE)
            Order.log(platformOrderId, Order.CLIENT_FINISHED, userId, appId,
                      clientId, paytype=paytype,
                      diamondid=chargeInfo.get('diamondId', 'na'),
                      charge_price=chargeInfo.get('chargeTotal', 'na'),
                      )
            # 对完成客户端请求的订单进行风控,之前在callback里进行风控效果不好,这里把total_fee=0
            # appids -> {"paytype": "appid"}
            appids = PayCodes(clientId).appids
            duandais = TyContext.Configure.get_global_item_json('all_duandai_paytypes', {})
            if paytype in appids.keys() and paytype in duandais:
                paytype = '_'.join([paytype, appids[paytype]])
                RiskControl(userId).record_usage(paytype, 0)

        # 充值中
        if state < PayConst.CHARGE_STATE_DONE:
            return cls.__get_query_mo(mo, state, 'process', chargeInfo, paytype, querynums)

        # 购买成功
        if state == PayConst.CHARGE_STATE_DONE:
            return cls.__get_query_mo(mo, state, 'success', chargeInfo, paytype, querynums)

        # 充值成功
        if state == PayConst.CHARGE_STATE_DONE_CONSUME:
            return cls.__get_query_mo(mo, state, 'success', chargeInfo, paytype, querynums)

        # 发货失败
        if state == PayConst.CHARGE_STATE_ERROR_CONSUME:
            return cls.__get_query_mo(mo, state, 'bug', chargeInfo, paytype, querynums)

        # 支付失败
        if state == PayConst.CHARGE_STATE_ERROR_CALLBACK:
            # 支付失败返回更多支付方式
            failreturnconfig = TyContext.Configure.get_global_item_json('payfail_returnconfig', {})
            payconfig = TyContext.Configure.get_global_item_json('store_payment', clientid=clientId)
            if payconfig and 'payment' in payconfig and 'more_categories' in payconfig['payment']:
                TyContext.ftlog.debug('CHARGE_STATE_ERROR_CALLBACK', payconfig['payment']['more_categories'],
                                      'diamondId', chargeInfo['diamondId'])
                if payconfig['payment']['more_categories'] in failreturnconfig and chargeInfo[
                    'diamondId'] in failreturnconfig:
                    mo.setResult('des', failreturnconfig[chargeInfo['diamondId']]['des'])

                    paytemplate = failreturnconfig[payconfig['payment']['more_categories']]
                    paytemplateconfig = TyContext.Configure.get_global_item_json(paytemplate)
                    mo.setResult('morepaytype', paytemplateconfig)
                    mo.setResult('priority', paytemplateconfig[0]['paytype'])
            return cls.__get_query_mo(mo, state, 'fail', chargeInfo, paytype, querynums)

        # 充值失败
        if errorInfo == None:
            errorInfo = ''
        else:
            errorInfo = u'充值失败原因:' + unicode(errorInfo)

        # 支付失败返回更多支付方式
        failreturnconfig = TyContext.Configure.get_global_item_json('payfail_returnconfig', {})
        payconfig = TyContext.Configure.get_global_item_json('store_payment', clientid=clientId)
        if payconfig and 'payment' in payconfig and 'more_categories' in payconfig['payment']:
            TyContext.ftlog.debug('CHARGE_STATE_ERROR_CALLBACK', payconfig['payment']['more_categories'], 'diamondId',
                                  chargeInfo['diamondId'])
            if payconfig['payment']['more_categories'] in failreturnconfig and chargeInfo[
                'diamondId'] in failreturnconfig:
                mo.setResult('des', failreturnconfig[chargeInfo['diamondId']]['des'])

                paytemplate = failreturnconfig[payconfig['payment']['more_categories']]
                paytemplateconfig = TyContext.Configure.get_global_item_json(paytemplate)
                mo.setResult('morepaytype', paytemplateconfig)
                mo.setResult('priority', paytemplateconfig[0]['paytype'])
        return cls.__get_query_mo(mo, state, 'fail', chargeInfo, paytype, querynums, errorInfo)
Example #8
0
    def callback(cls, platformOrderId, total_fee, state, rparam, errorInfo):
        TyContext.ftlog.info('****** callback platformOrderId=',
                             platformOrderId, 'total_fee=', total_fee,
                             'state=', state, 'errorInfo=', errorInfo,
                             'rparam=', rparam)

        chargeKey = 'sdk.charge:' + platformOrderId
        oldState, chargeInfo, consumeInfo = TyContext.RedisPayData.execute(
            'HMGET', chargeKey, 'state', 'charge', 'consume')
        if oldState == None or chargeInfo == None:
            TyContext.ftlog.error('platformOrderId not found !',
                                  platformOrderId)
            return True

        chargeInfo = TyContext.strutil.loads(chargeInfo, decodeutf8=True)
        paytype = rparam.get('chargeType', chargeInfo.get('chargeType', 'na'))
        if state == PayConst.CHARGE_STATE_ERROR_CALLBACK:
            if oldState < PayConst.CHARGE_STATE_ERROR_REQUEST:
                # 第三方通知充值失败
                if errorInfo == None or len(errorInfo) == 0:
                    errorInfo = '充值失败,请关闭页面重试'
                cls.__change_callback_state__(chargeKey, state, errorInfo,
                                              None)
            else:
                TyContext.ftlog.info('callback platformOrderId=',
                                     platformOrderId,
                                     'old state error, oldState=', oldState,
                                     'newState=', state)

            Order.log(
                platformOrderId,
                Order.CALLBACK_FAIL,
                chargeInfo['uid'],
                chargeInfo['appId'],
                chargeInfo['clientId'],
                info=errorInfo,
                prodid=chargeInfo.get('prodId', 'na'),
                diamondid=chargeInfo['diamondId'],
                charge_price=chargeInfo.get('chargeTotal', 'na'),
                succ_price=total_fee,
                paytype=paytype,
                sub_paytype=rparam.get('sub_paytype', 'na'),
                third_prodid=rparam.get('third_prodid', 'na'),
                third_orderid=rparam.get('third_orderid', 'na'),
                third_provid=rparam.get('third_provid', 'na'),
                third_userid=rparam.get('third_userid', 'na'),
                pay_appid=rparam.get('pay_appid', 'na'),
            )
            return True

        if state == PayConst.CHARGE_STATE_CALLBACK_OK:
            isDone = True
            if oldState < PayConst.CHARGE_STATE_CALLBACK_OK:
                if oldState < PayConst.CHARGE_STATE_CLIENT_PAY_DONE:
                    Order.log(platformOrderId,
                              Order.CLIENT_FINISHED,
                              chargeInfo['uid'],
                              chargeInfo['appId'],
                              chargeInfo['clientId'],
                              paytype=paytype,
                              prodid=chargeInfo.get('prodId', 'na'),
                              diamondid=chargeInfo['diamondId'],
                              charge_price=chargeInfo.get('chargeTotal', 'na'),
                              succ_price=total_fee)
                isDone = False
            if oldState >= PayConst.CHARGE_STATE_ERROR_REQUEST:
                isDone = False
            if isDone:
                # XXX if external orderid is new, consider re-delivery the order?!
                Order.log(
                    platformOrderId,
                    Order.INTERNAL_ERR,
                    chargeInfo['uid'],
                    chargeInfo['appId'],
                    chargeInfo['clientId'],
                    paytype=paytype,
                    prodid=chargeInfo.get('prodId', 'na'),
                    diamondid=chargeInfo['diamondId'],
                    charge_price=chargeInfo['chargeTotal'],
                    succ_price=total_fee,
                    sub_paytype=rparam.get('sub_paytype', 'na'),
                    third_prodid=rparam.get('third_prodid', 'na'),
                    third_orderid=rparam.get('third_orderid', 'na'),
                    third_provid=rparam.get('third_provid', 'na'),
                    third_userid=rparam.get('third_userid', 'na'),
                    pay_appid=rparam.get('pay_appid', 'na'),
                    info='order state charged',
                )
                TyContext.ftlog.info('callback platformOrderId=',
                                     platformOrderId,
                                     'old state is done, oldState=', oldState,
                                     'newState=', state)
                return True

            # save charge data
            UniversalUser().increase_user_charge_data(
                chargeInfo['uid'], chargeInfo['appId'], chargeInfo['clientId'],
                chargeInfo.get('chargeTotal', 1),
                chargeInfo.get('chargeType', 'na'))

            chargecategories_config = TyContext.Configure.get_global_item_json(
                'charge_categories_config', {})
            # 单机商城商品TY9999R00020DJ的订单,没有chargeType
            if 'chargeType' in chargeInfo:
                for key in chargecategories_config.keys():
                    if chargeInfo['chargeType'] in key:
                        lastChargeCategory = chargecategories_config[key]
                        TyContext.RedisUser.execute(
                            chargeInfo['uid'], 'HSET',
                            'user:'******'uid']),
                            'lastChargeCategory', lastChargeCategory)
                        break

            try:
                chargeInfo['isTestOrder'] = rparam['isTestOrder']
            except:
                pass
            try:
                chargeInfo['chargeType'] = rparam['chargeType']
            except:
                pass

            if consumeInfo:
                consumeInfo = json.loads(consumeInfo)

            Order.log(
                platformOrderId,
                Order.CALLBACK_OK,
                chargeInfo['uid'],
                chargeInfo['appId'],
                chargeInfo['clientId'],
                paytype=rparam.get('chargeType', 'na'),
                prodid=chargeInfo.get('prodId', 'na'),
                diamondid=chargeInfo['diamondId'],
                prod_price=consumeInfo['consumeCoin'] if consumeInfo else 'na',
                charge_price=chargeInfo['chargeTotal'],
                succ_price=total_fee,
                sub_paytype=rparam.get('sub_paytype', 'na'),
                third_prodid=rparam.get('third_prodid', 'na'),
                third_provid=rparam.get('third_provid', 'na'),
                third_userid=rparam.get('third_userid', 'na'),
                third_orderid=rparam.get('third_orderid', 'na'),
                pay_appid=rparam.get('pay_appid', 'na'),
                mobile=chargeInfo.get('vouchMobile', 'na'),
            )
            try:
                chargeInfo['paytype_w_appid'] = '_'.join(
                    [chargeInfo['chargeType'], rparam['pay_appid']])
            except:
                pass
            # 记录支付通道的子渠道
            try:
                chargeInfo['sub_paytype'] = rparam.get('sub_paytype', '')
            except:
                pass
            PayBaseV4.upgrade_user_paylimit_state(chargeInfo['uid'],
                                                  chargeInfo['chargeType'],
                                                  chargeInfo['chargeTotal'])
            cls.__change_user_coin__(platformOrderId, total_fee, chargeInfo,
                                     consumeInfo)

            if not consumeInfo:
                cls.__change_callback_state__(chargeKey,
                                              PayConst.CHARGE_STATE_DONE, '',
                                              None)
                Order.log(
                    platformOrderId,
                    Order.DELIVER_OK,
                    chargeInfo['uid'],
                    chargeInfo['appId'],
                    chargeInfo['clientId'],
                    paytype=paytype,
                    diamondid=chargeInfo['diamondId'],
                    charge_price=chargeInfo['chargeTotal'],
                    succ_price=total_fee,
                    sub_paytype=rparam.get('sub_paytype', 'na'),
                    third_prodid=rparam.get('third_prodid', 'na'),
                    third_orderid=rparam.get('third_orderid', 'na'),
                    pay_appid=rparam.get('pay_appid', 'na'),
                )
                PayHelper.notify_game_server_on_diamond_change({
                    'appId':
                    chargeInfo['appId'],
                    'clientId':
                    chargeInfo['clientId'],
                    'userId':
                    chargeInfo['uid'],
                    'buttonId':
                    chargeInfo['diamondId'],
                    'diamonds':
                    chargeInfo['chargedDiamonds'],
                    'rmbs':
                    chargeInfo['chargedRmbs']
                })
                return True

            cls.__change_callback_state__(chargeKey,
                                          PayConst.CHARGE_STATE_CONSUME, '',
                                          None)
            appId = consumeInfo['appId']
            appInfo = consumeInfo['appInfo']
            clientId = consumeInfo['clientId']
            userId = consumeInfo['userId']
            consumeCoin = consumeInfo['consumeCoin']
            prodId = consumeInfo['prodId']
            prodPrice = consumeInfo['prodPrice']
            prodCount = consumeInfo['prodCount']
            prodName = consumeInfo['prodName']
            prodOrderId = consumeInfo['prodOrderId']

            mo = TyContext.Cls_MsgPack()
            mo.setCmd('consume')
            # modified by zhangshibo at 2015-09-09
            if 'isYouyifuMonthVip' in rparam:
                TyContext.ftlog.debug(
                    'callback-> Has isYouyifuMonthVip info in rparam.')
                mo.setParam('is_monthly', '1')
            # end modify
            TuyouPayConsume.__consume_user_coin__(appId, appInfo, clientId,
                                                  userId, consumeCoin, prodId,
                                                  prodPrice, prodCount,
                                                  prodName, prodOrderId, mo,
                                                  chargeInfo)
            if mo.isError():
                cls.__change_callback_state__(
                    chargeKey, PayConst.CHARGE_STATE_ERROR_CONSUME, '', mo)
            else:
                cls.__change_callback_state__(
                    chargeKey, PayConst.CHARGE_STATE_DONE_CONSUME, '', mo)
            PayHelper.notify_game_server_on_diamond_change({
                'appId':
                appId,
                'clientId':
                clientId,
                'userId':
                userId,
                'buttonId':
                prodId,
                'diamonds':
                chargeInfo['chargedDiamonds'],
                'rmbs':
                chargeInfo['chargedRmbs']
            })
            return True

        TyContext.ftlog.error('SHOULDNOT REACH HERE: callback invalid state',
                              state, 'platformOrderId', platformOrderId)
        return True
Example #9
0
 def get_charge_info(self, mi):
     """
     获取购买信息,prodId可能是钻石Id,也可能是道具Id
     :param mi:
     :return:
     """
     userId = mi.getParamInt('userId', 0)
     appId = mi.getParamStr('appId', '9999')
     clientId = mi.getParamStr('clientId')
     appInfo = mi.getParamStr('appInfo', '')
     chargeType = mi.getParamStr('chargeType')
     prodId = mi.getParamStr('prodId')
     prodName = mi.getParamStr('prodName')
     prodCount = mi.getParamInt('prodCount', 0)
     prodPrice = float(mi.getParamStr('prodPrice', 0))
     mustcharge = mi.getParamInt('mustcharge', 0)
     # tyChannelName = mi.getParamStr('tyChannelName')
     platformOrderId = mi.getParamStr('platformOrderId', '')
     if not platformOrderId:
         platformOrderId = self.make_order_id(userId, appId, clientId)
     # 获取商品信息
     prod_info = ChargeConfigure.get_prod_info(appId,
                                               prodId,
                                               clientId=clientId)
     if not prod_info:
         raise PayErrorV4(1, '商品信息错误')
     if prodPrice >= 0.1 and abs(prodPrice - prod_info['price']) > 0.1:
         raise PayErrorV4(2, '商品信息错误')
     # 商品加个通过后台配置
     prodPrice = prod_info['price']
     if not prodCount or prodCount < 0:
         prodCount = 1
     if not prodName:
         prodName = prod_info.get('name', '')
         # 获取折扣信息
     cpExtInfo = ""
     cpExtObj = ChargeConfigure.get_cpExt_info(prodId,
                                               appId,
                                               clientId=clientId,
                                               chargeType=chargeType)
     if cpExtObj:
         cpExtInfo = cpExtObj.get('cpExtInfo', 0)
     chargeInfo = {
         'uid':
         userId,
         'userId':
         userId,
         'appId':
         int(appId),
         'clientId':
         clientId,
         'appInfo':
         appInfo,
         'chargeType':
         chargeType,
         'diamondId':
         prodId,
         'diamondName':
         prodName,
         'diamondPrice':
         prodPrice,
         'diamondCount':
         prodCount,
         'chargeTotal':
         prodPrice * prodCount,  # 充值的RMB数量
         'chargeCoin':
         prodCount * prod_info['diamondPrice'],  # 充值的钻石数量
         'platformOrderId':
         platformOrderId,
         'phoneType':
         TyContext.UserSession.get_session_phone_type(userId),
         'buttonId':
         prodId,
         'buttonName':
         prodName,
         'cpExtInfo':
         cpExtInfo,
         'mustcharge':
         mustcharge,
         'prodOrderId':
         mi.getParamStr('prodOrderId', ''),
         'mainChannel':
         clientId.split('.')[-2],
         'packageName':
         mi.getParamStr('tyPackageName', '')
         or mi.getParamStr('packageName', ''),
         'channelName':
         mi.getParamStr('tyChannelName', ''),
     }
     # 非钻石需要兑换或途游游戏
     if not int(prod_info.get('is_diamond', 0)) or int(appId) > 9999:
         consumeInfo = self.get_consume_info(chargeInfo)
     else:
         consumeInfo = None
     # 计费点获取(有些钻石也需要)
     self.check_charge_info(mi, chargeInfo)
     self.save_order(chargeInfo, consumeInfo)
     # bi report
     Order.log(platformOrderId,
               Order.CREATE,
               userId,
               appId,
               clientId,
               diamondid=chargeInfo['diamondId'],
               prodid=consumeInfo['prodId'] if consumeInfo else 'na',
               prod_price=consumeInfo['prodPrice'] if consumeInfo else 'na',
               paytype=chargeInfo.get('chargeType', 'na'),
               charge_price=chargeInfo['chargeTotal'],
               shortId='',
               pay_appid='')
     return chargeInfo
Example #10
0
class TuyouPayConsume(object):
    __consume_ext_diamond_funs__ = {}

    @classmethod
    def consume(cls, mi):
        userId = mi.getParamInt('userId')
        authorCode = mi.getParamStr('authorCode')
        appId = mi.getParamInt('appId')
        clientId = mi.getParamStr('clientId')
        appInfo = mi.getParamStr('appInfo')
        prodId = mi.getParamStr('prodId')
        prodName = mi.getParamStr('prodName')
        prodCount = mi.getParamInt('prodCount')
        prodPrice = mi.getParamInt('prodPrice')
        # 用于第三方应用(appId>10000)传递游戏订单号。途游的游戏不用传或传空串
        prodOrderId = mi.getParamStr('prodOrderId')
        mustcharge = mi.getParamInt('mustcharge')
        clientPayType = mi.getParamStr('payType')
        packageName = mi.getParamStr('packageName', '')
        channelName = mi.getParamStr('channelName', '')
        # example "payInfo": {"appid": {"ydmm": "300008410694"}}
        payInfo = mi.getParamStr('payInfo')
        if payInfo:
            payInfo = TyContext.strutil.loads(payInfo, decodeutf8=True)

        mo = TyContext.Cls_MsgPack()
        mo.setCmd('consume')

        m2 = _check_prod_price(mi)
        if m2 != None:
            return m2

        #         # 取得道具的配置PRICE
        #         appProdPrice = -1
        #         appProducts = TuyouPayProductList.productlist2(appId, clientId)
        #         for x in xrange(len(appProducts)):
        #             product = appProducts[x]
        #             if prodId == product['id'] :
        #                 appProdPrice = int(product['price'])
        #                 break
        #         if prodPrice <= 0 or appProdPrice <= 0 or appProdPrice != prodPrice :
        #             mo.setError(2, '商品信息错误,请重新购买')
        #             return mo

        # 取得当前用户的COIN
        userCoin = TyContext.RedisUser.execute(userId, 'HGET',
                                               'user:'******'diamond')
        if isinstance(userCoin, (int, float)):
            userCoin = int(userCoin)
        else:
            userCoin = 0

        TyContext.ftlog.info('consume->appId=', appId, 'clientId=', clientId,
                             'userId=', userId, 'userCoin=', userCoin,
                             'prodPrice=', prodPrice, 'prodId=', prodId,
                             'prodName=', prodName, 'prodCount=', prodCount,
                             'prodOrderId=', prodOrderId, 'mustcharge=',
                             mustcharge, 'clientPayType', clientPayType,
                             'payInfo=', payInfo)

        if prodCount <= 0:
            prodCount = 1
        else:
            prodCount = int(prodCount)

        # if prodCount != 1 :
        #    mo.setError(2, '商品信息错误,请重新购买')
        #    return mo

        prodPrice = int(prodPrice)
        consumeCoin = int(prodPrice * prodCount)
        if not consumeCoin:
            mo.setError(2, '商品价格信息错误,请检查')
            return mo

        fail, prodOrderId = cls._create_consume_transaction(
            appId, appInfo, clientId, userId, consumeCoin, prodId, prodPrice,
            prodCount, prodName, prodOrderId, mo)
        if fail:
            return mo

        if mustcharge == 1 or userCoin < consumeCoin:
            cls.__consume_charge__(appId,
                                   appInfo,
                                   clientId,
                                   userId,
                                   authorCode,
                                   consumeCoin,
                                   prodId,
                                   prodPrice,
                                   prodCount,
                                   prodName,
                                   prodOrderId,
                                   mustcharge,
                                   clientPayType,
                                   payInfo,
                                   mo,
                                   packageName=packageName,
                                   channelName=channelName)
        else:
            cls.__consume_user_coin__(appId, appInfo, clientId, userId,
                                      consumeCoin, prodId, prodPrice,
                                      prodCount, prodName, prodOrderId, mo)
        return mo

    @classmethod
    def __get_extra_delivery(cls, charge_info):
        found = None
        try:
            TyContext.ftlog.debug('__get_extra_delivery charge_info:',
                                  charge_info)
            categories = charge_info['chargeCategories']
            paytype = charge_info['chargeType']
            for cat in categories:
                _paytype = cat['paytype']
                if paytype == _paytype or paytype in _paytype:
                    found = cat['extra_deliver']
                    break
        finally:
            TyContext.ftlog.debug('__get_extra_delivery: extra_deliver', found)
            return found

    @classmethod
    def _create_consume_transaction(cls, appId, appInfo, clientId, userId,
                                    consumeCoin, prodId, prodPrice, prodCount,
                                    prodName, prodOrderId, mo):

        if appId > 10000:
            # 其他第三方游戏,如果未携带事务ID,缺省为-
            if not prodOrderId or len(prodOrderId) <= 0:
                prodOrderId = '-'
            return False, prodOrderId

        prodOrderId = TyContext.ServerControl.makeConsumeOrderIdV3(
            userId, appId, clientId)
        control = TyContext.ServerControl.findServerControl(appId, clientId)
        try:
            consumeUrl = control['http'] + '/v2/game/consume/transaction'
        except:
            mo.setError(3, '系统服务配置错误')
            return True, prodOrderId

        params = [
            'appId', appId, 'clientId', clientId, 'userId', userId,
            'prodPrice', prodPrice, 'prodId', prodId, 'prodCount', prodCount,
            'prodOrderId', prodOrderId
        ]
        datas, _ = TyContext.WebPage.webget_json(consumeUrl, params)
        try:
            mo.setError(5, datas['error']['info'])
            return True, prodOrderId
        except:
            if prodOrderId != datas['result']['prodOrderId']:
                mo.setError(4, '系统错误,无法建立商品购买事务')
                return True, prodOrderId

        return False, prodOrderId

    @classmethod
    def __consume_user_coin__(cls,
                              appId,
                              appInfo,
                              clientId,
                              userId,
                              consumeCoin,
                              prodId,
                              prodPrice,
                              prodCount,
                              prodName,
                              prodOrderId,
                              mo,
                              chargeInfo=None):
        # 获取服务配置
        deliveryUrl = None
        control = TyContext.ServerControl.findServerControl(appId, clientId)
        if appId < 10000:
            # 途游自己的游戏,固定的投递地址
            # control = TyContext.ServerControl.findServerControl(appId, clientId)
            # if control :
            deliveryUrl = control['http'] + '/v2/game/consume/delivery'
        else:
            deliveryUrl = TyContext.Configure.get_game_item_str(
                appId, 'deliveryUrl', '')
        appKey = TyContext.Configure.get_game_item_str(appId, 'appKey', '')
        if not appKey:
            gameConfig = TyContext.Configure.get_game_item_json(appId, 'game')
            appKey = gameConfig.get('appKey', '')
            deliveryUrl = gameConfig.get('deliveryUrl', '')
            isErrorNotify = gameConfig.get('isErrorNotify', '')
        TyContext.ftlog.debug('__consume_user_coin__ deliveryUrl=',
                              deliveryUrl, 'appKey=', appKey)
        if not deliveryUrl or not appKey or len(deliveryUrl) == 0 or len(
                appKey) == 0:
            TyContext.ftlog.error(
                '__consume_user_coin__ deliveryUrl or appKey error')
            mo.setError(3, '系统服务配置错误,缺少回调地址')
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.INTERNAL_ERR,
                          userId,
                          appId,
                          clientId,
                          info='consume delivery cfg err')
            return True

        # 取得唯一事物ID
        consumeId = TyContext.ServerControl.makeConsumeOrderIdV3(
            userId, appId, clientId)

        ct = datetime.datetime.now()
        timestamp = ct.strftime('%Y-%m-%d %H:%M:%S')
        paykey = ct.strftime('sdk.consume:%Y%m%d')
        consumeinfo = {
            'time': timestamp,
            'uid': userId,
            'appId': appId,
            'name': prodName,
            'fee': consumeCoin,
            'clientId': clientId,
            'appOrderId': prodOrderId,
            'prodId': prodId,
            'consumeId': consumeId
        }
        params = {
            'userId': userId,
            'orderId': prodOrderId,
            'consumeCoin': consumeCoin,
            'appId': appId,
            'appInfo': appInfo,
            'clientId': clientId,
            'prodPrice': prodPrice,
            'prodId': prodId,
            'prodCount': prodCount,
            'consumeId': consumeId,
            'apiver': '2'
        }
        if chargeInfo:
            if 'chargeType' in chargeInfo and appId < 10000:
                params['chargeType'] = chargeInfo['chargeType']
            params['platformOrder'] = chargeInfo['platformOrderId']
            params['chargedRmbs'] = chargeInfo['chargedRmbs']
            params['chargedDiamonds'] = chargeInfo['chargedDiamonds']
            if 'cpExtInfo' in chargeInfo and chargeInfo['cpExtInfo']:
                params['cpExtInfo'] = chargeInfo['cpExtInfo']
        # modified by zhangshibo at 2015-09-09,标识是优易付会员订阅
        if mo.getParam('is_monthly'):
            params['is_monthly'] = '1'
        # end modify

        extra_delivery = cls.__get_extra_delivery(chargeInfo)
        if extra_delivery is not None:
            params['extra_deliver'] = extra_delivery

        # 首先扣除三方钻石
        ok = cls.__consume_ext_diamond__(params, False)
        if not ok:
            mo.setError(8, '三方钻石扣款失败')
            TyContext.ftlog.error(
                '__consume_user_coin__ consume ext diamond '
                'ERROR: paykey', paykey, 'consumeinfo', consumeinfo)
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.INTERNAL_ERR,
                          userId,
                          appId,
                          clientId,
                          info='third party consume diamond err')
            return True

        # 扣除钻石
        # leftCoin = TyContext.RedisUser.execute(userId, 'HINCRBY', 'user:'******'diamond', -consumeCoin)
        delta, leftCoin = TyContext.UserProps.incr_diamond(
            int(userId), int(appId), -consumeCoin,
            TyContext.ChipNotEnoughOpMode.NOOP, TyContext.BIEventId.UNKNOWN)
        TyContext.BiReport.diamond_update(appId, userId, -consumeCoin,
                                          leftCoin, 'sdk.pay.v3.consume')
        if delta != -consumeCoin:
            TyContext.ftlog.error('__consume_user_coin__ diamond update error')
            # leftCoin = TyContext.RedisUser.execute(userId, 'HINCRBY', 'user:'******'diamond', consumeCoin)
            # TyContext.BiReport.diamond_update(appId, userId, consumeCoin, leftCoin, 'sdk.pay.v3.consume.cancel')
            mo.setError(4, '购买太频繁,请稍后购买')
            mo.setResult('leftCoin', leftCoin)
            mo.setResult('needCoin', consumeCoin)
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.INTERNAL_ERR,
                          userId,
                          appId,
                          clientId,
                          info='deduct diamond err')
            return True

        # 记录全局消费记录
        consumeinfo = json.dumps(consumeinfo)
        TyContext.ftlog.info('__consume_user_coin__ consumeinfo', paykey,
                             consumeinfo)
        TyContext.RedisPayData.execute('LPUSH', paykey, consumeinfo)

        mo.setResult('time', timestamp)
        mo.setResult('userId', userId)
        mo.setResult('orderId', prodOrderId)
        mo.setResult('consumeCoin', consumeCoin)
        mo.setResult('appId', appId)
        mo.setResult('appInfo', appInfo)
        mo.setResult('clientId', clientId)
        mo.setResult('prodPrice', prodPrice)
        mo.setResult('prodId', prodId)
        mo.setResult('prodCount', prodCount)
        mo.setResult('leftCoin', leftCoin)

        # 投递货物
        if deliveryUrl == 'http://none':
            response = 'success'
            httpurl = deliveryUrl
        else:
            retry_sleeps = [3, 10, 60, 600, 3600, 36000]
            for wait in retry_sleeps:
                try:
                    response, httpurl = TyContext.WebPage.webget(
                        deliveryUrl, params, appKey)
                    break
                except Exception, e:
                    TyContext.ftlog.error(
                        '__consume_user_coin__ failed deliver product to',
                        deliveryUrl, 'error:', e)
                    tasklet_sleep(wait)

        if 'success' == response:
            TyContext.ftlog.info('__consume_user_coin__ transaction ok',
                                 paykey, consumeinfo)
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.DELIVER_OK,
                          userId,
                          appId,
                          clientId,
                          prodOrderId=prodOrderId,
                          shortId=chargeInfo.get('shortDiamondOrderId', 'na'),
                          diamondid=chargeInfo.get('diamondId', 'na'),
                          charge_price=chargeInfo.get('chargeTotal', 'na'),
                          paytype=chargeInfo.get('chargeType', 'na'),
                          prodid=prodId,
                          prod_price=prodPrice)
        else:
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.DELIVER_FAIL,
                          userId,
                          appId,
                          clientId,
                          info='prod delivery err',
                          prodOrderId=prodOrderId,
                          shortId=chargeInfo.get('shortDiamondOrderId', 'na'),
                          diamondid=chargeInfo.get('diamondId', 'na'),
                          charge_price=chargeInfo.get('chargeTotal', 'na'),
                          prodid=prodId,
                          prod_price=prodPrice)
            mo.setError(5, '钻石扣款成功,商品投递失败')
            TyContext.ftlog.error('__consume_user_coin__ transaction ERROR',
                                  response, paykey, consumeinfo)
            # 回滚扣除三方钻石
            ok = cls.__consume_ext_diamond__(params, True)
            if not ok:
                TyContext.ftlog.error(
                    '__consume_user_coin__ transaction ERROR: cancel_consume_ext_diamond failed'
                )
        # 结束事务
        return True
Example #11
0
    def __consume_user_coin__(cls,
                              appId,
                              appInfo,
                              clientId,
                              userId,
                              consumeCoin,
                              prodId,
                              prodPrice,
                              prodCount,
                              prodName,
                              prodOrderId,
                              mo,
                              chargeInfo=None):
        # 获取服务配置
        deliveryUrl = None
        control = TyContext.ServerControl.findServerControl(appId, clientId)
        if appId < 10000:
            # 途游自己的游戏,固定的投递地址
            # control = TyContext.ServerControl.findServerControl(appId, clientId)
            # if control :
            deliveryUrl = control['http'] + '/v2/game/consume/delivery'
        else:
            deliveryUrl = TyContext.Configure.get_game_item_str(
                appId, 'deliveryUrl', '')
        appKey = TyContext.Configure.get_game_item_str(appId, 'appKey', '')
        if not appKey:
            gameConfig = TyContext.Configure.get_game_item_json(appId, 'game')
            appKey = gameConfig.get('appKey', '')
            deliveryUrl = gameConfig.get('deliveryUrl', '')
            isErrorNotify = gameConfig.get('isErrorNotify', '')
        TyContext.ftlog.debug('__consume_user_coin__ deliveryUrl=',
                              deliveryUrl, 'appKey=', appKey)
        if not deliveryUrl or not appKey or len(deliveryUrl) == 0 or len(
                appKey) == 0:
            TyContext.ftlog.error(
                '__consume_user_coin__ deliveryUrl or appKey error')
            mo.setError(3, '系统服务配置错误,缺少回调地址')
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.INTERNAL_ERR,
                          userId,
                          appId,
                          clientId,
                          info='consume delivery cfg err')
            return True

        # 取得唯一事物ID
        consumeId = TyContext.ServerControl.makeConsumeOrderIdV3(
            userId, appId, clientId)

        ct = datetime.datetime.now()
        timestamp = ct.strftime('%Y-%m-%d %H:%M:%S')
        paykey = ct.strftime('sdk.consume:%Y%m%d')
        consumeinfo = {
            'time': timestamp,
            'uid': userId,
            'appId': appId,
            'name': prodName,
            'fee': consumeCoin,
            'clientId': clientId,
            'appOrderId': prodOrderId,
            'prodId': prodId,
            'consumeId': consumeId
        }
        params = {
            'userId': userId,
            'orderId': prodOrderId,
            'consumeCoin': consumeCoin,
            'appId': appId,
            'appInfo': appInfo,
            'clientId': clientId,
            'prodPrice': prodPrice,
            'prodId': prodId,
            'prodCount': prodCount,
            'consumeId': consumeId,
            'apiver': '2'
        }
        if chargeInfo:
            if 'chargeType' in chargeInfo and appId < 10000:
                params['chargeType'] = chargeInfo['chargeType']
            params['platformOrder'] = chargeInfo['platformOrderId']
            params['chargedRmbs'] = chargeInfo['chargedRmbs']
            params['chargedDiamonds'] = chargeInfo['chargedDiamonds']
            if 'cpExtInfo' in chargeInfo and chargeInfo['cpExtInfo']:
                params['cpExtInfo'] = chargeInfo['cpExtInfo']
        # modified by zhangshibo at 2015-09-09,标识是优易付会员订阅
        if mo.getParam('is_monthly'):
            params['is_monthly'] = '1'
        # end modify

        extra_delivery = cls.__get_extra_delivery(chargeInfo)
        if extra_delivery is not None:
            params['extra_deliver'] = extra_delivery

        # 首先扣除三方钻石
        ok = cls.__consume_ext_diamond__(params, False)
        if not ok:
            mo.setError(8, '三方钻石扣款失败')
            TyContext.ftlog.error(
                '__consume_user_coin__ consume ext diamond '
                'ERROR: paykey', paykey, 'consumeinfo', consumeinfo)
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.INTERNAL_ERR,
                          userId,
                          appId,
                          clientId,
                          info='third party consume diamond err')
            return True

        # 扣除钻石
        # leftCoin = TyContext.RedisUser.execute(userId, 'HINCRBY', 'user:'******'diamond', -consumeCoin)
        delta, leftCoin = TyContext.UserProps.incr_diamond(
            int(userId), int(appId), -consumeCoin,
            TyContext.ChipNotEnoughOpMode.NOOP, TyContext.BIEventId.UNKNOWN)
        TyContext.BiReport.diamond_update(appId, userId, -consumeCoin,
                                          leftCoin, 'sdk.pay.v3.consume')
        if delta != -consumeCoin:
            TyContext.ftlog.error('__consume_user_coin__ diamond update error')
            # leftCoin = TyContext.RedisUser.execute(userId, 'HINCRBY', 'user:'******'diamond', consumeCoin)
            # TyContext.BiReport.diamond_update(appId, userId, consumeCoin, leftCoin, 'sdk.pay.v3.consume.cancel')
            mo.setError(4, '购买太频繁,请稍后购买')
            mo.setResult('leftCoin', leftCoin)
            mo.setResult('needCoin', consumeCoin)
            if chargeInfo:
                Order.log(chargeInfo['platformOrderId'],
                          Order.INTERNAL_ERR,
                          userId,
                          appId,
                          clientId,
                          info='deduct diamond err')
            return True

        # 记录全局消费记录
        consumeinfo = json.dumps(consumeinfo)
        TyContext.ftlog.info('__consume_user_coin__ consumeinfo', paykey,
                             consumeinfo)
        TyContext.RedisPayData.execute('LPUSH', paykey, consumeinfo)

        mo.setResult('time', timestamp)
        mo.setResult('userId', userId)
        mo.setResult('orderId', prodOrderId)
        mo.setResult('consumeCoin', consumeCoin)
        mo.setResult('appId', appId)
        mo.setResult('appInfo', appInfo)
        mo.setResult('clientId', clientId)
        mo.setResult('prodPrice', prodPrice)
        mo.setResult('prodId', prodId)
        mo.setResult('prodCount', prodCount)
        mo.setResult('leftCoin', leftCoin)

        # 投递货物
        if deliveryUrl == 'http://none':
            response = 'success'
            httpurl = deliveryUrl
        else:
            retry_sleeps = [3, 10, 60, 600, 3600, 36000]
            for wait in retry_sleeps:
                try:
                    response, httpurl = TyContext.WebPage.webget(
                        deliveryUrl, params, appKey)
                    break
                except Exception, e:
                    TyContext.ftlog.error(
                        '__consume_user_coin__ failed deliver product to',
                        deliveryUrl, 'error:', e)
                    tasklet_sleep(wait)
Example #12
0
    def _charge_begin_w_paytype(cls, appId, appInfo, clientId, userId, authorCode,
                                diamondId, diamondPrice, diamondCount, diamondName,
                                diamondsPerUnit, mo, consumeinfo, clientPayType, payInfo, **kwds):
        mo.setCmd('charge')
        # 取得钻石的购买信息
        if diamondCount <= 0:
            diamondCount = 1
        else:
            diamondCount = int(diamondCount)
        if diamondCount != 1:
            TyContext.ftlog.error(cls.__name__, 'charge diamond count error')
            mo.setError(2, '钻石信息错误,请重新充值')
            return mo

        diamondPrice = int(diamondPrice)
        chargeTotal = int(diamondPrice * diamondCount)

        # ios支付限制
        TyContext.ftlog.info('clientPayType', clientPayType, 'userId', userId)
        if clientPayType == 'tuyooios':
            from tysdk.entity.paythird.payios import TuYouPayIos
            check_ret, check_msg = TuYouPayIos._check_user_ios_pay(userId)
            TyContext.ftlog.info('check_ret', check_ret, 'check_msg', check_msg)
            if check_ret:
                mo.setError(2, check_msg)
                return mo
            # 判断5分钟内的充值
            if TuYouPayIos._check_ios_pay_5mins(userId) and TuYouPayIos._check_user_gametime(userId):
                mo.setError(2, '单日充值达到上限')
                return mo

        # 建立充值事物
        diamondOrderId = TyContext.ServerControl.makeChargeOrderIdV3(userId, appId, clientId)

        # 取得当前的客户端可使用的支付类型
        if consumeinfo and consumeinfo['mustcharge']:
            buttonId = consumeinfo['prodId']
            buttonName = consumeinfo['prodName']
        else:
            buttonId = diamondId
            buttonName = diamondName
        if clientPayType == 'tuyooios':
            chargeType = 'tuyooios'
            phoneType = ''
            zipcode = '1'
        else:
            phoneType = TyContext.UserSession.get_session_phone_type(userId)
            phoneType = TyContext.UserSession.get_phone_type_name(phoneType)
            zipcode, _ = TyContext.UserSession.get_session_zipcode(userId)
            zipcode = str(zipcode)
            chargeType = TyContext.PayType.get_paytype_by_user(appId, userId, buttonId, clientId)
            chargeType = cls._ydmm_ydjd_paytype_switch(userId, clientId, chargeType)
            limited, new_chargetype = cls._is_sms_pay_speed_limited(userId, chargeType, clientId)
            if limited:
                chargeType = new_chargetype

        timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        chargeinfo = {'uid': userId,
                      'appId': appId,
                      'appInfo': appInfo,
                      'clientId': clientId,
                      'diamondId': diamondId,
                      'diamondPrice': diamondPrice,
                      'diamondCount': diamondCount,
                      'diamondsPerUnit': diamondsPerUnit,
                      'diamondName': diamondName,
                      'chargeTotal': chargeTotal,
                      'chargeType': chargeType,
                      'platformOrderId': diamondOrderId,
                      'phoneType': phoneType,
                      'zipcode': zipcode,
                      'payInfo': payInfo,
                      'buttonId': buttonId,
                      'buttonName': buttonName,
                      'packageName': kwds.get('packageName', ''),
                      'channelName': kwds.get('channelName', ''),
                      }
        if consumeinfo:
            chargeinfo['prodId'] = consumeinfo['prodId']

        # 当前支付类型的特殊数据初始化
        cls._charge_data(chargeinfo)

        clientip = TyContext.UserSession.get_session_client_ip(userId)
        from tysdk.entity.pay_common.fengkong import Fengkong
        if Fengkong.is_ip_limited(clientip, clientId, chargeinfo['chargeType']):
            mo.setError(1, '对不起,您已超出支付限制,请联系客服4008-098-000')
            return

        TyContext.ftlog.info('_charge_begin_w_paytype transaction', diamondOrderId,
                             'chargeinfo', chargeinfo, 'consumeinfo', consumeinfo)
        datas = ['state', PayConst.CHARGE_STATE_BEGIN,
                 'charge', json.dumps(chargeinfo),
                 'createTime', timestamp]
        if consumeinfo:
            datas.append('consume')
            datas.append(json.dumps(consumeinfo))

        TyContext.RedisPayData.execute('HMSET', 'sdk.charge:' + diamondOrderId, *datas)
        # 返回数据
        mo.setResult('userId', userId)
        mo.setResult('appId', appId)
        mo.setResult('appInfo', appInfo)
        mo.setResult('clientId', clientId)
        mo.setResult('diamondId', diamondId)
        mo.setResult('diamondPrice', diamondPrice)
        mo.setResult('diamondCount', diamondCount)
        mo.setResult('diamondsPerUnit', diamondsPerUnit)
        mo.setResult('diamondName', diamondName)
        mo.setResult('chargeTotal', chargeTotal)
        mo.setResult('chargeType', chargeinfo['chargeType'])
        mo.setResult('chargeData', chargeinfo.get('chargeData', {}))
        shortOrderId = chargeinfo.get('shortDiamondOrderId')
        mo.setResult('platformOrderId', shortOrderId if shortOrderId else diamondOrderId)

        try:
            third_prodid = chargeinfo['chargeData']['paydata']['msgOrderCode']
        except:
            third_prodid = 'na'

        pay_appid = Order.get_pay_appid(chargeType, payInfo, clientId)
        Order.log(diamondOrderId, Order.CREATE, userId, appId, clientId,
                  diamondid=diamondId,
                  prodid=consumeinfo['prodId'] if consumeinfo else 'na',
                  prod_price=consumeinfo['prodPrice'] if consumeinfo else 'na',
                  paytype=chargeinfo['chargeType'],
                  charge_price=chargeTotal,
                  third_prodid=third_prodid, pay_appid=pay_appid,
                  shortId=shortOrderId if shortOrderId else 'na')
Example #13
0
    def _charge_begin_w_categories(cls, appId, appInfo, clientId, userId,
                                   authorCode, diamondId, diamondPrice, diamondCount, diamondName,
                                   diamondsPerUnit, mo, consumeinfo, payInfo, **kwds):
        mo.setCmd('charge')
        # 取得钻石的购买信息
        if diamondCount <= 0:
            diamondCount = 1
        else:
            diamondCount = int(diamondCount)
        if diamondCount != 1:
            TyContext.ftlog.error(cls.__name__, 'charge diamond count error')
            mo.setError(2, '钻石信息错误,请重新充值')
            return

        chargeTotal = diamondPrice * diamondCount

        # 建立充值事物
        diamondOrderId = TyContext.ServerControl.makeChargeOrderIdV3(userId, appId, clientId)
        shortDiamondOrderId = diamondOrderId

        product = None
        if consumeinfo:
            prodId = consumeinfo['prodId']
            product = TuyouPayProductList.product(appId, clientId, prodId)
        if product:
            buttonId = prodId
            buttonName = consumeinfo['prodName']
        else:
            product = TuyouPayProductList.product(appId, clientId, diamondId)
            buttonId = diamondId
            buttonName = diamondName
        TyContext.ftlog.debug(cls.__name__, 'product', product)
        if product is None or 'charge_categories' not in product:
            TyContext.ftlog.error(cls.__name__, 'product not exist or '
                                                'charge_categories absent in product', product)
            mo.setError(2, '商品配置信息错误,请稍后重试')
            return

        chargeCategories = copy.deepcopy(product['charge_categories'])
        phoneType = TyContext.UserSession.get_session_phone_type(userId)
        is_shortcut = cls._process_shortcut_category(userId, clientId, chargeCategories)
        TyContext.ftlog.debug(cls.__name__, 'after _process_shortcut_category is_shortcut',
                              is_shortcut, 'chargeCategories', chargeCategories)
        chargeinfo = {'uid': userId,
                      'appId': appId,
                      'appInfo': appInfo,
                      'clientId': clientId,
                      'diamondId': diamondId,
                      'diamondPrice': diamondPrice,
                      'diamondCount': diamondCount,
                      'diamondsPerUnit': diamondsPerUnit,
                      'diamondName': diamondName,
                      'chargeTotal': chargeTotal,
                      'platformOrderId': diamondOrderId,
                      'phoneType': phoneType,
                      'payInfo': payInfo,
                      'buttonId': buttonId,
                      'buttonName': buttonName,
                      'packageName': kwds.get('packageName', ''),
                      'channelName': kwds.get('channelName', ''),
                      }
        if consumeinfo:
            chargeinfo['prodId'] = prodId

        has_duandai, needShort = cls._process_duandai_category(
            appId, userId, clientId, phoneType, buttonId, chargeCategories, chargeinfo)
        if has_duandai:
            if needShort:
                shortDiamondOrderId = ShortOrderIdMap.get_short_order_id(diamondOrderId)
        elif is_shortcut:
            chargeCategories = copy.deepcopy(product['charge_categories'])
            cls._remove_duandai_category(chargeCategories)
            is_shortcut = 0
        TyContext.ftlog.debug(cls.__name__, 'after _process_duandai_category is_shortcut',
                              is_shortcut, 'chargeCategories', chargeCategories)

        timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        if len(shortDiamondOrderId) < len(diamondOrderId):
            chargeinfo['shortDiamondOrderId'] = shortDiamondOrderId
        if is_shortcut:
            chargeinfo['chargeType'] = chargeCategories[0]['paytype']
            chargeinfo['chargeData'] = chargeCategories[0]['payData']
        else:
            chargeinfo['chargeCategories'] = chargeCategories
        chargeinfo_dump = json.dumps(chargeinfo)

        TyContext.ftlog.info('_charge_begin_w_categories transaction',
                             chargeinfo_dump, consumeinfo)
        datas = ['state', PayConst.CHARGE_STATE_BEGIN,
                 'charge', chargeinfo_dump,
                 'createTime', timestamp]
        if consumeinfo:
            datas.append('consume')
            datas.append(json.dumps(consumeinfo))

        TyContext.RedisPayData.execute('HMSET', 'sdk.charge:' + diamondOrderId, *datas)
        # 返回数据
        mo.setResult('userId', userId)
        mo.setResult('appId', appId)
        mo.setResult('appInfo', appInfo)
        mo.setResult('clientId', clientId)
        mo.setResult('diamondId', diamondId)
        mo.setResult('diamondPrice', diamondPrice)
        mo.setResult('diamondCount', diamondCount)
        mo.setResult('diamondsPerUnit', diamondsPerUnit)
        mo.setResult('diamondName', diamondName)
        # 客户端SDK根据消息里是带chargeType还是chargeCategories来区分是老版支付
        # 界面还是新版支付界面
        if is_shortcut:
            mo.setResult('chargeType', chargeinfo['chargeType'])
            mo.setResult('chargeData', chargeinfo['chargeData'])
        else:
            mo.setResult('chargeCategories', chargeCategories)
        try:
            third_prodid = chargeinfo['chargeData']['paydata']['msgOrderCode']
        except:
            third_prodid = 'na'

        pay_appid = Order.get_pay_appid(chargeinfo.get('chargeType', 'na'), payInfo, clientId)
        shortId = shortDiamondOrderId if len(shortDiamondOrderId) < len(diamondOrderId) else 'na'
        Order.log(diamondOrderId, Order.CREATE, userId, appId, clientId,
                  diamondid=diamondId, prodid=prodId if consumeinfo else 'na',
                  prod_price=consumeinfo['prodPrice'] if consumeinfo else 'na',
                  paytype=chargeinfo.get('chargeType', 'na'),
                  charge_price=chargeTotal, shortId=shortId,
                  third_prodid=third_prodid, pay_appid=pay_appid)
        mo.setResult('platformOrderId', shortDiamondOrderId)
Example #14
0
    def _charge_begin_w_new_categories(cls, appId, appInfo, clientId, userId,
                                       authorCode, diamondId, diamondPrice, diamondCount, diamondName,
                                       diamondsPerUnit, mo, consumeinfo, clientPayType, payInfo, **kwds):
        mo.setCmd('charge')
        # 取得钻石的购买信息
        if diamondCount <= 0:
            diamondCount = 1
        else:
            diamondCount = int(diamondCount)
        if diamondCount != 1:
            TyContext.ftlog.error(cls.__name__, 'charge diamond count error')
            mo.setError(2, '钻石信息错误,请重新充值')
            return

        chargeTotal = diamondPrice * diamondCount

        # 建立充值事物
        diamondOrderId = TyContext.ServerControl.makeChargeOrderIdV3(userId, appId, clientId)

        if consumeinfo and consumeinfo['mustcharge']:
            buttonId = consumeinfo['prodId']
            buttonName = consumeinfo['prodName']
        else:
            buttonId = diamondId
            buttonName = diamondName

        payconfig = TyContext.Configure.get_global_item_json('store_payment', clientid=clientId)
        try:
            cats = payconfig['payment']['default_category']
            for cat in cats:
                if cat['id'] == buttonId:
                    break
            else:
                TyContext.ftlog.error(cls.__name__, 'buttonId', buttonId,
                                      'missing in store_payment', payconfig,
                                      'for clientid', clientId)
                mo.setError(2, '商品(%s)未配置,请检查store_payment配置' % buttonId)
                return
        except Exception as e:
            TyContext.ftlog.error(cls.__name__, 'exception', e,
                                  'store_payment', payconfig,
                                  'not configed for clientid', clientId,
                                  'or pay config error')
            mo.setError(2, '商品配置信息错误,请稍后重试')
            return

        TyContext.ftlog.debug(cls.__name__, 'buttonId', buttonId, 'default_category config', cat)

        timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        chargeinfo = {'uid': userId,
                      'appId': appId,
                      'appInfo': appInfo,
                      'clientId': clientId,
                      'diamondId': diamondId,
                      'diamondPrice': diamondPrice,
                      'diamondCount': diamondCount,
                      'diamondsPerUnit': diamondsPerUnit,
                      'diamondName': diamondName,
                      'chargeTotal': chargeTotal,
                      'platformOrderId': diamondOrderId,
                      'phoneType': TyContext.UserSession.get_session_phone_type(userId),
                      'payInfo': payInfo,
                      'buttonId': buttonId,
                      'buttonName': buttonName,
                      'packageName': kwds.get('packageName', ''),
                      'channelName': kwds.get('channelName', ''),
                      }
        if consumeinfo:
            chargeinfo['prodId'] = consumeinfo['prodId']
        # list more pay type if clientPayType is more_categories
        if clientPayType == 'more_categories':
            category = payconfig['payment']['more_categories'].lower()
        elif cat['category'] == 'CAT_THIRDPAY' and cat['paytype'] == 'fake':
            ios_control = TyContext.Configure.get_global_item_json('ios_weinxin_pay_control', {})
            strategy_name = cat.get('strategy', 'default_strategy')
            strategy = TuYooIOSPayWeixinStrategy(strategy_name)
            test_flag = strategy(appId=appId, userId=userId)
            if not test_flag:
                category = 'tuyooios'
            elif clientPayType:
                category = clientPayType
            else:
                category = cat['paytype']
            strategy = TuYooPayIOSAppStoreStrategy()
            if strategy(appId=appId, userId=userId, diamondId=diamondId):
                category = 'wxpay'
        elif cat['category'] == 'CAT_DUANDAI':
            category = 'cat_duandai'
        elif cat['category'] == 'CAT_THIRDPAY':
            category = cat['paytype']
        else:
            category = payconfig['payment']['more_categories'].lower()
        lastChargeCategory = TyContext.RedisUser.execute(
            userId, 'HGET', 'user:'******'lastChargeCategory')
        if not lastChargeCategory and cat['category'] != 'CAT_MORE':
            lastChargeCategory = cat['category']

        chargeinfo['chargeType'] = category
        # ios充值限制
        if category == 'tuyooios' and int(appId) < 10000:
            from tysdk.entity.paythird.payios import TuYouPayIos
            check_ret, check_msg = TuYouPayIos._check_user_ios_pay(userId)
            TyContext.ftlog.info('check_ret', check_ret, 'check_msg', check_msg)
            if check_ret:
                mo.setError(2, check_msg)
                return mo
            # 判断5分钟内的充值
            if TuYouPayIos._check_ios_pay_5mins(userId) and TuYouPayIos._check_user_gametime(userId):
                mo.setError(2, '单日充值达到上限')
                return mo

        try:
            cls._charge_data_new(chargeinfo)
        except TyContext.FreetimeException as e:
            TyContext.ftlog.error('_charge_begin_w_new_categories exception', e)
            mo.setError(e.errorCode, e.message)
            return

        TyContext.ftlog.info('_charge_begin_w_new_categories transaction',
                             chargeinfo, consumeinfo)

        chargeinfo_dump = json.dumps(chargeinfo)
        datas = ['state', PayConst.CHARGE_STATE_BEGIN,
                 'charge', chargeinfo_dump,
                 'createTime', timestamp]
        if consumeinfo:
            datas.append('consume')
            datas.append(json.dumps(consumeinfo))

        TyContext.RedisPayData.execute('HMSET', 'sdk.charge:' + diamondOrderId, *datas)
        # 返回数据
        mo.setResult('userId', userId)
        mo.setResult('appId', appId)
        mo.setResult('appInfo', appInfo)
        mo.setResult('clientId', clientId)
        # 兼容googleplay
        '''
        try:
            products_low_all = TyContext.Configure.get_global_item_json('products_low_all', ['googleiab'])
            if chargeinfo['chargeType'] == 'googleiab' or chargeinfo['chargeType'] in products_low_all:
                mo.setResult('diamondId', diamondId.lower())
            else:
                mo.setResult('diamondId', diamondId)
        except:
            pass
        TyContext.ftlog.info(products_low_all,chargeinfo['chargeType'], diamondId)
        '''
        mo.setResult('diamondId', diamondId)
        mo.setResult('diamondPrice', diamondPrice)
        mo.setResult('diamondCount', diamondCount)
        mo.setResult('diamondsPerUnit', diamondsPerUnit)
        mo.setResult('diamondName', diamondName)
        # 客户端SDK根据消息里是带chargeType还是chargeCategories来区分是老版支付
        # 界面还是新版支付界面
        try:
            mo.setResult('chargeData', chargeinfo['chargeData'])
            mo.setResult('chargeType', chargeinfo['chargeType'])
        except:
            categories = chargeinfo.get('chargeCategories', [])
            isenable = TyContext.Configure.get_global_item_int('last.charge.on', 1)
            if isenable:
                # temp workaround for client sdk bug: CAT_PHONECHARGE_CARD
                if lastChargeCategory and lastChargeCategory != 'CAT_PHONECHARGE_CARD':
                    for category in categories:
                        if lastChargeCategory == category['category']:
                            mo.setResult('lastChargeCategory', lastChargeCategory)
                            break
                else:
                    mo.setResult('lastChargeCategory', '')
            else:
                mo.setResult('lastChargeCategory', '')
            mo.setResult('chargeCategories', categories)
        pay_appid = Order.get_pay_appid(chargeinfo.get('chargeType', 'na'),
                                        payInfo, clientId)
        shortId = chargeinfo.get('shortDiamondOrderId', 'na')
        Order.log(diamondOrderId, Order.CREATE, userId, appId, clientId,
                  diamondid=diamondId, prodid=consumeinfo['prodId'] if consumeinfo else 'na',
                  prod_price=consumeinfo['prodPrice'] if consumeinfo else 'na',
                  paytype=chargeinfo.get('chargeType', 'na'),
                  charge_price=chargeTotal, shortId=shortId, pay_appid=pay_appid)
        mo.setResult('platformOrderId', chargeinfo.get('shortDiamondOrderId',
                                                       diamondOrderId))

        payConfig = TyContext.Configure.get_global_item_json('store_payment', clientid=clientId)
        failreturnconfig = TyContext.Configure.get_global_item_json('payfail_returnconfig', {})
        if payConfig and 'payment' in payConfig and 'more_categories' in payConfig['payment']:
            if payConfig['payment']['more_categories'] in failreturnconfig:
                failreturnconfig = TyContext.Configure.get_global_item_json('payfail_returnconfig', {})
                payMoreType = failreturnconfig[payConfig['payment']['more_categories']]
                paytemplateconfig = TyContext.Configure.get_global_item_json(payMoreType)
                mo.setResult('morePayType', paytemplateconfig)