where('tenant_id', $tenantId) ->first(); if (! $member || empty($member->barobill_id)) { return ['success' => false, 'error' => '바로빌 회원 정보 없음']; } $this->soapService->initForMember($member); $cards = $this->getRegisteredCards($member); if (empty($cards)) { return ['success' => true, 'message' => '등록된 카드 없음', 'synced' => 0]; } $totalSynced = 0; foreach ($cards as $card) { $cardNum = $card['cardNum']; $result = $this->soapService->getPeriodCardLog( $member->biz_no, $member->barobill_id, $cardNum, $startDateYmd, $endDateYmd ); if (! $result['success']) { Log::warning("[CardSync] 카드 조회 실패: {$cardNum}", [ 'error' => $result['error'] ?? '', ]); continue; } $data = $result['data']; if (is_numeric($data) && $data < 0) { continue; } $rawLogs = []; if (isset($data->CardLogList) && isset($data->CardLogList->CardLog)) { $logs = $data->CardLogList->CardLog; $rawLogs = is_array($logs) ? $logs : [$logs]; } if (! empty($rawLogs)) { $count = $this->cacheTransactions( $tenantId, $cardNum, $card['cardCompany'], $card['cardCompanyName'], $rawLogs ); $totalSynced += $count; Log::debug("[CardSync] 카드 {$cardNum}: {$count}건 저장"); } } return [ 'success' => true, 'synced' => $totalSynced, 'cards' => count($cards), ]; } /** * 바로빌 등록 카드 목록 조회 (SOAP) */ public function getRegisteredCards(BarobillMember $member): array { $result = $this->soapService->getCards($member->biz_no, false); if (! $result['success']) { return []; } $data = $result['data']; $cardList = []; if (isset($data->CardEx2)) { $cardList = is_array($data->CardEx2) ? $data->CardEx2 : [$data->CardEx2]; } elseif (isset($data->Card)) { $cardList = is_array($data->Card) ? $data->Card : [$data->Card]; } $cards = []; foreach ($cardList as $card) { if (! is_object($card)) { continue; } $cardNum = $card->CardNum ?? ''; if (empty($cardNum) || (is_numeric($cardNum) && $cardNum < 0)) { continue; } $cards[] = [ 'cardNum' => $cardNum, 'cardCompany' => $card->CardCompany ?? '', 'cardCompanyName' => BarobillSoapService::$cardCompanyCodes[$card->CardCompany ?? ''] ?? '', 'alias' => $card->Alias ?? '', ]; } return $cards; } /** * API 응답을 DB에 배치 저장 */ protected function cacheTransactions( int $tenantId, string $cardNum, string $cardCompany, string $cardCompanyName, array $rawLogs ): int { $rows = []; $now = now(); foreach ($rawLogs as $log) { $useDT = $log->UseDT ?? ''; $useDate = strlen($useDT) >= 8 ? substr($useDT, 0, 8) : ''; $useTime = strlen($useDT) >= 14 ? substr($useDT, 8, 6) : ''; $rows[] = [ 'tenant_id' => $tenantId, 'card_num' => $log->CardNum ?? $cardNum, 'card_company' => $log->CardCompany ?? $cardCompany, 'card_company_name' => $cardCompanyName, 'use_dt' => $useDT, 'use_date' => $useDate, 'use_time' => $useTime, 'approval_num' => $log->ApprovalNum ?? '', 'approval_type' => $log->ApprovalType ?? '', 'approval_amount' => floatval($log->ApprovalAmount ?? 0), 'tax' => floatval($log->Tax ?? 0), 'service_charge' => floatval($log->ServiceCharge ?? 0), 'payment_plan' => $log->PaymentPlan ?? '', 'currency_code' => $log->CurrencyCode ?? '', 'merchant_name' => $log->MerchantName ?? '', 'merchant_biz_num' => $log->MerchantBizNum ?? '', 'merchant_addr' => $log->MerchantAddr ?? '', 'merchant_ceo' => '', 'merchant_biz_type' => '', 'merchant_tel' => '', 'use_key' => $log->UseKey ?? '', 'is_manual' => false, 'created_at' => $now, 'updated_at' => $now, ]; } $inserted = 0; foreach (array_chunk($rows, 100) as $batch) { $inserted += DB::table('barobill_card_transactions')->insertOrIgnore($batch); } return $inserted; } }