transfer.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import, unicode_literals
  3. import random
  4. import datetime
  5. from library.wechatpy.pay.utils import get_external_ip, rsa_encrypt
  6. from library.wechatpy.pay.base import BaseWeChatPayAPI
  7. class WeChatTransfer(BaseWeChatPayAPI):
  8. def transfer(self, user_id, amount, desc, client_ip=None,
  9. check_name='FORCE_CHECK', real_name=None,
  10. out_trade_no=None, device_info=None):
  11. """
  12. 企业付款接口
  13. :param user_id: 接受收红包的用户在公众号下的 openid
  14. :param amount: 付款金额,单位分
  15. :param desc: 付款说明
  16. :param client_ip: 可选,调用接口机器的 IP 地址
  17. :param check_name: 可选,校验用户姓名选项,
  18. NO_CHECK:不校验真实姓名,
  19. FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账),
  20. :param real_name: 可选,收款用户真实姓名,
  21. 如果check_name设置为FORCE_CHECK,则必填用户真实姓名
  22. :param out_trade_no: 可选,商户订单号,需保持唯一性,默认自动生成
  23. :param device_info: 可选,微信支付分配的终端设备号
  24. :return: 返回的结果信息
  25. """
  26. if not out_trade_no:
  27. now = datetime.datetime.now()
  28. out_trade_no = '{0}{1}{2}'.format(
  29. self.mch_id,
  30. now.strftime('%Y%m%d%H%M%S'),
  31. random.randint(1000, 10000)
  32. )
  33. data = {
  34. 'mch_appid': self.appid,
  35. 'mchid': self.mch_id,
  36. 'device_info': device_info,
  37. 'partner_trade_no': out_trade_no,
  38. 'openid': user_id,
  39. 'check_name': check_name,
  40. 're_user_name': real_name,
  41. 'amount': amount,
  42. 'desc': desc,
  43. 'spbill_create_ip': client_ip or get_external_ip(),
  44. }
  45. return self._post('mmpaymkttransfers/promotion/transfers', data=data)
  46. def query(self, out_trade_no):
  47. """
  48. 企业付款查询接口
  49. :param out_trade_no: 商户调用企业付款API时使用的商户订单号
  50. :return: 返回的结果数据
  51. """
  52. data = {
  53. 'appid': self.appid,
  54. 'partner_trade_no': out_trade_no,
  55. }
  56. return self._post('mmpaymkttransfers/gettransferinfo', data=data)
  57. def transfer_bankcard(self, true_name, bank_card_no, bank_code, amount, desc=None, out_trade_no=None):
  58. """
  59. 企业付款到银行卡接口
  60. :param true_name: 开户人名称
  61. :param bank_card_no: 银行卡号
  62. :param bank_code: 银行编号
  63. :param amount: 付款金额,单位分
  64. :param desc: 付款说明
  65. :param out_trade_no: 可选,商户订单号,需保持唯一性,默认自动生成
  66. :return: 返回的结果信息
  67. """
  68. if not out_trade_no:
  69. now = datetime.datetime.now()
  70. out_trade_no = '{0}{1}{2}'.format(
  71. self.mch_id,
  72. now.strftime('%Y%m%d%H%M%S'),
  73. random.randint(1000, 10000)
  74. )
  75. data = {
  76. 'mch_id': self.mch_id,
  77. 'partner_trade_no': out_trade_no,
  78. 'amount': amount,
  79. 'desc': desc,
  80. 'enc_bank_no': self._rsa_encrypt(bank_card_no),
  81. 'enc_true_name': self._rsa_encrypt(true_name),
  82. 'bank_code': bank_code,
  83. }
  84. return self._post('mmpaysptrans/pay_bank', data=data)
  85. def query_bankcard(self, out_trade_no):
  86. """
  87. 企业付款查询接口
  88. :param out_trade_no: 商户调用企业付款API时使用的商户订单号
  89. :return: 返回的结果数据
  90. """
  91. data = {
  92. 'mch_id': self.mch_id,
  93. 'partner_trade_no': out_trade_no,
  94. }
  95. return self._post('mmpaysptrans/query_bank', data=data)
  96. def get_rsa_public_key(self):
  97. data = {
  98. 'mch_id': self.mch_id,
  99. 'sign_type': 'MD5',
  100. }
  101. return self._post('https://fraud.mch.weixin.qq.com/risk/getpublickey', data=data)
  102. def _rsa_encrypt(self, data):
  103. if not getattr(self, '_rsa_public_key', None):
  104. self._rsa_public_key = self.get_rsa_public_key()['pub_key']
  105. return rsa_encrypt(data, self._rsa_public_key)