TransfersBank.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | WeChatDeveloper
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2014~2023 ThinkAdmin [ thinkadmin.top ]
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: https://thinkadmin.top
  8. // +----------------------------------------------------------------------
  9. // | 开源协议 ( https://mit-license.org )
  10. // | 免责声明 ( https://thinkadmin.top/disclaimer )
  11. // +----------------------------------------------------------------------
  12. // | gitee 代码仓库:https://gitee.com/zoujingli/WeChatDeveloper
  13. // | github 代码仓库:https://github.com/zoujingli/WeChatDeveloper
  14. // +----------------------------------------------------------------------
  15. namespace WePay;
  16. use WeChat\Contracts\BasicWePay;
  17. use WeChat\Contracts\Tools;
  18. use WeChat\Exceptions\InvalidArgumentException;
  19. use WeChat\Exceptions\InvalidDecryptException;
  20. use WeChat\Exceptions\InvalidResponseException;
  21. /**
  22. * 微信商户打款到银行卡
  23. * Class TransfersBank
  24. * @package WePay
  25. */
  26. class TransfersBank extends BasicWePay
  27. {
  28. /**
  29. * 企业付款到银行卡
  30. * @param array $options
  31. * @return array
  32. * @throws \WeChat\Exceptions\InvalidDecryptException
  33. * @throws \WeChat\Exceptions\InvalidResponseException
  34. * @throws \WeChat\Exceptions\LocalCacheException
  35. */
  36. public function create(array $options)
  37. {
  38. if (!isset($options['partner_trade_no'])) {
  39. throw new InvalidArgumentException('Missing Options -- [partner_trade_no]');
  40. }
  41. if (!isset($options['enc_bank_no'])) {
  42. throw new InvalidArgumentException('Missing Options -- [enc_bank_no]');
  43. }
  44. if (!isset($options['enc_true_name'])) {
  45. throw new InvalidArgumentException('Missing Options -- [enc_true_name]');
  46. }
  47. if (!isset($options['bank_code'])) {
  48. throw new InvalidArgumentException('Missing Options -- [bank_code]');
  49. }
  50. if (!isset($options['amount'])) {
  51. throw new InvalidArgumentException('Missing Options -- [amount]');
  52. }
  53. $this->params->offsetUnset('appid');
  54. return $this->callPostApi('https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank', [
  55. 'amount' => $options['amount'],
  56. 'bank_code' => $options['bank_code'],
  57. 'partner_trade_no' => $options['partner_trade_no'],
  58. 'enc_bank_no' => $this->rsaEncode($options['enc_bank_no']),
  59. 'enc_true_name' => $this->rsaEncode($options['enc_true_name']),
  60. 'desc' => isset($options['desc']) ? $options['desc'] : '',
  61. ], true, 'MD5', false);
  62. }
  63. /**
  64. * 商户企业付款到银行卡操作进行结果查询
  65. * @param string $partnerTradeNo 商户订单号,需保持唯一
  66. * @return array
  67. * @throws \WeChat\Exceptions\InvalidResponseException
  68. * @throws \WeChat\Exceptions\LocalCacheException
  69. */
  70. public function query($partnerTradeNo)
  71. {
  72. $this->params->offsetUnset('appid');
  73. $url = 'https://api.mch.weixin.qq.com/mmpaysptrans/query_bank';
  74. return $this->callPostApi($url, ['partner_trade_no' => $partnerTradeNo], true, 'MD5', false);
  75. }
  76. /**
  77. * RSA加密处理
  78. * @param string $string
  79. * @param string $encrypted
  80. * @return string
  81. * @throws \WeChat\Exceptions\InvalidDecryptException
  82. * @throws \WeChat\Exceptions\InvalidResponseException
  83. * @throws \WeChat\Exceptions\LocalCacheException
  84. */
  85. private function rsaEncode($string, $encrypted = '')
  86. {
  87. $search = ['-----BEGIN RSA PUBLIC KEY-----', '-----END RSA PUBLIC KEY-----', "\n", "\r"];
  88. $pkc1 = str_replace($search, '', $this->getRsaContent());
  89. $publicKey = '-----BEGIN PUBLIC KEY-----' . PHP_EOL .
  90. wordwrap('MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A' . $pkc1, 64, PHP_EOL, true) . PHP_EOL .
  91. '-----END PUBLIC KEY-----';
  92. if (!openssl_public_encrypt("{$string}", $encrypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING)) {
  93. throw new InvalidDecryptException('Rsa Encrypt Error.');
  94. }
  95. return base64_encode($encrypted);
  96. }
  97. /**
  98. * 获取签名文件内容
  99. * @return string
  100. * @throws \WeChat\Exceptions\InvalidResponseException
  101. * @throws \WeChat\Exceptions\LocalCacheException
  102. */
  103. private function getRsaContent()
  104. {
  105. $cacheKey = "pub_ras_key_" . $this->config->get('mch_id');
  106. if (($pub_key = Tools::getCache($cacheKey))) {
  107. return $pub_key;
  108. }
  109. $data = $this->callPostApi('https://fraud.mch.weixin.qq.com/risk/getpublickey', [], true, 'MD5');
  110. if (!isset($data['return_code']) || $data['return_code'] !== 'SUCCESS' || $data['result_code'] !== 'SUCCESS') {
  111. $error = 'ResultError:' . $data['return_msg'];
  112. $error .= isset($data['err_code_des']) ? ' - ' . $data['err_code_des'] : '';
  113. throw new InvalidResponseException($error, 20000, $data);
  114. }
  115. Tools::setCache($cacheKey, $data['pub_key'], 600);
  116. return $data['pub_key'];
  117. }
  118. }