1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750 |
- # coding=utf-8
- import datetime
- import base64
- import json
- import logging
- import requests
- from mongoengine import DoesNotExist
- from typing import TYPE_CHECKING, Optional
- from apps.web.core.bridge.wechat.v3api import WechatApiProxy
- from apps.web.core.exceptions import MerchantError
- from apps.web.core.models import WechatServiceProvider, JDAggrePayApp, AliApp
- from apps.web.core.utils import async_operation_no_catch
- from apps.web.dealer.models import Dealer
- from apps.web.merchant.exceptions import JdOpenParamsError
- from apps.web.merchant.constant import ProductStatus, MerchantStatus, JdOpenMerchantType, JdOpenAccountType, JdOpenAuditStatus, JdOpenProductType, AuthStatus, ALI_PAY_QR_CODE
- from apps.web.merchant.models import MerchantSourceInfo, JDOpenApplyInfo, MerchantAgent
- from library.jdopen.constants import OPEN_SECRET_KEY, OPEN_ACCESS_KEY
- from library.jdopen.exceptions import JdOpenException
- from library.jdopen.client import JdOpenMerchantClient
- from library.jdpsi.client import JdPsiMerchantClient
- from library.jdpsi.exceptions import JdPsiException
- if TYPE_CHECKING:
- from apps.web.agent.models import Agent
- from apps.web.merchant.models import Attach
- logger = logging.getLogger(__name__)
- # 信号触发函数
- def upload_merchant_to_jd(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
- # 先查找到商户
- logger.info("[upload_merchant_to_jd] start to upload data to jd merchant, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[upload_merchant_to_jd] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- proxy = MerchantApplyProxy(merchant)
- async_operation_no_catch(proxy.submit_data)
- def upload_merchant_to_auth(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
- """
- 上传商户的实名确认信息 包括支付宝的和微信的
- """
- logger.info("[upload_merchant_to_auth] start to upload data to wechat, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[upload_merchant_to_auth] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- # 分别提交支付宝以及微信的实名认证资料
- proxy = MerchantApplyProxy(merchant)
- async_operation_no_catch(proxy.submit_wechat)
- async_operation_no_catch(proxy.submit_ali)
- def create_psi_product(sender, merchantId, **kwargs):
- logger.info("[create_psi_product] start to create psi merchant product, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[create_psi_product] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- applier = JdPsiMerchantApplier(merchant, get_psi_client())
- async_operation_no_catch(applier.create_product)
- def create_settle(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
- """
- 京东 open 创建商户
- """
- logger.info("[create_settle] start to create open merchant settle account, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[create_settle] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- applier = JdOpenMerchantApplier(merchant, get_open_client())
- async_operation_no_catch(applier.create_settle)
- def create_shop(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
- """
- 京东 open 创建商店
- """
- logger.info("[create_shop] start to create open shop, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[create_shop] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- applier = JdOpenMerchantApplier(merchant, get_open_client())
- async_operation_no_catch(applier.create_shop)
- def upload_attaches(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
- """
- 京东 open 上传附件
- """
- logger.info("[upload_attaches] start to upload open merchant attaches, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[upload_attaches] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- applier = JdOpenMerchantApplier(merchant, get_open_client())
- async_operation_no_catch(applier.upload_attaches)
- def complete_customer(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
- """
- 京东 open 完成报单
- """
- logger.info("[complete_customer] start to complete open merchant, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[complete_customer] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- applier = JdOpenMerchantApplier(merchant, get_open_client())
- async_operation_no_catch(applier.complete)
- def confirm_customer(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
- """
- 京东 open 报单确认
- """
- logger.info("[confirm_customer] start to confirm open merchant, merchantId = {}".format(merchantId))
- try:
- merchant = sender.objects.get(id=merchantId)
- except DoesNotExist:
- logger.error("[confirm_customer] find merchant error not exist!, merchantId = {}".format(merchantId))
- return
- applier = JdOpenMerchantApplier(merchant, get_open_client())
- async_operation_no_catch(applier.confirm)
- # 功能辅助函数
- def get_file(url):
- res = requests.get(url)
- return res.content
- def get_location_by_area(province, city, district, addr, webKey="109f7b4b81698f345f24aa3dc6684924"):
- """
- 根据地址获取经纬度
- """
- logger.info("[get_location_by_area] province = {}, city = {}, district = {}, addr = {}".format(province, city, district, addr))
- url = "https://restapi.amap.com/v3/geocode/geo?address={}{}{}{}&key={}".format(province, city, district, addr, webKey)
- try:
- result = requests.get(url).json()
- except Exception as e:
- logger.error("[get_location_by_area] error = {}, province = {}, city = {}, district = {}, addr = {}".format(e, province, city, district, addr))
- return "0.000000", "0.000000"
- if "status" not in result or result["status"] != "1":
- return "0.000000", "0.000000"
- geocode = result["geocodes"][0]
- lng, lat = geocode["location"].split(",")
- return lng, lat
- def get_wechat_proxy():
- provider = WechatServiceProvider.objects.get(mchid="398254625") # type: WechatServiceProvider
- return WechatApiProxy(provider) # type: WechatApiProxy
- def get_open_client():
- openClient = JdOpenMerchantClient(OPEN_ACCESS_KEY, OPEN_SECRET_KEY)
- return openClient
- def get_psi_client():
- psiClient = JdPsiMerchantClient()
- return psiClient
- def get_ali_client():
- app = AliApp.objects.get(appid="2021001191645419") # type: AliApp
- return app.client
- def query_merchant_settle(merchantOwner, st, et): # type: (Dealer, datetime.datetime, datetime.datetime) -> dict
- """
- 查询商户的结算信息 只查询1天的 (商户拥有者可能是代理商、经销商)
- """
- merchant = MerchantSourceInfo.get_source_record(merchantOwner) # type: MerchantSourceInfo
- if not merchant.merchantNo:
- app = merchantOwner.jd_env_pay_app() # type: JDAggrePayApp
- agentNo = MerchantAgent.default_merchant_agent
- merchantNo = app.merchant_no
- else:
- agentNo = merchant.agentNo
- merchantNo = merchant.merchantNo
- startTime = datetime.datetime.strftime(st, "%Y-%m-%d")
- endTime = datetime.datetime.strftime(et, "%Y-%m-%d")
- psiClient = get_psi_client()
- result = psiClient.query_settle(agentNo, startTime, endTime, merchantNo=merchantNo)
- return result
- def query_sub_merchantId(document, openClient): # type: (Optional[None, JDOpenApplyInfo], JdOpenMerchantClient) -> Optional[None, JDOpenApplyInfo]
- """
- 查询 jdopen 的子商户编号 (微信 支付宝)
- """
- # 首先查询 微信的子商编
- data = {
- "customerNum": document.customerNum,
- "payProduct": str(JdOpenProductType.WX.value)
- }
- try:
- result = openClient.support.get_product_customer(**data)
- except JdOpenException as je:
- logger.error("[query_sub_merchantId] duo_la_bao merchant <{}> query audit result error = {} ".format(document, je))
- return
- # 获取到了微信的子商编号
- for item in result["data"]:
- if item["status"] == "OPEN":
- subMerchantId = item["subCustomerNum"]
- break
- else:
- subMerchantId = ""
- logger.info("[query_sub_merchantId] duo_la_bao merchant <{}> query sub merchantId subMerchantId = {} ".format(document, subMerchantId))
- data["payProduct"] = str(JdOpenProductType.ALI.value)
- try:
- result = openClient.support.get_product_customer(**data)
- except JdOpenException as je:
- logger.error("[query_sub_merchantId] duo_la_bao merchant <{}> query audit result error = {} ".format(document, je))
- return
- for item in result["data"]:
- if item["status"] == "OPEN":
- subAliMerchantId = item["subCustomerNum"]
- break
- else:
- subAliMerchantId = ""
- logger.info("[query_sub_merchantId] duo_la_bao merchant <{}> query sub merchantId subAliMerchantId = {} ".format(document, subAliMerchantId))
- # 更新商户编号到 文档 然后等待进一步的资料
- return document.update_sub_merchant(subMerchantId=subMerchantId, subAliMerchantId=subAliMerchantId)
- def get_merchant_by_version(owner, version):
- if version == "v2":
- return JDOpenApplyInfo.get_merchant_by_owner(owner)
- else:
- return MerchantSourceInfo.get_source_record(owner)
- def update_channels_info(merchant):
- """
- 获取自研商户的子商编
- 新增获取支付宝的子商户编号
- """
- logger.info("[update_channels_info] ownerId = {}".format(merchant.ownerId))
- # 如果存在就不要去获取了
- if merchant.wxSource.subMerchantId and merchant.wxSource.subAliMerchantId:
- logger.info("[update_channels_info] ownerId = {}, channels has been ready<wechat: {}; ali: {}>".format(
- merchant.ownerId, merchant.wxSource.subMerchantId, merchant.wxSource.subAliMerchantId
- ))
- return merchant
- wxApplier = merchant.wxSource
- # 首先尝试获取微信子商编号
- psiClient = get_psi_client()
- result = psiClient.query_sub_channel(merchant.agentNo, merchant.merchantNo)
- if "hlbWxSubNoResultInfo" not in result["data"]:
- logger.info("[update_channels_info] owner = <{}-{}>, not get subMchId and channelId".format(merchant.ownerRole, merchant.ownerId))
- merchant.to_fail(u"渠道编号获取错误")
- return merchant.reload()
- channelsInfo = json.loads(result["data"]["hlbWxSubNoResultInfo"])
- subMchId, channelId = channelsInfo["threePartnerNoData"][0]["threePartnerNo"], channelsInfo["threePartnerNoData"][0]["channelMerchantNo"]
- # 获取支付宝的子商户编号
- openClient = get_open_client()
- result = openClient.support.get_product_customer(merchant.merchantNo, "ALIPAY")
- subCustomerNum = merchant.wxSource.subAliMerchantId = result["data"][0]["subCustomerNum"]
- # 直接更新渠道编号
- wxApplier.update_sub_merchant(subMchId=subMchId, channel=channelId, subCustomerNum=subCustomerNum)
- return merchant.reload()
- def is_wechat_authorized(merchant):
- """
- 是否已经通过微信的审核
- """
- proxy = get_wechat_proxy()
- result = proxy.get_merchant_apply_state(merchant.wxSource.subMerchantId)
- return result["authorize_state"] == "AUTHORIZE_STATE_AUTHORIZED"
- def is_alipay_authorized(merchant):
- """
- 是否已经通过支付宝的审核 目前没有办法获取到支付宝的实名状态 一律返回True
- """
- return True
- def query_audit_result(document, openClient): # type: (Optional[None, JDOpenApplyInfo], JdOpenMerchantClient) -> Optional[None, JDOpenApplyInfo]
- """
- 查询报单的结果
- """
- logger.info("[query_audit_result] duo_la_bao merchant <{}>".format(document))
- if not document:
- return
- data = {
- "agentNum": document.agentNum,
- "customerNum": document.customerNum
- }
- try:
- result = openClient.audit.get_audit_result(**data)
- except JdOpenException as je:
- logger.error("[query_audit_result] duo_la_bao merchant <{}> query audit result error = {} ".format(document, je))
- return
- logger.info("[query_audit_result] duo_la_bao merchant <{}>, result = {}".format(document, result))
- declareResult = result["data"]["declareList"][-1]
- # 根据京东审核的状态 确定不同的
- declareStatus = declareResult["declareStatus"]
- if declareStatus == JdOpenAuditStatus.PASS:
- logger.info("[query_audit_result] duo_la_bao merchant <{}>, audit pass".format(document))
- document.to_success()
- elif declareStatus == JdOpenAuditStatus.NOT_PASS:
- logger.info("[query_audit_result] duo_la_bao merchant <{}>, audit no pass".format(document))
- auditOpinion = declareResult["auditOpinion"]
- document.to_fail(auditOpinion)
- else:
- logger.info("[query_audit_result] duo_la_bao merchant <{}>, audit doing".format(document))
- return document
- def get_wechat_auth_info(merchant): # type:(Optional[JDOpenApplyInfo, MerchantSourceInfo]) -> dict
- """
- 获取微信的实名信息
- """
- data = {
- "channel": "wechat",
- "status": AuthStatus.AUDIT,
- "subMerchantId": "",
- "description": ""
- }
- subMerchantId = merchant.wxSource.subMerchantId
- if not subMerchantId:
- return data
- data.update({"subMerchantId": subMerchantId})
- if is_wechat_authorized(merchant):
- data["status"] = AuthStatus.AUTHED
- return data
- applymentId = merchant.wxSource.applymentId
- if not applymentId:
- return data
- wechatProxy = get_wechat_proxy()
- result = wechatProxy.get_merchant_audit(merchant.wxSource.applymentId)
- if "applyment_state" not in result:
- return data
- elif result["applyment_state"] in [
- "APPLYMENT_STATE_PASSED",
- "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_LEGALPERSON",
- "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_CONTACT"
- ]:
- data["status"] = AuthStatus.PASS
- data["qrCode"] = "data:image/png;base64,{}".format(result["qrcode_data"])
- return data
- elif result["applyment_state"] in ["APPLYMENT_STATE_REJECTED"]:
- data["status"] = AuthStatus.NO_PASS
- data["description"] = u"【审核驳回】{}:{},请联系平台客服处理".format(result["reject_param"], result["reject_reason"])
- return data
- else:
- return data
- def get_alipay_auth_info(merchant):
- """
- 获取支付宝的实名信息
- 支付宝的时候一定要兼容之前的版本 之前从来没有获取过支付宝的子商户编号
- """
- data = {
- "channel": "ali",
- "status": AuthStatus.AUDIT,
- "subMerchantId": "",
- "description": ""
- }
- subMerchantId = merchant.wxSource.subAliMerchantId
- if not subMerchantId:
- merchant = update_channels_info(merchant)
- subMerchantId = merchant.wxSource.subAliMerchantId
- if subMerchantId:
- data["subMerchantId"] = subMerchantId
- data["status"] = AuthStatus.PASS
- data["qrCode"] = ALI_PAY_QR_CODE
- return data
- class QueryMerchant(object):
- def __init__(self, merchant): # type:(MerchantSourceInfo) -> None
- self._mer = merchant
- def do(self):
- pass
- class JdOpenParamsChecker(object):
- def __init__(self, **kwargs):
- self.data = {"id": kwargs.pop("id", "")}
- self.source = kwargs
- @staticmethod
- def area_check(area):
- return "code" in area and "name" in area
- @staticmethod
- def date_check(date):
- if date == "forever":
- return True
- try:
- datetime.datetime.strptime(date, "%Y-%m-%d")
- except ValueError:
- return False
- return True
- def create(self, owner):
- # 公共参数的检查
- self.common_check()
- # 公司商户的参数检查以及 商户创建
- if self.data["customerType"] == JdOpenMerchantType.COMPANY:
- self.check_company_merchant()
- return JDOpenApplyInfo.create_company(owner, **self.data)
- # 个人商户的参数检查 商户创建
- elif self.data["customerType"] == JdOpenMerchantType.PERSON:
- self.check_person_merchant()
- return JDOpenApplyInfo.create_personal(owner, **self.data)
- # 个体工商户的参数检查 商户创建
- elif self.data["customerType"] == JdOpenMerchantType.INDIVIDUALBISS:
- self.check_individualbiss_merchant()
- return JDOpenApplyInfo.create_individualbiss(owner, **self.data)
- # 事业单位的参数检查 商户创建
- else:
- self.check_institution_merchant()
- return JDOpenApplyInfo.create_institution(owner, **self.data)
- def common_check(self):
- """
- 检测商户的基本信息 并将其赋值到data中
- """
- customerType = self.source.get("customerType")
- if customerType not in JdOpenMerchantType.choices():
- raise JdOpenParamsError(u"参数错误,商户类型错误")
- self.data["customerType"] = customerType
- shortName = self.source.get("shortName")
- if not shortName:
- raise JdOpenParamsError(u"参数错误,缺少商户简称")
- self.data["shortName"] = shortName
- province = self.source.get("province")
- city = self.source.get("city")
- district = self.source.get("district")
- address = self.source.get("address")
- if not all([province, city, district]):
- raise JdOpenParamsError(u"参数错误,缺少商户地区信息")
- if not self.area_check(province):
- raise JdOpenParamsError(u"参数错误,商户地区 省 信息错误")
- if not self.area_check(city):
- raise JdOpenParamsError(u"参数错误, 商户地区 市 信息错误")
- if not self.area_check(district):
- raise JdOpenParamsError(u"参数错误,商户地区 区 信息错误")
- if not address:
- raise JdOpenParamsError(u"参数错误,缺少商户详细地址")
- self.data["province"] = province
- self.data["city"] = city
- self.data["district"] = district
- self.data["address"] = address
- # 内部补充经纬度
- self.data["mapLng"], self.data["mapLat"] = get_location_by_area(province["name"], city["name"], district["name"], address)
- def check_person_merchant(self):
- """
- 创建一条个人商户的记录
- """
- # 用户填写的个人界面的信息提取
- legalImgFront = self.source.get("legalImgFront")
- legalImgBack = self.source.get("legalImgBack")
- legalImgHold = self.source.get("legalImgHold")
- legalName = self.source.get("legalName")
- legalCardNo = self.source.get("legalCardNo")
- legalStart = self.source.get("legalStart")
- legalEnd = self.source.get("legalEnd")
- legalForever = self.source.get("legalForever")
- if not legalImgFront:
- raise JdOpenParamsError(u"参数错误,请上传收款人证件正面照")
- if not legalImgBack:
- raise JdOpenParamsError(u"参数错误,请上传收款人证件反面照")
- if not legalImgHold:
- raise JdOpenParamsError(u"参数错误,请上传收款人手持证件照")
- if not legalName:
- raise JdOpenParamsError(u"参数错误,缺少收款人姓名")
- if not legalCardNo:
- raise JdOpenParamsError(u"参数错误,缺少收款人证件号码")
- if not self.date_check(legalStart) or not self.date_check(legalEnd):
- raise JdOpenParamsError(u"参数错误, 收款人证件有效期错误")
- self.data["legalImgFront"] = legalImgFront
- self.data["legalImgBack"] = legalImgBack
- self.data["legalImgHold"] = legalImgHold
- self.data["legalName"] = legalName
- self.data["legalCardNo"] = legalCardNo
- self.data["legalStart"] = legalStart
- self.data["legalEnd"] = legalEnd if not legalForever else "forever"
- # 用户填写的结算界面的信息提取
- accountType = self.source.get("accountType")
- bankImg = self.source.get("bankImg")
- bankCardNo = self.source.get("bankCardNo")
- bankName = self.source.get("bankName")
- bankBranchName = self.source.get("bankBranchName")
- bankProvince = self.source.get("bankProvince")
- bankCity = self.source.get("bankCity")
- bankPhone = self.source.get("bankPhone")
- if not accountType:
- raise JdOpenParamsError(u"参数错误,请选择账户类型")
- if not bankImg:
- raise JdOpenParamsError(u"参数错误,请上传银行卡图片")
- if not bankCardNo:
- raise JdOpenParamsError(u"参数错误,缺少银行卡号")
- if not bankName:
- raise JdOpenParamsError(u"参数错误,缺少银行名称")
- if not bankBranchName:
- raise JdOpenParamsError(u"参数错误,缺少银行支行名称")
- if not all([bankProvince, bankCity]):
- raise JdOpenParamsError(u"参数错误,缺少银行地区信息")
- if not self.area_check(bankProvince) or not self.area_check(bankCity):
- raise JdOpenParamsError(u"参数错误,银行开户地区选择错误")
- if not bankPhone:
- raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
- self.data["accountType"] = accountType
- self.data["bankImg"] = bankImg
- self.data["bankCardNo"] = bankCardNo
- self.data["bankName"] = bankName
- self.data["bankBranchName"] = bankBranchName
- self.data["bankProvince"] = bankProvince
- self.data["bankCity"] = bankCity
- self.data["bankPhone"] = bankPhone
- # 商店照片的信息的获取
- shopImgA = self.source.get("shopImgA")
- shopImgB = self.source.get("shopImgB")
- shopImgC = self.source.get("shopImgC")
- if not all([shopImgA, shopImgB, shopImgC]):
- raise JdOpenParamsError(u"参数错误,缺少营业照片")
- self.data["shopImgA"] = shopImgA
- self.data["shopImgB"] = shopImgB
- self.data["shopImgC"] = shopImgC
- # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
- phoneNumber = self.source.get("phoneNumber")
- if not phoneNumber:
- raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
- self.data["phoneNumber"] = phoneNumber
- # 非默认参数的补充
- self.data["fullName"] = u"个人_{}".format(self.data["legalName"])
- def check_individualbiss_merchant(self):
- """
- 个体工商户 (简易版的企业商户 区别在于 个体工商户可以对私)
- """
- # 公司法人的参数校验
- legalImgFront = self.source.get("legalImgFront")
- legalImgBack = self.source.get("legalImgBack")
- legalName = self.source.get("legalName")
- legalCardNo = self.source.get("legalCardNo")
- legalStart = self.source.get("legalStart")
- legalEnd = self.source.get("legalEnd")
- legalForever = self.source.get("legalForever")
- if not legalImgFront:
- raise JdOpenParamsError(u"参数错误,请上传收款人证件正面照")
- if not legalImgBack:
- raise JdOpenParamsError(u"参数错误,请上传收款人证件反面照")
- if not legalName:
- raise JdOpenParamsError(u"参数错误,缺少收款人姓名")
- if not legalCardNo:
- raise JdOpenParamsError(u"参数错误,缺少收款人证件号码")
- if not self.date_check(legalStart) or not self.date_check(legalEnd):
- raise JdOpenParamsError(u"参数错误, 收款人证件有效期错误")
- self.data["legalImgFront"] = legalImgFront
- self.data["legalImgBack"] = legalImgBack
- self.data["legalName"] = legalName
- self.data["legalCardNo"] = legalCardNo
- self.data["legalStart"] = legalStart
- self.data["legalEnd"] = legalEnd if not legalForever else "forever"
- # 联系人信息的填写
- contactImgFront = self.source.get("contactImgFront")
- contactImgBack = self.source.get("contactImgBack")
- contactName = self.source.get("contactName")
- contactCardNo = self.source.get("contactCardNo")
- contactStart = self.source.get("contactStart")
- contactEnd = self.source.get("contactEnd")
- contactForever = self.source.get("contactForever")
- if not contactImgFront:
- raise JdOpenParamsError(u"参数错误,请上传联系人证件正面照")
- if not contactImgBack:
- raise JdOpenParamsError(u"参数错误,请上传联系人证件反面照")
- if not contactName:
- raise JdOpenParamsError(u"参数错误,缺少联系人姓名")
- if not contactCardNo:
- raise JdOpenParamsError(u"参数有误,缺少联系人证件号码")
- if not self.date_check(contactStart) or not self.date_check(contactEnd):
- raise JdOpenParamsError(u"参数错误, 联系人证件有效期错误")
- self.data["contactImgFront"] = contactImgFront
- self.data["contactImgBack"] = contactImgBack
- self.data["contactName"] = contactName
- self.data["contactCardNo"] = legalCardNo
- self.data["contactStart"] = contactCardNo
- self.data["contactEnd"] = contactEnd if not contactForever else "forever"
- # 营业执照的参数校验
- organizationImg = self.source.get("organizationImg")
- organizationName = self.source.get("organizationName")
- organizationNo = self.source.get("organizationNo")
- organizationStart = self.source.get("organizationStart")
- organizationEnd = self.source.get("organizationEnd")
- organizationProvince = self.source.get("organizationProvince")
- organizationCity = self.source.get("organizationCity")
- organizationDistrict = self.source.get("organizationDistrict")
- organizationAddress = self.source.get("organizationAddress")
- organizationForever = self.source.get("organizationForever")
- if not organizationImg:
- raise JdOpenParamsError(u"参数错误,请上传营业执照")
- if not organizationName:
- raise JdOpenParamsError(u"参数错误,缺少公司名称")
- if not organizationNo:
- raise JdOpenParamsError(u"参数错误,缺少统一信用码")
- if not self.date_check(organizationStart) or not self.date_check(organizationEnd):
- raise JdOpenParamsError(u"参数错误, 营业执照有效期填写错误")
- if not self.area_check(organizationProvince):
- raise JdOpenParamsError(u"参数错误,营业执照 省 信息错误")
- if not self.area_check(organizationCity):
- raise JdOpenParamsError(u"参数错误,营业执照 市 信息错误")
- if not self.area_check(organizationDistrict):
- raise JdOpenParamsError(u"参数错误,营业执照 区 信息错误")
- if not organizationAddress:
- raise JdOpenParamsError(u"参数错误,缺少营业执照详细地址")
- self.data["organizationImg"] = organizationImg
- self.data["organizationName"] = organizationName
- self.data["organizationNo"] = organizationNo
- self.data["organizationStart"] = organizationStart
- self.data["organizationEnd"] = organizationEnd if not organizationForever else "forever"
- self.data["organizationProvince"] = organizationProvince
- self.data["organizationCity"] = organizationCity
- self.data["organizationDistrict"] = organizationDistrict
- self.data["organizationAddress"] = organizationAddress
- # 用户填写的结算界面的信息提取
- accountType = self.source.get("accountType")
- bankImg = self.source.get("bankImg")
- bankCardNo = self.source.get("bankCardNo")
- bankName = self.source.get("bankName")
- bankBranchName = self.source.get("bankBranchName")
- bankProvince = self.source.get("bankProvince")
- bankCity = self.source.get("bankCity")
- bankPhone = self.source.get("bankPhone")
- if not accountType:
- raise JdOpenParamsError(u"参数错误,请选择账户类型")
- if not bankImg:
- raise JdOpenParamsError(u"参数错误,请上传开户许可证图片")
- if not bankCardNo:
- raise JdOpenParamsError(u"参数错误,缺少结算账号")
- if not bankName:
- raise JdOpenParamsError(u"参数错误,缺少结算银行名称")
- if not bankBranchName:
- raise JdOpenParamsError(u"参数错误,缺少结算银行支行名称")
- if not all([bankProvince, bankCity]):
- raise JdOpenParamsError(u"参数错误,缺少结算银行地区信息")
- if not self.area_check(bankProvince) or not self.area_check(bankCity):
- raise JdOpenParamsError(u"参数错误,结算银行开户地区选择错误")
- if not bankPhone:
- raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
- self.data["accountType"] = accountType
- self.data["bankImg"] = bankImg
- self.data["bankCardNo"] = bankCardNo
- self.data["bankName"] = bankName
- self.data["bankBranchName"] = bankBranchName
- self.data["bankProvince"] = bankProvince
- self.data["bankCity"] = bankCity
- self.data["bankPhone"] = bankPhone
- # 商店照片的信息的获取
- shopImgA = self.source.get("shopImgA")
- shopImgB = self.source.get("shopImgB")
- shopImgC = self.source.get("shopImgC")
- if not all([shopImgA, shopImgB, shopImgC]):
- raise JdOpenParamsError(u"参数错误,缺少营业照片")
- self.data["shopImgA"] = shopImgA
- self.data["shopImgB"] = shopImgB
- self.data["shopImgC"] = shopImgC
- # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
- phoneNumber = self.source.get("phoneNumber")
- if not phoneNumber:
- raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
- self.data["phoneNumber"] = phoneNumber
- # 个体工商户的 商户全程为 营业执照名称
- self.data["fullName"] = u"{}".format(self.data["organizationName"])
- # 个体工商户的 组织机构代码 税务登记证 都是营业执照
- self.data["organizationcode"] = self.data["organizationImg"]
- self.data["taxregistration"] = self.data["organizationImg"]
- # 补充一下经办人的函件
- if contactName != legalName or contactCardNo != legalCardNo:
- businessAuthorizationLetter = self.source.get("businessAuthorizationLetter")
- if not businessAuthorizationLetter:
- raise JdOpenParamsError(u"参数错误,缺少业务办理授权函")
- else:
- self.data["businessAuthorizationLetter"] = businessAuthorizationLetter
- else:
- self.data["businessAuthorizationLetter"] = ""
- def check_company_merchant(self):
- """
- 创建一条公司商户记录
- """
- # 公司法人的参数校验
- legalImgFront = self.source.get("legalImgFront")
- legalImgBack = self.source.get("legalImgBack")
- legalName = self.source.get("legalName")
- legalCardNo = self.source.get("legalCardNo")
- legalStart = self.source.get("legalStart")
- legalEnd = self.source.get("legalEnd")
- legalForever = self.source.get("legalForever")
- legalProvince = self.source.get("legalProvince")
- legalCity = self.source.get("legalCity")
- legalDistrict = self.source.get("legalDistrict")
- legalAddress = self.source.get("legalAddress")
- if not legalImgFront:
- raise JdOpenParamsError(u"参数错误,请上传法人证件正面照")
- if not legalImgBack:
- raise JdOpenParamsError(u"参数错误,请上传法人证件反面照")
- if not legalName:
- raise JdOpenParamsError(u"参数错误,缺少法人姓名")
- if not legalCardNo:
- raise JdOpenParamsError(u"参数错误,缺少法人证件号码")
- if not self.date_check(legalStart) or not self.date_check(legalEnd):
- raise JdOpenParamsError(u"参数错误, 法人证件有效期错误")
- if not all([legalProvince, legalCity, legalDistrict]):
- raise JdOpenParamsError(u"参数错误,缺少法人地区信息")
- if not self.area_check(legalProvince):
- raise JdOpenParamsError(u"参数错误,法人地区 省 信息错误")
- if not self.area_check(legalCity):
- raise JdOpenParamsError(u"参数错误, 法人地区 市 信息错误")
- if not self.area_check(legalDistrict):
- raise JdOpenParamsError(u"参数错误,法人地区 区 信息错误")
- if not legalAddress:
- raise JdOpenParamsError(u"参数错误,缺少商户详细地址")
- self.data["legalImgFront"] = legalImgFront
- self.data["legalImgBack"] = legalImgBack
- self.data["legalName"] = legalName
- self.data["legalCardNo"] = legalCardNo
- self.data["legalStart"] = legalStart
- self.data["legalEnd"] = legalEnd if not legalForever else "forever"
- self.data["legalProvince"] = legalProvince
- self.data["legalCity"] = legalCity
- self.data["legalDistrict"] = legalDistrict
- self.data["legalAddress"] = legalAddress
- # 联系人信息的填写
- contactImgFront = self.source.get("contactImgFront")
- contactImgBack = self.source.get("contactImgBack")
- contactName = self.source.get("contactName")
- contactCardNo = self.source.get("contactCardNo")
- contactStart = self.source.get("contactStart")
- contactEnd = self.source.get("contactEnd")
- contactForever = self.source.get("contactForever")
- if not contactImgFront:
- raise JdOpenParamsError(u"参数错误,请上传联系人证件正面照")
- if not contactImgBack:
- raise JdOpenParamsError(u"参数错误,请上传联系人证件反面照")
- if not contactName:
- raise JdOpenParamsError(u"参数错误,缺少联系人姓名")
- if not contactCardNo:
- raise JdOpenParamsError(u"参数有误,缺少联系人证件号码")
- if not self.date_check(contactStart) or not self.date_check(contactEnd):
- raise JdOpenParamsError(u"参数错误, 联系人证件有效期错误")
- self.data["contactImgFront"] = contactImgFront
- self.data["contactImgBack"] = contactImgBack
- self.data["contactName"] = contactName
- self.data["contactCardNo"] = legalCardNo
- self.data["contactStart"] = contactCardNo
- self.data["contactEnd"] = contactEnd if not contactForever else "forever"
- # 营业执照的参数校验
- organizationImg = self.source.get("organizationImg")
- organizationName = self.source.get("organizationName")
- organizationNo = self.source.get("organizationNo")
- organizationStart = self.source.get("organizationStart")
- organizationEnd = self.source.get("organizationEnd")
- organizationProvince = self.source.get("organizationProvince")
- organizationCity = self.source.get("organizationCity")
- organizationDistrict = self.source.get("organizationDistrict")
- organizationAddress = self.source.get("organizationAddress")
- organizationForever = self.source.get("organizationForever")
- if not organizationImg:
- raise JdOpenParamsError(u"参数错误,请上传营业执照")
- if not organizationName:
- raise JdOpenParamsError(u"参数错误,缺少公司名称")
- if not organizationNo:
- raise JdOpenParamsError(u"参数错误,缺少统一信用码")
- if not self.date_check(organizationStart) or not self.date_check(organizationEnd):
- raise JdOpenParamsError(u"参数错误, 营业执照有效期填写错误")
- if not self.area_check(organizationProvince):
- raise JdOpenParamsError(u"参数错误,营业执照 省 信息错误")
- if not self.area_check(organizationCity):
- raise JdOpenParamsError(u"参数错误,营业执照 市 信息错误")
- if not self.area_check(organizationDistrict):
- raise JdOpenParamsError(u"参数错误,营业执照 区 信息错误")
- if not organizationAddress:
- raise JdOpenParamsError(u"参数错误,缺少营业执照详细地址")
- self.data["organizationImg"] = organizationImg
- self.data["organizationName"] = organizationName
- self.data["organizationNo"] = organizationNo
- self.data["organizationStart"] = organizationStart
- self.data["organizationEnd"] = organizationEnd if not organizationForever else "forever"
- self.data["organizationProvince"] = organizationProvince
- self.data["organizationCity"] = organizationCity
- self.data["organizationDistrict"] = organizationDistrict
- self.data["organizationAddress"] = organizationAddress
- # 用户填写的结算界面的信息提取
- accountType = self.source.get("accountType")
- bankImg = self.source.get("bankImg")
- bankCardNo = self.source.get("bankCardNo")
- bankName = self.source.get("bankName")
- bankBranchName = self.source.get("bankBranchName")
- bankProvince = self.source.get("bankProvince")
- bankCity = self.source.get("bankCity")
- bankPhone = self.source.get("bankPhone")
- if not accountType:
- raise JdOpenParamsError(u"参数错误,请选择账户类型")
- if not bankImg:
- raise JdOpenParamsError(u"参数错误,请上传开户许可证图片")
- if not bankCardNo:
- raise JdOpenParamsError(u"参数错误,缺少结算账号")
- if not bankName:
- raise JdOpenParamsError(u"参数错误,缺少结算银行名称")
- if not bankBranchName:
- raise JdOpenParamsError(u"参数错误,缺少结算银行支行名称")
- if not all([bankProvince, bankCity]):
- raise JdOpenParamsError(u"参数错误,缺少结算银行地区信息")
- if not self.area_check(bankProvince) or not self.area_check(bankCity):
- raise JdOpenParamsError(u"参数错误,结算银行开户地区选择错误")
- if not bankPhone:
- raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
- self.data["accountType"] = accountType
- self.data["bankImg"] = bankImg
- self.data["bankCardNo"] = bankCardNo
- self.data["bankName"] = bankName
- self.data["bankBranchName"] = bankBranchName
- self.data["bankProvince"] = bankProvince
- self.data["bankCity"] = bankCity
- self.data["bankPhone"] = bankPhone
- # 商店照片的信息的获取
- shopImgA = self.source.get("shopImgA")
- shopImgB = self.source.get("shopImgB")
- shopImgC = self.source.get("shopImgC")
- if not all([shopImgA, shopImgB, shopImgC]):
- raise JdOpenParamsError(u"参数错误,缺少营业照片")
- self.data["shopImgA"] = shopImgA
- self.data["shopImgB"] = shopImgB
- self.data["shopImgC"] = shopImgC
- # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
- phoneNumber = self.source.get("phoneNumber")
- if not phoneNumber:
- raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
- self.data["phoneNumber"] = phoneNumber
- # 企业商户的商户全称 为公司名称
- self.data["fullName"] = u"{}".format(self.data["organizationName"])
- # 企业商户的 组织机构代码 税务登记证 统一社会信用代码 都是营业执照
- self.data["organizationcode"] = self.data["organizationImg"]
- self.data["taxregistration"] = self.data["organizationImg"]
- self.data["unifiedsocialcreditcode"] = self.data["organizationImg"]
- # 补充一下经办人的函件
- if contactName != legalName or contactCardNo != legalCardNo:
- businessAuthorizationLetter = self.source.get("businessAuthorizationLetter")
- if not businessAuthorizationLetter:
- raise JdOpenParamsError(u"参数错误,缺少业务办理授权函")
- else:
- self.data["businessAuthorizationLetter"] = businessAuthorizationLetter
- else:
- self.data["businessAuthorizationLetter"] = ""
- def check_institution_merchant(self):
- """"""
- legalImgFront = self.source.get("legalImgFront")
- legalImgBack = self.source.get("legalImgBack")
- legalName = self.source.get("legalName")
- legalCardNo = self.source.get("legalCardNo")
- legalStart = self.source.get("legalStart")
- legalEnd = self.source.get("legalEnd")
- legalForever = self.source.get("legalForever")
- if not legalImgFront:
- raise JdOpenParamsError(u"参数错误,请上传法人证件正面照")
- if not legalImgBack:
- raise JdOpenParamsError(u"参数错误,请上传法人证件反面照")
- if not legalName:
- raise JdOpenParamsError(u"参数错误,缺少法人姓名")
- if not legalCardNo:
- raise JdOpenParamsError(u"参数错误,缺少法人证件号码")
- if not self.date_check(legalStart) or not self.date_check(legalEnd):
- raise JdOpenParamsError(u"参数错误, 法人证件有效期错误")
- self.data["legalImgFront"] = legalImgFront
- self.data["legalImgBack"] = legalImgBack
- self.data["legalName"] = legalName
- self.data["legalCardNo"] = legalCardNo
- self.data["legalStart"] = legalStart
- self.data["legalEnd"] = legalEnd if not legalForever else "forever"
- # 联系人信息的填写
- contactImgFront = self.source.get("contactImgFront")
- contactImgBack = self.source.get("contactImgBack")
- contactName = self.source.get("contactName")
- contactCardNo = self.source.get("contactCardNo")
- contactStart = self.source.get("contactStart")
- contactEnd = self.source.get("contactEnd")
- contactForever = self.source.get("contactForever")
- if not contactImgFront:
- raise JdOpenParamsError(u"参数错误,请上传联系人证件正面照")
- if not contactImgBack:
- raise JdOpenParamsError(u"参数错误,请上传联系人证件反面照")
- if not contactName:
- raise JdOpenParamsError(u"参数错误,缺少联系人姓名")
- if not contactCardNo:
- raise JdOpenParamsError(u"参数有误,缺少联系人证件号码")
- if not self.date_check(contactStart) or not self.date_check(contactEnd):
- raise JdOpenParamsError(u"参数错误, 联系人证件有效期错误")
- self.data["contactImgFront"] = contactImgFront
- self.data["contactImgBack"] = contactImgBack
- self.data["contactName"] = contactName
- self.data["contactCardNo"] = legalCardNo
- self.data["contactStart"] = contactCardNo
- self.data["contactEnd"] = contactEnd if not contactForever else "forever"
- # 营业执照的参数校验
- certType = self.source.get("certType")
- certImg = self.source.get("certImg")
- certName = self.source.get("certName")
- certNo = self.source.get("certNo")
- certStart = self.source.get("certStart")
- certEnd = self.source.get("certEnd")
- certProvince = self.source.get("certProvince")
- certCity = self.source.get("certCity")
- certDistrict = self.source.get("certDistrict")
- certAddress = self.source.get("certAddress")
- certForever = self.source.get("certForever")
- if not certType:
- raise JdOpenParamsError(u"参数错误")
- if not certImg:
- raise JdOpenParamsError(u"参数错误,请上传证书照片")
- if not certName:
- raise JdOpenParamsError(u"参数错误,缺少组织机构名称")
- if not certNo:
- raise JdOpenParamsError(u"参数错误,缺少组织机构码")
- if not self.date_check(certStart) or not self.date_check(certEnd):
- raise JdOpenParamsError(u"参数错误, 证书有效期填写错误")
- if not self.area_check(certProvince):
- raise JdOpenParamsError(u"参数错误,证书地区 省 信息错误")
- if not self.area_check(certCity):
- raise JdOpenParamsError(u"参数错误,证书地区 市 信息错误")
- if not self.area_check(certDistrict):
- raise JdOpenParamsError(u"参数错误,证书地区 区 信息错误")
- if not certAddress:
- raise JdOpenParamsError(u"参数错误,缺少证书详细地址")
- self.data["certType"] = certType
- self.data["certImg"] = certImg
- self.data["certName"] = certName
- self.data["certNo"] = certNo
- self.data["certStart"] = certStart
- self.data["certEnd"] = certEnd if not certForever else "forever"
- self.data["certProvince"] = certProvince
- self.data["certCity"] = certCity
- self.data["certDistrict"] = certDistrict
- self.data["certAddress"] = certAddress
- # 用户填写的结算界面的信息提取
- accountType = self.source.get("accountType")
- bankImg = self.source.get("bankImg")
- bankCardNo = self.source.get("bankCardNo")
- bankName = self.source.get("bankName")
- bankBranchName = self.source.get("bankBranchName")
- bankProvince = self.source.get("bankProvince")
- bankCity = self.source.get("bankCity")
- bankPhone = self.source.get("bankPhone")
- if not accountType:
- raise JdOpenParamsError(u"参数错误,请选择账户类型")
- if not bankImg:
- raise JdOpenParamsError(u"参数错误,请上传开户许可证图片")
- if not bankCardNo:
- raise JdOpenParamsError(u"参数错误,缺少结算账号")
- if not bankName:
- raise JdOpenParamsError(u"参数错误,缺少结算银行名称")
- if not bankBranchName:
- raise JdOpenParamsError(u"参数错误,缺少结算银行支行名称")
- if not all([bankProvince, bankCity]):
- raise JdOpenParamsError(u"参数错误,缺少结算银行地区信息")
- if not self.area_check(bankProvince) or not self.area_check(bankCity):
- raise JdOpenParamsError(u"参数错误,结算银行开户地区选择错误")
- if not bankPhone:
- raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
- self.data["accountType"] = accountType
- self.data["bankImg"] = bankImg
- self.data["bankCardNo"] = bankCardNo
- self.data["bankName"] = bankName
- self.data["bankBranchName"] = bankBranchName
- self.data["bankProvince"] = bankProvince
- self.data["bankCity"] = bankCity
- self.data["bankPhone"] = bankPhone
- # 商店照片的信息的获取
- shopImgA = self.source.get("shopImgA")
- shopImgB = self.source.get("shopImgB")
- shopImgC = self.source.get("shopImgC")
- if not all([shopImgA, shopImgB, shopImgC]):
- raise JdOpenParamsError(u"参数错误,缺少营业照片")
- self.data["shopImgA"] = shopImgA
- self.data["shopImgB"] = shopImgB
- self.data["shopImgC"] = shopImgC
- # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
- phoneNumber = self.source.get("phoneNumber")
- if not phoneNumber:
- raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
- self.data["phoneNumber"] = phoneNumber
- # 资质信息检查
- certificateFile = self.source.get("certificateFile")
- specialQualification = self.source.get("specialQualification")
- if not certificateFile:
- raise JdOpenParamsError(u"参数错误,请上传单位证明函")
- if not specialQualification:
- raise JdOpenParamsError(u"参数错误,请上传特殊资质证书")
- self.data["certificateFile"] = certificateFile
- self.data["specialQualification"] = specialQualification
- # 非默认参数的补充
- self.data["fullName"] = u"{}".format(self.data["certName"])
- # 事业单位的 组织机构代码、税务登记证、统一社会信用代码 就是营业执照(证书)
- self.data["organizationcode"] = self.data["certImg"]
- self.data["taxregistration"] = self.data["certImg"]
- self.data["unifiedsocialcreditcode"] = self.data["certImg"]
- # 补充一下经办人的函件
- if contactName != legalName or contactCardNo != legalCardNo:
- businessAuthorizationLetter = self.source.get("businessAuthorizationLetter")
- if not businessAuthorizationLetter:
- raise JdOpenParamsError(u"参数错误,缺少业务办理授权函")
- else:
- self.data["businessAuthorizationLetter"] = businessAuthorizationLetter
- else:
- self.data["businessAuthorizationLetter"] = ""
- class MerchantApplier(object):
- """
- 商户申请
- 负责维持状态到商户申请完成 包含递交商户资料 对商户申请状态轮询
- 不负责实名 的任何任务 将实名与商户进行解耦
- 各自商户申请完成各自实现函数
- """
- def __init__(self, merchant, client): # type:(Optional[JDOpenApplyInfo, MerchantSourceInfo], Optional[JdPsiMerchantClient, JdOpenMerchantClient]) -> None
- self._merchant = merchant
- self._client = client
- def submit(self):
- pass
- def query_audit_result(self):
- pass
- class JdPsiMerchantApplier(MerchantApplier):
- def submit(self):
- """
- 创建商户
- """
- logger.info("[create_customer] psi merchant <{}>".format(self._merchant))
- if not self._merchant:
- return
- data = {"agentNo": self._merchant.agentNo}
- data.update(self._merchant.load_enter_image_info())
- data.update(self._merchant.load_enter_entity_info())
- try:
- result = self._client.create_customer(**data)
- except JdPsiException as je:
- self._merchant.to_fail(je.errMsg)
- return
- merchantNo = result.get("merchantNo")
- serialNo = result["data"]["serialNo"]
- self._merchant.enter_success(merchantNo, serialNo)
- def query_audit_result(self):
- """
- 查询产品的开通状态 产品开通成功的情况下 进行秘钥查询
- """
- logger.info("[query_audit_result] query ownerId = {}".format(self._merchant.ownerId))
- if self._merchant.merchantStatus != int(MerchantStatus.WAITING):
- return
- # 将产品码和产品建立关系 方便后续处理
- productMap = {
- self._merchant.products[_name].productId: self._merchant.products[_name]
- for _name in self._merchant.products
- }
- # 发送查询的申请
- try:
- queryInfo = self._merchant.load_query_info()
- result = self._client.query_product(self._merchant.agentNo, **queryInfo)
- except JdPsiException as je:
- # 此处不需要切换失败的状态 等待下一次的轮询即可
- logger.error("query error!, record is <{}>, code = {}, error = {}".format(self._merchant.id, je.errCode, je.errMsg))
- return
- # 解析查询的结果
- products = result["dataList"]
- errorMsg = ""
- # 对每一个返回的产品信息进行轮询
- for _item in products:
- _productId = _item["productNo"]
- _product = productMap[_productId]
- status = _item.get("status")
- if int(status) == ProductStatus.FAIL:
- logger.error("product fail, record is <{}>, product is <{}>".format(self._merchant.id, _product.productId))
- errorMsg = _item.get("resultMsg", "")
- _product.to_fail()
- elif int(status) == ProductStatus.SUCCESS or int(status) == ProductStatus.CONFIRM:
- logger.info("product success, record is <{}>, product is <{}>".format(self._merchant.id, _product.productId))
- _product.to_success()
- else:
- logger.info("product waiting, record is <{}>, product is <{}>".format(self._merchant.id, _product.productId))
- # 商户重载一次 获取真实的产品开通状态
- merchant = self._merchant.reload()
- if merchant.is_product_fail():
- return merchant.to_fail(errorMsg)
- # 如果产品没有完全开通成功 直接退出 等待下一次的轮询
- if not merchant.is_product_success():
- return
- desKey, mdKey = self.query_secret()
- merchant.to_confirm(desKey=desKey, mdKey=mdKey)
- def query_secret(self):
- """
- 查询秘钥
- """
- try:
- queryInfo = self._merchant.load_query_info()
- result = self._client.query_secret_key(self._merchant.agentNo, **queryInfo)
- except JdPsiException as je:
- logger.error("[query_secret] query secret error = {}, code = {}, record = {}".format(je.errMsg, je.errCode, self._merchant.id))
- return "", ""
- desKey, mdKey = result["data"]["desKey"], result["data"]["mdKey"]
- return desKey, mdKey
- def create_product(self):
- if not self._merchant.support_apply():
- logger.error("can not find merchant source info!")
- self._merchant.to_fail(u"不支持开通产品 请联系工作人员协查")
- return
- for _name in self._merchant.products:
- _product = self._merchant.products[_name]
- # 不符合开通产品条件的产品直接跳过
- if not _product.support_apply():
- continue
- # 先将产品的状态切换为等待状态
- _product.to_wait()
- _productInfo = self._merchant.load_product_info(_product)
- try:
- self._client.create_product(**_productInfo)
- except MerchantError as e:
- # 失败的情况下 切换产品状态为失败 切换商户状态为失败 用户重新提交资料 重新建立初始化状态的产品
- _product.to_fail()
- self._merchant.to_fail(e.message)
- class JdOpenMerchantApplier(MerchantApplier):
- def submit(self):
- """
- 新增商户 有可能是新增 或者是修改
- """
- logger.info("[create_customer] duo_la_bao merchant <{}>".format(self._merchant))
- if not self._merchant:
- return
- # 抽取公共信息
- data = {
- "agentNum": self._merchant.agentNum,
- "fullName": self._merchant.fullName,
- "shortName": self._merchant.shortName,
- "industry": self._merchant.industry,
- "province": self._merchant.province,
- "city": self._merchant.city,
- "district": self._merchant.district,
- "customerType": self._merchant.customerType,
- "certificateType": self._merchant.certificateType,
- "certificateCode": self._merchant.legalCardNo,
- "certificateName": self._merchant.legalName,
- "certificateStartDate": self._merchant.legalStart,
- "certificateEndDate": self._merchant.legalEnd if self._merchant.legalEnd != "forever" else "",
- }
- # 根据商户类型的不同 填充不同的信息
- if self._merchant.is_personal:
- data["linkMan"] = self._merchant.legalName
- data["linkPhone"] = self._merchant.phoneNumber
- data["contactPhoneNum"] = self._merchant.phoneNumber
- data["linkManId"] = self._merchant.legalCardNo
- elif self._merchant.is_company:
- data["linkMan"] = self._merchant.contactName
- data["linkPhone"] = self._merchant.phoneNumber
- data["contactPhoneNum"] = self._merchant.phoneNumber
- data["linkManId"] = self._merchant.contactCardNo
- data["postalAddress"] = self._merchant.organizationAddr
- elif self._merchant.is_institution:
- data["linkMan"] = self._merchant.contactName
- data["linkPhone"] = self._merchant.phoneNumber
- data["contactPhoneNum"] = self._merchant.phoneNumber
- data["linkManId"] = self._merchant.contactCardNo
- data["certType"] = self._merchant.certType
- data["certNum"] = self._merchant.certNo
- data["postalAddress"] = self._merchant.certAddr
- else:
- data["linkMan"] = self._merchant.contactName
- data["linkPhone"] = self._merchant.phoneNumber
- data["contactPhoneNum"] = self._merchant.phoneNumber
- data["linkManId"] = self._merchant.contactCardNo
- data["postalAddress"] = self._merchant.organizationAddr
- # 根据是否已经有商户编号 决定是新增还是修改
- try:
- if not self._merchant.customerNum:
- result = self._client.customer.create_customer(**data)
- else:
- result = self._client.customer.modify_customer(customerNum=self._merchant.customerNum, **data)
- except JdOpenException as je:
- logger.error("[create_customer] duo_la_bao merchant <{}> create customer error = {}".format(self._merchant, je))
- self._merchant.to_fail(je.message)
- return
- logger.info("[create_customer] duo_la_bao merchant <{}> create customer success,result = {}".format(self._merchant, result))
- customerNum = result["data"]["customerNum"]
- return self._merchant.to_customer(customerNum)
- def query_audit_result(self):
- pass
- def create_settle(self):
- """
- 创建结算信息
- """
- logger.info("[create_settle] duo_la_bao merchant <{}>".format(self._merchant))
- if not self._merchant:
- return
- data = {
- "customerNum": self._merchant.customerNum,
- "bankAccountName": self._merchant.legalName,
- "bankAccountNum": self._merchant.bankCardNo,
- "province": self._merchant.bankProvince,
- "city": self._merchant.bankCity,
- "bankName": self._merchant.bankName,
- "bankBranchName": self._merchant.bankBranchName,
- "settleAmount": self._merchant.settleAmount,
- "payBankList": [pay.to_dict() for pay in self._merchant.payBankList],
- "accountType": self._merchant.accountType,
- "phone": self._merchant.bankPhone
- }
- if self._merchant.is_personal:
- data["accountType"] = self._merchant.accountType
- data["privateType"] = "PERSON"
- data["settlerCertificateCode"] = self._merchant.legalCardNo
- data["settlerCertificateStartDate"] = self._merchant.legalStart
- data["settlerCertificateEndDate"] = self._merchant.legalEnd if self._merchant.legalEnd != "forever" else ""
- elif self._merchant.is_company:
- data["accountType"] = self._merchant.accountType
- elif self._merchant.is_institution:
- data["accountType"] = self._merchant.accountType
- else:
- data["accountType"] = self._merchant.accountType
- if self._merchant.accountType == JdOpenAccountType.PRIVATE:
- data["privateType"] = "INDIVIDUAL"
- data["settlerCertificateCode"] = self._merchant.legalCardNo
- data["settlerCertificateStartDate"] = self._merchant.legalStart
- data["settlerCertificateEndDate"] = self._merchant.legalEnd if self._merchant.legalEnd != "forever" else ""
- try:
- if not self._merchant.settleNum:
- result = self._client.settle.create_account(**data)
- else:
- result = self._client.settle.modify_account(settleNum=self._merchant.settleNum, **data)
- except JdOpenException as je:
- logger.error("[create_settle] duo_la_bao merchant <{}> create settle error = {}".format(self._merchant, je))
- self._merchant.to_fail(je.message)
- return
- logger.info("[create_settle] duo_la_bao merchant <{}> create settle success, result = {}".format(self._merchant, result))
- settleNum = result["data"]["settleNum"]
- return self._merchant.to_settle(settleNum)
- def create_shop(self):
- logger.info("[create_shop] duo_la_bao merchant <{}>".format(self._merchant))
- if not self._merchant:
- return
- data = {
- "agentNum": self._merchant.agentNum,
- "customerNum": self._merchant.customerNum,
- "shopName": self._merchant.shortName,
- "address": self._merchant.merchantAddr,
- "oneIndustry": self._merchant.industry,
- "twoIndustry": self._merchant.subIndustry,
- "mobilePhone": self._merchant.phoneNumber,
- "mapLng": self._merchant.mapLng,
- "mapLat": self._merchant.mapLat
- }
- # 个人商户的类型暂时定死
- if self._merchant.is_personal:
- data["microBizType"] = "MICRO_TYPE_STORE"
- try:
- if not self._merchant.shopNum:
- result = self._client.shop.create_shop(**data)
- else:
- result = self._client.shop.modify_shop(shopNum=self._merchant.shopNum, **data)
- except JdOpenException as je:
- logger.error("[create_shop] duo_la_bao merchant <{}> create shop error = {}".format(self._merchant, je))
- self._merchant.to_fail(je.message)
- return
- logger.info("[create_shop] duo_la_bao merchant <{}> create shop success, result = {}".format(self._merchant, result))
- shopNum = result["data"]["shopNum"]
- return self._merchant.to_shop(shopNum)
- def upload_attaches(self):
- logger.info("[update_attach] duo_la_bao merchant <{}>".format(self._merchant))
- if not self._merchant:
- return
- # 组件公共组件
- attaches = {
- "CASHIERDESK": self._merchant.shopImgA,
- "SHOP": self._merchant.shopImgB,
- "IDENTITYDOOR": self._merchant.shopImgC,
- "IDENTITYFRONT": self._merchant.legalImgFront,
- "IDENTITYOPPOSITE": self._merchant.legalImgBack
- }
- if self._merchant.is_personal:
- attaches["IDENTIFYHANDHOLD"] = self._merchant.identifyhandhold
- attaches["BANKFRONT"] = self._merchant.bankImg
- elif self._merchant.is_company:
- attaches["PERMIT"] = self._merchant.bankImg
- attaches["LICENCE"] = self._merchant.organizationImg
- attaches["ORGANIZATIONCODE"] = self._merchant.organizationcode
- attaches["TAXREGISTRATION"] = self._merchant.taxregistration
- attaches["UNIFIEDSOCIALCREDITCODE"] = self._merchant.unifiedsocialcreditcode
- elif self._merchant.is_institution:
- attaches["PERMIT"] = self._merchant.bankImg
- attaches["LICENCE"] = self._merchant.certImg
- attaches["TAXREGISTRATION"] = self._merchant.taxregistration
- attaches["ORGANIZATIONCODE"] = self._merchant.organizationcode
- attaches["UNIFIEDSOCIALCREDITCODE"] = self._merchant.unifiedsocialcreditcode
- attaches["CERTIFICATE_FILE"] = self._merchant.certificateFile
- attaches["SPECIAL_QUALIFICATION"] = self._merchant.specialQualification
- else:
- if self._merchant.accountType == JdOpenAccountType.PUBLIC:
- attaches["PERMIT"] = self._merchant.bankImg
- else:
- attaches["BANKFRONT"] = self._merchant.bankImg
- attaches["LICENCE"] = self._merchant.organizationImg
- attaches["ORGANIZATIONCODE"] = self._merchant.organizationcode
- attaches["TAXREGISTRATION"] = self._merchant.taxregistration
- for attachType, img in attaches.items(): # type:(str, Attach)
- data = {
- "customerNum": self._merchant.customerNum,
- "attachType": attachType,
- "content": base64.b64encode(img.content)
- }
- try:
- if not img.attachNum:
- result = self._client.attach.upload_attach(**data)
- else:
- result = self._client.attach.modify_attach(attachNum=img.attachNum, **data)
- attachNum = result["data"]["attachNum"]
- img.upload_success(attachNum)
- except JdOpenException as je:
- logger.error("[update_attach] duo_la_bao merchant <{}> update attach <{}> error = {} ".format(self._merchant, attachType, je))
- self._merchant.to_fail(je.message)
- return
- logger.info("[update_attach] duo_la_bao merchant <{}> update attach <{}> success".format(self._merchant, attachType))
- else:
- return self._merchant.to_attach()
- def complete(self):
- logger.info("[complete_merchant] duo_la_bao merchant <{}>".format(self._merchant))
- if not self._merchant:
- return
- if self._merchant.is_personal:
- data = {
- "customerNum": self._merchant.customerNum
- }
- elif self._merchant.is_company:
- data = {
- "customerNum": self._merchant.customerNum,
- "licenseId": self._merchant.organizationNo,
- "licenseStartTime": self._merchant.organizationStart,
- "licenseEndTime": self._merchant.organizationEnd,
- }
- elif self._merchant.is_institution:
- data = {
- "customerNum": self._merchant.customerNum,
- "licenseId": self._merchant.certNo,
- "licenseStartTime": self._merchant.certStart,
- "licenseEndTime": self._merchant.certEnd,
- }
- else:
- data = {
- "customerNum": self._merchant.customerNum,
- "licenseId": self._merchant.organizationNo,
- "licenseStartTime": self._merchant.organizationStart,
- "licenseEndTime": self._merchant.organizationEnd,
- }
- try:
- result = self._client.complete.complete_customer(**data)
- except JdOpenException as je:
- logger.error("[complete_merchant] duo_la_bao merchant <{}> complete merchant result error = {} ".format(self._merchant, je))
- self._merchant.to_fail(je.message)
- return
- logger.info("[complete_merchant] duo_la_bao merchant <{}> complete merchant success ".format(self._merchant))
- return self._merchant.to_complete()
- def confirm(self):
- logger.info("[confirm_merchant] duo_la_bao merchant <{}>".format(self._merchant))
- if not self._merchant:
- return
- data = {
- "agentNum": self._merchant.agentNum,
- "customerNum": self._merchant.customerNum
- }
- try:
- result = self._client.complete.confirm_customer(**data)
- except JdOpenException as je:
- logger.error("[confirm_merchant] duo_la_bao merchant <{}> confirm merchant result error = {} ".format(self._merchant, je))
- self._merchant.to_fail(je.message)
- return
- logger.info("[confirm_merchant] duo_la_bao merchant <{}> confirm merchant success ".format(self._merchant))
- return self._merchant.to_confirm()
- class MerchantApplyProxy(object):
- def __init__(self, merchant): # type:(Optional[MerchantSourceInfo, JDOpenApplyInfo]) -> None
- self.merchant = merchant
- def submit_data(self):
- """
- 将数据提供到商户方供给审核
- """
- merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
- if not merchant.support_enter():
- logger.error("[MerchantApplyProxy submit_data] not support enter merchant, merchantId = {}".format(self.merchant.id))
- return
- if isinstance(merchant, MerchantSourceInfo):
- applier = JdPsiMerchantApplier(merchant=merchant, client=get_psi_client())
- elif isinstance(merchant, JDOpenApplyInfo):
- applier = JdOpenMerchantApplier(merchant=merchant, client=get_open_client())
- else:
- logger.error("[MerchantApplyProxy submit_data] not support merchant type, merchantId = {}".format(self.merchant.id))
- return
- return applier.submit()
- def query_merchant_audit(self):
- """
- 查询商户的审核状态
- """
- merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
- if not merchant.support_query_audit():
- logger.error("[MerchantApplyProxy query_merchant_audit] not support query audit, merchantId = {}".format(self.merchant.id))
- return
- if isinstance(merchant, MerchantSourceInfo):
- applier = JdPsiMerchantApplier(merchant=merchant, client=get_psi_client())
- elif isinstance(merchant, JDOpenApplyInfo):
- applier = JdOpenMerchantApplier(merchant=merchant, client=get_open_client())
- else:
- logger.error("[MerchantApplyProxy submit_data] not support merchant type, merchantId = {}".format(self.merchant.id))
- return
- # 查询商户的审核状态 如果审核成功 触发 下一步的行为 ()
- return applier.query_audit_result()
- def submit_auth(self):
- """
- 提交 实名信息 分别向支付宝和微信提交
- """
- merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
- if not merchant.support_jdaggre():
- logger.error("[MerchantApplyProxy submit_auth] not support submit auth, merchantId = {}".format(self.merchant.id))
- return
- # 微信没有申请的
- if not merchant.is_wechat_submit:
- self.submit_wechat()
- # 支付宝没有提交申请资料的
- if not merchant.is_ali_submit:
- self.submit_ali()
- # 如果提交都成功了 切换状态
- merchant = self.merchant.reload()
- if all([merchant.is_wechat_submit, merchant.is_ali_submit]):
- merchant.to_auth_wait()
- def query_auth_audit(self):
- """
- 查询实名审核的状态
- """
- wechatResult = self.query_wechat_audit()
- aliResult = self.query_ali_audit()
- if all([wechatResult, aliResult]):
- self.merchant.to_auth_apply_success()
- def submit_wechat(self):
- """
- 提交微信审核资料
- """
- # 重载一次 防止状态变更失败
- merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
- if isinstance(merchant, MerchantSourceInfo):
- merchant = update_channels_info(merchant)
- elif isinstance(merchant, JDOpenApplyInfo):
- openClient = get_open_client()
- merchant = query_sub_merchantId(merchant, openClient)
- else:
- return
- wechatProxy = get_wechat_proxy()
- wxApplier = merchant.wxSource
- if not wxApplier.subMerchantId:
- logger.error("[submit_wechat] ownerId = {} no subMerchantId!".format(merchant.ownerId))
- return
- try:
- result = wechatProxy.submit_merchant(wxApplier)
- except MerchantError:
- logger.error("[submit_wechat] ownerId = {} submit error!".format(merchant.ownerId))
- return
- if "applyment_id" in result:
- applymentId = result["applyment_id"]
- merchant.to_wx_waiting(applymentId=applymentId)
- else:
- merchant.to_fail(result["message"])
- def query_wechat_audit(self):
- """
- 查询微信 的审核
- """
- # 重载一次 防止状态变更失败
- merchant = self.merchant.reload()
- logger.info("[query_wechat_audit] ownerId = {}".format(merchant.ownerId))
- # 获取微信服务商
- wechatProxy = get_wechat_proxy()
- wxApplier = merchant.wxSource
- if not wxApplier.applymentId:
- logger.error("[query_wechat_audit] ownerId = {} not found applymentId".format(merchant.ownerId))
- return
- try:
- result = wechatProxy.get_merchant_audit(wxApplier.applymentId)
- except MerchantError:
- logger.error("[query_wechat_audit] ownerId = {} query error!".format(merchant.ownerId))
- return
- if "applyment_state" not in result:
- return False
- # 审核通过的
- if result["applyment_state"] in [
- "APPLYMENT_STATE_PASSED",
- "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_LEGALPERSON",
- "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_CONTACT"
- ]:
- return True
- # 审核驳回的
- if result["applyment_state"] in ["APPLYMENT_STATE_REJECTED"]:
- merchant.to_fail(u"【审核驳回】 {}:{}".format(result["reject_param"], result["reject_reason"]))
- return False
- def submit_ali(self):
- """
- 提交支付宝的审核资料
- """
- pass
- def query_ali_audit(self):
- """
- 阿里暂时全返回为True
- """
- return True
|