Security
Security in a Manatee integration has four main parts: keep API keys server-side, verify webhook signatures, prevent replay, and keep wallet private keys out of the integration.
API keys
- Store API keys only on your backend.
- Do not put API keys into frontend JavaScript, mobile apps, screenshots, or public repositories.
- Use testnet keys for testing and mainnet keys only for real payments.
- Rotate a key if it is exposed.
Webhook signature verification
Manatee signs webhook requests with HMAC-SHA256. Verify the signature before changing order state.
Required rules:
- Use the webhook signing secret for the API key that created the payment.
- Verify the raw request body.
- Verify
X-Manatee-SignatureoverX-Manatee-Timestamp + "." + raw request body. - Reject requests whose
X-Manatee-Timestampis outside your allowed clock-skew window. Five minutes is a reasonable default. - Compare signatures with a timing-safe comparison.
- Reject requests with missing or malformed signatures.
See Verify Webhook Signatures for a Node.js example.
Replay protection
Webhook delivery is at-least-once. Your endpoint may receive the same event more than once.
Use X-Manatee-Event-Id for replay protection:
- Verify the signature.
- Check whether
X-Manatee-Event-Idwas already processed. - If it is new, update the order and store the event ID.
- If it was already processed, return
2xxwithout repeating fulfillment.
Payment creation should also be idempotent. Use an Idempotency-Key header for POST /v1/btc/payments. See Idempotency Keys.
Non-custodial wallet handling
Manatee does not need your wallet seed phrase or private keys. Customer payments go directly to wallet addresses you control.
For production, use a dedicated business wallet account and read-only receive data such as a descriptor or extended public key. Learn more in Receive Descriptors and xpubs.
Endpoint hardening
Your webhook endpoint must accept server-to-server HTTP requests. If your site uses Cloudflare, a WAF, bot protection, captchas, browser challenges, or login redirects, bypass those protections only for the webhook path and rely on X-Manatee-Signature verification there.
Do not disable protection for your whole domain.