| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- <?php
- namespace App\Http\Controllers\Api;
- use App\Http\logic\api\SfPayLogic;
- use App\Http\logic\api\SfPayCashierLogic;
- use App\Inter\PayMentInterFace;
- use App\Notification\TelegramBot;
- use App\Services\SfPay;
- use App\Util;
- use App\Utility\SetNXLock;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Redis;
- class SfPayController implements PayMentInterFace
- {
- /**
- * 代收下单
- */
- public function pay_order(
- $userId,
- $payAmt,
- $userName,
- $userEmail,
- $userPhone,
- $GiftsID,
- $buyIP,
- $AdId,
- $eventType,
- $pay_method = ''
- ) {
- $logic = new SfPayLogic();
- try {
- $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
- } catch (\Exception $exception) {
- Redis::set("PayErro_SfPay", 1);
- Redis::expire("PayErro_SfPay", 600);
- Util::WriteLog('SfPay_error', $exception->getMessage() . json_encode($logic->result ?? []));
- TelegramBot::getDefault()->sendProgramNotify("SfPay Except ", $exception->getMessage(), $exception);
- return apiReturnFail($logic->getError());
- }
- if (!empty($res) && isset($res['code']) && $res['code'] === 0) {
- // SfPay 成功返回: data.paymentLinkUrl 是支付链接
- $data = [
- 'content' => $res['data']['paymentLinkUrl'] ?? '',
- 'money' => $payAmt,
- 'prdOrdNo' => $res['data']['orderNo'] ?? '',
- ];
- return apiReturnSuc($data);
- }
- if ($res == false) {
- return apiReturnFail($logic->getError() ?: 'Payment failed');
- }
- // 非0的响应,记录错误
- Redis::set("PayErro_SfPay", 1);
- Redis::expire("PayErro_SfPay", 600);
- $errMsg = $res['msg'] ?? 'Unknown error';
- TelegramBot::getDefault()->sendProgramNotify("SfPay ReturnFail ", $errMsg . " | " . json_encode($res) . "$userId");
- return apiReturnFail(['web.payment.paytype_error', $errMsg]);
- }
- /**
- * 代收异步回调通知
- *
- * SfPay回调格式(POST JSON,不加密):
- * {
- * "data": {
- * "amount": "20.00",
- * "orderNo": "...",
- * "message": "Success",
- * "type": "payment",
- * "merchantOrderNo": "...",
- * "processedTime": "...",
- * "transferMode": "PIX",
- * "status": "SUCCESS"
- * },
- * "signature_n": "..."
- * }
- */
- public function notify(Request $request)
- {
- $post = $request->all();
- $payload = json_encode($post);
- Util::WriteLog('SfPay', "SfPay回调订单\n" . $payload);
- $callbackData = $post['data'] ?? [];
- $signatureN = $post['signature_n'] ?? '';
- if (empty($callbackData) || empty($signatureN)) {
- Util::WriteLog('SfPay', '回调数据不完整');
- return response()->json(['code' => 200]);
- }
- // 验签
- $service = new SfPay();
- if (!$service->verifySign($callbackData, $signatureN)) {
- Util::WriteLog('SfPay', '签名错误');
- return response()->json(['code' => 200]);
- }
- $order_sn = $callbackData['merchantOrderNo'] ?? '';
- if (empty($order_sn)) {
- Util::WriteLog('SfPay', '缺少商户订单号');
- return response()->json(['code' => 200]);
- }
- // 代收回调加锁,防止并发重复处理
- $lockKey = 'pay_notify_SfPay_' . $order_sn;
- if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
- Util::WriteLog('SfPay', '代收回调并发,订单已处理或处理中: ' . $order_sn);
- return response()->json(['code' => 200]);
- }
- $logic = new SfPayLogic();
- try {
- $ret = $logic->notify($post);
- return response()->json(['code' => 200]);
- } catch (\Exception $exception) {
- Redis::set("PayErro_SfPay", 1);
- Redis::expire("PayErro_SfPay", 600);
- TelegramBot::getDefault()->sendProgramNotify("SfPay 订单回调执行异常 ", json_encode($post), $exception);
- Util::WriteLog("SfPay_error", $post);
- return response()->json(['code' => 200]);
- } finally {
- SetNXLock::release($lockKey);
- }
- }
- /**
- * 代付异步回调通知
- *
- * SfPay代付回调格式(POST JSON,不加密):
- * {
- * "data": {
- * "amount": "30.00",
- * "orderNo": "...",
- * "message": "...",
- * "type": "payout",
- * "merchantOrderNo": "...",
- * "processedTime": "...",
- * "processAmount": "0.00",
- * "status": "SUCCESS"
- * },
- * "signature_n": "..."
- * }
- */
- public function cash_notify(Request $request)
- {
- $post = $request->all();
- $payload = json_encode($post);
- Util::WriteLog('SfPay', "SfPay 提现回调\n" . $payload);
- $callbackData = $post['data'] ?? [];
- $signatureN = $post['signature_n'] ?? '';
- if (empty($callbackData) || empty($signatureN)) {
- Util::WriteLog('SfPay', '提现回调数据不完整');
- return response('SUCCESS');
- }
- // 验签
- $service = new SfPay();
- if (!$service->verifySign($callbackData, $signatureN)) {
- Util::WriteLog('SfPay', '提现回调签名错误');
- return response('SUCCESS');
- }
- $logic = new SfPayCashierLogic();
- try {
- return $logic->notify($post);
- } catch (\Exception $exception) {
- TelegramBot::getDefault()->sendProgramNotify(
- "SfPay 提现异步回调执行异常 ",
- json_encode($post),
- $exception
- );
- Util::WriteLog("SfPay_error", $post);
- return response('SUCCESS');
- }
- }
- /**
- * 代收订单主动查询
- *
- * POST /api/sfpay/orderQuery
- * 用于回调未到达时主动查询订单状态
- */
- public function orderQuery(Request $request)
- {
- $merchantOrderNo = $request->input('merchantOrderNo', '');
- if (empty($merchantOrderNo)) {
- return apiReturnFail('merchantOrderNo is required');
- }
- $logic = new SfPayLogic();
- try {
- $res = $logic->orderQuery($merchantOrderNo);
- } catch (\Exception $e) {
- Util::WriteLog('SfPay_error', 'orderQuery exception: ' . $e->getMessage());
- return apiReturnFail('Query failed');
- }
- if ($res === false) {
- return apiReturnFail($logic->getError() ?: 'Query failed');
- }
- if (isset($res['code']) && $res['code'] === 0) {
- return apiReturnSuc($res['data'] ?? []);
- }
- return apiReturnFail($res['msg'] ?? 'Query error');
- }
- }
|