verify($userId, $GiftsID, $pay_amount); if ($PayVerify->verify($userId, $GiftsID, $pay_amount) === false) { $this->error = $PayVerify->getError(); return false; } if ($pay_amount < 0) { $this->error = 'Payment error_4'; return false; } $service = new SupefinaSpei('SupefinaSpei'); $config = $service->config; $merId = $config['merId'] ?? ''; $baseUrl = $config['baseUrl'] ?? ''; $payinPath = $config['payinPath'] ?? '/api/supefina/transactions/collection'; $callbackUrl = $config['callbackUrl'] ?? ''; $countryId = $config['countryId'] ?? 'MEX'; $currency = $config['currency'] ?? 'MXN'; $minOrderAmount = $config['minOrderAmount'] ?? '10.00'; $maxOrderAmount = $config['maxOrderAmount'] ?? '15000.00'; if ($merId === '' || $baseUrl === '' || empty($config['key']) || $callbackUrl === '') { $this->error = 'Payment config error'; return false; } $order_sn = CreateOrder::order_sn($userId); $logic = new OrderLogic(); $amount = (int) round($pay_amount * NumConfig::NUM_VALUE); $logic->orderCreate($order_sn, $amount, 'SupefinaSpei', $userId, $pay_method, $GiftsID, $AdId, $eventType); $orderAmount = (string) (int) $pay_amount; if ($pay_amount != (int) $pay_amount) { $orderAmount = number_format($pay_amount, 2, '.', ''); } $params = [ 'callbackUrl' => $callbackUrl, 'countryId' => $countryId, 'currency' => $currency, 'maxOrderAmount' => $maxOrderAmount, 'merId' => (string) $merId, 'merOrderNo' => $order_sn, 'minOrderAmount' => $minOrderAmount, 'nonceStr' => $service->generateNonceStr(32), 'orderAmount' => $orderAmount, 'payProduct' => '15', 'repeat' => 'true', ]; $signedParams = $service->sign($params); $request_extra = \GuzzleHttp\json_encode($signedParams); CreateLog::pay_request($userPhone, $request_extra, $order_sn, $userEmail, $userId, $userName); $url = rtrim($baseUrl, '/') . $payinPath; Util::WriteLog('SupefinaSpei', 'payin request: ' . $url . ' | ' . $request_extra); try { $result = $service->postJson($url, $signedParams); } catch (\Throwable $e) { Util::WriteLog('SupefinaSpei_error', 'payin request exception: ' . $e->getMessage()); $this->error = 'Payment processing error'; return false; } Util::WriteLog('SupefinaSpei', 'payin response: ' . $result); try { $data = \GuzzleHttp\json_decode($result, true); } catch (\Throwable $e) { Util::WriteLog('SupefinaSpei_error', [$result, $e->getMessage()]); $this->error = 'Payment processing error'; return false; } if (!isset($data['code']) || (string)$data['code'] !== '200') { $this->error = $data['msg'] ?? 'Payment request failed'; return false; } $this->result = $data; return $data; } /** * 代收回调:仅代收存在“实际金额与订单金额不一致”,以 realityAmount 入账 * * @param array $post */ public function notify($post) { $order_sn = $post['merOrderId'] ?? $post['merOrderNo'] ?? ''; if ($order_sn === '') { Util::WriteLog('SupefinaSpei_error', 'payin notify missing merOrderId'); return 'fail'; } try { $order = DB::connection('write')->table('agent.dbo.order')->where('order_sn', $order_sn)->first(); if (!$order) { Util::WriteLog('SupefinaSpei', 'payin order not found: ' . $order_sn); return 'SUCCESS'; } if (!empty($order->pay_at) || !empty($order->finished_at)) { return 'SUCCESS'; } $status = (string)($post['status'] ?? ''); if ($status === '03') { $body = ['pay_status' => 2, 'updated_at' => date('Y-m-d H:i:s')]; DB::connection('write')->table('agent.dbo.order')->where('order_sn', $order_sn)->update($body); return 'SUCCESS'; } if ($status !== '01') { Util::WriteLog('SupefinaSpei', 'payin notify status not success: ' . $status); return 'SUCCESS'; } $GiftsID = $order->GiftsID ?: ''; $userID = $order->user_id ?: ''; $AdId = $order->AdId ?: ''; $eventType = $order->eventType ?: ''; $realityAmount = isset($post['realityAmount']) ? (float)$post['realityAmount'] : (float)($post['amount'] ?? 0); if ($realityAmount <= 0) { Util::WriteLog('SupefinaSpei_error', 'payin notify invalid realityAmount: ' . json_encode($post)); return 'fail'; } $payAmt = round($realityAmount, 2); $amountInScore = (int) round($payAmt * NumConfig::NUM_VALUE); $body = [ 'payment_sn' => $post['supefinaOrderId'] ?? $post['reference'] ?? '', 'pay_status' => 1, 'pay_at' => date('Y-m-d H:i:s'), 'finished_at' => date('Y-m-d H:i:s'), 'amount' => $amountInScore, 'updated_at' => date('Y-m-d H:i:s'), ]; $config = (new PayConfig())->getConfig('SupefinaSpei'); $body['payment_fee'] = isset($config['payin_fee']) ? $amountInScore * $config['payin_fee'] : 0; $service = new OrderServices(); if ((int)$order->amount != $amountInScore) { $body['GiftsID'] = 0; $body['amount'] = $amountInScore; $Recharge = $payAmt; $give = 0; $favorable_price = $Recharge + $give; $czReason = 1; $cjReason = 45; } else { [$give, $favorable_price, $Recharge, $czReason, $cjReason] = $service->getPayInfo($GiftsID, $userID, $payAmt); } [$Score] = $service->addRecord($userID, $payAmt, $favorable_price, $order_sn, $GiftsID, $Recharge, $czReason, $give, $cjReason, $AdId, $eventType); Order::dispatch([$userID, $payAmt, $Score, $favorable_price, $GiftsID, $order_sn]); DB::connection('write')->table('agent.dbo.order')->where('order_sn', $order_sn)->update($body); Util::WriteLog('SupefinaSpei', 'payin success, order_sn=' . $order_sn . ', realityAmount=' . $realityAmount); return 'SUCCESS'; } catch (\Throwable $exception) { Util::WriteLog('SupefinaSpei_error', $exception->getMessage() . "\n" . $exception->getTraceAsString()); throw $exception; } } }