payuni-webhooklisted
Install: claude install-skill Oelshafei1/skills
# 統一金流 Webhook 處理任務
你的任務是在用戶的專案中實作統一金流 Webhook 接收與處理功能。
## 串接 Checklist
- [ ] **框架確認** - 確認使用的框架
- [ ] **端點建立** - 建立 Webhook 接收端點
- [ ] **簽名驗證** - 實作 CheckCode 驗證
- [ ] **防重放** - 實作重複請求檢測
- [ ] **狀態更新** - 更新訂單狀態
- [ ] **測試驗證** - 驗證 Webhook 處理流程
---
## Step 1: 確認專案環境
用戶輸入: `$ARGUMENTS`
詢問用戶:
1. **框架類型**:
- Next.js (App Router / Pages Router)
- Express / Fastify
- NestJS
- 其他
2. **資料庫**:用什麼來儲存訂單?
- PostgreSQL / MySQL
- MongoDB
- Prisma / Drizzle
- Supabase
- 其他
## Step 2: 建立 Webhook 端點
### Next.js App Router
```typescript
// app/api/webhooks/payuni/route.ts
import { NextRequest, NextResponse } from 'next/server';
import crypto from 'crypto';
const config = {
hashKey: process.env.PAYUNI_HASH_KEY!,
hashIV: process.env.PAYUNI_HASH_IV!,
};
// 簽名驗證(使用 constant-time 比較防止 timing attack)
function verifyCheckCode(params: Record<string, string>): boolean {
const { CheckCode, ...otherParams } = params;
if (!CheckCode) return false;
const sortedKeys = Object.keys(otherParams).sort();
const paramStr = sortedKeys.map(k => `${k}=${otherParams[k]}`).join('&');
const signStr = `HashKey=${config.hashKey}&${paramStr}&HashIV=${config.hashIV}`;
const calculated = crypto
.createHash('sha256')
.update(signStr)
.digest('hex')
.toUpperCase();
try {
return crypto.timingSafeEqual(
Buffer.from(calculated),
Buffer.from(CheckCode)
);
} catch {
return false;
}
}
export async function POST(request: Nex