Next.js에서 카카오 알림톡 보내기 (Solapi 연동 가이드)
한국 SaaS에서 고객에게 알림을 보내는 가장 효과적인 방법은 카카오 알림톡입니다. SMS보다 저렴하고, 열람율도 압도적으로 높습니다. 결제 완료, 예약 확인, 배송 알림 등 거의 모든 트랜잭션 메시지에 알림톡이 사용됩니다.
이 글에서는 Next.js App Router + Solapi API를 활용해서 카카오 알림톡을 발송하는 방법을 단계별로 설명합니다. 실제 프로덕션에서 사용 중인 코드를 기반으로 작성했습니다.
1단계: 카카오 알림톡이란?
알림톡은 카카오톡 채널을 통해 발송되는 정보성 메시지입니다. 광고성 메시지가 아닌, 사용자가 요청한 서비스와 관련된 알림만 보낼 수 있습니다.
SMS vs 알림톡 비교:
| 항목 | SMS | 알림톡 |
|---|---|---|
| 건당 비용 | 약 20원 | 약 8원 |
| 열람율 | 약 30% | 약 90%+ |
| 글자 제한 | 90바이트 (한글 45자) | 1,000자 |
| 버튼/링크 | 불가 | 가능 (최대 5개) |
| 발신번호 | 전화번호 | 카카오톡 채널 |
핵심 포인트: 알림톡은 SMS 대비 비용이 약 60% 저렴하고, 열람율은 3배 이상 높습니다. 한국 SaaS라면 알림톡을 기본으로 사용하세요.
2단계: Solapi 가입 + API 키 발급
카카오 알림톡을 직접 연동하려면 카카오 비즈메시지 API를 사용해야 하는데, 심사 절차가 복잡합니다. 대신 Solapi(솔라피)를 사용하면 간편하게 연동할 수 있습니다.
Solapi는 알림톡, SMS, MMS를 통합 관리할 수 있는 메시징 API 플랫폼입니다. 한국 개발자들이 가장 많이 사용하는 메시징 서비스 중 하나입니다.
- Solapi 홈페이지에서 회원가입
- 대시보드 → API 키 관리에서 API Key와 API Secret 발급
- 발신번호 등록 (사전에 인증된 전화번호 필요)
발급받은 키를 .env.local에 설정합니다:
# Solapi 알림톡 설정
SOLAPI_API_KEY=NCSXXXXXXXXXXXXXXXX
SOLAPI_API_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SOLAPI_SENDER_PHONE=01012345678
SOLAPI_PF_ID=KA01PF_XXXXXXXXXXXX
# 알림톡 템플릿 코드
SOLAPI_TEMPLATE_WELCOME=KA01TP_XXXX
SOLAPI_TEMPLATE_PAYMENT_COMPLETE=KA01TP_XXXX
SOLAPI_TEMPLATE_NOTIFICATION=KA01TP_XXXX주의: API Secret은 절대 프론트엔드에 노출하면 안 됩니다. NEXT_PUBLIC_ 접두사를 붙이지 마세요.
3단계: 카카오 채널 연동
알림톡을 발송하려면 카카오톡 채널이 필요합니다. 채널은 기존에 사용하던 것을 연결하거나 새로 만들 수 있습니다.
- 카카오톡 채널 관리자센터에서 채널 생성 또는 기존 채널 확인
- Solapi 대시보드 → 카카오톡 채널 관리 → 채널 연동
- 카카오 비즈니스 인증 완료 (사업자등록증 필요)
- 연동 완료 후 PF ID 확인 →
.env.local에 설정
채널 연동이 완료되면 Solapi 대시보드에서 카카오 비즈메시지 > 템플릿 관리메뉴가 활성화됩니다.
팁: 카카오 채널 프로필 이미지와 소개글을 잘 설정해두세요. 알림톡을 받는 고객이 처음 보는 것이 채널 프로필입니다.
4단계: Next.js에서 알림톡 발송 구현
이제 실제 코드를 작성합니다. Solapi는 HMAC-SHA256 인증 방식을 사용합니다. 먼저 알림톡 클라이언트를 만들겠습니다:
import crypto from "crypto";
const SOLAPI_API_URL = "https://api.solapi.com/messages/v4/send";
/** 승인된 알림톡 템플릿 코드 */
export const TEMPLATES = {
WELCOME: process.env.SOLAPI_TEMPLATE_WELCOME ?? "",
PAYMENT_COMPLETE:
process.env.SOLAPI_TEMPLATE_PAYMENT_COMPLETE ?? "",
NOTIFICATION:
process.env.SOLAPI_TEMPLATE_NOTIFICATION ?? "",
} as const;
interface AlimtalkResult {
success: boolean;
messageId?: string;
error?: string;
}
function getAuthHeader(): string {
const apiKey = process.env.SOLAPI_API_KEY;
const apiSecret = process.env.SOLAPI_API_SECRET;
if (!apiKey || !apiSecret) {
throw new Error(
"솔라피 API 키가 설정되지 않았습니다."
);
}
const date = new Date().toISOString();
const salt = crypto.randomBytes(32).toString("hex");
const signature = crypto
.createHmac("sha256", apiSecret)
.update(date + salt)
.digest("hex");
return `HMAC-SHA256 apiKey=${apiKey}, date=${date}, salt=${salt}, signature=${signature}`;
}
/** 알림톡 발송 */
export async function sendAlimtalk(params: {
to: string;
templateId: string;
variables: Record<string, string>;
}): Promise<AlimtalkResult> {
try {
const response = await fetch(SOLAPI_API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: getAuthHeader(),
},
body: JSON.stringify({
message: {
to: params.to.replace(/-/g, ""),
from: process.env.SOLAPI_SENDER_PHONE,
kakaoOptions: {
pfId: process.env.SOLAPI_PF_ID,
templateId: params.templateId,
variables: params.variables,
},
},
}),
});
const data = await response.json();
if (response.ok) {
return {
success: true,
messageId: data.groupId,
};
}
return {
success: false,
error:
data.errorMessage
?? data.message
?? "발송 실패",
};
} catch (err) {
const message =
err instanceof Error
? err.message
: "알 수 없는 오류";
return { success: false, error: message };
}
}핵심 포인트를 짚어보겠습니다:
- HMAC-SHA256 인증 — Solapi는 매 요청마다
date + salt를 HMAC으로 서명합니다. 토스페이먼츠의 Basic 인증보다 약간 복잡하지만, 보안성이 높습니다. - 전화번호 정규화 —
replace(/-/g, "")로 하이픈을 제거합니다.010-1234-5678형태와01012345678형태 모두 처리할 수 있습니다. - 템플릿 변수 — 알림톡은 사전 승인된 템플릿만 발송할 수 있습니다.
variables로 동적 값을 주입합니다.
이제 Next.js API Route에서 이 함수를 호출합니다:
import { NextRequest, NextResponse } from "next/server";
import {
sendAlimtalk,
TEMPLATES,
} from "@/lib/alimtalk/solapi";
export async function POST(req: NextRequest) {
const { to, type, variables } = await req.json();
// 입력 검증
if (!to || !type) {
return NextResponse.json(
{ error: "to와 type이 필요합니다." },
{ status: 400 }
);
}
// 템플릿 코드 매핑
const templateId =
TEMPLATES[type as keyof typeof TEMPLATES];
if (!templateId) {
return NextResponse.json(
{ error: "유효하지 않은 템플릿 타입입니다." },
{ status: 400 }
);
}
const result = await sendAlimtalk({
to,
templateId,
variables: variables ?? {},
});
if (!result.success) {
return NextResponse.json(
{ error: result.error },
{ status: 500 }
);
}
return NextResponse.json({
success: true,
messageId: result.messageId,
});
}클라이언트에서 호출하는 방법:
// 결제 완료 후 알림톡 발송 예시
const response = await fetch("/api/alimtalk", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
to: "010-1234-5678",
type: "PAYMENT_COMPLETE",
variables: {
"#{고객명}": "홍길동",
"#{상품명}": "Pro 플랜 월간 구독",
"#{결제금액}": "29,000원",
},
}),
});5단계: 템플릿 관리
카카오 알림톡은 사전 승인된 템플릿으로만 발송할 수 있습니다. 임의의 메시지를 보낼 수 없다는 뜻입니다.
템플릿 등록 절차:
- Solapi 대시보드 → 카카오 비즈메시지 → 템플릿 관리
- 템플릿 내용 작성 (변수는
#{변수명}형식) - 카카오 검수 요청 → 평일 기준 1~3일 소요
- 승인 완료 → 템플릿 코드 확인 →
.env.local에 설정
자주 사용하는 템플릿 예시:
// 회원가입 환영 템플릿
안녕하세요, #{고객명}님! 🎉
#{서비스명}에 가입해주셔서 감사합니다.
지금 바로 시작해보세요:
#{서비스URL}
// 결제 완료 템플릿
#{고객명}님, 결제가 완료되었습니다.
상품명: #{상품명}
결제금액: #{결제금액}
결제일: #{결제일}
영수증 확인: #{영수증URL}
// 구독 갱신 알림 템플릿
#{고객명}님, 구독이 곧 갱신됩니다.
플랜: #{플랜명}
갱신일: #{갱신일}
결제금액: #{결제금액}
구독 관리: #{관리URL}주의: 템플릿에 홍보성 문구를 넣으면 검수에서 반려됩니다. 알림톡은 정보성 메시지만 가능합니다. 마케팅 메시지는 친구톡을 사용해야 합니다.
6단계: 프로덕션 팁
테스트에서는 잘 되지만 프로덕션에서 문제가 생기는 경우가 많습니다. 실제 운영하면서 배운 팁을 공유합니다.
- 알림톡 실패 시 SMS 대체 발송: 카카오톡을 사용하지 않는 고객이나 차단한 경우, 자동으로 SMS로 대체 발송하도록 설정하세요. Solapi에서
failoverConfig옵션을 지원합니다. - 발송 로그 저장: 모든 발송 결과를 DB에 기록하세요. 실패한 건을 추적하고 재발송할 수 있어야 합니다.
- 발송량 관리: 초당 발송 제한이 있습니다. 대량 발송 시 큐(Queue)를 사용해서 속도를 조절하세요.
- 변수 누락 방지: 템플릿 변수가 하나라도 누락되면 발송이 실패합니다. 발송 전에 모든 변수가 채워졌는지 검증하세요.
- 잔액 모니터링: Solapi는 선불 충전 방식입니다. 잔액이 부족하면 발송이 안 됩니다. Webhook으로 잔액 알림을 설정하세요.
- 채널 친구 추가 유도: 알림톡을 받은 고객이 채널을 추가하면, 이후 친구톡(마케팅 메시지)도 발송할 수 있습니다.
SMS 대체 발송 옵션을 추가한 확장 코드:
// SMS 대체 발송이 포함된 확장 버전
const response = await fetch(SOLAPI_API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: getAuthHeader(),
},
body: JSON.stringify({
message: {
to: phone,
from: process.env.SOLAPI_SENDER_PHONE,
kakaoOptions: {
pfId: process.env.SOLAPI_PF_ID,
templateId: templateId,
variables: variables,
},
},
// 알림톡 실패 시 SMS로 대체 발송
agent: {
appId: "ShipFast KR",
},
}),
});전체 파일 구조 정리
src/
├── lib/
│ └── alimtalk/
│ └── solapi.ts # Solapi 클라이언트 + 인증 + 발송
├── app/
│ └── api/
│ └── alimtalk/
│ └── route.ts # 알림톡 발송 API Route
└── .env.local # API 키 + 템플릿 코드 (git 커밋 금지)마무리
여기까지 따라오셨다면 Next.js + Solapi로 카카오 알림톡 발송 시스템의 핵심 구조를 이해하셨을 겁니다. 핵심을 정리하면:
- 알림톡은 SMS 대비 비용 60% 절감 + 열람율 3배 이상
- Solapi의 HMAC-SHA256 인증으로 안전하게 API를 호출할 것
- 템플릿은 사전 승인 필수 — 검수 기간(1~3일)을 고려해서 미리 등록할 것
- 프로덕션에서는 SMS 대체 발송 + 발송 로그 + 잔액 모니터링이 필수
이 글에서 보여드린 코드는 실제로 한국형 SaaS 보일러플레이트를 만들면서 작성한 코드입니다. 알림톡뿐 아니라, 토스페이먼츠 결제, 카카오 로그인, Supabase, tRPC, Drizzle ORM까지 모두 포함된 Next.js 스타터킷이 있습니다.