bank_card_utils.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. # coding=utf-8
  2. import logging
  3. import json
  4. import requests
  5. from urlparse import urljoin
  6. from django.conf import settings
  7. from apilib.exceptions import AliBankCardParamError, AliBankCardSysError
  8. from apilib.utils_url import add_query
  9. from apps.web.utils import LimitAttemptsManager
  10. logger = logging.getLogger(__name__)
  11. class BankRecognizer(object):
  12. """
  13. 查询银行卡联行号相关信息
  14. helps: https://market.aliyun.com/products/57000002/cmapi017567.html?spm=5176.12901015.0.i12901015.5737525cxikPYJ#sku=yuncode1156700000
  15. """
  16. HOST = "https://cnaps.market.alicloudapi.com"
  17. def __init__(self, visitor, appCode=None, timeout=None):
  18. self._appCode = appCode or settings.ALI_BANK_CARD_APP_CODE
  19. self._timeout = timeout or 5
  20. self._visitor = visitor or "visitor"
  21. limiter = LimitAttemptsManager(self._visitor, self.__class__.__name__, maxTimes=30 if not settings.DEBUG else 9999)
  22. if limiter.is_exceeded_limit():
  23. raise AliBankCardParamError(u"访问频率超限")
  24. limiter.incr()
  25. def _request(self, path, callback=None):
  26. """
  27. 目前使用的两个接口比较简单, request没有必要实现的太过于复杂 get请求足矣
  28. """
  29. url = urljoin(self.HOST, path)
  30. headers = {
  31. "Authorization": "APPCODE {}".format(self._appCode)
  32. }
  33. try:
  34. res = requests.get(url ,headers=headers, timeout=self._timeout)
  35. res.raise_for_status()
  36. except requests.RequestException as ree:
  37. logger.warning("[{} _request] send error request error = {}, path={}, appCode = {}******".format(
  38. self.__class__.__name__, ree, path, self._appCode[:-6]
  39. ))
  40. raise AliBankCardParamError(ree.message)
  41. return callback(res) if callback else res
  42. @staticmethod
  43. def _handle_response(res):
  44. """
  45. 处理查询支行联行号的回调函数
  46. """
  47. try:
  48. result = json.loads(res.content.decode('utf-8', 'ignore'), strict=False)
  49. except (TypeError, ValueError):
  50. logger.debug('[_handle_sub_code] Can not decode response as JSON', exc_info=True)
  51. raise AliBankCardSysError(u"请求错误(10000)")
  52. if "resp" not in result:
  53. raise AliBankCardSysError(u"请求错误(10001)")
  54. if "RespCode" not in result["resp"]:
  55. raise AliBankCardSysError(u"请求错误(10002)")
  56. respCode = result["resp"]["RespCode"]
  57. if respCode != "200":
  58. raise AliBankCardParamError(result["resp"]["RespMsg"])
  59. return result
  60. def query_sub_code(self, bank=None, card=None, province=None, city=None, queryKey=None, page=None):
  61. """
  62. 多条件查询银行支行信息
  63. :param bank:
  64. :param card:
  65. :param province:
  66. :param city:
  67. :param queryKey:
  68. :param page:
  69. """
  70. path = "/lianzhuo/searchcnaps"
  71. params = {
  72. "card": card or "", "bank": str(bank or ""),
  73. "province": str(province or ""), "city": str(city or ""), "key": str(queryKey or ""), "page": page or 1
  74. }
  75. path = add_query(path, params)
  76. return self._request(path, self._handle_response)
  77. def query_bank(self, card):
  78. """
  79. 根据银行卡查询总行的信息
  80. """
  81. path = "/lundroid/querybankno"
  82. params = {
  83. "bankno": card
  84. }
  85. return self._request(add_query(path, params), self._handle_response)
  86. def query_all_bank(self, bank):
  87. """
  88. 查询支持的银行总行
  89. 这个接口不是很好用 建议不要使用
  90. bank为关键字
  91. """
  92. path = "/lundroid/querybank"
  93. params = {
  94. "bank": str(bank)
  95. }
  96. return self._request(add_query(path, params), self._handle_response)
  97. def query_sub_bank(self, subCode):
  98. """
  99. 根据银行的支行联行号 查询银行
  100. """
  101. path = "/lundroid/querybankcode"
  102. params = {
  103. "bankcode": subCode
  104. }
  105. return self._request(add_query(path, params), self._handle_response)