IpaynowPayService.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: lts
  5. * Date: 2019-04-28
  6. * Time: 15:48
  7. */
  8. namespace app\main\service;
  9. use app\main\constants\ApiConstants;
  10. use GuzzleHttp\Client as Http;
  11. use GuzzleHttp\Exception\GuzzleException;
  12. use think\Exception;
  13. class IpaynowPayService
  14. {
  15. protected static $self = null;
  16. private $_key;
  17. function __construct($key)
  18. {
  19. $this->_key = $key;
  20. }
  21. public static function instance($key)
  22. {
  23. if (self::$self == null) {
  24. self::$self = new self($key);
  25. }
  26. return self::$self;
  27. }
  28. /**
  29. * 构造sign签名参数
  30. * @param array $params
  31. * @return bool|string
  32. */
  33. public function makeSign($params)
  34. {
  35. if (!empty($params)) {
  36. ksort($params);
  37. $str = '';
  38. foreach ($params as $k => $v) {
  39. if ($v == '' || $k == 'signature') {
  40. continue;
  41. }
  42. $str .= $k . '=' . $v . '&';
  43. }
  44. return strtolower(md5($str . md5($this->_key)));
  45. }
  46. return false;
  47. }
  48. /**
  49. * 验证sign签名参数
  50. * @param array $params
  51. * @return bool
  52. */
  53. public function verifySign($params)
  54. {
  55. if (empty($params['signature'])) {
  56. LogService::info('signature参数不存在,现在支付签名校验失败');
  57. return false;
  58. }
  59. $originalSign = $params['signature'];
  60. $sign = $this->makeSign($params);
  61. if ($originalSign != $sign) {
  62. LogService::info('signature参数有误,现在支付签名校验失败');
  63. return false;
  64. } else {
  65. LogService::info('signature参数成功,现在支付签名校验成功');
  66. return true;
  67. }
  68. }
  69. /**
  70. * 现在支付调用API接口
  71. * @param $data 加密前的明文参数
  72. * @param $payInfo 支付信息
  73. * @param $goodsInfo 商品信息
  74. * @param $orderInfo 订单信息
  75. * @param int $loopIndex 循环调用API的次数
  76. * @return \Psr\Http\Message\ResponseInterface
  77. * @throws Exception
  78. */
  79. public function payIpaynowApi($data, $payInfo, $goodsInfo, $orderInfo, $loopIndex = 1)
  80. {
  81. $payUrl = ApiConstants::IPAYNOW_PAY_URL;
  82. $ipaynowApiStartTime = microtime(true);
  83. try {
  84. $client = new Http([
  85. 'connect_timeout' => 10,
  86. 'timeout' => 30,
  87. 'http_errors' => true, //抛出异常 true是 false否
  88. 'verify' => false, //不验证ssl证书
  89. 'curl' => [
  90. CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_1
  91. ],
  92. ]);
  93. $result = $client->post($payUrl, ['form_params' => $data]);
  94. $ipaynowApiEndTime = microtime(true);
  95. $apiRunTime = round($ipaynowApiEndTime - $ipaynowApiStartTime, 3);
  96. if ($result->getStatusCode() != '200') {
  97. LogService::error(sprintf('ipaynow_create_order_fail!wxpay_id:%s,wxpay_name:%s,mch_id:%s,channel_id:%s,user_id:%s,money:%s,good_id:%s,out_trade_no:%s,api_run_time:%s s,loop_index:%s,errmessage:%s',
  98. $payInfo['id'], $payInfo['name'], $payInfo['quartet_merchant_id'], $orderInfo['admin_id'],
  99. $orderInfo['user_id'], $goodsInfo['money'], $orderInfo['goods_id'], $orderInfo['out_trade_no'],
  100. $apiRunTime, $loopIndex, json_encode(var_export($result, true), JSON_UNESCAPED_UNICODE)));
  101. LogService::error('现在支付平台订单创建失败!订单内容1: ' . json_encode(var_export($data, true),
  102. JSON_UNESCAPED_UNICODE) . " 现在支付平台返回内容: " . json_encode(var_export($result, true),
  103. JSON_UNESCAPED_UNICODE));
  104. throw new Exception('订单创建失败,请重新下单!');
  105. } else {
  106. $resStr = $result->getBody()->getContents();
  107. parse_str($resStr, $result);
  108. $verifyResponseResult = $this->verifySign($result);
  109. if ($result['responseCode'] != 'A001' || !$verifyResponseResult) {
  110. LogService::error(sprintf('ipaynow_create_order_fail!wxpay_id:%s,wxpay_name:%s,mch_id:%s,channel_id:%s,user_id:%s,money:%s,good_id:%s,out_trade_no:%s,api_run_time:%s s,loop_index:%s,errmessage:%s',
  111. $payInfo['id'], $payInfo['name'], $payInfo['quartet_merchant_id'], $orderInfo['admin_id'],
  112. $orderInfo['user_id'], $goodsInfo['money'], $orderInfo['goods_id'], $orderInfo['out_trade_no'],
  113. $apiRunTime, $loopIndex, $result['responseMsg']));
  114. LogService::error('现在支付平台订单创建失败!订单内容2:' . json_encode(var_export($data,
  115. true)) . " 现在支付平台返回错误码: " . $result['responseCode']);
  116. throw new Exception('订单创建失败,请重新下单!');
  117. }
  118. }
  119. LogService::info(sprintf('ipaynow_create_order_success!wxpay_id:%s,wxpay_name:%s,mch_id:%s,channel_id:%s,user_id:%s,money:%s,good_id:%s,out_trade_no:%s,api_run_time:%s s,loop_index:%s',
  120. $payInfo['id'], $payInfo['name'], $payInfo['quartet_merchant_id'], $orderInfo['admin_id'],
  121. $orderInfo['user_id'], $goodsInfo['money'], $orderInfo['goods_id'], $orderInfo['out_trade_no'],
  122. $apiRunTime, $loopIndex));
  123. return $result;
  124. } catch (GuzzleException $exception) {
  125. $ipaynowApiEndTime = microtime(true);
  126. $apiRunTime = round($ipaynowApiEndTime - $ipaynowApiStartTime, 3);
  127. LogService::error(sprintf('ipaynow_create_order_fail!wxpay_id:%s,wxpay_name:%s,mch_id:%s,channel_id:%s,user_id:%s,money:%s,good_id:%s,out_trade_no:%s,api_run_time:%s s,loop_index:%s,errmessage:%s',
  128. $payInfo['id'], $payInfo['name'], $payInfo['quartet_merchant_id'], $orderInfo['admin_id'],
  129. $orderInfo['user_id'], $goodsInfo['money'], $orderInfo['goods_id'], $orderInfo['out_trade_no'],
  130. $apiRunTime, $loopIndex, $exception->getMessage()));
  131. LogService::error('现在支付平台订单创建失败!订单内容3: ' . json_encode(var_export($data, true), JSON_UNESCAPED_UNICODE));
  132. LogService::error($exception->getMessage());
  133. LogService::error($exception->getTraceAsString());
  134. if ($loopIndex <= ApiConstants::LOOP_EXEC_API_COUNT) {
  135. $loopIndex++;
  136. return $this->payIpaynowApi($data, $payInfo, $goodsInfo, $orderInfo, $loopIndex);
  137. }
  138. throw new Exception('订单创建失败,请重新下单!');
  139. }
  140. }
  141. }