Alipay.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. /**
  3. * Alipay.php UTF-8
  4. * 支付宝支付
  5. *
  6. * @date : 2018/2/8 11:55
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HUOSDK 8.0
  11. */
  12. namespace huolib\withdraw\driver;
  13. use huolib\constant\SettleConst;
  14. use huolib\withdraw\Driver;
  15. use think\Loader;
  16. class Alipay extends Driver {
  17. private $config
  18. = [
  19. 'partner' => '',
  20. 'seller_email' => '',
  21. 'key' => '',
  22. 'sign_type' => '',
  23. 'input_charset' => 'utf-8', // 编码 (固定值不用改)
  24. 'transport' => 'http', // 协议 (固定值不用改)
  25. 'cacert' => '',
  26. 'notify_url' => '',
  27. 'return_url' => '',
  28. 'show_url' => '',
  29. 'private_key_path' => '',
  30. 'public_key_path' => '',
  31. ];
  32. /**
  33. * 构造函数
  34. */
  35. public function __construct() {
  36. if (file_exists(GLOBAL_CONF_PATH."extra/pay/zfb/config.php")) {
  37. $_config = include GLOBAL_CONF_PATH."extra/pay/zfb/config.php";
  38. } else {
  39. $_config = array();
  40. }
  41. $this->config = array_merge($this->config, $_config);
  42. $this->config['sign_type'] = strtoupper(trim('RSA'));
  43. $this->config['cacert'] = GLOBAL_CONF_PATH.'extra/pay/zfb/cacert.pem';
  44. $this->config['private_key_path'] = GLOBAL_CONF_PATH.'extra/pay/zfb/key/rsa_private_key.pem';
  45. $this->config['public_key_path'] = GLOBAL_CONF_PATH.'extra/pay/zfb/key/rsa_public_key.pem';
  46. $this->notify_url = get_val($this->config, 'notify_url', '');
  47. }
  48. /**
  49. * 支付宝提现
  50. * https://docs.open.alipay.com/api_28/alipay.fund.trans.toaccount.transfer
  51. * https://docs.open.alipay.com/309
  52. *
  53. * @throws \Exception
  54. */
  55. public function withDraw() {
  56. $_re_data = [];
  57. Loader::import('withdraw.alipay.aop.AopClient', EXTEND_PATH, '.php');
  58. Loader::import('withdraw.alipay.aop.request.AlipayFundTransToaccountTransferRequest', EXTEND_PATH, '.php');
  59. Loader::import('withdraw.alipay.aop.SignData', EXTEND_PATH, '.php');
  60. $_gateway_url = 'https://openapi.alipay.com/gateway.do';
  61. $_aop = new \AopClient();
  62. $_aop->gatewayUrl = $_gateway_url;//支付宝网关 这个是不变的
  63. $_aop->appId = $this->config['app_id'];//商户appid 在支付宝控制台找
  64. $_aop->rsaPrivateKey = $this->getPrivateKey($this->config['private_key_path']);//私钥 工具生成的
  65. $_aop->alipayrsaPublicKey = $this->getPublicKey($this->config['public_key_path']);//支付宝公钥 上传应用公钥后 支付宝生成的支付宝公钥
  66. $_aop->apiVersion = '1.0';
  67. $_aop->signType = 'RSA';
  68. $_aop->postCharset = 'utf-8';
  69. $_aop->format = 'json';
  70. $_request = new \AlipayFundTransToaccountTransferRequest();
  71. $_request->setBizContent(
  72. "{".
  73. "\"out_biz_no\":\"$this->order_id\",".
  74. "\"payee_type\":\"ALIPAY_LOGONID\",".
  75. "\"payee_account\":\"$this->payee_account\",".
  76. "\"amount\":\"$this->real_amount\",".
  77. "\"payer_show_name\":\"$this->payer_show_name\",".
  78. "\"payee_real_name\":\"$this->payee_real_name\",".
  79. "\"remark\":\"$this->remark\"".
  80. "}"
  81. );
  82. $_result = $_aop->execute($_request);
  83. $_response_node = str_replace(".", "_", $_request->getApiMethodName())."_response";
  84. $_resultCode = $_result->$_response_node->code;
  85. $_re_data['result'] = json_encode($_result);
  86. $_re_data['code'] = $_resultCode;
  87. $_re_data['msg'] = $_result->$_response_node->msg;
  88. if (!empty($_resultCode) && $_resultCode == 10000) {
  89. $_re_data['code'] = SettleConst::SETTLE_SUCCESS;
  90. //发起支付查询
  91. $_rs = $this->orderQuery('s1530961465310009494');
  92. $_re_data['query_result'] = $_rs['result'];
  93. } else {
  94. $_re_data['msg'] = $_result->$_response_node->sub_msg;
  95. }
  96. return $_re_data;
  97. }
  98. /**
  99. * 查询是否订单是否到账
  100. * https://docs.open.alipay.com/api_28/alipay.fund.trans.order.query
  101. *
  102. *
  103. * @param string $order_id 商户系统内部订单号
  104. * @param null $ext 扩展信息
  105. *
  106. * @return array
  107. * @throws \Exception
  108. */
  109. public function orderQuery($order_id, $ext = null) {
  110. $_re_data = [];
  111. Loader::import('withdraw.alipay.aop.AopClient', EXTEND_PATH, '.php');
  112. Loader::import('withdraw.alipay.aop.request.AlipayFundTransOrderQueryRequest', EXTEND_PATH, '.php');
  113. Loader::import('withdraw.alipay.aop.SignData', EXTEND_PATH, '.php');
  114. $_gateway_url = 'https://openapi.alipay.com/gateway.do';
  115. $_aop = new \AopClient();
  116. $_aop->gatewayUrl = $_gateway_url;//支付宝网关 这个是不变的
  117. $_aop->appId = $this->config['app_id'];//商户appid 在支付宝控制台找
  118. $_aop->format = 'json';
  119. $_aop->postCharset = 'utf-8';
  120. $_aop->signType = 'RSA';
  121. $_aop->apiVersion = '1.0';
  122. $_aop->rsaPrivateKey = $this->getPrivateKey($this->config['private_key_path']);//私钥 工具生成的
  123. $_aop->alipayrsaPublicKey = $this->getPublicKey($this->config['public_key_path']);//支付宝公钥 上传应用公钥后 支付宝生成的支付宝公钥
  124. $_request = new \AlipayFundTransOrderQueryRequest();
  125. $_request->setBizContent(
  126. "{".
  127. "\"out_biz_no\":\"$order_id\",".
  128. "}"
  129. );
  130. $_result = $_aop->execute($_request);
  131. $_response_node = str_replace(".", "_", $_request->getApiMethodName())."_response";
  132. $_resultCode = $_result->$_response_node->code;
  133. $_re_data['result'] = json_encode($_result);
  134. $_re_data['code'] = $_result->$_response_node->code;
  135. $_re_data['msg'] = $_result->$_response_node->msg;
  136. if (!empty($_resultCode) && $_resultCode == 10000) {
  137. switch ($_result->$_response_node->status) {
  138. case 'SUCCESS':
  139. $_re_data['status'] = SettleConst::SETTLE_PAY_SUCCESS;
  140. break;
  141. case 'INIT':
  142. case 'DEALING':
  143. $_re_data['status'] = SettleConst::SETTLE_PAY_PROCESSING;
  144. break;
  145. default:
  146. $_re_data['status'] = SettleConst::SETTLE_PAY_FAILED;
  147. }
  148. } else {
  149. $_re_data['msg'] = $_result->$_response_node->sub_msg;
  150. }
  151. return $_re_data;
  152. }
  153. /**
  154. * 通过路径获取RSA 私钥内容
  155. *
  156. * @param string $private_key_path 私钥路径
  157. *
  158. * @return null|string
  159. */
  160. public function getPrivateKey($private_key_path) {
  161. if (!file_exists($private_key_path)) {
  162. return null;
  163. }
  164. $_private_key = file_get_contents($private_key_path);
  165. $_private_key = str_replace("-----BEGIN RSA PRIVATE KEY-----", "", $_private_key);
  166. $_private_key = str_replace("-----END RSA PRIVATE KEY-----", "", $_private_key);
  167. $_private_key = str_replace("\n", "", $_private_key);
  168. $private_key = wordwrap($_private_key, 64, "\n", true);
  169. return $private_key;
  170. }
  171. /**
  172. * 通过路径获取RSA公钥内容
  173. *
  174. * @param string $public_key_path 公钥路径
  175. *
  176. * @return null|string
  177. */
  178. function getPublicKey($public_key_path) {
  179. if (!file_exists($public_key_path)) {
  180. return null;
  181. }
  182. $_public_key = file_get_contents($public_key_path);
  183. //以下为了初始化私钥,保证在您填写私钥时不管是带格式还是不带格式都可以通过验证。
  184. $_public_key = str_replace("-----BEGIN PUBLIC KEY-----", "", $_public_key);
  185. $_public_key = str_replace("-----END PUBLIC KEY-----", "", $_public_key);
  186. $_public_key = str_replace("\n", "", $_public_key);
  187. $_public_key = wordwrap($_public_key, 64, "\n", true);
  188. return $_public_key;
  189. }
  190. }