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
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'))
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'])
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
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
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
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)
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
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
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
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)
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')
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)
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)