웹훅 연동
게임에 백엔드 서버가 있다면, 웹훅으로 결제 이벤트를 수신하여 서버사이드에서 아이템을 지급할 수 있습니다.
설정
게임 설정에서 웹훅 URL과 시크릿을 등록합니다.
| 필드 | 설명 |
|---|---|
| Webhook URL | 결제 이벤트를 수신할 URL |
| Webhook Secret | HMAC 서명 검증용 시크릿 키 (자동 생성) |
웹훅 페이로드
크레딧 결제가 완료되면 아래 형태의 POST 요청이 전송됩니다.
POST https://your-server.com/webhooks/purchase
Content-Type: application/json
X-Webhook-Signature: sha256=abc123...
{
"event": "purchase",
"transactionId": "tx-uuid-456",
"userId": "user-abc123",
"userName": "홍길동",
"amount": 50,
"itemId": "power-up-123",
"description": "Triple Points",
"timestamp": "2025-01-15T10:30:00Z"
}
서명 검증
X-Webhook-Signature 헤더는 HMAC-SHA256(body, webhookSecret) 입니다. 반드시 검증하세요.
Node.js 예시
const crypto = require('crypto');
function verifySignature(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return `sha256=${expected}` === signature;
}
// Express 핸들러
app.post('/webhooks/purchase', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const body = req.body.toString();
if (!verifySignature(body, signature, WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const event = JSON.parse(body);
// 아이템 지급 로직
if (event.event === 'purchase') {
grantItem(event.userId, event.itemId, event.transactionId);
}
res.json({ ok: true });
});
Python 예시
import hmac
import hashlib
def verify_signature(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return f"sha256={expected}" == signature
멱등성 (Idempotency)
네트워크 문제로 같은 웹훅이 여러 번 전송될 수 있습니다. transactionId를 키로 중복 처리를 방지하세요.
// DB에서 transactionId 중복 확인
const existing = await db.findTransaction(event.transactionId);
if (existing) {
return res.json({ ok: true }); // 이미 처리됨
}
주의사항
- 웹훅 URL은 HTTPS만 지원됩니다
- 응답 타임아웃: 10초 (초과 시 재시도)
- 실패 시 최대 3회 재시도 (지수 백오프)
- 서명 검증 없이 웹훅을 처리하지 마세요