saobei.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import logging
  4. from typing import TYPE_CHECKING
  5. import simplejson as json
  6. from apps.web.core import SaobeiMixin
  7. from library.saobei import SaobeiSignatureError, SaobeiValidationError
  8. from library.saobei import SaobeiPay
  9. from apilib.monetary import RMB
  10. from apps.web.constant import AppPlatformType
  11. from apps.web.core.payment.base import PaymentGateway
  12. if TYPE_CHECKING:
  13. from apps.web.core.models import SaobeiPayApp
  14. logger = logging.getLogger(__name__)
  15. class SaobeiPaymentGateway(PaymentGateway, SaobeiMixin):
  16. PayTypeMap = {
  17. AppPlatformType.WECHAT: '010',
  18. AppPlatformType.ALIPAY: '020',
  19. AppPlatformType.JD: '080'
  20. }
  21. def __init__(self, app, gateway_type): # type: (SaobeiPayApp, AppPlatformType)->None
  22. super(SaobeiPaymentGateway, self).__init__(app)
  23. self.__gateway_type__ = gateway_type
  24. @property
  25. def __client__(self):
  26. # type: ()->SaobeiPay
  27. return SaobeiPay(self.merchant_no, self.terminal_id, self.app.access_token, self.debug)
  28. def _to_fen(self, rmb):
  29. # type: (RMB)->int
  30. return str(int(rmb.amount * 100))
  31. def create_pay_url(self, pay_trace, pay_time, money, attach, body, notify_url, front_url = ''):
  32. data = {
  33. 'attach': json.dumps(attach, separators = (',', ':')) if attach else '',
  34. 'order_body': body,
  35. 'auto_pay': '0',
  36. 'notify_url': notify_url
  37. }
  38. if front_url:
  39. data.update({'front_url': front_url})
  40. url = self.client.generate_wap_pay_url(
  41. pay_trace = pay_trace,
  42. pay_time = pay_time,
  43. total_fee = str(self._to_fen(money)),
  44. **data)
  45. return url
  46. def api_trade_query(self, pay_trace, pay_time):
  47. result = self.client.api_trade_query(pay_type = self.PayTypeMap[self.gateway_type],
  48. pay_trace = pay_trace,
  49. pay_time = pay_time)
  50. return result
  51. def check(self, data, order = True, token = True):
  52. key_sign = data.pop('key_sign')
  53. if self.merchant_no != data['merchant_no']:
  54. raise SaobeiValidationError(
  55. errmsg = u'商户号不一致',
  56. lvalue = self.merchant_no,
  57. rvalue = data['merchant_no'],
  58. client = self)
  59. if self.terminal_id != data['terminal_id']:
  60. raise SaobeiValidationError(
  61. errmsg = u'终端ID不一致',
  62. lvalue = self.terminal_id,
  63. rvalue = data['terminal_id'],
  64. client = self)
  65. re_key_sign = self.client.sign(data, order, token)
  66. if key_sign != re_key_sign:
  67. raise SaobeiSignatureError(lvalue = re_key_sign, rvalue = key_sign, client = self)
  68. def __repr__(self):
  69. return \
  70. '<SaobeiPaymentGateway(agentId = %s, merchant_no = %s, terminal_id = %s, debug = %s)>' % (
  71. str(self.occupantId), self.merchant_no, self.terminal_id, self.debug)