AliPay.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. /**
  3. * 支付宝
  4. */
  5. namespace utils;
  6. use alipay\AopCertClient;
  7. use alipay\AopClient;
  8. use Alipay\EasySDK\Kernel\Factory;
  9. use Alipay\EasySDK\Kernel\Util\ResponseChecker;
  10. use Alipay\EasySDK\Kernel\Config;
  11. use alipay\request\AlipayFundTransToaccountTransferRequest;
  12. use alipay\request\AlipayTradeAppPayRequest;
  13. use think\Exception;
  14. use think\facade\Db;
  15. class AliPay
  16. {
  17. protected $conf;
  18. public $pay_v = 1; // 1 通用 2 Easy
  19. private static $appCertPath = ''; //应用公钥证书
  20. private static $alipayCertPath = '';//支付宝公钥证书
  21. private static $rootCertPath = '';//支付宝根证书
  22. private static $appId = 0; //APPID
  23. private static $rsaPrivateKey = ''; //支付宝应用私钥
  24. private static $gatewayUrl = 'https://openapi.alipay.com/gateway.do';//网关地址
  25. private static $apiVersion = '1.0';
  26. private static $signType = 'RSA2';
  27. private static $postCharset = 'utf-8';
  28. private static $format = 'json';
  29. // private static $notifyUrl = 'http://zy.suncorex.com:2080/api/aliResult';
  30. private static $notifyUrl = 'https://api.meikangjw.com/api/aliResult';
  31. private $class;
  32. public function __construct ($type = 'pay')
  33. {
  34. if ($type == 'pay') {
  35. self::payConfig();
  36. if ($this->pay_v == 1) {
  37. // self::payConfig();
  38. } else {
  39. Factory::setOptions(self::getOptions());
  40. }
  41. }
  42. }
  43. /**
  44. * 支付宝统一下单(通用版本sdk)
  45. * @param array $param
  46. * @return array
  47. */
  48. public function unifiedOrder (array $param)
  49. {
  50. try {
  51. $this->class = new AopCertClient();
  52. $this->class->gatewayUrl = self::$gatewayUrl;
  53. $this->class->appId = self::$appId;
  54. $this->class->rsaPrivateKey = self::$rsaPrivateKey;
  55. $this->class->format = self::$format;
  56. $this->class->postCharset = self::$postCharset;
  57. $this->class->signType = self::$signType;
  58. //调用getPublicKey从支付宝公钥证书中提取公钥
  59. $this->class->alipayrsaPublicKey = $this->class->getPublicKey(self::$alipayCertPath);
  60. //是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
  61. $this->class->isCheckAlipayPublicCert = true;
  62. //调用getCertSN获取证书序列号
  63. $this->class->appCertSN = $this->class->getCertSN(self::$appCertPath);
  64. //调用getRootCertSN获取支付宝根证书序列号
  65. $this->class->alipayRootCertSN = $this->class->getRootCertSN(self::$rootCertPath);
  66. //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.open.public.template.message.industry.modify
  67. $request = new AlipayTradeAppPayRequest();
  68. //SDK已经封装掉了公共参数,这里只需要传入业务参数
  69. //此次只是参数展示,未进行字符串转义,实际情况下请转义
  70. $arrData = [
  71. 'total_amount' => $param['total_amount'],
  72. 'subject' => $param['body'],
  73. 'out_trade_no' => $param['out_trade_no'],
  74. ];
  75. // $request->setNotifyUrl(self::$notifyUrl);
  76. $request->setNotifyUrl(getWebUrl().'/api/aliResult');
  77. $request->setBizContent(json_encode($arrData, JSON_UNESCAPED_UNICODE));
  78. $result = $this->class->sdkExecute($request);
  79. if (!empty($result))
  80. return ['flag' => true, 'msg' => '调用成功', 'data' => ['result' => $result]];
  81. else
  82. return ['flag' => false, 'msg' => "统一下单失败"];
  83. } catch (\Exception $e) {
  84. // return ['flag' => false, 'msg' => "统一下单失败"];
  85. return ['flag' => false, 'msg' => $e->getMessage()];
  86. }
  87. }
  88. /**
  89. * 支付宝统一下单(Easy版本sdk)
  90. * @param array $param
  91. * @return array
  92. */
  93. public function easyUnifiedOrder (array $param)
  94. {
  95. try {
  96. $result = Factory::payment()->common()->create($param['body'], $param['out_trade_no'], $param['total_amount'], null);
  97. $responseChecker = new ResponseChecker();
  98. //3. 处理响应或异常
  99. if ($responseChecker->success($result)) {
  100. return ['flag' => true, 'msg' => '调用成功', 'data' => $result];
  101. } else {
  102. return ['flag' => false, 'msg' => "调用失败,原因:" . $result->msg . "," . $result->subMsg . PHP_EOL];
  103. }
  104. } catch (\Exception $e) {
  105. return ['flag' => false, 'msg' => "调用失败," . $e->getMessage() . PHP_EOL];
  106. }
  107. }
  108. /**
  109. * 提现
  110. * @param array $param
  111. * @return array
  112. * @throws \think\Exception
  113. */
  114. public function withdrawal (array $param)
  115. {
  116. $aop = new AopClient();
  117. $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
  118. $conf = Db::name('pay_config')->where('status', 1)->where('channel', 1)->field('public_key,app_id,private_key,app_cert_path,pay_root_cert,pay_cert_path,mchid')->find();
  119. sr_log(json_encode($conf));
  120. $aop->appId = $conf['app_id'];
  121. $aop->rsaPrivateKey = $conf['private_key']; // 应用私钥
  122. $aop->alipayrsaPublicKey = $conf['public_key']; // 支付宝公钥
  123. $aop->apiVersion = '1.0';
  124. $aop->signType = 'RSA2';
  125. $aop->postCharset = 'utf-8';
  126. $aop->format = 'json';
  127. $bizContent = [
  128. 'out_biz_no' => time() . rand(10000, 99999) . $param['uid'],
  129. 'trans_amount' => $param['practical_money'],
  130. 'product_code' => 'TRANS_ACCOUNT_NO_PWD',
  131. 'biz_scene' => 'DIRECT_TRANSFER',
  132. 'order_title' => '用户提现',
  133. 'payee_info' => [
  134. 'identity_type' => 'ALIPAY_LOGON_ID',
  135. 'identity' => $param['zfb_number'],
  136. 'name' => $param['zfb_name'],
  137. ],
  138. 'remark' => '用户提现'
  139. ];
  140. $request = new AlipayFundTransToaccountTransferRequest();
  141. $request->setBizContent(json_encode($bizContent, JSON_UNESCAPED_UNICODE));
  142. $result = $aop->execute($request);
  143. // sr_log('code'. json_encode($result));
  144. if (!$result) {
  145. return ['flag' => false, 'msg' => '系统出错'];
  146. }
  147. $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
  148. $resultCode = $result->{$responseNode}->code;
  149. if (!empty($resultCode) && $resultCode == 10000) {
  150. return ['flag' => true, 'data' => ['out_biz_no' => $result->{$responseNode}->out_biz_no]];
  151. } else {
  152. // sr_log($request->{$responseNode}->sub_msg);
  153. return ['flag' => false, 'msg' => $request->{$responseNode}->sub_msg];
  154. }
  155. }
  156. /**
  157. * 验签
  158. * @param array $param
  159. * @return bool
  160. */
  161. public function checkSign (array $param)
  162. {
  163. try {
  164. if ($this->pay_v == 1) {
  165. $obj = new AopCertClient();
  166. $param['fund_bill_list'] = html_entity_decode($param['fund_bill_list']); // 处理数据中存在&quot;
  167. return $obj->rsaCheckV1($param, self::$alipayCertPath, 'RSA2');
  168. } else {
  169. return Factory::payment()->common()->verifyNotify($param);
  170. }
  171. } catch (\Exception $e) {
  172. return false;
  173. }
  174. }
  175. /**
  176. * 公共参数
  177. * @return Config
  178. */
  179. static protected function getOptions ()
  180. {
  181. $options = new Config();
  182. $options->protocol = 'https';
  183. $options->gatewayHost = self::$gatewayUrl;
  184. $options->signType = self::$signType;
  185. $options->appId = self::$appId;
  186. $options->merchantPrivateKey = self::$rsaPrivateKey; // 应用私钥
  187. $options->alipayCertPath = self::$alipayCertPath; // 支付宝公钥证书文件路径
  188. $options->alipayRootCertPath = self::$rootCertPath; // 支付宝根证书文件路径
  189. $options->merchantCertPath = self::$appCertPath; // 应用公钥证书文件路径
  190. return $options;
  191. }
  192. /**
  193. * 支付宝配置
  194. * @throws \think\db\exception\DataNotFoundException
  195. * @throws \think\db\exception\DbException
  196. * @throws \think\db\exception\ModelNotFoundException
  197. */
  198. static protected function payConfig ()
  199. {
  200. $conf = Db::name('pay_config')->where('status', 1)->where('channel', 1)->field('app_id,private_key,app_cert_path,pay_root_cert,pay_cert_path,mchid')->find();
  201. if (empty($conf))
  202. throw new Exception('支付宝配置错误');
  203. self::$appCertPath = $conf['app_cert_path']; //应用公钥证书
  204. self::$alipayCertPath = $conf['pay_cert_path'];//支付宝公钥证书
  205. self::$rootCertPath = $conf['pay_root_cert'];//支付宝根证书
  206. self::$appId = $conf['app_id']; //APPID
  207. self::$rsaPrivateKey = $conf['private_key']; //支付宝应用私钥
  208. }
  209. }