← ClaudeAtlas

payuni-webhooklisted

Implements PAYUNi webhook handling including signature verification, replay attack prevention, and payment status updates. Use when building payment notification endpoints for 統一金流.
Oelshafei1/skills · ★ 1 · Web & Frontend · score 80
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