hitpay について
hitpayは、JavaScriptまたはTypeScriptを使うNext.jsアプリ向けのHitPay連携スキルです。APAC事業者向けに、カード決済、QR決済、Webhook、決済状況の確認、返金を扱います。
主な機能
- 01リダイレクト型カード決済
- 02埋め込みQR決済フロー
- 03決済方法の選択
- 04Webhook署名の検証
- 05決済状況の確認と返金
活用シーン
- 01Next.jsストアへのホスト型カード決済の追加
- 02ウェブサイトでのQR決済の提供
- 03Webhookによる決済確認
- 04決済状況の確認や返金処理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ hit-pay/ agent-skills --skill hitpayインストール後、Claude Code で/hitpayを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/payment-request-api.mdrefunds.mdwebhook-events.mdscripts/verify-webhook.sh詳細
HitPay の統合
Next.js と JavaScript/TypeScript を使用する APAC 企業向けの決済ゲートウェイ統合です。リダイレクトによるカード決済と、埋め込み QR コードによる QR 決済(PayNow、GrabPay など)に対応しています。
適用するタイミング
次の場合にこのスキルを参照してください。
- HitPay 決済ゲートウェイを統合する
- 決済チェックアウトフローを作成する
- QR コード決済(PayNow、GrabPay、ShopeePay)を実装する
- 決済 Webhook を処理する
- 返金を処理する
ステップ 1:決済方法を決定する
顧客が対応を希望する決済方法を確認します。
カードのみの方法
card(Visa、Mastercard、Amex)
QR のみの方法
paynow_online(シンガポール)grabpay_directshopee_paywechatalipayfpx(マレーシア)promptpay(タイ)truemoney(タイ)vietqr(ベトナム)qris(インドネシア)upi(インド)gcash(フィリピン)
ステップ 2:フロントエンドの方法を選択する
| 決済方法 | 推奨されるフロントエンド |
|---|---|
| カードのみ | HitPay のチェックアウトにリダイレクト |
| QR のみ | サイトにQR を埋め込み |
| カードと QR の両方 | 決済方法セレクターを表示し、適切なフローを選択 |
API の基本
| 環境 | ベース URL |
|---|---|
| サンドボックス | https://api.sandbox.hit-pay.com |
| 本番環境 | https://api.hit-pay.com |
認証
const headers = {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY,
'Content-Type': 'application/json',
};
HitPay ダッシュボードの Settings → Payment Gateway → API Keys から API キーを取得します。
フロントエンドの方法 A:リダイレクト(カード)
カード決済、またはチェックアウト UI 全体を HitPay に任せたい場合に最適です。
フロー
- バックエンドが決済リクエストを作成します
- フロントエンドが
response.urlにリダイレクトします - 顧客が HitPay のホストページで支払います
- 顧客が
redirect_urlに戻ります - バックエンドが Webhook で確認します
Next.js API ルート
// app/api/payments/create/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { amount, currency, orderId } = await request.json();
const response = await fetch('https://api.sandbox.hit-pay.com/v1/payment-requests', {
method: 'POST',
headers: {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount,
currency,
payment_methods: ['card'],
reference_number: orderId,
redirect_url: `${process.env.NEXT_PUBLIC_APP_URL}/payment/complete`,
webhook: `${process.env.NEXT_PUBLIC_APP_URL}/api/webhooks/hitpay`,
}),
});
const data = await response.json();
return NextResponse.json({ url: data.url, paymentRequestId: data.id });
}
フロントエンドコンポーネント
// components/CheckoutButton.tsx
'use client';
export function CheckoutButton({ amount, currency, orderId }: Props) {
const handleCheckout = async () => {
const response = await fetch('/api/payments/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, currency, orderId }),
});
const { url } = await response.json();
window.location.href = url; // Redirect to HitPay
};
return <button onClick={handleCheckout}>Pay with Card</button>;
}
フロントエンドの方法 B:QR コードの埋め込み
顧客がサイトに留まる QR 決済に最適です。
フロー
- バックエンドが
generate_qr: trueを指定して決済リクエストを作成します - フロントエンドが
response.qr_code_dataから QR コードを表示します - 顧客が決済アプリでスキャンします
- フロントエンドがステータスをポーリングするか、Webhook を待ち受けます
- バックエンドが Webhook で確認します
Next.js API ルート
// app/api/payments/create-qr/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { amount, currency, orderId, paymentMethod } = await request.json();
const response = await fetch('https://api.sandbox.hit-pay.com/v1/payment-requests', {
method: 'POST',
headers: {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount,
currency,
payment_methods: [paymentMethod],
generate_qr: true,
reference_number: orderId,
webhook: `${process.env.NEXT_PUBLIC_APP_URL}/api/webhooks/hitpay`,
}),
});
const data = await response.json();
return NextResponse.json({
paymentRequestId: data.id,
qrCodeData: data.qr_code_data,
});
}
フロントエンドコンポーネント
// components/QRPayment.tsx
'use client';
import { useEffect, useRef } from 'react';
import QRCode from 'qrcode';
export function QRPayment({ amount, currency, orderId, paymentMethod }: Props) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const createQR = async () => {
const response = await fetch('/api/payments/create-qr', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, currency, orderId, paymentMethod }),
});
const { qrCodeData } = await response.json();
if (canvasRef.current && qrCodeData) {
await QRCode.toCanvas(canvasRef.current, qrCodeData, { width: 256 });
}
};
createQR();
}, [amount, currency, orderId, paymentMethod]);
return (
<div>
<canvas ref={canvasRef} />
<p>Scan with your payment app</p>
</div>
);
}
フロントエンドの方法 C:決済方法セレクター
カード決済と QR 決済の両方に対応する場合に最適です。
フロントエンドコンポーネント
// components/PaymentMethodSelector.tsx
'use client';
import { useState } from 'react';
import { QRPayment } from './QRPayment';
const PAYMENT_METHODS = [
{ id: 'card', label: 'Credit/Debit Card', type: 'redirect' },
{ id: 'paynow_online', label: 'PayNow', type: 'qr' },
{ id: 'grabpay_direct', label: 'GrabPay', type: 'qr' },
{ id: 'shopee_pay', label: 'ShopeePay', type: 'qr' },
];
export function PaymentMethodSelector({ amount, currency, orderId }: Props) {
const [selected, setSelected] = useState<string | null>(null);
const handlePayment = async (method: typeof PAYMENT_METHODS[0]) => {
if (method.type === 'redirect') {
const response = await fetch('/api/payments/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount, currency, orderId }),
});
const { url } = await response.json();
window.location.href = url;
} else {
setSelected(method.id);
}
};
if (selected) {
return (
<QRPayment
amount={amount}
currency={currency}
orderId={orderId}
paymentMethod={selected}
/>
);
}
return (
<div>
<h3>Select Payment Method</h3>
{PAYMENT_METHODS.map((method) => (
<button key={method.id} onClick={() => handlePayment(method)}>
{method.label}
</button>
))}
</div>
);
}
Webhook の処理
処理を行う前に、必ず Webhook の署名を検証してください。詳細は references/webhook-events.md を参照してください。
// app/api/webhooks/hitpay/route.ts
import { NextResponse } from 'next/server';
import crypto from 'crypto';
export async function POST(request: Request) {
const body = await request.text();
const signature = request.headers.get('Hitpay-Signature');
// Verify signature
const expectedSignature = crypto
.createHmac('sha256', process.env.HITPAY_SALT!)
.update(body)
.digest('hex');
if (signature !== expectedSignature) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
}
const payload = JSON.parse(body);
// Process payment confirmation
if (payload.status === 'completed') {
// Mark order as paid
await markOrderAsPaid(payload.reference_number);
}
return NextResponse.json({ received: true });
}
決済ステータスの確認
API の全リファレンスについては、references/payment-request-api.md を参照してください。
// app/api/payments/[id]/route.ts
export async function GET(
request: Request,
{ params }: { params: { id: string } }
) {
const response = await fetch(
`https://api.sandbox.hit-pay.com/v1/payment-requests/${params.id}`,
{
headers: {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
},
}
);
const data = await response.json();
return NextResponse.json(data);
}
返金
詳細については、references/refunds.md を参照してください。
// app/api/payments/[id]/refund/route.ts
export async function POST(
request: Request,
{ params }: { params: { id: string } }
) {
const { amount } = await request.json();
const response = await fetch(
`https://api.sandbox.hit-pay.com/v1/payment-requests/${params.id}/refund`,
{
method: 'POST',
headers: {
'X-BUSINESS-API-KEY': process.env.HITPAY_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({ amount }),
}
);
const data = await response.json();
return NextResponse.json(data);
}
環境変数
# .env.local
HITPAY_API_KEY=your_api_key
HITPAY_SALT=your_webhook_salt
NEXT_PUBLIC_APP_URL=http://localhost:3000
テストカード(サンドボックス)
| 結果 | 番号 | 有効期限 | CVC |
|---|---|---|---|
| 成功 | 4242 4242 4242 4242 | 任意の未来の日付 | 任意の 3 桁 |
| 拒否 | 4000 0000 0000 0002 | 任意の未来の日付 | 任意の 3 桁 |
リソース
- サンドボックスダッシュボード:https://dashboard.sandbox.hit-pay.com
- 本番ダッシュボード:https://dashboard.hit-pay.com
- API ドキュメント:https://docs.hitpayapp.com
コメント
Markdown 対応