決済完了の通知
自分のサーバーで決済が終わったらサーバーREST API(v2)でチャットルームに知らせ、ページスクリプトが受け取ってチャット画面に表示するサンプルです。
最終更新 2026年10月19日
自分のサーバーで決済が終わった瞬間に、チャットルームにいる全員へ「購入完了」の通知を表示します。サーバーはサーバーREST APIで payment チャンネルにデータを送り、ページスクリプトはサーバーが送ったものかを確認してからチャット画面に表示します。
流れ
- 決済代行会社が自分のサーバーに決済完了を通知します(自分のサーバーの既存の処理)。
- 自分のサーバーが
POST https://api.uchat.io/v2/rooms/{id}/eventsでpaymentチャンネルに送ります。 - いまチャットルームに接続している全員のページに、
paymentチャンネルでデータが届きます。 - ページスクリプトが送信者の権限が
4(サーバー)であることを確認し、room.printで表示します。
サーバー: Node.js
Node.js 18以上の組み込み fetch を使います。APIキーとAPIチャットルームID(room_…)は管理ページの API メニューで発行・確認し、キーはサーバーの環境変数にだけ置きます。キーの権限には イベント が必要です。
// notify-payment.mjs
const ROOM = 'room_xxxxxxxxxxxxxxxx'; // APIチャットルームID
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で送ったデータか、モデレーター以上が保存した値にだけ付きます。保存値は入室時にtype1で届くため、上のコードはtype0(サーバーAPIで全員に送ったもの)だけを受け取ります。ニックネームを指定して送ったサーバーAPIのデータもtype1なので、保存値と区別できません。 - RESTリクエストの本文の先頭部分とリクエスト元IPは、管理ページの API メニューの呼び出し履歴に30日間残ります。購入者の名前・連絡先・カード情報のような個人情報は送らないでください。
- そのまま送ったデータは、いま接続している人にだけ届きます。チャットルームに誰もいなくても成功を返し、失敗した場合でも決済処理そのものを失敗扱いにせず、記録だけ残します。決済通知は過ぎた出来事なので、
saveで保存しないのが適切です。 - 1人にだけ送るには、本文に
"to":"ニックネーム"を入れます(日本語のニックネームも使えます)。この方法で送ったデータはtype1で届くので、上のコードのtypeの確認を外す必要があります。 - 無料チャットルームでは、直近60秒間に受け取る人数の合計が上限を超えるとHTTP 429
chat_rate_limitedになります(チャンネルAPIと上限)。 - コードを書かずにチャットルームに表示するだけなら、イベント通知ウィンドウプラグインをオンにして、
pluginをalertBox、dataを["custom", "購入完了", 商品名]にして送ることもできます。 - サーバーから通知を送る一般的な流れはサーバーからチャットルームに通知を送るにあります。
読んでもよくわからない場合は お問い合わせ掲示板に質問を書き込んでください。