- esign-notification-guide.md 신규 작성 (환경별 설정, 역할 기반 알림, 템플릿 분기) - README.md 현황 업데이트 (완료 템플릿, OTP SMS, 환경별 분기 반영) - INDEX.md에 새 문서 등록
9.4 KiB
전자계약 알림톡/SMS 환경별 설정 가이드
작성일: 2026-02-27 상태: 운영 중 대상 프로젝트: MNG
1. 개요
1.1 목적
전자계약(E-Sign) 시스템의 카카오톡 알림톡, SMS, 이메일 발송을 **3개 환경(로컬/개발/운영)**에서 올바르게 설정하고 테스트하기 위한 가이드이다.
1.2 핵심 원칙
- 역할 기반 알림: 본사(creator)는 이메일, 상대방(counterpart)은 카카오톡/SMS
- 환경별 템플릿 분리: 운영은 원본 템플릿, 개발은
_DEV접미사 템플릿 사용 - URL 자동 분기:
config('app.url')로 환경별 도메인 자동 적용
2. 환경별 설정
2.1 도메인 및 APP_URL
| 환경 | APP_ENV |
APP_URL |
알림톡 버튼 URL 도메인 |
|---|---|---|---|
| 로컬 (Docker) | local |
https://mng.sam.kr |
로컬 — 알림톡 미사용 |
| 개발 서버 | local |
https://admin.codebridge-x.com |
admin.codebridge-x.com |
| 운영 서버 | production |
https://mng.codebridge-x.com |
mng.codebridge-x.com |
2.2 바로빌 서버 모드
barobill_members.server_mode 컬럼으로 바로빌 API 엔드포인트를 결정한다:
| server_mode | WSDL (카카오톡) | WSDL (SMS) | 용도 |
|---|---|---|---|
test |
testws.baroservice.com/KAKAOTALK.asmx |
testws.baroservice.com/SMS.asmx |
테스트 |
production |
ws.baroservice.com/KAKAOTALK.asmx |
ws.baroservice.com/SMS.asmx |
실제 발송 |
server_mode는 환경(로컬/개발/운영)과 독립적이다. 개발서버에서도production모드로 실제 발송 가능.
2.3 알림톡 템플릿 환경별 분기
코드에서 resolveTemplateName() 메서드가 APP_ENV에 따라 템플릿명을 자동 결정한다:
private function resolveTemplateName(string $baseName): string
{
return $baseName . (app()->environment('production') ? '' : '_DEV');
}
| 기본 템플릿명 | 운영 (production) |
개발/로컬 (기타) |
|---|---|---|
전자계약_서명요청 |
전자계약_서명요청 |
전자계약_서명요청_DEV |
전자계약_완료 |
전자계약_완료 |
전자계약_완료_DEV |
전자계약_리마인드 |
전자계약_리마인드 |
전자계약_리마인드_DEV |
3. 등록된 알림톡 템플릿
3.1 운영 템플릿 (mng.codebridge-x.com)
| 템플릿명 | 용도 | 상태 | 버튼 URL |
|---|---|---|---|
전자계약_서명요청 |
서명 요청 알림 | 승인 완료 | https://mng.codebridge-x.com/esign/sign/#{토큰} |
전자계약_완료 |
서명 완료 알림 | 승인 완료 | https://mng.codebridge-x.com/esign/sign/#{토큰} |
전자계약_리마인드 |
서명 독촉 알림 | 승인 완료 | https://mng.codebridge-x.com/esign/sign/#{토큰} |
3.2 개발 템플릿 (admin.codebridge-x.com)
| 템플릿명 | 용도 | 상태 | 버튼 URL |
|---|---|---|---|
전자계약_서명요청_DEV |
서명 요청 알림 | 심사 중 | https://admin.codebridge-x.com/esign/sign/#{토큰} |
전자계약_완료_DEV |
서명 완료 알림 | 심사 중 | https://admin.codebridge-x.com/esign/sign/#{토큰} |
전자계약_리마인드_DEV |
서명 독촉 알림 | 심사 중 | https://admin.codebridge-x.com/esign/sign/#{토큰} |
개발 템플릿 본문은 운영 템플릿과 동일하며, 버튼 URL 도메인만 다르다.
3.3 템플릿 변수
| 변수 | 용도 | 사용 템플릿 |
|---|---|---|
#{이름} |
서명자 이름 | 서명요청, 완료, 리마인드 |
#{계약명} |
계약 제목 | 서명요청, 완료, 리마인드 |
#{기한} |
서명 기한 | 서명요청, 리마인드 |
#{완료일} |
계약 완료일 | 완료 |
#{토큰} |
서명자 액세스 토큰 | 버튼 URL |
4. 역할 기반 알림 흐름
4.1 전체 흐름
① 계약 발송 ─→ 본사: 이메일 / 상대방: 카카오톡 알림톡
② OTP 인증 ─→ 본사: 이메일 / 상대방: SMS
③ 다음 서명자 ─→ 본사: 이메일 / 상대방: 카카오톡 알림톡
④ 서명 완료 ─→ 본사: 이메일(PDF) / 상대방: 카카오톡(PDF 다운로드)
4.2 역할 판별
$isCounterpart = $signer->role === EsignSigner::ROLE_COUNTERPART;
| 역할 | 상수 | 알림톡 | SMS(OTP) | 이메일 |
|---|---|---|---|---|
| 본사 (creator) | ROLE_CREATOR |
❌ | ❌ | ✅ 항상 |
| 상대방 (counterpart) | ROLE_COUNTERPART |
✅ 우선 | ✅ OTP만 | ✅ 폴백 |
4.3 이메일 폴백 조건
상대방(counterpart)에게도 이메일을 보내는 경우:
- 전화번호가 없을 때 (
$signer->phone없음) - 알림톡 발송 실패 시 (
$alimtalkFailed = true) - 발송 방식이
email또는both일 때
4.4 완료 알림 특수 처리
완료 알림톡 버튼은 서명 페이지가 아닌 문서 다운로드 URL로 강제 변경된다:
// sendCompletionAlimtalk() 내부
$documentUrl = config('app.url') . '/esign/sign/' . $signer->access_token . '/api/document';
// 버튼 URL 강제 변경 (서명페이지 → 문서 다운로드)
if (str_contains($btn[$urlKey], '/esign/sign/') && !str_contains($btn[$urlKey], '/api/document')) {
$btn[$urlKey] = $documentUrl;
}
5. SMS (OTP 인증)
5.1 발송 조건
상대방(counterpart)이 alimtalk 또는 both 발송 방식이고 전화번호가 있을 때 SMS로 OTP 발송:
if (in_array($sendMethod, ['alimtalk', 'both'])
&& $signer->phone
&& $signer->role === EsignSigner::ROLE_COUNTERPART) {
$this->sendOtpViaSms($contract, $signer, $otpCode);
}
5.2 SMS 발송 파라미터
| 항목 | 값 |
|---|---|
| API | BarobillService::sendSMSMessage() |
| 발신번호 | barobill_members.manager_hp |
| 수신번호 | esign_signers.phone |
| 메시지 | [SAM] 전자계약 인증코드: {코드} (5분 이내 입력) |
| OTP 유효시간 | 5분 |
| 최대 시도 | 5회 |
5.3 SMS 실패 시 이메일 폴백
SMS 발송 실패 → 이메일 OTP 폴백 → 이메일도 없으면 500 에러 반환.
6. 바로빌 템플릿 등록 절차
6.1 관리자 페이지
https://www.barobill.co.kr 로그인 → 카카오톡 → 템플릿관리
6.2 DEV 템플릿 등록 시 주의사항
- 본문: 운영 템플릿과 완전히 동일 (1글자도 다르면 안 됨)
- 버튼 URL: 도메인만
admin.codebridge-x.com으로 변경 - 템플릿명: 운영 이름 +
_DEV접미사 (예:전자계약_서명요청_DEV) - 검수 기간: 영업일 기준 2~3일
6.3 새 템플릿 추가 시 체크리스트
- 바로빌에서 운영용 + 개발용 2개 등록
- 코드에서
resolveTemplateName('기본명')으로 호출 - 본문의 변수 치환 로직 추가 (str_replace)
- 버튼 URL의
#{토큰}치환 확인 - 2단계 검증 (SendKey → GetSendKakaotalk) 포함
7. 관련 파일
| 파일 | 역할 |
|---|---|
app/Http/Controllers/ESign/EsignApiController.php |
계약 발송, sendAlimtalk(), resolveTemplateName() |
app/Http/Controllers/ESign/EsignPublicController.php |
OTP SMS, 완료 알림톡, sendCompletionAlimtalk() |
app/Services/Barobill/BarobillService.php |
SOAP 클라이언트 (sendATKakaotalkEx, sendSMSMessage) |
app/Models/ESign/EsignSigner.php |
ROLE_CREATOR, ROLE_COUNTERPART 상수 |
app/Mail/EsignCompletedMail.php |
완료 이메일 (PDF 다운로드 링크) |
app/Services/ESign/PdfSignatureService.php |
서명 PDF 합성 (mergeSignatures) |
8. 트러블슈팅
8.1 환경별 템플릿 미스매치
증상: ResultCode=4 (템플릿 데이터 일치 오류)
원인: 개발서버에서 운영용 템플릿(전자계약_서명요청)으로 발송 시 버튼 URL 도메인 불일치
해결: DEV 템플릿 등록 후 APP_ENV가 production이 아닌지 확인
8.2 서명 PDF 누락 (이메일)
증상: 완료 이메일의 다운로드 링크가 서명 없는 초안 PDF 반환
원인: mergeSignatures() 실패 → signed_file_path 미설정 → preview PDF 폴백
해결: downloadDocument()가 완료 상태에서 자동 재생성 시도. 로그에서 trace 확인:
# 개발서버 로그 확인
ssh pro@114.203.209.83 "tail -100 /home/webservice/mng/storage/logs/laravel.log | grep 'PDF 서명'"
주요 실패 원인:
storage/fonts/Pretendard-Regular.ttf폰트 파일 누락- FPDI/TCPDF 패키지 미설치 →
composer install필요 storage/app/esign/{tenant_id}/signed/디렉토리 권한 문제
8.3 MNG 모델 상수 누락
증상: Undefined constant App\Models\ESign\EsignSigner::ROLE_COUNTERPART
원인: API 프로젝트와 MNG 프로젝트의 모델이 독립적 — API에만 상수 정의됨
해결: MNG EsignSigner.php에도 동일한 상수 추가 (2026-02-26 핫픽스 완료)
관련 문서
- 바로빌 카카오톡 연동 README — SOAP API 전체 연동 가이드
- E-Sign 기술 설계 — 전자계약 아키텍처
- E-Sign API 명세 — API 엔드포인트
- 알림톡 연동 계획 — 초기 계획 (구현 완료)
최종 업데이트: 2026-02-27