Webhooks
Get notified in real-time when payments are detected, confirmed, or settled.
Setupโ
Set your webhook_url when registering as a merchant, or update it later:
curl -X PATCH https://api.encrypto.fun/checkout/merchants/me \
-H "X-Checkout-Secret-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"webhook_url": "https://mystore.com/api/webhooks/encrypto"}'
Verifying Signaturesโ
Every webhook includes an X-Checkout-Signature header. Always verify it to ensure the request came from Encrypto.
Node.jsโ
const crypto = require('crypto');
function verifyWebhook(req) {
const signature = req.headers['x-checkout-signature'];
const body = JSON.stringify(req.body);
const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(body).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Pythonโ
import hmac, hashlib
def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)
Event Referenceโ
payment.detectedโ
Payment seen on-chain but not yet confirmed. Don't fulfill the order yet.
payment.confirmingโ
Payment has partial confirmations. Almost there.
payment.confirmedโ
Payment fully confirmed. This is when you fulfill the order.
session.expiredโ
The 30-minute window elapsed without payment. Clean up the pending order.
settlement.completedโ
USDC has been settled to your wallet address. This confirms you've been paid out.
Best Practicesโ
- Always verify signatures โ Never trust unverified webhooks
- Return 200 quickly โ Process asynchronously if your logic is slow
- Handle duplicates โ Use
session_external_idas an idempotency key - Act on
payment.confirmedโ Don't fulfill onpayment.detected(it could fail) - Log everything โ Store the raw webhook payload for debugging