Best Practices
Production recommendations
Recommendations for a robust, secure production integration.
Security
- Keep API keys server-side. Never expose them to browsers or mobile apps. Frontends call your backend; your backend calls Liqo.
- Load keys from environment variables, never hard-coded or committed.
- Verify every webhook with
liqo.webhooks.verify()using the raw body before acting on it. - Separate sandbox and live keys and never test against production.
Idempotency
- Pass a stable
idempotencyKey(e.g., your order id) topay()/checkout.sessions.create()so retries never create duplicate sessions. - Make webhook handlers idempotent — dedupe on
data.transactionId+ event name; the same event can arrive more than once.
Prefer webhooks over polling
- Use webhooks as your source of truth for fulfillment — they're immediate and cheap.
- Reserve
waitForCompletion()for short-lived, interactive flows or as a fallback. KeeptimeoutMssane.
Reliability
- The SDK retries network errors and
429automatically. Keep your own operations idempotent so retries are safe. - Respond to webhooks fast (return 2xx immediately) and do heavy work asynchronously; slow handlers cause redelivery.
- Set a
timeoutMsappropriate to your environment (serverless functions have their own limits).
Client lifecycle
- Reuse a single
Liqoinstance across requests instead of constructing one per request — it holds a configured HTTP client. - In serverless, construct it at module scope so it's reused across warm invocations.
Observability
- Use
liqo.on('request' | 'response' | 'error', …)to feed your logging/metrics. - Enable
debug: trueonly in development — it logs request/response bodies. - Persist
error.requestIdfromLiqoApiErrorto correlate with Liqo support.
Money & correctness
- Treat amounts explicitly in the
fromCurrencyunit; don't mix currencies. - Confirm the destination
toWalletmatchestargetChain(the SDK validates this, but validate upstream in your own UI too). - Use quotes to show estimated output/fees before creating a payment; quotes expire (
expiresAt).
Error handling
- Branch on
err.code(canonical codes) and fall back toerr.message. See Error Handling. - Distinguish
LiqoSdkError(client-side/validation) fromLiqoApiError(server) to decide whether to retry or surface to the user.
Testing
- Develop against
environment: 'sandbox'. - Mock the HTTP layer in unit tests (the SDK uses
axios), or pointbaseUrlat a local mock server.