# 바로빌 카카오톡 (알림톡/친구톡) 연동 > **문서 버전**: 1.0 > **작성일**: 2026-02-14 > **최종 수정**: 2026-02-24 > **상태**: 운영 중 (전자계약 알림톡 발송 완료) > **대상 프로젝트**: MNG --- ## 1. 개요 ### 1.1 목적 바로빌(Barobill) 플랫폼의 카카오톡 알림톡/친구톡 API를 SAM에 연동하여, 고객사에 카카오톡 메시지를 자동 또는 수동으로 발송하는 기능을 제공한다. ### 1.2 사전 요구사항 | 항목 | 상태 | 설명 | |------|------|------| | 법인 명의 휴대폰 준비 | **완료** | 카카오톡 채널 가입에 법인 명의 번호 사용 | | 카카오톡 채널 개설 | **완료** (2026-02-20) | 채널 ID: `@codebridge`, 채널명: (주)코드브릿지엑스 | | 바로빌 카카오톡 서비스 신청 | **완료** (2026-02-20) | 바로빌 관리자 페이지에서 카카오톡 서비스 활성화 | | 채널 연동 (바로빌↔카카오) | **완료** (2026-02-20) | 바로빌 관리 URL에서 채널 연동 처리 | | 바로빌 파트너 과금 설정 | **완료** (2026-02-23) | 바로빌 측에서 파트너사 과금 설정 완료 | | 알림톡 템플릿 v1 검수 | **완료** (2026-02-22) | `전자계약_서명요청`, `전자계약_리마인드` 2종 승인 | | 알림톡 템플릿 v2 검수 | **심사 중** (2026-02-24 접수) | 버튼 URL에 `#{토큰}` 변수 포함 2종 재등록 | > 상세 등록 가이드: [카카오톡 알림톡 채널 및 템플릿 등록 가이드](../../guides/카카오톡-알림톡-채널-템플릿-등록.md) ### 1.3 알림톡 vs 친구톡 | 구분 | 알림톡 | 친구톡 | |------|--------|--------| | **용도** | 정보성 메시지 (주문확인, 배송안내 등) | 광고성 메시지 (프로모션, 이벤트 등) | | **수신 대상** | 모든 카카오톡 사용자 | 채널 친구 추가한 사용자만 | | **템플릿** | 필수 (카카오 사전 검수) | 불필요 (자유 형식) | | **광고 표시** | 불가 | 필수 (`(광고)` 표기) | | **이미지 첨부** | 불가 | 가능 (이미지/와이드 이미지) | | **비용** | 건당 약 8~9원 | 건당 약 15~20원 | | **SMS 대체발송** | 설정 가능 | 설정 가능 | --- ## 2. 아키텍처 ### 2.1 시스템 구조 ``` SAM MNG (브라우저) │ ├─ [페이지] /barobill/kakaotalk/* ← Blade 뷰 │ KakaotalkController (페이지 렌더링) │ ├─ [API] /api/admin/barobill/kakaotalk/* ← AJAX 호출 │ BarobillKakaotalkController │ └─ [전자계약] /esign/* ← 자동 발송 EsignApiController::sendAlimtalk() │ └─ BarobillService (SOAP 클라이언트) │ └─ 바로빌 KAKAOTALK.asmx (WSDL) │ └─ 카카오톡 서버 ``` ### 2.2 바로빌 SOAP API 엔드포인트 | 환경 | WSDL URL | |------|----------| | **테스트** | `https://testws.baroservice.com/KAKAOTALK.asmx?WSDL` | | **운영** | `https://ws.baroservice.com/KAKAOTALK.asmx?WSDL` | --- ## 3. 전자계약 알림톡 연동 (핵심) ### 3.1 발송 흐름 ``` 전자계약 생성 (E-Sign) │ ├─ [1단계] EsignApiController::sendAlimtalk() │ │ │ ├─ 채널 ID 조회 (getKakaotalkChannelId) │ ├─ 템플릿 본문 + 버튼 조회 (getTemplateData) │ ├─ 변수 치환 (#{이름}, #{계약명}, #{기한}) │ └─ SendATKakaotalkEx 호출 │ ├─ [2단계] 바로빌 접수 → SendKey 반환 │ ├─ [3단계] 3초 대기 후 GetSendKakaotalk으로 전달 결과 확인 │ │ │ ├─ ResultCode = 1 → 성공 │ └─ ResultCode != 1 → 실패 (에러 반환) │ └─ [이메일 폴백] 알림톡 실패 시 이메일로 자동 전환 ``` ### 3.2 등록된 템플릿 (v1 — 현재 운영) **`전자계약_서명요청`** ``` 안녕하세요, #{이름}님. 전자계약 서명 요청이 도착했습니다. ■ 계약명: #{계약명} ■ 서명 기한: #{기한} 아래 버튼을 눌러 계약서를 확인하고 서명해 주세요. ``` - 버튼: `계약서 확인하기` (WL) - Url1/Url2: `https://mng.codebridge-x.com` **`전자계약_리마인드`** ``` 안녕하세요, #{이름}님. 아직 서명이 완료되지 않은 전자계약이 있습니다. ■ 계약명: #{계약명} ■ 서명 기한: #{기한} 기한 내에 서명을 완료해 주세요. ``` - 버튼: `계약서 확인하기` (WL) - Url1/Url2: `https://mng.codebridge-x.com` ### 3.3 등록 예정 템플릿 (v2 — 심사 중) > **2026-02-24 재등록**: 버튼 URL에 `#{토큰}` 변수를 포함하여 동적 서명 URL 지원 - Url1/Url2: `https://mng.codebridge-x.com/esign/sign/#{토큰}` v2 승인 후 코드 변경 필요: - `EsignApiController::sendAlimtalk()`에서 동적 `$signUrl`을 버튼 URL로 전달 - 현재 코드의 등록된 URL 그대로 사용 → 동적 URL 사용으로 전환 ### 3.4 임시 우회: 로그인 페이지 서명 확인 v1 템플릿의 버튼 URL이 대시보드(`https://mng.codebridge-x.com`)로 고정되어 있어, 로그인 페이지에 전화번호 기반 서명 확인 기능을 추가하였다. ``` 알림톡 버튼 클릭 → https://mng.codebridge-x.com → 로그인 페이지 │ └─ "전자계약 서명하기" 섹션 │ ├─ 전화번호 입력 ├─ POST /esign/verify-phone └─ 대기 중인 계약 조회 → /esign/sign/{token} 리다이렉트 ``` - 라우트: `POST /esign/verify-phone` - 컨트롤러: `EsignPublicController::verifyPhone()` - v2 템플릿 승인 후에도 유지 (비로그인 사용자 대응) ### 3.5 관련 파일 | 파일 | 역할 | |------|------| | `app/Http/Controllers/ESign/EsignApiController.php` | `sendAlimtalk()`, `getTemplateData()` | | `app/Http/Controllers/ESign/EsignPublicController.php` | `verifyPhone()` 전화번호 확인 | | `app/Services/Barobill/BarobillService.php` | SOAP 클라이언트, `sendATKakaotalkEx()` | | `resources/views/auth/login.blade.php` | 로그인 페이지 서명 확인 UI | | `routes/web.php` | `/esign/verify-phone` 라우트 | --- ## 4. 트러블슈팅 (실전 경험) > **경고: 아래 내용은 실제 연동 과정에서 발견한 핵심 이슈다. 반드시 숙지할 것.** ### 4.1 바로빌 API 응답 구조 바로빌 SOAP 응답은 `stdClass` 객체로 반환된다. 배열이 아니므로 주의: ```php // ❌ 잘못된 접근 $channels = $result['data']; // 배열이 아님 // ✅ 올바른 접근 $data = $result['data']; // stdClass $channels = is_array($data->KakaotalkChannel) ? $data->KakaotalkChannel : [$data->KakaotalkChannel]; // 1건이면 객체, N건이면 배열 ``` ### 4.2 SendKey vs ResultCode (2단계 검증 필수) > **핵심**: 바로빌이 SendKey를 반환해도 **실제 카카오톡 전달이 실패할 수 있다.** ``` [1단계] SendATKakaotalkEx 호출 → SendKey 반환 (예: BB_6648603713_AT_3044107_260224) → 이것은 "접수 성공"이지 "전달 성공"이 아님! [2단계] 3초 후 GetSendKakaotalk(SendKey) 호출 → ResultCode = 1: 전달 성공 ✅ → ResultCode = 4: 템플릿 데이터 일치 오류 ❌ → ResultCode != 1: 기타 실패 ❌ ``` ```php // 반드시 2단계 검증 필요 if ($result['success'] && is_string($result['data'])) { $sendKey = $result['data']; sleep(3); // 카카오톡 전달 대기 $sendResult = $barobill->getSendKakaotalk($member->biz_no, $sendKey); $resultCode = $sendResult['data']->ResultCode ?? null; if ($resultCode != 1) { // 실패 처리! } } ``` ### 4.3 템플릿 URL 정확 일치 규칙 > **핵심**: 버튼 URL은 등록된 템플릿의 URL과 **정확히 일치**해야 한다. 1글자라도 다르면 실패. | 등록된 URL | 전송 시 URL | 결과 | |------------|------------|------| | `https://mng.codebridge-x.com` | `https://mng.codebridge-x.com` | ResultCode=1 (성공) | | `https://mng.codebridge-x.com` | `https://mng.codebridge-x.com/esign/sign/xxx` | ResultCode=4 (실패) | | `https://mng.codebridge-x.com` | `https://mng.codebridge-x.com?sign=xxx` | ResultCode=4 (실패) | | `https://mng.codebridge-x.com` | `https://mng.codebridge-x.com#sign=xxx` | ResultCode=4 (실패) | - 경로 추가: 실패 - 쿼리 파라미터 추가: 실패 - URL 프래그먼트(#) 추가: 실패 - **동적 URL을 사용하려면 템플릿에 `#{변수}` 포함하여 재등록 필요** ### 4.4 SmsReply 오류 (-31325) `SmsReply` 파라미터가 `'S'`(대체발송 사용)인데 `SmsSenderNum`이 비어있으면 `-31325` 오류 발생. ```php // ❌ 오류 발생 'SmsReply' => empty($smsMessage) ? 'N' : 'S', // SmsSenderNum이 비어도 S로 설정 // ✅ 수정 'SmsReply' => (empty($smsMessage) || empty($smsSenderNum)) ? 'N' : 'S', ``` ### 4.5 SOAP 파라미터 구조 바로빌 SOAP API의 파라미터 구조에 주의: ```php // 올바른 구조 $params = [ 'CorpNum' => $bizNo, // 사업자번호 (하이픈 포함: 123-45-67890) 'SenderID' => $barobillId, // 바로빌 계정 ID 'YellowId' => $channelId, // 카카오 채널 ID (@codebridge) 'TemplateName' => '전자계약_서명요청', 'SendDT' => '', // 즉시발송: 빈 문자열 'SmsReply' => 'N', // SMS 발신번호 없으면 반드시 'N' 'SmsSenderNum' => '', 'KakaotalkMessage' => [ 'ReceiverName' => $name, 'ReceiverNum' => $phone, // 하이픈 없이: 01012345678 'Title' => '', 'Message' => $message, // 템플릿 변수 치환 완료된 본문 'SmsMessage' => '', 'SmsSubject' => '', 'Buttons' => ['KakaotalkButton' => $buttons], // 버튼 배열 ], ]; ``` ### 4.6 에러 코드 정리 | 코드 | 메시지 | 원인 | 해결 | |------|--------|------|------| | 1 | 성공 | 정상 전달 | - | | 4 | 템플릿 데이터 일치 오류 | 본문/버튼 URL이 등록 템플릿과 불일치 | 등록된 템플릿과 동일하게 전송 | | -31325 | 대체문자 유형 오류 | SmsReply=S인데 SmsSenderNum 비어있음 | SmsReply를 N으로 설정 | | 음수값 | 바로빌 API 오류 | 파라미터 오류 또는 서비스 미설정 | 바로빌 에러코드 문서 참조 | --- ## 5. 구현 현황 ### 5.1 완료된 항목 | 구분 | 파일 | 설명 | |------|------|------| | SOAP 서비스 | `app/Services/Barobill/BarobillService.php` | kakaotalk SOAP 클라이언트 + 15개 API 메서드 | | 전자계약 알림톡 | `app/Http/Controllers/ESign/EsignApiController.php` | `sendAlimtalk()`, `getTemplateData()` | | 서명 확인 | `app/Http/Controllers/ESign/EsignPublicController.php` | `verifyPhone()` 전화번호 기반 서명 확인 | | API 컨트롤러 | `app/Http/Controllers/Api/Admin/Barobill/BarobillKakaotalkController.php` | 15개 API 엔드포인트 | | 페이지 컨트롤러 | `app/Http/Controllers/Barobill/KakaotalkController.php` | 6개 관리 페이지 | | 로그인 페이지 | `resources/views/auth/login.blade.php` | 전자계약 서명하기 섹션 | | 라우트 | `routes/web.php` | `/esign/verify-phone`, `/barobill/kakaotalk/*` | | 메뉴 등록 | DB (menus 테이블) | 로컬/서버 모두 등록 완료 | ### 5.2 검증 완료 항목 | 항목 | 결과 | 날짜 | |------|------|------| | 채널 API 호출 | **성공** | 2026-02-22 | | 템플릿 조회 | **성공** | 2026-02-22 | | 알림톡 발송 (본문) | **성공** (ResultCode=1) | 2026-02-24 | | 알림톡 버튼 URL | **성공** (등록된 URL 사용 시) | 2026-02-24 | | 전달 결과 확인 (2단계) | **구현 완료** | 2026-02-24 | | 로그인 페이지 서명 확인 | **성공** | 2026-02-24 | ### 5.3 대기 중인 항목 | 항목 | 상태 | 비고 | |------|------|------| | 템플릿 v2 승인 | **심사 중** | 버튼 URL에 `#{토큰}` 변수 포함 | | v2 승인 후 코드 수정 | **대기** | 동적 서명 URL을 버튼에 전달 | | `전자계약_완료` 템플릿 | **미등록** | 서명 완료 알림 발송용 | | SMS 대체발송 | **미설정** | 발신번호 등록 필요 | | 친구톡 발송 | **대기** | 채널 친구 추가 후 가능 | | 대량 발송 | **대기** | 단건 안정화 후 | --- ## 6. v2 템플릿 승인 후 코드 변경 가이드 ### 6.1 변경 대상 `EsignApiController::sendAlimtalk()` (약 1059~1063행) ### 6.2 현재 코드 (v1) ```php // 등록된 버튼 URL을 그대로 사용 (동적 URL 사용 시 템플릿 불일치 오류) $buttons = ! empty($templateButtons) ? $templateButtons : [ ['Name' => '계약서 확인하기', 'ButtonType' => 'WL', 'Url1' => 'https://mng.codebridge-x.com', 'Url2' => 'https://mng.codebridge-x.com'], ]; ``` ### 6.3 변경 코드 (v2 승인 후) ```php // v2 템플릿: 버튼 URL에 동적 서명 URL 사용 $buttons = [ ['Name' => '계약서 확인하기', 'ButtonType' => 'WL', 'Url1' => $signUrl, 'Url2' => $signUrl], ]; ``` - `$signUrl`은 1033행에서 이미 생성됨: `config('app.url').'/esign/sign/'.$signer->access_token` - `getTemplateData()`에서 등록된 버튼 조회는 더 이상 필요 없음 (제거 가능) --- ## 7. API 메서드 목록 ### 7.1 BarobillService 카카오톡 메서드 | 메서드 | SOAP Action | 설명 | |--------|-------------|------| | `getKakaotalkChannels` | `GetKakaotalkChannels` | 채널 목록 조회 | | `getKakaotalkChannelManagementUrl` | `GetKakaotalkChannelManagementURL` | 채널 관리 URL | | `getKakaotalkTemplates` | `GetKakaotalkTemplates` | 템플릿 목록 조회 | | `getKakaotalkTemplateManagementUrl` | `GetKakaotalkTemplateManagementURL` | 템플릿 관리 URL | | `sendATKakaotalk` | `SendATKakaotalk` | 알림톡 단건 발송 | | `sendATKakaotalkEx` | `SendATKakaotalkEx` | 알림톡 단건 발송 (버튼 포함) | | `sendATKakaotalks` | `SendATKakaotalks` | 알림톡 대량 발송 | | `sendFTKakaotalk` | `SendFTKakaotalk` | 친구톡 텍스트 단건 | | `sendFTKakaotalks` | `SendFTKakaotalks` | 친구톡 텍스트 대량 | | `sendFIKakaotalk` | `SendFIKakaotalk` | 친구톡 이미지 | | `sendFWKakaotalk` | `SendFWKakaotalk` | 친구톡 와이드 이미지 | | `getSendKakaotalk` | `GetSendKakaotalk` | 전송 결과 단건 조회 | | `getSendKakaotalks` | `GetSendKakaotalks` | 전송 결과 다건 조회 | | `cancelReservedKakaotalk` | `CancelReservedKakaotalk` | 예약 전송 취소 | --- ## 8. API 측 바로빌 연동 (세금계산서) MNG의 카카오톡 연동 외에, API(`api/`)에서도 바로빌 서비스를 사용한다: ### 8.1 바로빌 설정 API | HTTP | URI | 설명 | |------|-----|------| | GET | `/v1/barobill-settings` | 바로빌 설정 조회 | | PUT | `/v1/barobill-settings` | 바로빌 설정 저장 (사업자번호, 인증키, 자동발행 등) | | POST | `/v1/barobill-settings/test-connection` | 연동 테스트 | ### 8.2 세금계산서 발행 `BarobillService`는 세금계산서 발행/취소/국세청 전송 상태 조회도 담당한다: | API 메서드 | 설명 | |-----------|------| | `issueTaxInvoice()` | 세금계산서 발행 (RegistAndIssueTaxInvoice) | | `cancelTaxInvoice()` | 세금계산서 취소 | | `checkNtsSendStatus()` | 국세청 전송 상태 조회 | | `checkBusinessNumber()` | 사업자번호 휴폐업 조회 | | `testConnection()` | GetAccessToken으로 연동 테스트 | **인증키 보안:** `cert_key`는 Laravel `Crypt` 파사드로 자동 암/복호화 → 상세: [세금계산서 관리](../finance/tax-invoices.md) --- ## 9. 참고 자료 - [바로빌 API 문서](https://dev.barobill.co.kr) - [카카오비즈니스 채널 관리](https://business.kakao.com) - [카카오 알림톡 가이드](https://kakaobusiness.gitbook.io) - 바로빌 템플릿 관리: 로그인 후 `https://www.barobill.co.kr` → 카카오톡 템플릿 관리 --- ## 변경 이력 | 날짜 | 버전 | 변경 내용 | |------|------|----------| | 2026-02-24 | 1.0 | 전자계약 알림톡 연동 완료, 트러블슈팅 문서화, v2 템플릿 가이드 추가 | | 2026-02-14 | 0.2 | 전자계약(E-Sign) 알림톡 연동 활용 계획 추가 | | 2026-02-14 | 0.1 | 초안 작성 - 코드 구현 완료, 실 서비스 연동 대기 |