CoinPayController.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Http\logic\api\CoinPayCashierLogic;
  4. use App\Http\logic\api\CoinPayLogic;
  5. use App\Inter\PayMentInterFace;
  6. use App\Notification\TelegramBot;
  7. use App\Services\CoinPay;
  8. use App\Util;
  9. use App\Utility\SetNXLock;
  10. use Illuminate\Http\Request;
  11. use Illuminate\Support\Facades\Redis;
  12. class CoinPayController implements PayMentInterFace
  13. {
  14. private $retryTimes = 0;
  15. public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
  16. {
  17. $logic = new CoinPayLogic();
  18. try {
  19. $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
  20. } catch (\Throwable $exception) {
  21. Redis::set('PayErro_CoinPay', 1, 'EX', 600);
  22. Util::WriteLog('CoinPay_error', $exception->getMessage());
  23. TelegramBot::getDefault()->sendProgramNotify('CoinPay pay error', $exception->getMessage(), $exception);
  24. return apiReturnFail($logic->getError());
  25. }
  26. if (isset($res['code']) && (int)$res['code'] === 0) {
  27. $data = [
  28. 'content' => $res['data']['url'] ?? '',
  29. 'money' => $payAmt,
  30. 'prdOrdNo' => $res['data']['orderNo'] ?? '',
  31. ];
  32. return apiReturnSuc($data);
  33. }
  34. if ($res === false) {
  35. return apiReturnFail($logic->getError());
  36. }
  37. if ($this->retryTimes > 0) {
  38. Redis::set('PayErro_CoinPay', 1, 'EX', 600);
  39. return apiReturnFail($logic->getError());
  40. }
  41. $this->retryTimes++;
  42. return $this->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
  43. }
  44. public function notify(Request $request)
  45. {
  46. $post = $request->all();
  47. Util::WriteLog('CoinPay', 'pay notify: ' . json_encode($post, JSON_UNESCAPED_UNICODE));
  48. $service = new CoinPay();
  49. if (!$service->verify($post)) {
  50. Util::WriteLog('CoinPay', 'pay notify verify failed');
  51. return 'fail';
  52. }
  53. $order_sn = $post['merchantOrderNo'] ?? '';
  54. if (empty($order_sn)) {
  55. Util::WriteLog('CoinPay', '缺少订单号');
  56. return 'fail';
  57. }
  58. // 代收回调加锁,防止并发重复处理
  59. $lockKey = 'pay_notify_CoinPay_' . $order_sn;
  60. if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
  61. Util::WriteLog('CoinPay', '代收回调并发,订单已处理或处理中: ' . $order_sn);
  62. return 'SUCCESS';
  63. }
  64. $logic = new CoinPayLogic();
  65. try {
  66. return $logic->notify($post);
  67. } catch (\Throwable $exception) {
  68. Redis::set('PayErro_CoinPay', 1, 'EX', 600);
  69. return '{"success":false,"message":"internal error"}';
  70. } finally {
  71. SetNXLock::release($lockKey);
  72. }
  73. }
  74. public function sync_notify(Request $request)
  75. {
  76. Util::WriteLog('CoinPay', 'sync callback: ' . json_encode($request->all(), JSON_UNESCAPED_UNICODE));
  77. return 'success';
  78. }
  79. public function cash_notify(Request $request)
  80. {
  81. $post = $request->all();
  82. Util::WriteLog('CoinPay', 'cash notify: ' . json_encode($post, JSON_UNESCAPED_UNICODE));
  83. $service = new CoinPay('CoinPayOut');
  84. if (!$service->verify($post)) {
  85. Util::WriteLog('CoinPay', 'cash notify verify failed');
  86. return 'fail';
  87. }
  88. $logic = new CoinPayCashierLogic();
  89. try {
  90. return $logic->notify($post);
  91. } catch (\Throwable $exception) {
  92. return '{"success":false,"message":"internal error"}';
  93. }
  94. }
  95. }