gift-cards について
Shopify、WooCommerce、BigCommerce、ヘッドレスストアでのギフトカード導入を案内するスキルです。残高管理、一部利用、返金時のストアクレジット、台帳設計を扱います。
主な機能
- 01プラットフォーム別の方式選択
- 02販売とメール配信の設定
- 03残高の一部利用
- 04返金用ギフトカードの発行
- 05台帳による残高管理
活用シーン
- 01オンラインストアでのギフトカード販売
- 02現金返金に代わるストアクレジット
- 03ギフトカードとクレジットカードの併用決済
- 04法人顧客向けの一括発行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill gift-cardsインストール後、Claude Code で/gift-cardsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
tile.jsonevals/append-only-ledger-schema-design/criteria.jsontask.mdevals/concurrent-redemption-safety-and-refund-/criteria.jsontask.mdevals/secure-code-generation-and-issuance-flow/criteria.jsontask.md詳細
ギフトカード
概要
ギフトカードを利用すると、お客様はストアクレジットを購入して、贈り物として他の方に贈ったり、ご自身で使用したりできます。ギフトカードはチェックアウト時の支払い方法として機能します。お客様は注文の一部をギフトカードで支払い、残額をクレジットカードで支払うことができ、未使用の残高はカードに残ります。主要なすべての e コマースプラットフォームにギフトカード機能が標準搭載されています。独自の実装が必要なのは、ヘッドレスストアフロントや、非常に特殊な会計要件がある場合に限られます。
このスキルを使用する場面
- お客様が購入して他の方に贈れる商品として、ギフトカードを追加するとき
- 現金での返金に代わる返金方法として、ストアクレジットを実装するとき
- B2B クライアント向けに、法人用ギフトカードプログラムを一括作成するとき
- チェックアウト時に、お客様がギフトカードとクレジットカードを組み合わせて支払えるようにするとき
- 会計照合やカスタマーサポートのために、残高の完全な履歴が必要なとき
基本手順
ステップ 1:マーチャントのプラットフォームを特定し、適切なツールを選ぶ
| プラットフォーム | 推奨事項 | 備考 |
|---|---|---|
| Shopify | Shopify 標準のギフトカードを使用する(Basic を除くすべてのプランで利用可能) | チェックアウト、残高管理、メール配信と標準で連携されるため、アプリは不要です |
| WooCommerce | WooCommerce Gift Cards プラグイン(公式、約 49 ドル/年)または YITH WooCommerce Gift Cards(約 80 ドル/年) | WooCommerce のコア機能にはギフトカードが含まれていません。これらのプラグインは適切に保守され、広く利用されています |
| BigCommerce | BigCommerce Gift Certificates(標準搭載、全プラン) | 標準でサポートされており、管理パネルからギフト券の作成、販売、利用が可能です |
| カスタム/ヘッドレス | 台帳ベースの残高管理を構築する | 以下の「カスタム」セクションを参照してください |
ステップ 2:プラットフォームでギフトカードを設定する
Shopify
Shopify のギフトカードは、Shopify、Advanced、Plus の各プランで利用できます(Basic では利用できません)。ギフトカードは商品として発行され、チェックアウト時に 16 文字のコードを使って利用します。
ギフトカードを有効にして作成する:
- Shopify 管理画面で、Products → Gift cards に移動します
- Add gift card product をクリックします
- 金額を設定します(例:25 ドル、50 ドル、100 ドル)。各金額が商品バリエーションになります
- ギフトカード商品のタイトル、説明、画像を追加します
- Save をクリックします
お客様にギフトカードを発行する:
- 販売による発行:お客様がギフトカードを購入すると、Shopify が固有のコードを自動生成し、受取人にメールで送信します
- 手動発行:Customers に移動し、該当のお客様を見つけて、Gift cards タブから Issue gift card を選択します。金額と有効期限を設定します
有効期限を設定する:
- Settings → Gift cards に移動します
- ギフトカードの有効期限を有効にし、既定の有効期間を設定します
- 注意:ギフトカードの有効期限が禁止されている地域もあります(有効にする前に現地の法律を確認してください)
B2B またはマーケティング向けにギフトカードを一括作成する:
- Products → Gift cards → Export に移動し、既存のコードをダウンロードします
- Shopify Admin API(
POST /admin/api/2024-04/gift_cards.json)を使用して、プログラムからギフトカードを一括作成します - API の応答にコードが含まれます。メールプラットフォームを通じて配布してください
返金としてストアクレジットを発行する: 返金を発行する際、Shopify では元の支払い方法ではなく、ギフトカードに返金できます。
- Orders に移動し、注文を開いて Refund を選択します
- 「Refund to」で Gift card を選択し、金額を指定します
- Shopify が新しいギフトカードを作成し、そのコードをお客様にメールで送信します
WooCommerce
WooCommerce Gift Cards(WooCommerce.com 提供)または YITH WooCommerce Gift Cards 拡張機能をインストールします。これらは、最も機能が充実した選択肢です。
WooCommerce Gift Cards の設定:
- プラグインをインストールして有効化します
- Products → Add New に移動し、商品タイプを Gift card に設定します
- Gift card data で以下を設定します:
- 配送方法を設定します:メールで配送(デジタル用)または印刷したカード
- 利用可能な金額を設定するか、金額を自由に指定できるようにします
- 受取人にコードを送信するメールテンプレートを設定します
- 商品を公開します
利用方法: プラグインによって、チェックアウトページに「Gift card」欄が追加されます。顧客はコードを入力すると、残高が注文合計から差し引かれます。一部利用にも対応しており、残高はカードに残ります。
返金をストアクレジットにする:
- 注文を開き、Refund を選択します
- プラグインによって「Refund to gift card」オプションが追加されます
- 新しいギフトカードコードが生成され、顧客にメールで送信されます
残高の照会:
WooCommerce Gift Cards と YITH のどちらも、ページに追加できる残高照会ショートコードを提供しています:[woo_gift_card_balance_check]
BigCommerce
BigCommerce では「Gift Certificates」と呼ばれ、標準機能として含まれています。
ギフト券の作成と販売:
- Marketing → Gift Certificates → Create Gift Certificate に移動します
- 以下を入力します:
- To(受取人の氏名とメールアドレス)
- From(贈り主の氏名とメールアドレス)
- Amount:固定金額
- Expiry date(任意)
- BigCommerce が証明書コードをメールで受取人に送信します
商品としてギフト券を販売する:
- Products → Gift Certificates に移動します
- ギフト券の商品ページを有効にします
- 顧客はストアフロントから、金額を自由に指定するか固定金額を選んで証明書を購入できます
利用方法: ギフト券コードは、チェックアウト時に支払い方法として表示されます。一部利用にも対応しており、残高は証明書コードに保持されます。
カスタム/ヘッドレス
ヘッドレスのストアフロントでは、台帳ベースのギフトカードシステムを実装します。台帳パターンでは、すべての借方と貸方を変更不可のトランザクション行として記録します。残高のカラムを直接更新してはいけません。
CREATE TABLE gift_cards (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(32) NOT NULL UNIQUE,
initial_value_cents INTEGER NOT NULL,
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
issued_to VARCHAR(255),
expires_at TIMESTAMPTZ,
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE gift_card_ledger (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
card_id UUID NOT NULL REFERENCES gift_cards(id),
amount_cents INTEGER NOT NULL, -- positive = credit, negative = debit
type VARCHAR(16) NOT NULL CHECK (type IN ('issue', 'redeem', 'refund', 'void')),
order_id UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
残高の計算 — 保存されたカラムの値ではなく、常に台帳から算出します:
async function getBalance(cardCode: string): Promise<number> {
const card = await db.giftCards.findByCode(cardCode.toUpperCase());
if (!card || !card.is_active) throw new Error('CARD_NOT_FOUND');
if (card.expires_at && card.expires_at < new Date()) throw new Error('CARD_EXPIRED');
const result = await db.raw(
'SELECT COALESCE(SUM(amount_cents), 0) AS balance FROM gift_card_ledger WHERE card_id = ?',
[card.id]
);
return Math.max(0, parseInt(result.rows[0].balance, 10));
}
行レベルのロックによる一部利用で、同時利用による過剰な引き落としを防ぎます:
async function redeemGiftCard(code: string, orderId: string, orderTotalCents: number) {
return db.transaction(async tx => {
// Lock the card row to prevent concurrent redemptions
const card = await tx.raw(
'SELECT * FROM gift_cards WHERE UPPER(code) = ? FOR UPDATE',
[code.toUpperCase()]
).then(r => r.rows[0]);
if (!card || !card.is_active) throw new Error('CARD_NOT_FOUND');
const balance = await getBalance(code);
const appliedCents = Math.min(balance, orderTotalCents);
if (appliedCents === 0) throw new Error('ZERO_BALANCE');
await tx.giftCardLedger.insert({
card_id: card.id,
amount_cents: -appliedCents,
type: 'redeem',
order_id: orderId,
});
return { appliedCents, remainingBalance: balance - appliedCents };
});
}
ベストプラクティス
- 追記専用の台帳を使用する — 残高のカラムを更新せず、すべての借方と貸方をトランザクション行として記録して、完全な監査証跡を残します(会計照合に必要です)
- 紛らわしい文字を使わずにコードを生成する — メールに記載されたコードを読む際の顧客の混乱を防ぐため、文字セットから
0、O、1、Iを除外します - カードコード全体を URL やログに公開しない — 部分的なマスキング(
ABCD-xxxx-xxxx-MNOP)なら表示に使用しても安全です。コード全体を記載するのは発行メールだけにします - 発行時に会計上の負債を計上する — ギフトカードの残高は、利用されるまで繰延収益負債です。会計連携で正しく記録されるようにしてください
- 有効期限を設定する前に地域の規制を確認する — 米国の多くの州やその他の地域では、ギフトカードの有効期限を制限または禁止しています。有効化する前に確認してください
- ギフトカードへの返金フローをテストする — これはカスタマーサービスでよくあるケースです。公開前に、新しく発行されたカードにアクセスでき、利用できることを確認してください
よくある落とし穴
| 問題 | 解決策 |
|---|---|
| 同じカードを使った2件のチェックアウトが同時に成功する | (カスタム実装の場合)残高を読み取る前に、データベーストランザクション内で行レベルのロック(SELECT ... FOR UPDATE)を使用します。プラットフォームでは標準で処理されます |
| 分割払いの丸め処理が原因で残高がマイナスになる | Math.min(balance, orderTotal) を使用し、現在の残高を超える額を適用しないでください |
| 返金で残高が再加算された後、顧客がカードを見つけられない | ギフトカードに返金した後、残高がなくなったためにカードが無効化されていた場合は、再有効化してください |
| ギフトカードのコードがサーバーのアクセスログに記録される | コードを URL のパスパラメーターに含めないでください。POST 本文またはハッシュ化した検索トークンを使用してください |
| ギフトカードを購入したのにコードが届かない | プラットフォーム標準のギフトカードは自動送信されます。カスタム実装では、配信状況の追跡と顧客サービスパネルからの再送オプションを備えたトランザクションメールを使用してください |
関連スキル
- @coupon-management
- @loyalty-points-system
- @stripe-integration
- @returns-management
- @checkout-flow-optimization