NewSupefinaSpeiController.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Http\logic\api\NewSupefinaSpeiLogic;
  4. use App\Http\logic\api\NewSupefinaSpeiCashierLogic;
  5. use App\Inter\PayMentInterFace;
  6. use App\Notification\TelegramBot;
  7. use App\Services\Aes;
  8. use App\Services\PayConfig;
  9. use App\Util;
  10. use App\Utility\SetNXLock;
  11. use Illuminate\Http\Request;
  12. use Illuminate\Support\Facades\Log;
  13. use Illuminate\Support\Facades\Redis;
  14. class NewSupefinaSpeiController implements PayMentInterFace
  15. {
  16. private $retryTimes = 0;
  17. public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
  18. {
  19. $logic = new NewSupefinaSpeiLogic();
  20. try {
  21. $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
  22. } catch (\Exception $exception) {
  23. Redis::set('PayErro_NewSupefinaSpei', 1);
  24. Redis::expire('PayErro_NewSupefinaSpei', 600);
  25. Util::WriteLog('NewSupefinaSpei_error', $exception->getMessage() . json_encode($logic->result ?? []));
  26. TelegramBot::getDefault()->sendProgramNotify('SupefinaSpei Except ', $exception->getMessage(), $exception);
  27. return apiReturnFail($logic->getError());
  28. }
  29. if (!empty($res) && isset($res['checkoutUrl'])) {
  30. $content = $res['checkoutUrl'] ?? '';
  31. if (empty($content) && !empty($res['receiveCode'])) {
  32. $content = 'CLABE:' . $res['receiveCode'];
  33. }
  34. return apiReturnSuc([
  35. 'content' => $content,
  36. 'money' => $payAmt,
  37. 'prdOrdNo' => $res['merchantOrderNo'] ?? '',
  38. 'identifier' => $res['receiveCode'] ?? '',
  39. 'clabe' => $res['receiveCode'] ?? '',
  40. 'bank' => $data['bankInfo']['bankCode'] ?? ''
  41. ]);
  42. }
  43. if ($res === false) {
  44. return apiReturnFail($logic->getError());
  45. }
  46. if ($this->retryTimes > 0) {
  47. Redis::set('PayErro_NewSupefinaSpei', 1);
  48. Redis::expire('PayErro_NewSupefinaSpei', 600);
  49. TelegramBot::getDefault()->sendProgramNotify('NewSupefinaSpei ReturnFail ', $logic->getError() . ' | ' . json_encode($res));
  50. return apiReturnFail($logic->getError());
  51. }
  52. $this->retryTimes++;
  53. return $this->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
  54. }
  55. /**
  56. * 统一回调入口:代收(01) + 代付(02),验签后按 transactionType 分发
  57. */
  58. public function notify(Request $request)
  59. {
  60. $headers = $request->headers->all();
  61. $payload = $request->getContent();
  62. $post = json_decode($payload, true);
  63. if (!is_array($post)) {
  64. $post = $request->all();
  65. }
  66. Util::WriteLog('NewSupefinaSpei', "raw notify\n" . $payload . ' ' . json_encode($headers));
  67. if (!isset($post['data'])) {
  68. Util::WriteLog('NewSupefinaSpei_error', 'empty data');
  69. return 'fail';
  70. }
  71. $sign = $request->header('sign');
  72. $logic = new NewSupefinaSpeiLogic();
  73. $signHeaders = [
  74. 'version' => $request->header('version'),
  75. 'merchantNo' => $request->header('merchantno'),
  76. 'requestId' => $request->header('requestid'),
  77. 'requestTime' => $request->header('requesttime'),
  78. ];
  79. $config = (new PayConfig())->getConfig('NewSupefinaSpei');
  80. $string = $logic->getSignString($signHeaders, $post);
  81. $res = $logic->verifySign($string, $sign, $config['publickey']);
  82. if ($res !== true) {
  83. Util::WriteLog('NewSupefinaSpei_error', 'notify sign invalid' . $string);
  84. return 'fail';
  85. }
  86. $data = Aes::decrypt($post['data'], base64_decode($config['aesKey']));
  87. Util::WriteLog('NewSupefinaSpei', 'decoded data'.$data);
  88. if (empty($data)) {
  89. Util::WriteLog('NewSupefinaSpei_error', 'des decrypt fail ' . $post['data']);
  90. return 'fail';
  91. }
  92. $data = json_decode($data, true);
  93. $lockKey = '';
  94. $orderId = $data['merchantOrderNo'];
  95. if ($orderId) {
  96. $lockKey = 'pay_notify_NewSupefinaSpei_' . $orderId;
  97. if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
  98. Util::WriteLog('NewSupefinaSpei', 'notify concurrent, ignore: ' . $orderId);
  99. return 'SUCCESS';
  100. }
  101. }
  102. try {
  103. $res = $logic->notify($data);
  104. } finally {
  105. if ($lockKey !== '') {
  106. SetNXLock::release($lockKey);
  107. }
  108. }
  109. return $res;
  110. }
  111. /**
  112. * 代付回调(保留兼容,建议统一用 notify)
  113. */
  114. public function cash_notify(Request $request)
  115. {
  116. $headers = $request->headers->all();
  117. $payload = $request->getContent();
  118. $post = json_decode($payload, true);
  119. if (!is_array($post)) {
  120. $post = $request->all();
  121. }
  122. Util::WriteLog('NewSupefinaSpei', "raw payout notify\n" . $payload . json_encode($headers));
  123. $sign = $request->header('sign');
  124. $logic = new NewSupefinaSpeiLogic();
  125. $signHeaders = [
  126. 'version' => $request->header('version'),
  127. 'merchantNo' => $request->header('merchantno'),
  128. 'requestId' => $request->header('requestid'),
  129. 'requestTime' => $request->header('requesttime'),
  130. ];
  131. $config = (new PayConfig())->getConfig('NewSupefinaSpei');
  132. $string = $logic->getSignString($signHeaders, $post);
  133. $res = $logic->verifySign($string, $sign, $config['publickey']);
  134. if ($res !== true) {
  135. Util::WriteLog('NewSupefinaSpei_error', 'payout notify sign invalid' . $string);
  136. return 'fail';
  137. }
  138. $data = Aes::decrypt($post['data'], base64_decode($config['aesKey']));
  139. Util::WriteLog('NewSupefinaSpei', 'decoded data'.$data);
  140. if (empty($data)) {
  141. Util::WriteLog('NewSupefinaSpei_error', 'des decrypt fail ' . $post['data']);
  142. return 'fail';
  143. }
  144. $data = json_decode($data, true);
  145. $lockKey = '';
  146. $orderId = $data['merchantOrderNo'];
  147. if ($orderId) {
  148. $lockKey = 'payout_notify_NewSupefinaSpei_' . $orderId;
  149. if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
  150. Util::WriteLog('NewSupefinaSpei', 'payout notify concurrent, ignore: ' . $orderId);
  151. return 'SUCCESS';
  152. }
  153. }
  154. try {
  155. $logic = new NewSupefinaSpeiLogic();
  156. $ret = $logic->cashNotify($data);
  157. } finally {
  158. if ($lockKey !== '') {
  159. SetNXLock::release($lockKey);
  160. }
  161. }
  162. return $ret;
  163. }
  164. }