utils.py 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
  1. # coding=utf-8
  2. import datetime
  3. import base64
  4. import json
  5. import logging
  6. import requests
  7. from mongoengine import DoesNotExist
  8. from typing import TYPE_CHECKING, Optional
  9. from apps.web.core.bridge.wechat.v3api import WechatApiProxy
  10. from apps.web.core.exceptions import MerchantError
  11. from apps.web.core.models import WechatServiceProvider, JDAggrePayApp, AliApp
  12. from apps.web.core.utils import async_operation_no_catch
  13. from apps.web.dealer.models import Dealer
  14. from apps.web.merchant.exceptions import JdOpenParamsError
  15. from apps.web.merchant.constant import ProductStatus, MerchantStatus, JdOpenMerchantType, JdOpenAccountType, JdOpenAuditStatus, JdOpenProductType, AuthStatus, ALI_PAY_QR_CODE
  16. from apps.web.merchant.models import MerchantSourceInfo, JDOpenApplyInfo, MerchantAgent
  17. from library.jdopen.constants import OPEN_SECRET_KEY, OPEN_ACCESS_KEY
  18. from library.jdopen.exceptions import JdOpenException
  19. from library.jdopen.client import JdOpenMerchantClient
  20. from library.jdpsi.client import JdPsiMerchantClient
  21. from library.jdpsi.exceptions import JdPsiException
  22. if TYPE_CHECKING:
  23. from apps.web.agent.models import Agent
  24. from apps.web.merchant.models import Attach
  25. logger = logging.getLogger(__name__)
  26. # 信号触发函数
  27. def upload_merchant_to_jd(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
  28. # 先查找到商户
  29. logger.info("[upload_merchant_to_jd] start to upload data to jd merchant, merchantId = {}".format(merchantId))
  30. try:
  31. merchant = sender.objects.get(id=merchantId)
  32. except DoesNotExist:
  33. logger.error("[upload_merchant_to_jd] find merchant error not exist!, merchantId = {}".format(merchantId))
  34. return
  35. proxy = MerchantApplyProxy(merchant)
  36. async_operation_no_catch(proxy.submit_data)
  37. def upload_merchant_to_auth(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
  38. """
  39. 上传商户的实名确认信息 包括支付宝的和微信的
  40. """
  41. logger.info("[upload_merchant_to_auth] start to upload data to wechat, merchantId = {}".format(merchantId))
  42. try:
  43. merchant = sender.objects.get(id=merchantId)
  44. except DoesNotExist:
  45. logger.error("[upload_merchant_to_auth] find merchant error not exist!, merchantId = {}".format(merchantId))
  46. return
  47. # 分别提交支付宝以及微信的实名认证资料
  48. proxy = MerchantApplyProxy(merchant)
  49. async_operation_no_catch(proxy.submit_wechat)
  50. async_operation_no_catch(proxy.submit_ali)
  51. def create_psi_product(sender, merchantId, **kwargs):
  52. logger.info("[create_psi_product] start to create psi merchant product, merchantId = {}".format(merchantId))
  53. try:
  54. merchant = sender.objects.get(id=merchantId)
  55. except DoesNotExist:
  56. logger.error("[create_psi_product] find merchant error not exist!, merchantId = {}".format(merchantId))
  57. return
  58. applier = JdPsiMerchantApplier(merchant, get_psi_client())
  59. async_operation_no_catch(applier.create_product)
  60. def create_settle(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
  61. """
  62. 京东 open 创建商户
  63. """
  64. logger.info("[create_settle] start to create open merchant settle account, merchantId = {}".format(merchantId))
  65. try:
  66. merchant = sender.objects.get(id=merchantId)
  67. except DoesNotExist:
  68. logger.error("[create_settle] find merchant error not exist!, merchantId = {}".format(merchantId))
  69. return
  70. applier = JdOpenMerchantApplier(merchant, get_open_client())
  71. async_operation_no_catch(applier.create_settle)
  72. def create_shop(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
  73. """
  74. 京东 open 创建商店
  75. """
  76. logger.info("[create_shop] start to create open shop, merchantId = {}".format(merchantId))
  77. try:
  78. merchant = sender.objects.get(id=merchantId)
  79. except DoesNotExist:
  80. logger.error("[create_shop] find merchant error not exist!, merchantId = {}".format(merchantId))
  81. return
  82. applier = JdOpenMerchantApplier(merchant, get_open_client())
  83. async_operation_no_catch(applier.create_shop)
  84. def upload_attaches(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
  85. """
  86. 京东 open 上传附件
  87. """
  88. logger.info("[upload_attaches] start to upload open merchant attaches, merchantId = {}".format(merchantId))
  89. try:
  90. merchant = sender.objects.get(id=merchantId)
  91. except DoesNotExist:
  92. logger.error("[upload_attaches] find merchant error not exist!, merchantId = {}".format(merchantId))
  93. return
  94. applier = JdOpenMerchantApplier(merchant, get_open_client())
  95. async_operation_no_catch(applier.upload_attaches)
  96. def complete_customer(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
  97. """
  98. 京东 open 完成报单
  99. """
  100. logger.info("[complete_customer] start to complete open merchant, merchantId = {}".format(merchantId))
  101. try:
  102. merchant = sender.objects.get(id=merchantId)
  103. except DoesNotExist:
  104. logger.error("[complete_customer] find merchant error not exist!, merchantId = {}".format(merchantId))
  105. return
  106. applier = JdOpenMerchantApplier(merchant, get_open_client())
  107. async_operation_no_catch(applier.complete)
  108. def confirm_customer(sender, merchantId, **kwargs): # type: (Optional[MerchantSourceInfo, JDOpenApplyInfo], str, dict) -> None
  109. """
  110. 京东 open 报单确认
  111. """
  112. logger.info("[confirm_customer] start to confirm open merchant, merchantId = {}".format(merchantId))
  113. try:
  114. merchant = sender.objects.get(id=merchantId)
  115. except DoesNotExist:
  116. logger.error("[confirm_customer] find merchant error not exist!, merchantId = {}".format(merchantId))
  117. return
  118. applier = JdOpenMerchantApplier(merchant, get_open_client())
  119. async_operation_no_catch(applier.confirm)
  120. # 功能辅助函数
  121. def get_file(url):
  122. res = requests.get(url)
  123. return res.content
  124. def get_location_by_area(province, city, district, addr, webKey="109f7b4b81698f345f24aa3dc6684924"):
  125. """
  126. 根据地址获取经纬度
  127. """
  128. logger.info("[get_location_by_area] province = {}, city = {}, district = {}, addr = {}".format(province, city, district, addr))
  129. url = "https://restapi.amap.com/v3/geocode/geo?address={}{}{}{}&key={}".format(province, city, district, addr, webKey)
  130. try:
  131. result = requests.get(url).json()
  132. except Exception as e:
  133. logger.error("[get_location_by_area] error = {}, province = {}, city = {}, district = {}, addr = {}".format(e, province, city, district, addr))
  134. return "0.000000", "0.000000"
  135. if "status" not in result or result["status"] != "1":
  136. return "0.000000", "0.000000"
  137. geocode = result["geocodes"][0]
  138. lng, lat = geocode["location"].split(",")
  139. return lng, lat
  140. def get_wechat_proxy():
  141. provider = WechatServiceProvider.objects.get(mchid="398254625") # type: WechatServiceProvider
  142. return WechatApiProxy(provider) # type: WechatApiProxy
  143. def get_open_client():
  144. openClient = JdOpenMerchantClient(OPEN_ACCESS_KEY, OPEN_SECRET_KEY)
  145. return openClient
  146. def get_psi_client():
  147. psiClient = JdPsiMerchantClient()
  148. return psiClient
  149. def get_ali_client():
  150. app = AliApp.objects.get(appid="2021001191645419") # type: AliApp
  151. return app.client
  152. def query_merchant_settle(merchantOwner, st, et): # type: (Dealer, datetime.datetime, datetime.datetime) -> dict
  153. """
  154. 查询商户的结算信息 只查询1天的 (商户拥有者可能是代理商、经销商)
  155. """
  156. merchant = MerchantSourceInfo.get_source_record(merchantOwner) # type: MerchantSourceInfo
  157. if not merchant.merchantNo:
  158. app = merchantOwner.jd_env_pay_app() # type: JDAggrePayApp
  159. agentNo = MerchantAgent.default_merchant_agent
  160. merchantNo = app.merchant_no
  161. else:
  162. agentNo = merchant.agentNo
  163. merchantNo = merchant.merchantNo
  164. startTime = datetime.datetime.strftime(st, "%Y-%m-%d")
  165. endTime = datetime.datetime.strftime(et, "%Y-%m-%d")
  166. psiClient = get_psi_client()
  167. result = psiClient.query_settle(agentNo, startTime, endTime, merchantNo=merchantNo)
  168. return result
  169. def query_sub_merchantId(document, openClient): # type: (Optional[None, JDOpenApplyInfo], JdOpenMerchantClient) -> Optional[None, JDOpenApplyInfo]
  170. """
  171. 查询 jdopen 的子商户编号 (微信 支付宝)
  172. """
  173. # 首先查询 微信的子商编
  174. data = {
  175. "customerNum": document.customerNum,
  176. "payProduct": str(JdOpenProductType.WX.value)
  177. }
  178. try:
  179. result = openClient.support.get_product_customer(**data)
  180. except JdOpenException as je:
  181. logger.error("[query_sub_merchantId] duo_la_bao merchant <{}> query audit result error = {} ".format(document, je))
  182. return
  183. # 获取到了微信的子商编号
  184. for item in result["data"]:
  185. if item["status"] == "OPEN":
  186. subMerchantId = item["subCustomerNum"]
  187. break
  188. else:
  189. subMerchantId = ""
  190. logger.info("[query_sub_merchantId] duo_la_bao merchant <{}> query sub merchantId subMerchantId = {} ".format(document, subMerchantId))
  191. data["payProduct"] = str(JdOpenProductType.ALI.value)
  192. try:
  193. result = openClient.support.get_product_customer(**data)
  194. except JdOpenException as je:
  195. logger.error("[query_sub_merchantId] duo_la_bao merchant <{}> query audit result error = {} ".format(document, je))
  196. return
  197. for item in result["data"]:
  198. if item["status"] == "OPEN":
  199. subAliMerchantId = item["subCustomerNum"]
  200. break
  201. else:
  202. subAliMerchantId = ""
  203. logger.info("[query_sub_merchantId] duo_la_bao merchant <{}> query sub merchantId subAliMerchantId = {} ".format(document, subAliMerchantId))
  204. # 更新商户编号到 文档 然后等待进一步的资料
  205. return document.update_sub_merchant(subMerchantId=subMerchantId, subAliMerchantId=subAliMerchantId)
  206. def get_merchant_by_version(owner, version):
  207. if version == "v2":
  208. return JDOpenApplyInfo.get_merchant_by_owner(owner)
  209. else:
  210. return MerchantSourceInfo.get_source_record(owner)
  211. def update_channels_info(merchant):
  212. """
  213. 获取自研商户的子商编
  214. 新增获取支付宝的子商户编号
  215. """
  216. logger.info("[update_channels_info] ownerId = {}".format(merchant.ownerId))
  217. # 如果存在就不要去获取了
  218. if merchant.wxSource.subMerchantId and merchant.wxSource.subAliMerchantId:
  219. logger.info("[update_channels_info] ownerId = {}, channels has been ready<wechat: {}; ali: {}>".format(
  220. merchant.ownerId, merchant.wxSource.subMerchantId, merchant.wxSource.subAliMerchantId
  221. ))
  222. return merchant
  223. wxApplier = merchant.wxSource
  224. # 首先尝试获取微信子商编号
  225. psiClient = get_psi_client()
  226. result = psiClient.query_sub_channel(merchant.agentNo, merchant.merchantNo)
  227. if "hlbWxSubNoResultInfo" not in result["data"]:
  228. logger.info("[update_channels_info] owner = <{}-{}>, not get subMchId and channelId".format(merchant.ownerRole, merchant.ownerId))
  229. merchant.to_fail(u"渠道编号获取错误")
  230. return merchant.reload()
  231. channelsInfo = json.loads(result["data"]["hlbWxSubNoResultInfo"])
  232. subMchId, channelId = channelsInfo["threePartnerNoData"][0]["threePartnerNo"], channelsInfo["threePartnerNoData"][0]["channelMerchantNo"]
  233. # 获取支付宝的子商户编号
  234. openClient = get_open_client()
  235. result = openClient.support.get_product_customer(merchant.merchantNo, "ALIPAY")
  236. subCustomerNum = merchant.wxSource.subAliMerchantId = result["data"][0]["subCustomerNum"]
  237. # 直接更新渠道编号
  238. wxApplier.update_sub_merchant(subMchId=subMchId, channel=channelId, subCustomerNum=subCustomerNum)
  239. return merchant.reload()
  240. def is_wechat_authorized(merchant):
  241. """
  242. 是否已经通过微信的审核
  243. """
  244. proxy = get_wechat_proxy()
  245. result = proxy.get_merchant_apply_state(merchant.wxSource.subMerchantId)
  246. return result["authorize_state"] == "AUTHORIZE_STATE_AUTHORIZED"
  247. def is_alipay_authorized(merchant):
  248. """
  249. 是否已经通过支付宝的审核 目前没有办法获取到支付宝的实名状态 一律返回True
  250. """
  251. return True
  252. def query_audit_result(document, openClient): # type: (Optional[None, JDOpenApplyInfo], JdOpenMerchantClient) -> Optional[None, JDOpenApplyInfo]
  253. """
  254. 查询报单的结果
  255. """
  256. logger.info("[query_audit_result] duo_la_bao merchant <{}>".format(document))
  257. if not document:
  258. return
  259. data = {
  260. "agentNum": document.agentNum,
  261. "customerNum": document.customerNum
  262. }
  263. try:
  264. result = openClient.audit.get_audit_result(**data)
  265. except JdOpenException as je:
  266. logger.error("[query_audit_result] duo_la_bao merchant <{}> query audit result error = {} ".format(document, je))
  267. return
  268. logger.info("[query_audit_result] duo_la_bao merchant <{}>, result = {}".format(document, result))
  269. declareResult = result["data"]["declareList"][-1]
  270. # 根据京东审核的状态 确定不同的
  271. declareStatus = declareResult["declareStatus"]
  272. if declareStatus == JdOpenAuditStatus.PASS:
  273. logger.info("[query_audit_result] duo_la_bao merchant <{}>, audit pass".format(document))
  274. document.to_success()
  275. elif declareStatus == JdOpenAuditStatus.NOT_PASS:
  276. logger.info("[query_audit_result] duo_la_bao merchant <{}>, audit no pass".format(document))
  277. auditOpinion = declareResult["auditOpinion"]
  278. document.to_fail(auditOpinion)
  279. else:
  280. logger.info("[query_audit_result] duo_la_bao merchant <{}>, audit doing".format(document))
  281. return document
  282. def get_wechat_auth_info(merchant): # type:(Optional[JDOpenApplyInfo, MerchantSourceInfo]) -> dict
  283. """
  284. 获取微信的实名信息
  285. """
  286. data = {
  287. "channel": "wechat",
  288. "status": AuthStatus.AUDIT,
  289. "subMerchantId": "",
  290. "description": ""
  291. }
  292. subMerchantId = merchant.wxSource.subMerchantId
  293. if not subMerchantId:
  294. return data
  295. data.update({"subMerchantId": subMerchantId})
  296. if is_wechat_authorized(merchant):
  297. data["status"] = AuthStatus.AUTHED
  298. return data
  299. applymentId = merchant.wxSource.applymentId
  300. if not applymentId:
  301. return data
  302. wechatProxy = get_wechat_proxy()
  303. result = wechatProxy.get_merchant_audit(merchant.wxSource.applymentId)
  304. if "applyment_state" not in result:
  305. return data
  306. elif result["applyment_state"] in [
  307. "APPLYMENT_STATE_PASSED",
  308. "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_LEGALPERSON",
  309. "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_CONTACT"
  310. ]:
  311. data["status"] = AuthStatus.PASS
  312. data["qrCode"] = "data:image/png;base64,{}".format(result["qrcode_data"])
  313. return data
  314. elif result["applyment_state"] in ["APPLYMENT_STATE_REJECTED"]:
  315. data["status"] = AuthStatus.NO_PASS
  316. data["description"] = u"【审核驳回】{}:{},请联系平台客服处理".format(result["reject_param"], result["reject_reason"])
  317. return data
  318. else:
  319. return data
  320. def get_alipay_auth_info(merchant):
  321. """
  322. 获取支付宝的实名信息
  323. 支付宝的时候一定要兼容之前的版本 之前从来没有获取过支付宝的子商户编号
  324. """
  325. data = {
  326. "channel": "ali",
  327. "status": AuthStatus.AUDIT,
  328. "subMerchantId": "",
  329. "description": ""
  330. }
  331. subMerchantId = merchant.wxSource.subAliMerchantId
  332. if not subMerchantId:
  333. merchant = update_channels_info(merchant)
  334. subMerchantId = merchant.wxSource.subAliMerchantId
  335. if subMerchantId:
  336. data["subMerchantId"] = subMerchantId
  337. data["status"] = AuthStatus.PASS
  338. data["qrCode"] = ALI_PAY_QR_CODE
  339. return data
  340. class QueryMerchant(object):
  341. def __init__(self, merchant): # type:(MerchantSourceInfo) -> None
  342. self._mer = merchant
  343. def do(self):
  344. pass
  345. class JdOpenParamsChecker(object):
  346. def __init__(self, **kwargs):
  347. self.data = {"id": kwargs.pop("id", "")}
  348. self.source = kwargs
  349. @staticmethod
  350. def area_check(area):
  351. return "code" in area and "name" in area
  352. @staticmethod
  353. def date_check(date):
  354. if date == "forever":
  355. return True
  356. try:
  357. datetime.datetime.strptime(date, "%Y-%m-%d")
  358. except ValueError:
  359. return False
  360. return True
  361. def create(self, owner):
  362. # 公共参数的检查
  363. self.common_check()
  364. # 公司商户的参数检查以及 商户创建
  365. if self.data["customerType"] == JdOpenMerchantType.COMPANY:
  366. self.check_company_merchant()
  367. return JDOpenApplyInfo.create_company(owner, **self.data)
  368. # 个人商户的参数检查 商户创建
  369. elif self.data["customerType"] == JdOpenMerchantType.PERSON:
  370. self.check_person_merchant()
  371. return JDOpenApplyInfo.create_personal(owner, **self.data)
  372. # 个体工商户的参数检查 商户创建
  373. elif self.data["customerType"] == JdOpenMerchantType.INDIVIDUALBISS:
  374. self.check_individualbiss_merchant()
  375. return JDOpenApplyInfo.create_individualbiss(owner, **self.data)
  376. # 事业单位的参数检查 商户创建
  377. else:
  378. self.check_institution_merchant()
  379. return JDOpenApplyInfo.create_institution(owner, **self.data)
  380. def common_check(self):
  381. """
  382. 检测商户的基本信息 并将其赋值到data中
  383. """
  384. customerType = self.source.get("customerType")
  385. if customerType not in JdOpenMerchantType.choices():
  386. raise JdOpenParamsError(u"参数错误,商户类型错误")
  387. self.data["customerType"] = customerType
  388. shortName = self.source.get("shortName")
  389. if not shortName:
  390. raise JdOpenParamsError(u"参数错误,缺少商户简称")
  391. self.data["shortName"] = shortName
  392. province = self.source.get("province")
  393. city = self.source.get("city")
  394. district = self.source.get("district")
  395. address = self.source.get("address")
  396. if not all([province, city, district]):
  397. raise JdOpenParamsError(u"参数错误,缺少商户地区信息")
  398. if not self.area_check(province):
  399. raise JdOpenParamsError(u"参数错误,商户地区 省 信息错误")
  400. if not self.area_check(city):
  401. raise JdOpenParamsError(u"参数错误, 商户地区 市 信息错误")
  402. if not self.area_check(district):
  403. raise JdOpenParamsError(u"参数错误,商户地区 区 信息错误")
  404. if not address:
  405. raise JdOpenParamsError(u"参数错误,缺少商户详细地址")
  406. self.data["province"] = province
  407. self.data["city"] = city
  408. self.data["district"] = district
  409. self.data["address"] = address
  410. # 内部补充经纬度
  411. self.data["mapLng"], self.data["mapLat"] = get_location_by_area(province["name"], city["name"], district["name"], address)
  412. def check_person_merchant(self):
  413. """
  414. 创建一条个人商户的记录
  415. """
  416. # 用户填写的个人界面的信息提取
  417. legalImgFront = self.source.get("legalImgFront")
  418. legalImgBack = self.source.get("legalImgBack")
  419. legalImgHold = self.source.get("legalImgHold")
  420. legalName = self.source.get("legalName")
  421. legalCardNo = self.source.get("legalCardNo")
  422. legalStart = self.source.get("legalStart")
  423. legalEnd = self.source.get("legalEnd")
  424. legalForever = self.source.get("legalForever")
  425. if not legalImgFront:
  426. raise JdOpenParamsError(u"参数错误,请上传收款人证件正面照")
  427. if not legalImgBack:
  428. raise JdOpenParamsError(u"参数错误,请上传收款人证件反面照")
  429. if not legalImgHold:
  430. raise JdOpenParamsError(u"参数错误,请上传收款人手持证件照")
  431. if not legalName:
  432. raise JdOpenParamsError(u"参数错误,缺少收款人姓名")
  433. if not legalCardNo:
  434. raise JdOpenParamsError(u"参数错误,缺少收款人证件号码")
  435. if not self.date_check(legalStart) or not self.date_check(legalEnd):
  436. raise JdOpenParamsError(u"参数错误, 收款人证件有效期错误")
  437. self.data["legalImgFront"] = legalImgFront
  438. self.data["legalImgBack"] = legalImgBack
  439. self.data["legalImgHold"] = legalImgHold
  440. self.data["legalName"] = legalName
  441. self.data["legalCardNo"] = legalCardNo
  442. self.data["legalStart"] = legalStart
  443. self.data["legalEnd"] = legalEnd if not legalForever else "forever"
  444. # 用户填写的结算界面的信息提取
  445. accountType = self.source.get("accountType")
  446. bankImg = self.source.get("bankImg")
  447. bankCardNo = self.source.get("bankCardNo")
  448. bankName = self.source.get("bankName")
  449. bankBranchName = self.source.get("bankBranchName")
  450. bankProvince = self.source.get("bankProvince")
  451. bankCity = self.source.get("bankCity")
  452. bankPhone = self.source.get("bankPhone")
  453. if not accountType:
  454. raise JdOpenParamsError(u"参数错误,请选择账户类型")
  455. if not bankImg:
  456. raise JdOpenParamsError(u"参数错误,请上传银行卡图片")
  457. if not bankCardNo:
  458. raise JdOpenParamsError(u"参数错误,缺少银行卡号")
  459. if not bankName:
  460. raise JdOpenParamsError(u"参数错误,缺少银行名称")
  461. if not bankBranchName:
  462. raise JdOpenParamsError(u"参数错误,缺少银行支行名称")
  463. if not all([bankProvince, bankCity]):
  464. raise JdOpenParamsError(u"参数错误,缺少银行地区信息")
  465. if not self.area_check(bankProvince) or not self.area_check(bankCity):
  466. raise JdOpenParamsError(u"参数错误,银行开户地区选择错误")
  467. if not bankPhone:
  468. raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
  469. self.data["accountType"] = accountType
  470. self.data["bankImg"] = bankImg
  471. self.data["bankCardNo"] = bankCardNo
  472. self.data["bankName"] = bankName
  473. self.data["bankBranchName"] = bankBranchName
  474. self.data["bankProvince"] = bankProvince
  475. self.data["bankCity"] = bankCity
  476. self.data["bankPhone"] = bankPhone
  477. # 商店照片的信息的获取
  478. shopImgA = self.source.get("shopImgA")
  479. shopImgB = self.source.get("shopImgB")
  480. shopImgC = self.source.get("shopImgC")
  481. if not all([shopImgA, shopImgB, shopImgC]):
  482. raise JdOpenParamsError(u"参数错误,缺少营业照片")
  483. self.data["shopImgA"] = shopImgA
  484. self.data["shopImgB"] = shopImgB
  485. self.data["shopImgC"] = shopImgC
  486. # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
  487. phoneNumber = self.source.get("phoneNumber")
  488. if not phoneNumber:
  489. raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
  490. self.data["phoneNumber"] = phoneNumber
  491. # 非默认参数的补充
  492. self.data["fullName"] = u"个人_{}".format(self.data["legalName"])
  493. def check_individualbiss_merchant(self):
  494. """
  495. 个体工商户 (简易版的企业商户 区别在于 个体工商户可以对私)
  496. """
  497. # 公司法人的参数校验
  498. legalImgFront = self.source.get("legalImgFront")
  499. legalImgBack = self.source.get("legalImgBack")
  500. legalName = self.source.get("legalName")
  501. legalCardNo = self.source.get("legalCardNo")
  502. legalStart = self.source.get("legalStart")
  503. legalEnd = self.source.get("legalEnd")
  504. legalForever = self.source.get("legalForever")
  505. if not legalImgFront:
  506. raise JdOpenParamsError(u"参数错误,请上传收款人证件正面照")
  507. if not legalImgBack:
  508. raise JdOpenParamsError(u"参数错误,请上传收款人证件反面照")
  509. if not legalName:
  510. raise JdOpenParamsError(u"参数错误,缺少收款人姓名")
  511. if not legalCardNo:
  512. raise JdOpenParamsError(u"参数错误,缺少收款人证件号码")
  513. if not self.date_check(legalStart) or not self.date_check(legalEnd):
  514. raise JdOpenParamsError(u"参数错误, 收款人证件有效期错误")
  515. self.data["legalImgFront"] = legalImgFront
  516. self.data["legalImgBack"] = legalImgBack
  517. self.data["legalName"] = legalName
  518. self.data["legalCardNo"] = legalCardNo
  519. self.data["legalStart"] = legalStart
  520. self.data["legalEnd"] = legalEnd if not legalForever else "forever"
  521. # 联系人信息的填写
  522. contactImgFront = self.source.get("contactImgFront")
  523. contactImgBack = self.source.get("contactImgBack")
  524. contactName = self.source.get("contactName")
  525. contactCardNo = self.source.get("contactCardNo")
  526. contactStart = self.source.get("contactStart")
  527. contactEnd = self.source.get("contactEnd")
  528. contactForever = self.source.get("contactForever")
  529. if not contactImgFront:
  530. raise JdOpenParamsError(u"参数错误,请上传联系人证件正面照")
  531. if not contactImgBack:
  532. raise JdOpenParamsError(u"参数错误,请上传联系人证件反面照")
  533. if not contactName:
  534. raise JdOpenParamsError(u"参数错误,缺少联系人姓名")
  535. if not contactCardNo:
  536. raise JdOpenParamsError(u"参数有误,缺少联系人证件号码")
  537. if not self.date_check(contactStart) or not self.date_check(contactEnd):
  538. raise JdOpenParamsError(u"参数错误, 联系人证件有效期错误")
  539. self.data["contactImgFront"] = contactImgFront
  540. self.data["contactImgBack"] = contactImgBack
  541. self.data["contactName"] = contactName
  542. self.data["contactCardNo"] = legalCardNo
  543. self.data["contactStart"] = contactCardNo
  544. self.data["contactEnd"] = contactEnd if not contactForever else "forever"
  545. # 营业执照的参数校验
  546. organizationImg = self.source.get("organizationImg")
  547. organizationName = self.source.get("organizationName")
  548. organizationNo = self.source.get("organizationNo")
  549. organizationStart = self.source.get("organizationStart")
  550. organizationEnd = self.source.get("organizationEnd")
  551. organizationProvince = self.source.get("organizationProvince")
  552. organizationCity = self.source.get("organizationCity")
  553. organizationDistrict = self.source.get("organizationDistrict")
  554. organizationAddress = self.source.get("organizationAddress")
  555. organizationForever = self.source.get("organizationForever")
  556. if not organizationImg:
  557. raise JdOpenParamsError(u"参数错误,请上传营业执照")
  558. if not organizationName:
  559. raise JdOpenParamsError(u"参数错误,缺少公司名称")
  560. if not organizationNo:
  561. raise JdOpenParamsError(u"参数错误,缺少统一信用码")
  562. if not self.date_check(organizationStart) or not self.date_check(organizationEnd):
  563. raise JdOpenParamsError(u"参数错误, 营业执照有效期填写错误")
  564. if not self.area_check(organizationProvince):
  565. raise JdOpenParamsError(u"参数错误,营业执照 省 信息错误")
  566. if not self.area_check(organizationCity):
  567. raise JdOpenParamsError(u"参数错误,营业执照 市 信息错误")
  568. if not self.area_check(organizationDistrict):
  569. raise JdOpenParamsError(u"参数错误,营业执照 区 信息错误")
  570. if not organizationAddress:
  571. raise JdOpenParamsError(u"参数错误,缺少营业执照详细地址")
  572. self.data["organizationImg"] = organizationImg
  573. self.data["organizationName"] = organizationName
  574. self.data["organizationNo"] = organizationNo
  575. self.data["organizationStart"] = organizationStart
  576. self.data["organizationEnd"] = organizationEnd if not organizationForever else "forever"
  577. self.data["organizationProvince"] = organizationProvince
  578. self.data["organizationCity"] = organizationCity
  579. self.data["organizationDistrict"] = organizationDistrict
  580. self.data["organizationAddress"] = organizationAddress
  581. # 用户填写的结算界面的信息提取
  582. accountType = self.source.get("accountType")
  583. bankImg = self.source.get("bankImg")
  584. bankCardNo = self.source.get("bankCardNo")
  585. bankName = self.source.get("bankName")
  586. bankBranchName = self.source.get("bankBranchName")
  587. bankProvince = self.source.get("bankProvince")
  588. bankCity = self.source.get("bankCity")
  589. bankPhone = self.source.get("bankPhone")
  590. if not accountType:
  591. raise JdOpenParamsError(u"参数错误,请选择账户类型")
  592. if not bankImg:
  593. raise JdOpenParamsError(u"参数错误,请上传开户许可证图片")
  594. if not bankCardNo:
  595. raise JdOpenParamsError(u"参数错误,缺少结算账号")
  596. if not bankName:
  597. raise JdOpenParamsError(u"参数错误,缺少结算银行名称")
  598. if not bankBranchName:
  599. raise JdOpenParamsError(u"参数错误,缺少结算银行支行名称")
  600. if not all([bankProvince, bankCity]):
  601. raise JdOpenParamsError(u"参数错误,缺少结算银行地区信息")
  602. if not self.area_check(bankProvince) or not self.area_check(bankCity):
  603. raise JdOpenParamsError(u"参数错误,结算银行开户地区选择错误")
  604. if not bankPhone:
  605. raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
  606. self.data["accountType"] = accountType
  607. self.data["bankImg"] = bankImg
  608. self.data["bankCardNo"] = bankCardNo
  609. self.data["bankName"] = bankName
  610. self.data["bankBranchName"] = bankBranchName
  611. self.data["bankProvince"] = bankProvince
  612. self.data["bankCity"] = bankCity
  613. self.data["bankPhone"] = bankPhone
  614. # 商店照片的信息的获取
  615. shopImgA = self.source.get("shopImgA")
  616. shopImgB = self.source.get("shopImgB")
  617. shopImgC = self.source.get("shopImgC")
  618. if not all([shopImgA, shopImgB, shopImgC]):
  619. raise JdOpenParamsError(u"参数错误,缺少营业照片")
  620. self.data["shopImgA"] = shopImgA
  621. self.data["shopImgB"] = shopImgB
  622. self.data["shopImgC"] = shopImgC
  623. # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
  624. phoneNumber = self.source.get("phoneNumber")
  625. if not phoneNumber:
  626. raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
  627. self.data["phoneNumber"] = phoneNumber
  628. # 个体工商户的 商户全程为 营业执照名称
  629. self.data["fullName"] = u"{}".format(self.data["organizationName"])
  630. # 个体工商户的 组织机构代码 税务登记证 都是营业执照
  631. self.data["organizationcode"] = self.data["organizationImg"]
  632. self.data["taxregistration"] = self.data["organizationImg"]
  633. # 补充一下经办人的函件
  634. if contactName != legalName or contactCardNo != legalCardNo:
  635. businessAuthorizationLetter = self.source.get("businessAuthorizationLetter")
  636. if not businessAuthorizationLetter:
  637. raise JdOpenParamsError(u"参数错误,缺少业务办理授权函")
  638. else:
  639. self.data["businessAuthorizationLetter"] = businessAuthorizationLetter
  640. else:
  641. self.data["businessAuthorizationLetter"] = ""
  642. def check_company_merchant(self):
  643. """
  644. 创建一条公司商户记录
  645. """
  646. # 公司法人的参数校验
  647. legalImgFront = self.source.get("legalImgFront")
  648. legalImgBack = self.source.get("legalImgBack")
  649. legalName = self.source.get("legalName")
  650. legalCardNo = self.source.get("legalCardNo")
  651. legalStart = self.source.get("legalStart")
  652. legalEnd = self.source.get("legalEnd")
  653. legalForever = self.source.get("legalForever")
  654. legalProvince = self.source.get("legalProvince")
  655. legalCity = self.source.get("legalCity")
  656. legalDistrict = self.source.get("legalDistrict")
  657. legalAddress = self.source.get("legalAddress")
  658. if not legalImgFront:
  659. raise JdOpenParamsError(u"参数错误,请上传法人证件正面照")
  660. if not legalImgBack:
  661. raise JdOpenParamsError(u"参数错误,请上传法人证件反面照")
  662. if not legalName:
  663. raise JdOpenParamsError(u"参数错误,缺少法人姓名")
  664. if not legalCardNo:
  665. raise JdOpenParamsError(u"参数错误,缺少法人证件号码")
  666. if not self.date_check(legalStart) or not self.date_check(legalEnd):
  667. raise JdOpenParamsError(u"参数错误, 法人证件有效期错误")
  668. if not all([legalProvince, legalCity, legalDistrict]):
  669. raise JdOpenParamsError(u"参数错误,缺少法人地区信息")
  670. if not self.area_check(legalProvince):
  671. raise JdOpenParamsError(u"参数错误,法人地区 省 信息错误")
  672. if not self.area_check(legalCity):
  673. raise JdOpenParamsError(u"参数错误, 法人地区 市 信息错误")
  674. if not self.area_check(legalDistrict):
  675. raise JdOpenParamsError(u"参数错误,法人地区 区 信息错误")
  676. if not legalAddress:
  677. raise JdOpenParamsError(u"参数错误,缺少商户详细地址")
  678. self.data["legalImgFront"] = legalImgFront
  679. self.data["legalImgBack"] = legalImgBack
  680. self.data["legalName"] = legalName
  681. self.data["legalCardNo"] = legalCardNo
  682. self.data["legalStart"] = legalStart
  683. self.data["legalEnd"] = legalEnd if not legalForever else "forever"
  684. self.data["legalProvince"] = legalProvince
  685. self.data["legalCity"] = legalCity
  686. self.data["legalDistrict"] = legalDistrict
  687. self.data["legalAddress"] = legalAddress
  688. # 联系人信息的填写
  689. contactImgFront = self.source.get("contactImgFront")
  690. contactImgBack = self.source.get("contactImgBack")
  691. contactName = self.source.get("contactName")
  692. contactCardNo = self.source.get("contactCardNo")
  693. contactStart = self.source.get("contactStart")
  694. contactEnd = self.source.get("contactEnd")
  695. contactForever = self.source.get("contactForever")
  696. if not contactImgFront:
  697. raise JdOpenParamsError(u"参数错误,请上传联系人证件正面照")
  698. if not contactImgBack:
  699. raise JdOpenParamsError(u"参数错误,请上传联系人证件反面照")
  700. if not contactName:
  701. raise JdOpenParamsError(u"参数错误,缺少联系人姓名")
  702. if not contactCardNo:
  703. raise JdOpenParamsError(u"参数有误,缺少联系人证件号码")
  704. if not self.date_check(contactStart) or not self.date_check(contactEnd):
  705. raise JdOpenParamsError(u"参数错误, 联系人证件有效期错误")
  706. self.data["contactImgFront"] = contactImgFront
  707. self.data["contactImgBack"] = contactImgBack
  708. self.data["contactName"] = contactName
  709. self.data["contactCardNo"] = legalCardNo
  710. self.data["contactStart"] = contactCardNo
  711. self.data["contactEnd"] = contactEnd if not contactForever else "forever"
  712. # 营业执照的参数校验
  713. organizationImg = self.source.get("organizationImg")
  714. organizationName = self.source.get("organizationName")
  715. organizationNo = self.source.get("organizationNo")
  716. organizationStart = self.source.get("organizationStart")
  717. organizationEnd = self.source.get("organizationEnd")
  718. organizationProvince = self.source.get("organizationProvince")
  719. organizationCity = self.source.get("organizationCity")
  720. organizationDistrict = self.source.get("organizationDistrict")
  721. organizationAddress = self.source.get("organizationAddress")
  722. organizationForever = self.source.get("organizationForever")
  723. if not organizationImg:
  724. raise JdOpenParamsError(u"参数错误,请上传营业执照")
  725. if not organizationName:
  726. raise JdOpenParamsError(u"参数错误,缺少公司名称")
  727. if not organizationNo:
  728. raise JdOpenParamsError(u"参数错误,缺少统一信用码")
  729. if not self.date_check(organizationStart) or not self.date_check(organizationEnd):
  730. raise JdOpenParamsError(u"参数错误, 营业执照有效期填写错误")
  731. if not self.area_check(organizationProvince):
  732. raise JdOpenParamsError(u"参数错误,营业执照 省 信息错误")
  733. if not self.area_check(organizationCity):
  734. raise JdOpenParamsError(u"参数错误,营业执照 市 信息错误")
  735. if not self.area_check(organizationDistrict):
  736. raise JdOpenParamsError(u"参数错误,营业执照 区 信息错误")
  737. if not organizationAddress:
  738. raise JdOpenParamsError(u"参数错误,缺少营业执照详细地址")
  739. self.data["organizationImg"] = organizationImg
  740. self.data["organizationName"] = organizationName
  741. self.data["organizationNo"] = organizationNo
  742. self.data["organizationStart"] = organizationStart
  743. self.data["organizationEnd"] = organizationEnd if not organizationForever else "forever"
  744. self.data["organizationProvince"] = organizationProvince
  745. self.data["organizationCity"] = organizationCity
  746. self.data["organizationDistrict"] = organizationDistrict
  747. self.data["organizationAddress"] = organizationAddress
  748. # 用户填写的结算界面的信息提取
  749. accountType = self.source.get("accountType")
  750. bankImg = self.source.get("bankImg")
  751. bankCardNo = self.source.get("bankCardNo")
  752. bankName = self.source.get("bankName")
  753. bankBranchName = self.source.get("bankBranchName")
  754. bankProvince = self.source.get("bankProvince")
  755. bankCity = self.source.get("bankCity")
  756. bankPhone = self.source.get("bankPhone")
  757. if not accountType:
  758. raise JdOpenParamsError(u"参数错误,请选择账户类型")
  759. if not bankImg:
  760. raise JdOpenParamsError(u"参数错误,请上传开户许可证图片")
  761. if not bankCardNo:
  762. raise JdOpenParamsError(u"参数错误,缺少结算账号")
  763. if not bankName:
  764. raise JdOpenParamsError(u"参数错误,缺少结算银行名称")
  765. if not bankBranchName:
  766. raise JdOpenParamsError(u"参数错误,缺少结算银行支行名称")
  767. if not all([bankProvince, bankCity]):
  768. raise JdOpenParamsError(u"参数错误,缺少结算银行地区信息")
  769. if not self.area_check(bankProvince) or not self.area_check(bankCity):
  770. raise JdOpenParamsError(u"参数错误,结算银行开户地区选择错误")
  771. if not bankPhone:
  772. raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
  773. self.data["accountType"] = accountType
  774. self.data["bankImg"] = bankImg
  775. self.data["bankCardNo"] = bankCardNo
  776. self.data["bankName"] = bankName
  777. self.data["bankBranchName"] = bankBranchName
  778. self.data["bankProvince"] = bankProvince
  779. self.data["bankCity"] = bankCity
  780. self.data["bankPhone"] = bankPhone
  781. # 商店照片的信息的获取
  782. shopImgA = self.source.get("shopImgA")
  783. shopImgB = self.source.get("shopImgB")
  784. shopImgC = self.source.get("shopImgC")
  785. if not all([shopImgA, shopImgB, shopImgC]):
  786. raise JdOpenParamsError(u"参数错误,缺少营业照片")
  787. self.data["shopImgA"] = shopImgA
  788. self.data["shopImgB"] = shopImgB
  789. self.data["shopImgC"] = shopImgC
  790. # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
  791. phoneNumber = self.source.get("phoneNumber")
  792. if not phoneNumber:
  793. raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
  794. self.data["phoneNumber"] = phoneNumber
  795. # 企业商户的商户全称 为公司名称
  796. self.data["fullName"] = u"{}".format(self.data["organizationName"])
  797. # 企业商户的 组织机构代码 税务登记证 统一社会信用代码 都是营业执照
  798. self.data["organizationcode"] = self.data["organizationImg"]
  799. self.data["taxregistration"] = self.data["organizationImg"]
  800. self.data["unifiedsocialcreditcode"] = self.data["organizationImg"]
  801. # 补充一下经办人的函件
  802. if contactName != legalName or contactCardNo != legalCardNo:
  803. businessAuthorizationLetter = self.source.get("businessAuthorizationLetter")
  804. if not businessAuthorizationLetter:
  805. raise JdOpenParamsError(u"参数错误,缺少业务办理授权函")
  806. else:
  807. self.data["businessAuthorizationLetter"] = businessAuthorizationLetter
  808. else:
  809. self.data["businessAuthorizationLetter"] = ""
  810. def check_institution_merchant(self):
  811. """"""
  812. legalImgFront = self.source.get("legalImgFront")
  813. legalImgBack = self.source.get("legalImgBack")
  814. legalName = self.source.get("legalName")
  815. legalCardNo = self.source.get("legalCardNo")
  816. legalStart = self.source.get("legalStart")
  817. legalEnd = self.source.get("legalEnd")
  818. legalForever = self.source.get("legalForever")
  819. if not legalImgFront:
  820. raise JdOpenParamsError(u"参数错误,请上传法人证件正面照")
  821. if not legalImgBack:
  822. raise JdOpenParamsError(u"参数错误,请上传法人证件反面照")
  823. if not legalName:
  824. raise JdOpenParamsError(u"参数错误,缺少法人姓名")
  825. if not legalCardNo:
  826. raise JdOpenParamsError(u"参数错误,缺少法人证件号码")
  827. if not self.date_check(legalStart) or not self.date_check(legalEnd):
  828. raise JdOpenParamsError(u"参数错误, 法人证件有效期错误")
  829. self.data["legalImgFront"] = legalImgFront
  830. self.data["legalImgBack"] = legalImgBack
  831. self.data["legalName"] = legalName
  832. self.data["legalCardNo"] = legalCardNo
  833. self.data["legalStart"] = legalStart
  834. self.data["legalEnd"] = legalEnd if not legalForever else "forever"
  835. # 联系人信息的填写
  836. contactImgFront = self.source.get("contactImgFront")
  837. contactImgBack = self.source.get("contactImgBack")
  838. contactName = self.source.get("contactName")
  839. contactCardNo = self.source.get("contactCardNo")
  840. contactStart = self.source.get("contactStart")
  841. contactEnd = self.source.get("contactEnd")
  842. contactForever = self.source.get("contactForever")
  843. if not contactImgFront:
  844. raise JdOpenParamsError(u"参数错误,请上传联系人证件正面照")
  845. if not contactImgBack:
  846. raise JdOpenParamsError(u"参数错误,请上传联系人证件反面照")
  847. if not contactName:
  848. raise JdOpenParamsError(u"参数错误,缺少联系人姓名")
  849. if not contactCardNo:
  850. raise JdOpenParamsError(u"参数有误,缺少联系人证件号码")
  851. if not self.date_check(contactStart) or not self.date_check(contactEnd):
  852. raise JdOpenParamsError(u"参数错误, 联系人证件有效期错误")
  853. self.data["contactImgFront"] = contactImgFront
  854. self.data["contactImgBack"] = contactImgBack
  855. self.data["contactName"] = contactName
  856. self.data["contactCardNo"] = legalCardNo
  857. self.data["contactStart"] = contactCardNo
  858. self.data["contactEnd"] = contactEnd if not contactForever else "forever"
  859. # 营业执照的参数校验
  860. certType = self.source.get("certType")
  861. certImg = self.source.get("certImg")
  862. certName = self.source.get("certName")
  863. certNo = self.source.get("certNo")
  864. certStart = self.source.get("certStart")
  865. certEnd = self.source.get("certEnd")
  866. certProvince = self.source.get("certProvince")
  867. certCity = self.source.get("certCity")
  868. certDistrict = self.source.get("certDistrict")
  869. certAddress = self.source.get("certAddress")
  870. certForever = self.source.get("certForever")
  871. if not certType:
  872. raise JdOpenParamsError(u"参数错误")
  873. if not certImg:
  874. raise JdOpenParamsError(u"参数错误,请上传证书照片")
  875. if not certName:
  876. raise JdOpenParamsError(u"参数错误,缺少组织机构名称")
  877. if not certNo:
  878. raise JdOpenParamsError(u"参数错误,缺少组织机构码")
  879. if not self.date_check(certStart) or not self.date_check(certEnd):
  880. raise JdOpenParamsError(u"参数错误, 证书有效期填写错误")
  881. if not self.area_check(certProvince):
  882. raise JdOpenParamsError(u"参数错误,证书地区 省 信息错误")
  883. if not self.area_check(certCity):
  884. raise JdOpenParamsError(u"参数错误,证书地区 市 信息错误")
  885. if not self.area_check(certDistrict):
  886. raise JdOpenParamsError(u"参数错误,证书地区 区 信息错误")
  887. if not certAddress:
  888. raise JdOpenParamsError(u"参数错误,缺少证书详细地址")
  889. self.data["certType"] = certType
  890. self.data["certImg"] = certImg
  891. self.data["certName"] = certName
  892. self.data["certNo"] = certNo
  893. self.data["certStart"] = certStart
  894. self.data["certEnd"] = certEnd if not certForever else "forever"
  895. self.data["certProvince"] = certProvince
  896. self.data["certCity"] = certCity
  897. self.data["certDistrict"] = certDistrict
  898. self.data["certAddress"] = certAddress
  899. # 用户填写的结算界面的信息提取
  900. accountType = self.source.get("accountType")
  901. bankImg = self.source.get("bankImg")
  902. bankCardNo = self.source.get("bankCardNo")
  903. bankName = self.source.get("bankName")
  904. bankBranchName = self.source.get("bankBranchName")
  905. bankProvince = self.source.get("bankProvince")
  906. bankCity = self.source.get("bankCity")
  907. bankPhone = self.source.get("bankPhone")
  908. if not accountType:
  909. raise JdOpenParamsError(u"参数错误,请选择账户类型")
  910. if not bankImg:
  911. raise JdOpenParamsError(u"参数错误,请上传开户许可证图片")
  912. if not bankCardNo:
  913. raise JdOpenParamsError(u"参数错误,缺少结算账号")
  914. if not bankName:
  915. raise JdOpenParamsError(u"参数错误,缺少结算银行名称")
  916. if not bankBranchName:
  917. raise JdOpenParamsError(u"参数错误,缺少结算银行支行名称")
  918. if not all([bankProvince, bankCity]):
  919. raise JdOpenParamsError(u"参数错误,缺少结算银行地区信息")
  920. if not self.area_check(bankProvince) or not self.area_check(bankCity):
  921. raise JdOpenParamsError(u"参数错误,结算银行开户地区选择错误")
  922. if not bankPhone:
  923. raise JdOpenParamsError(u"参数错误,缺少银行卡预留手机号码")
  924. self.data["accountType"] = accountType
  925. self.data["bankImg"] = bankImg
  926. self.data["bankCardNo"] = bankCardNo
  927. self.data["bankName"] = bankName
  928. self.data["bankBranchName"] = bankBranchName
  929. self.data["bankProvince"] = bankProvince
  930. self.data["bankCity"] = bankCity
  931. self.data["bankPhone"] = bankPhone
  932. # 商店照片的信息的获取
  933. shopImgA = self.source.get("shopImgA")
  934. shopImgB = self.source.get("shopImgB")
  935. shopImgC = self.source.get("shopImgC")
  936. if not all([shopImgA, shopImgB, shopImgC]):
  937. raise JdOpenParamsError(u"参数错误,缺少营业照片")
  938. self.data["shopImgA"] = shopImgA
  939. self.data["shopImgB"] = shopImgB
  940. self.data["shopImgC"] = shopImgC
  941. # 联系人手机号码获取 这个字段的位置不固定 如果是个人 跟随法人信息确认 其余均在联系人地方
  942. phoneNumber = self.source.get("phoneNumber")
  943. if not phoneNumber:
  944. raise JdOpenParamsError(u"参数错误,缺少联系人手机号码")
  945. self.data["phoneNumber"] = phoneNumber
  946. # 资质信息检查
  947. certificateFile = self.source.get("certificateFile")
  948. specialQualification = self.source.get("specialQualification")
  949. if not certificateFile:
  950. raise JdOpenParamsError(u"参数错误,请上传单位证明函")
  951. if not specialQualification:
  952. raise JdOpenParamsError(u"参数错误,请上传特殊资质证书")
  953. self.data["certificateFile"] = certificateFile
  954. self.data["specialQualification"] = specialQualification
  955. # 非默认参数的补充
  956. self.data["fullName"] = u"{}".format(self.data["certName"])
  957. # 事业单位的 组织机构代码、税务登记证、统一社会信用代码 就是营业执照(证书)
  958. self.data["organizationcode"] = self.data["certImg"]
  959. self.data["taxregistration"] = self.data["certImg"]
  960. self.data["unifiedsocialcreditcode"] = self.data["certImg"]
  961. # 补充一下经办人的函件
  962. if contactName != legalName or contactCardNo != legalCardNo:
  963. businessAuthorizationLetter = self.source.get("businessAuthorizationLetter")
  964. if not businessAuthorizationLetter:
  965. raise JdOpenParamsError(u"参数错误,缺少业务办理授权函")
  966. else:
  967. self.data["businessAuthorizationLetter"] = businessAuthorizationLetter
  968. else:
  969. self.data["businessAuthorizationLetter"] = ""
  970. class MerchantApplier(object):
  971. """
  972. 商户申请
  973. 负责维持状态到商户申请完成 包含递交商户资料 对商户申请状态轮询
  974. 不负责实名 的任何任务 将实名与商户进行解耦
  975. 各自商户申请完成各自实现函数
  976. """
  977. def __init__(self, merchant, client): # type:(Optional[JDOpenApplyInfo, MerchantSourceInfo], Optional[JdPsiMerchantClient, JdOpenMerchantClient]) -> None
  978. self._merchant = merchant
  979. self._client = client
  980. def submit(self):
  981. pass
  982. def query_audit_result(self):
  983. pass
  984. class JdPsiMerchantApplier(MerchantApplier):
  985. def submit(self):
  986. """
  987. 创建商户
  988. """
  989. logger.info("[create_customer] psi merchant <{}>".format(self._merchant))
  990. if not self._merchant:
  991. return
  992. data = {"agentNo": self._merchant.agentNo}
  993. data.update(self._merchant.load_enter_image_info())
  994. data.update(self._merchant.load_enter_entity_info())
  995. try:
  996. result = self._client.create_customer(**data)
  997. except JdPsiException as je:
  998. self._merchant.to_fail(je.errMsg)
  999. return
  1000. merchantNo = result.get("merchantNo")
  1001. serialNo = result["data"]["serialNo"]
  1002. self._merchant.enter_success(merchantNo, serialNo)
  1003. def query_audit_result(self):
  1004. """
  1005. 查询产品的开通状态 产品开通成功的情况下 进行秘钥查询
  1006. """
  1007. logger.info("[query_audit_result] query ownerId = {}".format(self._merchant.ownerId))
  1008. if self._merchant.merchantStatus != int(MerchantStatus.WAITING):
  1009. return
  1010. # 将产品码和产品建立关系 方便后续处理
  1011. productMap = {
  1012. self._merchant.products[_name].productId: self._merchant.products[_name]
  1013. for _name in self._merchant.products
  1014. }
  1015. # 发送查询的申请
  1016. try:
  1017. queryInfo = self._merchant.load_query_info()
  1018. result = self._client.query_product(self._merchant.agentNo, **queryInfo)
  1019. except JdPsiException as je:
  1020. # 此处不需要切换失败的状态 等待下一次的轮询即可
  1021. logger.error("query error!, record is <{}>, code = {}, error = {}".format(self._merchant.id, je.errCode, je.errMsg))
  1022. return
  1023. # 解析查询的结果
  1024. products = result["dataList"]
  1025. errorMsg = ""
  1026. # 对每一个返回的产品信息进行轮询
  1027. for _item in products:
  1028. _productId = _item["productNo"]
  1029. _product = productMap[_productId]
  1030. status = _item.get("status")
  1031. if int(status) == ProductStatus.FAIL:
  1032. logger.error("product fail, record is <{}>, product is <{}>".format(self._merchant.id, _product.productId))
  1033. errorMsg = _item.get("resultMsg", "")
  1034. _product.to_fail()
  1035. elif int(status) == ProductStatus.SUCCESS or int(status) == ProductStatus.CONFIRM:
  1036. logger.info("product success, record is <{}>, product is <{}>".format(self._merchant.id, _product.productId))
  1037. _product.to_success()
  1038. else:
  1039. logger.info("product waiting, record is <{}>, product is <{}>".format(self._merchant.id, _product.productId))
  1040. # 商户重载一次 获取真实的产品开通状态
  1041. merchant = self._merchant.reload()
  1042. if merchant.is_product_fail():
  1043. return merchant.to_fail(errorMsg)
  1044. # 如果产品没有完全开通成功 直接退出 等待下一次的轮询
  1045. if not merchant.is_product_success():
  1046. return
  1047. desKey, mdKey = self.query_secret()
  1048. merchant.to_confirm(desKey=desKey, mdKey=mdKey)
  1049. def query_secret(self):
  1050. """
  1051. 查询秘钥
  1052. """
  1053. try:
  1054. queryInfo = self._merchant.load_query_info()
  1055. result = self._client.query_secret_key(self._merchant.agentNo, **queryInfo)
  1056. except JdPsiException as je:
  1057. logger.error("[query_secret] query secret error = {}, code = {}, record = {}".format(je.errMsg, je.errCode, self._merchant.id))
  1058. return "", ""
  1059. desKey, mdKey = result["data"]["desKey"], result["data"]["mdKey"]
  1060. return desKey, mdKey
  1061. def create_product(self):
  1062. if not self._merchant.support_apply():
  1063. logger.error("can not find merchant source info!")
  1064. self._merchant.to_fail(u"不支持开通产品 请联系工作人员协查")
  1065. return
  1066. for _name in self._merchant.products:
  1067. _product = self._merchant.products[_name]
  1068. # 不符合开通产品条件的产品直接跳过
  1069. if not _product.support_apply():
  1070. continue
  1071. # 先将产品的状态切换为等待状态
  1072. _product.to_wait()
  1073. _productInfo = self._merchant.load_product_info(_product)
  1074. try:
  1075. self._client.create_product(**_productInfo)
  1076. except MerchantError as e:
  1077. # 失败的情况下 切换产品状态为失败 切换商户状态为失败 用户重新提交资料 重新建立初始化状态的产品
  1078. _product.to_fail()
  1079. self._merchant.to_fail(e.message)
  1080. class JdOpenMerchantApplier(MerchantApplier):
  1081. def submit(self):
  1082. """
  1083. 新增商户 有可能是新增 或者是修改
  1084. """
  1085. logger.info("[create_customer] duo_la_bao merchant <{}>".format(self._merchant))
  1086. if not self._merchant:
  1087. return
  1088. # 抽取公共信息
  1089. data = {
  1090. "agentNum": self._merchant.agentNum,
  1091. "fullName": self._merchant.fullName,
  1092. "shortName": self._merchant.shortName,
  1093. "industry": self._merchant.industry,
  1094. "province": self._merchant.province,
  1095. "city": self._merchant.city,
  1096. "district": self._merchant.district,
  1097. "customerType": self._merchant.customerType,
  1098. "certificateType": self._merchant.certificateType,
  1099. "certificateCode": self._merchant.legalCardNo,
  1100. "certificateName": self._merchant.legalName,
  1101. "certificateStartDate": self._merchant.legalStart,
  1102. "certificateEndDate": self._merchant.legalEnd if self._merchant.legalEnd != "forever" else "",
  1103. }
  1104. # 根据商户类型的不同 填充不同的信息
  1105. if self._merchant.is_personal:
  1106. data["linkMan"] = self._merchant.legalName
  1107. data["linkPhone"] = self._merchant.phoneNumber
  1108. data["contactPhoneNum"] = self._merchant.phoneNumber
  1109. data["linkManId"] = self._merchant.legalCardNo
  1110. elif self._merchant.is_company:
  1111. data["linkMan"] = self._merchant.contactName
  1112. data["linkPhone"] = self._merchant.phoneNumber
  1113. data["contactPhoneNum"] = self._merchant.phoneNumber
  1114. data["linkManId"] = self._merchant.contactCardNo
  1115. data["postalAddress"] = self._merchant.organizationAddr
  1116. elif self._merchant.is_institution:
  1117. data["linkMan"] = self._merchant.contactName
  1118. data["linkPhone"] = self._merchant.phoneNumber
  1119. data["contactPhoneNum"] = self._merchant.phoneNumber
  1120. data["linkManId"] = self._merchant.contactCardNo
  1121. data["certType"] = self._merchant.certType
  1122. data["certNum"] = self._merchant.certNo
  1123. data["postalAddress"] = self._merchant.certAddr
  1124. else:
  1125. data["linkMan"] = self._merchant.contactName
  1126. data["linkPhone"] = self._merchant.phoneNumber
  1127. data["contactPhoneNum"] = self._merchant.phoneNumber
  1128. data["linkManId"] = self._merchant.contactCardNo
  1129. data["postalAddress"] = self._merchant.organizationAddr
  1130. # 根据是否已经有商户编号 决定是新增还是修改
  1131. try:
  1132. if not self._merchant.customerNum:
  1133. result = self._client.customer.create_customer(**data)
  1134. else:
  1135. result = self._client.customer.modify_customer(customerNum=self._merchant.customerNum, **data)
  1136. except JdOpenException as je:
  1137. logger.error("[create_customer] duo_la_bao merchant <{}> create customer error = {}".format(self._merchant, je))
  1138. self._merchant.to_fail(je.message)
  1139. return
  1140. logger.info("[create_customer] duo_la_bao merchant <{}> create customer success,result = {}".format(self._merchant, result))
  1141. customerNum = result["data"]["customerNum"]
  1142. return self._merchant.to_customer(customerNum)
  1143. def query_audit_result(self):
  1144. pass
  1145. def create_settle(self):
  1146. """
  1147. 创建结算信息
  1148. """
  1149. logger.info("[create_settle] duo_la_bao merchant <{}>".format(self._merchant))
  1150. if not self._merchant:
  1151. return
  1152. data = {
  1153. "customerNum": self._merchant.customerNum,
  1154. "bankAccountName": self._merchant.legalName,
  1155. "bankAccountNum": self._merchant.bankCardNo,
  1156. "province": self._merchant.bankProvince,
  1157. "city": self._merchant.bankCity,
  1158. "bankName": self._merchant.bankName,
  1159. "bankBranchName": self._merchant.bankBranchName,
  1160. "settleAmount": self._merchant.settleAmount,
  1161. "payBankList": [pay.to_dict() for pay in self._merchant.payBankList],
  1162. "accountType": self._merchant.accountType,
  1163. "phone": self._merchant.bankPhone
  1164. }
  1165. if self._merchant.is_personal:
  1166. data["accountType"] = self._merchant.accountType
  1167. data["privateType"] = "PERSON"
  1168. data["settlerCertificateCode"] = self._merchant.legalCardNo
  1169. data["settlerCertificateStartDate"] = self._merchant.legalStart
  1170. data["settlerCertificateEndDate"] = self._merchant.legalEnd if self._merchant.legalEnd != "forever" else ""
  1171. elif self._merchant.is_company:
  1172. data["accountType"] = self._merchant.accountType
  1173. elif self._merchant.is_institution:
  1174. data["accountType"] = self._merchant.accountType
  1175. else:
  1176. data["accountType"] = self._merchant.accountType
  1177. if self._merchant.accountType == JdOpenAccountType.PRIVATE:
  1178. data["privateType"] = "INDIVIDUAL"
  1179. data["settlerCertificateCode"] = self._merchant.legalCardNo
  1180. data["settlerCertificateStartDate"] = self._merchant.legalStart
  1181. data["settlerCertificateEndDate"] = self._merchant.legalEnd if self._merchant.legalEnd != "forever" else ""
  1182. try:
  1183. if not self._merchant.settleNum:
  1184. result = self._client.settle.create_account(**data)
  1185. else:
  1186. result = self._client.settle.modify_account(settleNum=self._merchant.settleNum, **data)
  1187. except JdOpenException as je:
  1188. logger.error("[create_settle] duo_la_bao merchant <{}> create settle error = {}".format(self._merchant, je))
  1189. self._merchant.to_fail(je.message)
  1190. return
  1191. logger.info("[create_settle] duo_la_bao merchant <{}> create settle success, result = {}".format(self._merchant, result))
  1192. settleNum = result["data"]["settleNum"]
  1193. return self._merchant.to_settle(settleNum)
  1194. def create_shop(self):
  1195. logger.info("[create_shop] duo_la_bao merchant <{}>".format(self._merchant))
  1196. if not self._merchant:
  1197. return
  1198. data = {
  1199. "agentNum": self._merchant.agentNum,
  1200. "customerNum": self._merchant.customerNum,
  1201. "shopName": self._merchant.shortName,
  1202. "address": self._merchant.merchantAddr,
  1203. "oneIndustry": self._merchant.industry,
  1204. "twoIndustry": self._merchant.subIndustry,
  1205. "mobilePhone": self._merchant.phoneNumber,
  1206. "mapLng": self._merchant.mapLng,
  1207. "mapLat": self._merchant.mapLat
  1208. }
  1209. # 个人商户的类型暂时定死
  1210. if self._merchant.is_personal:
  1211. data["microBizType"] = "MICRO_TYPE_STORE"
  1212. try:
  1213. if not self._merchant.shopNum:
  1214. result = self._client.shop.create_shop(**data)
  1215. else:
  1216. result = self._client.shop.modify_shop(shopNum=self._merchant.shopNum, **data)
  1217. except JdOpenException as je:
  1218. logger.error("[create_shop] duo_la_bao merchant <{}> create shop error = {}".format(self._merchant, je))
  1219. self._merchant.to_fail(je.message)
  1220. return
  1221. logger.info("[create_shop] duo_la_bao merchant <{}> create shop success, result = {}".format(self._merchant, result))
  1222. shopNum = result["data"]["shopNum"]
  1223. return self._merchant.to_shop(shopNum)
  1224. def upload_attaches(self):
  1225. logger.info("[update_attach] duo_la_bao merchant <{}>".format(self._merchant))
  1226. if not self._merchant:
  1227. return
  1228. # 组件公共组件
  1229. attaches = {
  1230. "CASHIERDESK": self._merchant.shopImgA,
  1231. "SHOP": self._merchant.shopImgB,
  1232. "IDENTITYDOOR": self._merchant.shopImgC,
  1233. "IDENTITYFRONT": self._merchant.legalImgFront,
  1234. "IDENTITYOPPOSITE": self._merchant.legalImgBack
  1235. }
  1236. if self._merchant.is_personal:
  1237. attaches["IDENTIFYHANDHOLD"] = self._merchant.identifyhandhold
  1238. attaches["BANKFRONT"] = self._merchant.bankImg
  1239. elif self._merchant.is_company:
  1240. attaches["PERMIT"] = self._merchant.bankImg
  1241. attaches["LICENCE"] = self._merchant.organizationImg
  1242. attaches["ORGANIZATIONCODE"] = self._merchant.organizationcode
  1243. attaches["TAXREGISTRATION"] = self._merchant.taxregistration
  1244. attaches["UNIFIEDSOCIALCREDITCODE"] = self._merchant.unifiedsocialcreditcode
  1245. elif self._merchant.is_institution:
  1246. attaches["PERMIT"] = self._merchant.bankImg
  1247. attaches["LICENCE"] = self._merchant.certImg
  1248. attaches["TAXREGISTRATION"] = self._merchant.taxregistration
  1249. attaches["ORGANIZATIONCODE"] = self._merchant.organizationcode
  1250. attaches["UNIFIEDSOCIALCREDITCODE"] = self._merchant.unifiedsocialcreditcode
  1251. attaches["CERTIFICATE_FILE"] = self._merchant.certificateFile
  1252. attaches["SPECIAL_QUALIFICATION"] = self._merchant.specialQualification
  1253. else:
  1254. if self._merchant.accountType == JdOpenAccountType.PUBLIC:
  1255. attaches["PERMIT"] = self._merchant.bankImg
  1256. else:
  1257. attaches["BANKFRONT"] = self._merchant.bankImg
  1258. attaches["LICENCE"] = self._merchant.organizationImg
  1259. attaches["ORGANIZATIONCODE"] = self._merchant.organizationcode
  1260. attaches["TAXREGISTRATION"] = self._merchant.taxregistration
  1261. for attachType, img in attaches.items(): # type:(str, Attach)
  1262. data = {
  1263. "customerNum": self._merchant.customerNum,
  1264. "attachType": attachType,
  1265. "content": base64.b64encode(img.content)
  1266. }
  1267. try:
  1268. if not img.attachNum:
  1269. result = self._client.attach.upload_attach(**data)
  1270. else:
  1271. result = self._client.attach.modify_attach(attachNum=img.attachNum, **data)
  1272. attachNum = result["data"]["attachNum"]
  1273. img.upload_success(attachNum)
  1274. except JdOpenException as je:
  1275. logger.error("[update_attach] duo_la_bao merchant <{}> update attach <{}> error = {} ".format(self._merchant, attachType, je))
  1276. self._merchant.to_fail(je.message)
  1277. return
  1278. logger.info("[update_attach] duo_la_bao merchant <{}> update attach <{}> success".format(self._merchant, attachType))
  1279. else:
  1280. return self._merchant.to_attach()
  1281. def complete(self):
  1282. logger.info("[complete_merchant] duo_la_bao merchant <{}>".format(self._merchant))
  1283. if not self._merchant:
  1284. return
  1285. if self._merchant.is_personal:
  1286. data = {
  1287. "customerNum": self._merchant.customerNum
  1288. }
  1289. elif self._merchant.is_company:
  1290. data = {
  1291. "customerNum": self._merchant.customerNum,
  1292. "licenseId": self._merchant.organizationNo,
  1293. "licenseStartTime": self._merchant.organizationStart,
  1294. "licenseEndTime": self._merchant.organizationEnd,
  1295. }
  1296. elif self._merchant.is_institution:
  1297. data = {
  1298. "customerNum": self._merchant.customerNum,
  1299. "licenseId": self._merchant.certNo,
  1300. "licenseStartTime": self._merchant.certStart,
  1301. "licenseEndTime": self._merchant.certEnd,
  1302. }
  1303. else:
  1304. data = {
  1305. "customerNum": self._merchant.customerNum,
  1306. "licenseId": self._merchant.organizationNo,
  1307. "licenseStartTime": self._merchant.organizationStart,
  1308. "licenseEndTime": self._merchant.organizationEnd,
  1309. }
  1310. try:
  1311. result = self._client.complete.complete_customer(**data)
  1312. except JdOpenException as je:
  1313. logger.error("[complete_merchant] duo_la_bao merchant <{}> complete merchant result error = {} ".format(self._merchant, je))
  1314. self._merchant.to_fail(je.message)
  1315. return
  1316. logger.info("[complete_merchant] duo_la_bao merchant <{}> complete merchant success ".format(self._merchant))
  1317. return self._merchant.to_complete()
  1318. def confirm(self):
  1319. logger.info("[confirm_merchant] duo_la_bao merchant <{}>".format(self._merchant))
  1320. if not self._merchant:
  1321. return
  1322. data = {
  1323. "agentNum": self._merchant.agentNum,
  1324. "customerNum": self._merchant.customerNum
  1325. }
  1326. try:
  1327. result = self._client.complete.confirm_customer(**data)
  1328. except JdOpenException as je:
  1329. logger.error("[confirm_merchant] duo_la_bao merchant <{}> confirm merchant result error = {} ".format(self._merchant, je))
  1330. self._merchant.to_fail(je.message)
  1331. return
  1332. logger.info("[confirm_merchant] duo_la_bao merchant <{}> confirm merchant success ".format(self._merchant))
  1333. return self._merchant.to_confirm()
  1334. class MerchantApplyProxy(object):
  1335. def __init__(self, merchant): # type:(Optional[MerchantSourceInfo, JDOpenApplyInfo]) -> None
  1336. self.merchant = merchant
  1337. def submit_data(self):
  1338. """
  1339. 将数据提供到商户方供给审核
  1340. """
  1341. merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
  1342. if not merchant.support_enter():
  1343. logger.error("[MerchantApplyProxy submit_data] not support enter merchant, merchantId = {}".format(self.merchant.id))
  1344. return
  1345. if isinstance(merchant, MerchantSourceInfo):
  1346. applier = JdPsiMerchantApplier(merchant=merchant, client=get_psi_client())
  1347. elif isinstance(merchant, JDOpenApplyInfo):
  1348. applier = JdOpenMerchantApplier(merchant=merchant, client=get_open_client())
  1349. else:
  1350. logger.error("[MerchantApplyProxy submit_data] not support merchant type, merchantId = {}".format(self.merchant.id))
  1351. return
  1352. return applier.submit()
  1353. def query_merchant_audit(self):
  1354. """
  1355. 查询商户的审核状态
  1356. """
  1357. merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
  1358. if not merchant.support_query_audit():
  1359. logger.error("[MerchantApplyProxy query_merchant_audit] not support query audit, merchantId = {}".format(self.merchant.id))
  1360. return
  1361. if isinstance(merchant, MerchantSourceInfo):
  1362. applier = JdPsiMerchantApplier(merchant=merchant, client=get_psi_client())
  1363. elif isinstance(merchant, JDOpenApplyInfo):
  1364. applier = JdOpenMerchantApplier(merchant=merchant, client=get_open_client())
  1365. else:
  1366. logger.error("[MerchantApplyProxy submit_data] not support merchant type, merchantId = {}".format(self.merchant.id))
  1367. return
  1368. # 查询商户的审核状态 如果审核成功 触发 下一步的行为 ()
  1369. return applier.query_audit_result()
  1370. def submit_auth(self):
  1371. """
  1372. 提交 实名信息 分别向支付宝和微信提交
  1373. """
  1374. merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
  1375. if not merchant.support_jdaggre():
  1376. logger.error("[MerchantApplyProxy submit_auth] not support submit auth, merchantId = {}".format(self.merchant.id))
  1377. return
  1378. # 微信没有申请的
  1379. if not merchant.is_wechat_submit:
  1380. self.submit_wechat()
  1381. # 支付宝没有提交申请资料的
  1382. if not merchant.is_ali_submit:
  1383. self.submit_ali()
  1384. # 如果提交都成功了 切换状态
  1385. merchant = self.merchant.reload()
  1386. if all([merchant.is_wechat_submit, merchant.is_ali_submit]):
  1387. merchant.to_auth_wait()
  1388. def query_auth_audit(self):
  1389. """
  1390. 查询实名审核的状态
  1391. """
  1392. wechatResult = self.query_wechat_audit()
  1393. aliResult = self.query_ali_audit()
  1394. if all([wechatResult, aliResult]):
  1395. self.merchant.to_auth_apply_success()
  1396. def submit_wechat(self):
  1397. """
  1398. 提交微信审核资料
  1399. """
  1400. # 重载一次 防止状态变更失败
  1401. merchant = self.merchant.reload() # type: Optional[MerchantSourceInfo, JDOpenApplyInfo]
  1402. if isinstance(merchant, MerchantSourceInfo):
  1403. merchant = update_channels_info(merchant)
  1404. elif isinstance(merchant, JDOpenApplyInfo):
  1405. openClient = get_open_client()
  1406. merchant = query_sub_merchantId(merchant, openClient)
  1407. else:
  1408. return
  1409. wechatProxy = get_wechat_proxy()
  1410. wxApplier = merchant.wxSource
  1411. if not wxApplier.subMerchantId:
  1412. logger.error("[submit_wechat] ownerId = {} no subMerchantId!".format(merchant.ownerId))
  1413. return
  1414. try:
  1415. result = wechatProxy.submit_merchant(wxApplier)
  1416. except MerchantError:
  1417. logger.error("[submit_wechat] ownerId = {} submit error!".format(merchant.ownerId))
  1418. return
  1419. if "applyment_id" in result:
  1420. applymentId = result["applyment_id"]
  1421. merchant.to_wx_waiting(applymentId=applymentId)
  1422. else:
  1423. merchant.to_fail(result["message"])
  1424. def query_wechat_audit(self):
  1425. """
  1426. 查询微信 的审核
  1427. """
  1428. # 重载一次 防止状态变更失败
  1429. merchant = self.merchant.reload()
  1430. logger.info("[query_wechat_audit] ownerId = {}".format(merchant.ownerId))
  1431. # 获取微信服务商
  1432. wechatProxy = get_wechat_proxy()
  1433. wxApplier = merchant.wxSource
  1434. if not wxApplier.applymentId:
  1435. logger.error("[query_wechat_audit] ownerId = {} not found applymentId".format(merchant.ownerId))
  1436. return
  1437. try:
  1438. result = wechatProxy.get_merchant_audit(wxApplier.applymentId)
  1439. except MerchantError:
  1440. logger.error("[query_wechat_audit] ownerId = {} query error!".format(merchant.ownerId))
  1441. return
  1442. if "applyment_state" not in result:
  1443. return False
  1444. # 审核通过的
  1445. if result["applyment_state"] in [
  1446. "APPLYMENT_STATE_PASSED",
  1447. "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_LEGALPERSON",
  1448. "APPLYMENT_STATE_WAITTING_FOR_CONFIRM_CONTACT"
  1449. ]:
  1450. return True
  1451. # 审核驳回的
  1452. if result["applyment_state"] in ["APPLYMENT_STATE_REJECTED"]:
  1453. merchant.to_fail(u"【审核驳回】 {}:{}".format(result["reject_param"], result["reject_reason"]))
  1454. return False
  1455. def submit_ali(self):
  1456. """
  1457. 提交支付宝的审核资料
  1458. """
  1459. pass
  1460. def query_ali_audit(self):
  1461. """
  1462. 阿里暂时全返回为True
  1463. """
  1464. return True