def init_merchant_user(merchant_id, merchant_name, password): from app.main import flask_app from app.libs.string_kit import RandomString if not password: password = RandomString.gen_random_str(10, (CharOp.N, CharOp.L, CharOp.U)) with flask_app.app_context(): from scripts.init_data import InitData InitData.merchant_name = merchant_name InitData.merchant_id = merchant_id InitData.password = RandomString.gen_md5_string( password.encode('utf8')) merchant = InitData.get_merchant_user() if not merchant: InitData.init_merchant_user() merchant = InitData.get_merchant_user() print("Merchant generated, merchant: %s, password: %s" % (merchant_name, password)) else: merchant.reset_password(mid=merchant_id, password=InitData.password) print("password changed, merchant: %s, password: %s" % (merchant_name, password)) rst = merchant.verify_login(merchant_name, InitData.password) if rst: return merchant_name, password return None, None
def init_admin_user(account, password): from app.main import flask_app from app.libs.string_kit import RandomString from scripts.init_data import InitData if not password: password = RandomString.gen_random_str(10, (CharOp.N, CharOp.L, CharOp.U)) with flask_app.app_context(): InitData.admin_user_account = account InitData.password = RandomString.gen_md5_string( password.encode('utf8')) admin = InitData.get_admin_user() if not admin: InitData.init_admin_user() admin = InitData.get_admin_user() print("account generated, admin: %s, password: %s" % (account, password)) else: admin.reset_password(account=account, login_pwd=InitData.password) print("password changed, admin: %s, password: %s" % (account, password)) rst = admin.verify_login(account, InitData.password) print('verify login %s' % rst) if rst: return account, password return None, None
def gen_unique_ref_id(cls): """ 生成唯一票据ID :return: """ return hashlib.md5( RandomString.gen_random_str( length=128).encode('utf8')).hexdigest()
def generate_sign(self, params: dict): """ 生成签名 :param params: :return: """ raw_str = self.join_sign_str(params) raw_str += '&key=' + self.get_secret_key() sign = RandomString.gen_md5_string(raw_str.encode('utf8')).upper() return sign
def generate_sign(request_fields_str, third_config): """ 生成签名 :param merchant_id: 通道分配给我们的商户ID :param channel_tx_id: 通道交易ID(由通道侧生成) :param tx_amount: 实际支付金额 :return: """ sign_str = request_fields_str + "&key=" sign_str += third_config['secret_key'] return RandomString.gen_md5_string(sign_str.encode("utf8")).upper()
def generate_sign(cls, merchant_id, channel_tx_id, tx_amount): """ 生成签名 :param merchant_id: 通道分配给我们的商户ID :param channel_tx_id: 通道交易ID(由通道侧生成) :param tx_amount: 实际支付金额 :return: """ sign_str = "".join([merchant_id, channel_tx_id, tx_amount]) sign_str += cls.third_config['secret_key'] return RandomString.gen_md5_string(sign_str.encode("gb2312")).lower()
def generate_sign(cls, request_fields_str): """ 生成签名 :param merchant_id: 通道分配给我们的商户ID :param channel_tx_id: 通道交易ID(由通道侧生成) :param tx_amount: 实际支付金额 :return: """ sign_str = request_fields_str + "&key=" sign_str += cls.third_config['secret_key'] current_app.logger.info('sign data: %s', sign_str) return RandomString.gen_md5_string(sign_str.encode("utf8")).upper()
def generate_sign(self, params: dict): """ 生成签名 :param params: :return: """ raw_str = self.join_sign_str(params) raw_str += '&secret_key=' + self.get_secret_key() print('raw_str:', raw_str) sign = RandomString.gen_md5_string(raw_str.encode('utf8')) print('sign:', sign) return sign
def generate_sign(self, params: dict): """ 生成签名 :param params: :return: """ raw_str = self.join_sign_str(params) raw_str += '&key=' + self.get_secret_key() # current_app.logger.info('raw_str: %s', raw_str) # current_app.logger.info('raw_str utf8: %s', raw_str.encode('utf8')) sign = RandomString.gen_md5_string(raw_str.encode('utf8')).upper() return sign
def test_random_str(self): for l in [2, 32, 64, 128]: for op in [CharOp.U, CharOp.L, CharOp.N, CharOp.S]: s = RandomString.gen_random_str(l, op) self.print(op, l, s) assert len(s) == l if op == CharOp.U: assert s.isupper() if op == CharOp.L: assert s.islower() if op == CharOp.N: assert s.isnumeric() if op == CharOp.S: assert set(RandomString.specials).issuperset( set([c for c in s])) op = [CharOp.U, CharOp.L, CharOp.N, CharOp.S] s = RandomString.gen_random_str(l, op) self.print(op, l, s) assert len(s) == l assert s.isascii() op = [ CharOp.U, CharOp.L, CharOp.N, ] s = RandomString.gen_random_str(l, op) self.print(op, l, s) assert len(s) == l assert s.isalnum() op = [ CharOp.U, CharOp.L, ] s = RandomString.gen_random_str(l, op) self.print(op, l, s) assert len(s) == l assert s.isalpha()
def generate_sign(self, corderid, money): """ merchant_id 商户编号 是 商户号 corderid 订单号 是 商户订单号 money 订单金额 是 订单金额 status 交易状态 否 1 为已成功,2,为作废(金额退回)。 sign 签名 否 string parastring = merchant_id + corderid + money + key; sign=MD5(parastring); """ params_string = ''.join([ self.third_config['mch_id'], corderid, str(money), self.third_config['secret_key'] ]) return RandomString.gen_md5_string( params_string.encode("gb2312")).upper()
def construct_request(self, order, params: dict): """ 填写请求参数 :param order: :param params: :return: """ request_data = dict( appId=self.channel_conf.app_id, nonce_str=RandomString.gen_random_str(16), pay_type=self.channel_conf.third_paytype, callback_url=self.channel_conf.callback_url, money_amount=str(order.amount), # 可以通过remark来传自己的订单号,回调的时候传回 remark=order.sys_tx_id, ) sign = self.generate_sign(request_data) request_data['sign'] = sign return request_data
def test_md5_string(self): s = RandomString.random_md5_string() self.assertEqual(len(s), 32) i = StringUtils.string_to_int16(s) self.assertIsInstance(i, int)
def __test_api_withdraw(self): """ 后台准备数据: 充值通道数据 代付通道数据 商户费率配置数据 钱包端: 1. 创建充值订单 2. 充值 3. 用户设置支付密码 4. 用户绑定银行卡 5. 获取充值配置信息(用户余额,充值最低最高限制) 发起提现请求: :return: """ merchant = MerchantEnum.from_name("TEST") info = dict(merchant=merchant, account="+8618988888888", auth_code="8888", password="******", trade_pwd="b943a52cc24dcdd12bf2ba3afda92351", ac_type=AccountTypeEnum.MOBILE) user = User.register_account(info['merchant'], info['account'], info['ac_type'], info['password']) self.path = '/auth/account/login' login_data = dict(number=info['account'], password=info['password']) response = self.do_request(login_data) self.assertEqual(ResponseSuccessLogin.code, response.status_code) self.assertEqual(ResponseSuccessLogin.error_code, response.json['error_code']) self.token = response.json['data']['token'] self.path = "/withdraw/banks/list" # 1. 向数据库添加代付通道信息 withdraw_item = dict(fee="2.5", fee_type=PaymentFeeTypeEnum(1), limit_per_min="200", limit_per_max="5000", limit_day_max="50000", trade_begin_hour="00", trade_begin_minute="00", trade_end_hour="23", trade_end_minute="59", maintain_begin=DateTimeKit.str_to_datetime( "2019-09-27 00:00:00", DateTimeFormatEnum.SECONDS_FORMAT), maintain_end=DateTimeKit.str_to_datetime( "2019-10-20 23:59:00", DateTimeFormatEnum.SECONDS_FORMAT), state=ChannelStateEnum(10), banks=[ PaymentBankEnum(1), PaymentBankEnum(2), PaymentBankEnum(4), PaymentBankEnum(3), PaymentBankEnum(15) ]) ProxyChannelConfig.update_channel(ChannelConfigEnum.CHANNEL_1001, **withdraw_item) # 2. 向数据库插入 商户费率配置信息 # 充值费率设置 merchant_fee_dict = [] merchant_fee_dict.append( dict( merchant=MerchantEnum.from_name('TEST'), payment_way=PayTypeEnum.DEPOSIT, value="3.5", fee_type=PaymentFeeTypeEnum.PERCENT_PER_ORDER, payment_method=PayMethodEnum.ZHIFUBAO_SAOMA, )) # 提现费率 merchant_fee_dict.append( dict( merchant=MerchantEnum.from_name('TEST'), payment_way=PayTypeEnum.WITHDRAW, value="3.5", fee_type=PaymentFeeTypeEnum.PERCENT_PER_ORDER, )) rst, error = MerchantFeeConfig.update_fee_config( merchant, merchant_fee_dict) self.assertEqual(True, rst) # 3. 给用户和商户充值 uid = user.uid ref_id = hashlib.md5('lakjdflasjfadl;kfja'.encode('utf8')).hexdigest() data = dict( uid=uid, merchant=merchant, ref_id=ref_id, source=OrderSourceEnum.TESTING, order_type=PayTypeEnum.DEPOSIT, bl_type=BalanceTypeEnum.AVAILABLE, ad_type=BalanceAdjustTypeEnum.PLUS, tx_id=OrderUtils.gen_normal_tx_id(uid), value=Decimal("10000.00"), comment="xxx", ) rst, msg = UserBalanceEvent.update_user_balance(**data) self.assertEqual(0, rst) balance = UserBalance.query_balance(data['uid'], data['merchant']).first() # 添加商户余额 data = dict( merchant=MerchantEnum.TEST, source=OrderSourceEnum.TESTING, order_type=PayTypeEnum.DEPOSIT, bl_type=BalanceTypeEnum.AVAILABLE, ad_type=BalanceAdjustTypeEnum.PLUS, tx_id=OrderUtils.gen_normal_tx_id(100), value=Decimal("10000.00"), comment=msg, ) ref_id = hashlib.md5( RandomString.gen_random_str( length=128).encode('utf8')).hexdigest() data['ref_id'] = ref_id event_check = dict(total=1) event_check.update(data) rst, msg = MerchantBalanceEvent.update_balance(**data) self.assertEqual(0, rst) # 设置支付密码 flag = User.set_payment_password(merchant, uid=uid, trade_pwd=info["trade_pwd"]) self.assertEqual(True, flag) # 绑定银行卡 bank_info = { "payment_password": info['trade_pwd'], "bank_name": "中国工商银行", "bank_code": "ICBC", "card_no": "6212260405014627955", "account_name": "张三", "branch": "广东东莞东莞市长安镇支行", "province": "广东省", "city": "东莞市" } flag = BankCard.add_bank_card(merchant, uid=uid, bank_name=bank_info['bank_name'], bank_code=bank_info['bank_code'], card_no=bank_info['card_no'], account_name=bank_info['account_name'], branch=bank_info['branch'], province=bank_info['province'], city=bank_info['city']) self.assertEqual(bank_info['card_no'], flag.card_no) self.path = "/withdraw/limit/config/get" response = self.do_request() self.assertEqual(ResponseBankWithdraw.code, response.status_code) self.assertEqual(ResponseBankWithdraw.error_code, response.json['error_code']) self.assertEqual("10000", response.json['data']['balance']) self.assertEqual("200", response.json['data']['limit_min']) self.assertEqual("5000", response.json['data']['limit_max']) self.path = "/withdraw/order/create" create_data = dict(amount=1000.001, user_bank=1, trade_password=info['trade_pwd']) # 测试小于 最低限额 create_data['amount'] = 100 response = self.do_request(json_data=create_data) self.assertEqual(WithdrawOrderAmountInvalidError.code, response.status_code) self.assertEqual(WithdrawOrderAmountInvalidError.error_code, response.json['error_code']) create_data['amount'] = 6000 response = self.do_request(json_data=create_data) self.assertEqual(WithdrawOrderAmountInvalidError.code, response.status_code) self.assertEqual(WithdrawOrderAmountInvalidError.error_code, response.json['error_code']) create_data['amount'] = str(500.56) create_data['user_bank'] = 100 response = self.do_request(json_data=create_data) self.assertEqual(WithdrawBankNoExistError.code, response.status_code) self.assertEqual(WithdrawBankNoExistError.error_code, response.json['error_code'], response.json['message']) use_balance = UserBalance.query_balance(user.uid, merchant).first() ori_merchant = MerchantInfo.query_merchant(merchant) balance = ori_merchant.bl_ava - BalanceKit.round_4down_5up( Decimal(create_data['amount'])) * 100 - BalanceKit.round_4down_5up( Decimal(create_data['amount']) * Decimal(3.5)) merchant_balance = BalanceKit.round_4down_5up( balance / Decimal(100)) * 100 u_balance = BalanceKit.round_4down_5up( Decimal(use_balance.balance) / Decimal(100) - Decimal(create_data['amount'])) * Decimal(100) create_data['user_bank'] = 1 response = self.do_request(json_data=create_data) self.assertEqual(ResponseSuccess.code, response.status_code) self.assertEqual(ResponseSuccess.error_code, response.json['error_code']) cur_balance = UserBalance.query_balance(user.uid, merchant).first() cur_merchant = MerchantInfo.query_merchant(merchant) self.assertEqual(int(merchant_balance), int(cur_merchant.bl_ava)) self.assertEqual(int(u_balance), int(cur_balance.balance))