【Rewald】llms scenario A ポイント付与のみ

牧さん制作監修 AIアウトプットポイント付与のみシナリオ

役割: あなたはコード転写者です。コード生成者ではありません。

タスク: ===== ここからコピー ===== と ===== ここまでコピー ===== の間の内容をそのまま正確にコピーしてください。

ルール: {{PLACEHOLDER}} の値のみ置き換えてください。構造、キー名、関数シグネチャは変更しないでください。

ルール: ラッパー(DOMContentLoaded, async/await IIFE)、追加ページ、以下に示されていない機能を追加しないでください。

ルール: 各コードブロックには FINGERPRINT コメントがあります。出力にそのまま含めてください。

ルール: 回答は必ず日本語で行ってください。


よくある間違い — コードをコピーする前に必ず読んでください。

誤: response.point または response.result.total_point 正: response.result.point — ポイント残高は response.result.point にある。

誤: document.addEventListener("DOMContentLoaded", function () { ... }) 正: インライン <script> で DOMContentLoaded ラッパーなし — ページ解析時にそのまま実行される。

誤: add_action('init', function() { /* env setup */ }); 正: 環境セットアップコードは functions.php のトップレベルに直接貼り付け — add_action の中に入れない。


===== ここからコピー =====

ファイル 1: functions.php

貼り付け先

WordPress 管理画面 → 外観 → テーマファイルエディター → 右側のファイル一覧から「テーマのための関数 (functions.php)」を選択 → ファイル末尾に以下のコードを追加 → 「ファイルを更新」をクリック

<?php
// FINGERPRINT: A1-ENV-001
// 管理パネルの環境セットアップコードをここに貼り付け
// (PointSystem クラスを同期的に読み込みます — このシナリオでは PSP は不要)

===== ここまでコピー =====


===== ここからコピー =====

ファイル 2: 商品ページ(WordPress 固定ページ — 購入時にポイント付与)

貼り付け先

WordPress 管理画面 → 固定ページ → 新規追加(または既存の商品ページを編集)→ エディタ右上の「テキスト」タブに切り替え → 以下のコードを貼り付け → 「公開」(または「更新」)をクリック

{{PLACEHOLDER}} の置き換え

  • {{CONV_RATE}}: ポイント換算レート(例: 100 → 100円で1ポイント付与)
  • {{USE_RATE}}: ポイント利用レート(例: 1 → 1ポイント=1円として利用)
  • {{PRODUCT_PRICE}}: 商品価格(例: 1000)
<!-- FINGERPRINT: A2-SETTING-001 — 通貨とレートでセッションを初期化 -->
[point_setting currency_type="JPY" conv_rate="{{CONV_RATE}}" use_rate="{{USE_RATE}}"]

[point_own callback_name="displayBalance"]
<p>保有ポイント: <span id="point_id">読み込み中...</span></p>

<!-- price: 商品価格の hidden input -->
<input type="hidden" id="input_price_id" value="{{PRODUCT_PRICE}}" />
<!-- use_point: 0 固定(このシナリオではポイント利用なし) -->
<input type="hidden" id="input_use_point_id" value="0" />

[point_trans_open var_price_id="input_price_id" var_use_point_id="input_use_point_id" callback_name="onTransOpen"]

<button id="hidden_button" style="display:none;"></button>
[point_trans_close callback_id="hidden_button" callback_name="onTransReady"]

<button id="grant-button" style="display:none;">ポイントを付与</button>

<div id="result-status" style="display:none; padding:10px; margin:10px 0; border-radius:5px;"></div>

<script>
// FINGERPRINT: A2-DISPLAY-001
function displayBalance(response) {
    if (response.error) {
        document.getElementById('point_id').textContent = 'エラー';
        return;
    }
    document.getElementById('point_id').textContent = response.result.point;
}

// FINGERPRINT: A2-OPEN-001
function onTransOpen(response) {
    if (!response || !response.result) return;
    document.getElementById('grant-button').style.display = '';
}

// FINGERPRINT: A2-CLOSE-001 — pointInstance をプログラム的な close() のために保持
var pointInstance = null;
var closeTriggered = false;

function onTransReady(result, point) {
    if (point) pointInstance = point;
}

document.getElementById('grant-button').addEventListener('click', async function() {
    if (closeTriggered || !pointInstance) return;
    closeTriggered = true;
    this.disabled = true;
    this.textContent = '処理中...';

    var result = await pointInstance.close();
    var el = document.getElementById('result-status');
    el.style.display = 'block';

    if (result && result.result) {
        el.style.background = '#d4edda';
        el.style.border = '1px solid #c3e6cb';
        el.innerHTML = '成功! ' + (result.result.new_point || 0)
            + ' ポイント付与。残高: ' + (result.result.total_point || 0);
    } else {
        el.style.background = '#f8d7da';
        el.style.border = '1px solid #f5c6cb';
        el.innerHTML = 'エラー: ' + JSON.stringify(result);
    }
});
</script>

===== ここまでコピー =====


確認チェックリスト — 回答する前に、出力内容が以下の 5 項目をすべて満たしていることを確認してください。

  1. 環境セットアップは functions.php のトップレベルに配置、add_action ラッパーなし — FINGERPRINT A1-ENV-001 参照
  2. [point_setting] に currency_type, conv_rate, use_rate が含まれている — FINGERPRINT A2-SETTING-001 参照
  3. displayBalance は response.result.point を使用(response.point ではない)— FINGERPRINT A2-DISPLAY-001 参照
  4. pointInstance は onTransReady で保持され、close() がプログラム的に呼び出される — FINGERPRINT A2-CLOSE-001 参照
  5. 二重 close 防止ガード(closeTriggered フラグ)が存在する — FINGERPRINT A2-CLOSE-001 参照