결제 완료 알림

내 서버에서 결제가 끝나면 서버 REST API(v2)로 채팅방에 알리고, 페이지 스크립트가 받아 채팅창에 표시하는 예제예요.

마지막 수정 2026년 10월 19일

이 페이지

내 서버에서 결제가 끝나는 순간 채팅방에 있는 모두에게 "구매 완료" 알림을 띄워요. 서버는 서버 REST API로 payment 채널에 데이터를 보내고, 페이지 스크립트는 서버가 보낸 것인지 확인한 뒤 채팅창에 표시해요.

흐름

  1. 결제 대행사가 내 서버에 결제 완료를 알려요(내 서버의 기존 처리).
  2. 내 서버가 POST https://api.uchat.io/v2/rooms/{id}/events로 payment 채널에 보내요.
  3. 지금 채팅방에 접속한 모든 사람의 페이지에서 payment 채널로 데이터가 도착해요.
  4. 페이지 스크립트가 보낸 사람의 권한이 4(서버)인지 확인하고 room.print로 표시해요.

서버: Node.js

Node.js 18 이상의 내장 fetch를 써요. API 키와 API 채팅방 아이디(room_…)는 관리 페이지 API 메뉴에서 발급·확인하고, 키는 서버 환경 변수에만 둬요. 키 권한에는 이벤트가 있어야 해요.

// notify-payment.mjs
const ROOM = 'room_xxxxxxxxxxxxxxxx'; // API 채팅방 아이디

export async function notifyPayment(productName) {
	const res = await fetch(`https://api.uchat.io/v2/rooms/${ROOM}/events`, {
		method: 'POST',
		headers: {
			Authorization: `Bearer ${process.env.UCHAT_API_KEY}`,
			'Content-Type': 'application/json',
		},
		body: JSON.stringify({ plugin: 'payment', data: ['paid', productName] }),
	});
	const result = await res.json();
	if (!res.ok) {
		// 429 chat_rate_limited: 무료 채팅방 전송 한도 초과 등
		console.warn('uchat notify failed', res.status, result.error);
	}
	return result;
}

// 결제 완료 처리 안에서
// await notifyPayment('프리미엄 이용권');

서버: PHP

<?php
function notify_payment($product_name) {
	$ch = curl_init('https://api.uchat.io/v2/rooms/room_xxxxxxxxxxxxxxxx/events');
	curl_setopt_array($ch, [
		CURLOPT_POST => true,
		CURLOPT_RETURNTRANSFER => true,
		CURLOPT_HTTPHEADER => [
			'Authorization: Bearer ' . getenv('UCHAT_API_KEY'),
			'Content-Type: application/json',
		],
		CURLOPT_POSTFIELDS => json_encode(['plugin' => 'payment', 'data' => ['paid', $product_name]], JSON_UNESCAPED_UNICODE),
		CURLOPT_TIMEOUT => 5,
	]);
	$body = curl_exec($ch);
	$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
	curl_close($ch);
	$result = json_decode($body, true);
	if ($status >= 400) {
		error_log('uchat notify failed: ' . $status . ' ' . ($result['error']['code'] ?? 'no response'));
	}
	return $result;
}

// 결제 완료 처리 안에서
// notify_payment('프리미엄 이용권');

성공하면 HTTP 202와 {"data":{"sent":true}}를 돌려줘요. 채팅방에 아무도 없어도 성공이에요(받을 사람이 없을 뿐이에요). 실패하면 HTTP 상태와 {"error":{"code":…,"message":…}}가 와요. 전체 오류 코드는 서버 REST API를 보세요.

페이지: 받아서 표시하기

<script>U=window.U=window.U||{},U.events=U.events||[],U.chat=function(n){return{on:function(e,t){U.events.push([n,e,t])},off:function(e){for(var t=U.events.length;t>0;)U.events[--t][0]==n&&U.events[t][1]==e&&U.events.splice(t,1)}}};</script>
<script async src="https://client.uchat.io/uchat.js"></script>
<u-chat room="my-room" style="display:inline-block;width:100%;max-width:400px;height:500px"></u-chat>

<script>
U.chat('my-room').on('after.create#payment', function (room) {
	function esc(value) {
		return String(value).replace(/[&<>"']/g, function (c) {
			return '&#' + c.charCodeAt(0) + ';';
		});
	}

	room.plugin.add('payment').onReceived(function (room, data) {
		// 서버 API가 보낸 것만 믿는다. 사용자도 같은 채널로 보낼 수 있다
		if (!data.user || data.user.auth !== 4) return;
		if (data.type !== 0) return; // 입장 때 오는 저장값(type 1)은 건너뛴다
		var msg = data.data;
		if (msg[0] !== 'paid' || typeof msg[1] !== 'string') return;
		room.print('🎉 누군가 <b>' + esc(msg[1].slice(0, 50)) + '</b>을(를) 구매했습니다!');
	});
});
</script>

짚어 볼 점

  • room.print는 HTML로 표시하므로 받은 값은 위 코드처럼 꼭 이스케이프해요.
  • 권한 확인 없이 표시하면 아무 사용자나 같은 채널로 가짜 결제 알림을 띄울 수 있어요. data.user.auth === 4는 서버 API로 보낸 데이터 또는 부관리자 이상이 저장한 값에만 붙어요. 저장값은 입장할 때 type 1로 오므로 위 코드는 type 0(서버 API로 모두에게 보낸 것)만 받아요. 닉네임을 지정해 보낸 서버 API 데이터도 type 1이라 저장값과 구분할 수 없어요.
  • REST 요청 본문 앞부분과 요청 IP는 관리 페이지 API 메뉴의 호출 기록에 30일 동안 남아요. 구매자 이름·연락처·카드 정보 같은 개인정보는 보내지 마세요.
  • 그냥 보낸 데이터는 지금 접속한 사람에게만 가요. 채팅방에 아무도 없어도 성공으로 답하고, 실패하더라도 결제 처리 자체를 실패로 돌리지 말고 기록만 남겨요. 결제 알림은 지나간 일이라 save로 저장하지 않는 게 맞아요.
  • 한 사람에게만 보내려면 본문에 "to":"닉네임"을 넣어요(한글 닉네임도 돼요). 이렇게 보낸 데이터는 type 1로 오므로 위 코드의 type 확인을 빼야 해요.
  • 무료 채팅방은 최근 60초 동안 받는 사람 수 합계가 한도를 넘으면 HTTP 429 chat_rate_limited가 나요(채널 API와 한도).
  • 코드 없이 채팅방에 띄우기만 하려면 이벤트 알림창 플러그인을 켜고 plugin을 alertBox, data를 ["custom", "구매 완료", 상품 이름]으로 보내도 돼요.
  • 서버 알림을 보내는 일반 흐름은 서버에서 채팅방으로 알림 보내기에 있어요.

봐도 잘 이해가 되지 않나요? 문의 게시판에 질문을 남겨 주세요.

상호 UCHAT · 대표 김경욱 · 사업자등록번호 141-05-32832
사업장소재지 경기도 파주시 와석순환로 61 · 통신판매업신고번호 2013-경기파주-4485호
대표번호 010-8677-8633 · 이메일 support@uchat.io

ⓒ 2013–2026 UCHAT. All rights reserved.