transfer.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. from ..api.base import BaseWeChatAPI
  4. from ...type import RequestType
  5. class Transfer(BaseWeChatAPI):
  6. def transfer(self, out_trade_no, user_id, amount, desc, check_name = 'FORCE_CHECK', real_name = None):
  7. """
  8. 企业付款到微信 该接口为了和v1接口兼容提供
  9. :param out_trade_no:
  10. :param user_id:
  11. :param amount:
  12. :param desc:
  13. :param check_name:
  14. :param real_name:
  15. :return:
  16. """
  17. out_batch_no = out_trade_no
  18. total_amount = amount
  19. batch_name = desc
  20. batch_remark = desc
  21. total_num = 1
  22. transfer_detail_list = [
  23. {
  24. "out_detail_no": out_batch_no,
  25. "transfer_amount": amount,
  26. "transfer_remark": desc,
  27. "openid": user_id,
  28. "user_name": real_name
  29. }]
  30. return self.transfer_batch(
  31. out_batch_no, batch_name, batch_remark, total_amount, total_num, transfer_detail_list)
  32. def query(self, out_trade_no):
  33. """
  34. 企业付款查询接口 该接口为了和v1接口兼容提供
  35. :param out_trade_no: 商户调用企业付款API时使用的商户订单号
  36. :return: 返回的结果数据
  37. """
  38. return self.transfer_query_out_detail_no(out_trade_no, out_trade_no)
  39. def transfer_bankcard(self, true_name, bank_card_no, bank_code, amount, desc = None, out_trade_no = None):
  40. raise NotImplementedError('not support transfer bank card')
  41. def query_bankcard(self, out_trade_no):
  42. raise NotImplementedError('not support query bank card transfer')
  43. def transfer_batch(self, out_batch_no, batch_name, batch_remark, total_amount, total_num, transfer_detail_list):
  44. """发起商家转账
  45. :param out_batch_no: 商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一,示例值:'plfk2020042013'
  46. :param batch_name: 该笔批量转账的名称,示例值:'2019年1月深圳分部报销单'
  47. :param batch_remark: 转账说明,UTF8编码,最多允许32个字符,示例值:'2019年1月深圳分部报销单'
  48. :param total_amount: 转账总金额,单位为分,必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作,示例值:'4000000'
  49. :param total_num: 转账总笔数,必须与批次内所有明细之和保持一致,否则无法发起转账操作,示例值:200
  50. :param transfer_detail_list: 发起批量转账的明细列表,最多三千笔,示例值:[{"out_detail_no": "x23zy545Bd5436", "transfer_amount": 200000, "transfer_remark": "2020年4月报销", "openid": "o-MYE42l80oelYMDE34nYD456Xoy", "user_name": "张三"}]
  51. """
  52. params = {}
  53. if out_batch_no:
  54. params.update({'out_batch_no': out_batch_no})
  55. else:
  56. raise Exception('out_batch_no is not assigned')
  57. if batch_name:
  58. params.update({'batch_name': batch_name})
  59. else:
  60. raise Exception('batch_name is not assigned')
  61. if batch_remark:
  62. params.update({'batch_remark': batch_remark})
  63. else:
  64. raise Exception('batch_remark is not assigned')
  65. if total_amount:
  66. params.update({'total_amount': total_amount})
  67. else:
  68. raise Exception('total_amount is not assigned')
  69. if total_num:
  70. params.update({'total_num': total_num})
  71. else:
  72. raise Exception('total_num is not assigned')
  73. if transfer_detail_list:
  74. params.update({'transfer_detail_list': transfer_detail_list})
  75. else:
  76. raise Exception('transfer_detail_list is not assigned')
  77. cipher_data = False
  78. for transfer_detail in params.get('transfer_detail_list'):
  79. if transfer_detail.get('user_name'):
  80. transfer_detail['user_name'] = self.client.core.encrypt(transfer_detail.get('user_name'))
  81. cipher_data = True
  82. params.update({'appid': self.client.appid})
  83. path = '/v3/transfer/batches'
  84. return self.client.core.request(path, method = RequestType.POST, data = params, cipher_data = cipher_data)
  85. def transfer_query_batchid(self, batch_id, need_query_detail = False, offset = 0, limit = 20,
  86. detail_status = 'ALL'):
  87. """微信批次单号查询批次单
  88. :param batch_id: 微信批次单号,微信商家转账系统返回的唯一标识,示例值:1030000071100999991182020050700019480001
  89. :param need_query_detail: 是否查询转账明细单,枚举值:true:是;false:否,默认否。
  90. :param offset: 请求资源起始位置,默认值为0
  91. :param limit: 最大资源条数,默认值为20
  92. :param detail_status: 明细状态, ALL:全部。需要同时查询转账成功和转账失败的明细单;SUCCESS:转账成功。只查询转账成功的明细单;FAIL:转账失败。
  93. """
  94. if batch_id:
  95. path = '/v3/transfer/batches/batch-id/%s' % batch_id
  96. else:
  97. raise Exception('batch_id is not assigned')
  98. if need_query_detail:
  99. path += '?need_query_detail=true'
  100. else:
  101. path += '?need_query_detail=false'
  102. path += '&offset=%s' % offset
  103. path += '&limit=%s' % limit
  104. path += '&detail_status=%s' % detail_status
  105. return self.client.core.request(path)
  106. def transfer_query_detail_id(self, batch_id, detail_id):
  107. """微信明细单号查询明细单
  108. :param batch_id: 微信批次单号,微信商家转账系统返回的唯一标识,示例值:1030000071100999991182020050700019480001
  109. :param detail_id: 微信明细单号,微信支付系统内部区分转账批次单下不同转账明细单的唯一标识,示例值:1040000071100999991182020050700019500100
  110. """
  111. if batch_id and detail_id:
  112. path = '/v3/transfer/batches/batch-id/%s/details/detail-id/%s' % (batch_id, detail_id)
  113. else:
  114. raise Exception('batch_id or detail_id is not assigned')
  115. return self.client.core.request(path)
  116. def transfer_query_out_batch_no(self, out_batch_no, need_query_detail = False, offset = 0, limit = 20,
  117. detail_status = 'ALL'):
  118. """商家批次单号查询批次单
  119. :param out_batch_no: 商家批次单号,示例值:plfk2020042013
  120. :param need_query_detail: 是否查询转账明细单,枚举值:true:是;false:否,默认否。
  121. :param offset: 请求资源起始位置,默认值为0
  122. :param limit: 最大资源条数,默认值为20
  123. :param detail_status: 明细状态, ALL:全部。需要同时查询转账成功和转账失败的明细单;SUCCESS:转账成功。只查询转账成功的明细单;FAIL:转账失败。
  124. """
  125. if out_batch_no:
  126. path = '/v3/transfer/batches/out-batch-no/%s' % out_batch_no
  127. else:
  128. raise Exception('batch_id is not assigned')
  129. if need_query_detail:
  130. path += '?need_query_detail=true'
  131. else:
  132. path += '?need_query_detail=false'
  133. path += '&offset=%s' % offset
  134. path += '&limit=%s' % limit
  135. path += '&detail_status=%s' % detail_status
  136. return self.client.core.request(path)
  137. def transfer_query_out_detail_no(self, out_detail_no, out_batch_no):
  138. """商家明细单号查询明细单
  139. :param out_detail_no: 商家明细单号,示例值:x23zy545Bd5436
  140. :param out_batch_no: 商家批次单号,示例值:plfk2020042013
  141. """
  142. if out_detail_no and out_batch_no:
  143. path = '/v3/transfer/batches/out-batch-no/%s/details/out-detail-no/%s' % (out_batch_no, out_detail_no)
  144. else:
  145. raise Exception('out_detail_no or out_batch_no is not assigned')
  146. return self.client.core.request(path)
  147. def transfer_bill_receipt(self, out_batch_no):
  148. """转账电子回单申请受理
  149. :param out_batch_no: 商家批次单号,示例值:plfk2020042013
  150. """
  151. params = {}
  152. if out_batch_no:
  153. params.update({'out_batch_no': out_batch_no})
  154. else:
  155. raise Exception('out_batch_no is assigned')
  156. path = '/v3/transfer/bill-receipt'
  157. return self.client.core.request(path, method = RequestType.POST, params = params)
  158. def transfer_query_bill_receipt(self, out_batch_no):
  159. """查询转账电子回单
  160. :param out_batch_no: 商家批次单号,示例值:plfk2020042013
  161. """
  162. if out_batch_no:
  163. path = '/v3/transfer/bill-receipt/%s' % out_batch_no
  164. else:
  165. raise Exception('out_batch_no is not assigned')
  166. return self.client.core.request(path)
  167. def transfer_detail_receipt(self, accept_type, out_detail_no, out_batch_no = None, ):
  168. """转账明细电子回单受理
  169. :param accept_type: 受理类型
  170. :param out_detail_no: 商家明细单号,示例值:x23zy545Bd5436
  171. :param out_batch_no: 商家批次单号,示例值:plfk2020042013
  172. """
  173. params = {}
  174. if accept_type:
  175. params.update({'accept_type': accept_type})
  176. else:
  177. raise Exception('accept_type is not assigned')
  178. if out_detail_no:
  179. params.update({'out_detail_no': out_detail_no})
  180. else:
  181. raise Exception('out_detail_no is not assigned')
  182. if out_batch_no:
  183. params.update({'out_batch_no': out_batch_no})
  184. path = '/v3/transfer-detail/electronic-receipts'
  185. return self.client.core.request(path, method = RequestType.POST, params = params)
  186. def transfer_query_receipt(self, accept_type, out_detail_no, out_batch_no = None):
  187. """查询转账明细电子回单受理结果
  188. :param accept_type: 受理类型
  189. :param out_detail_no: 商家明细单号,示例值:x23zy545Bd5436
  190. :param out_batch_no: 商家批次单号,示例值:plfk2020042013
  191. """
  192. if accept_type:
  193. path = '/v3/transfer-detail/electronic-receipts?accept_type=%s' % accept_type
  194. else:
  195. raise Exception('accept_type is not assigned')
  196. if out_detail_no:
  197. path += '&out_batch_no=%s' % out_detail_no
  198. else:
  199. raise Exception('out_detail_no is not assigned')
  200. if out_batch_no:
  201. path += '&out_batch_no=%s' % out_batch_no
  202. return self.client.core_request(path)