Error Handling
Error response format
All API errors return a JSON body:
json
{
"error": {
"code": "SESSION_EXPIRED",
"message": "The payment session has expired.",
"detail": "Session ops_01HZGV expired at 2026-04-24T06:15:00Z",
"request_id": "req_abc123"
}
}SDK error types
typescript
import { AstroError } from '@neptune.fintech/astro-sdk'
try {
const session = await astro.payments.createSession(...)
} catch (err) {
if (err instanceof AstroError) {
console.error(`[${err.code}] ${err.message}`)
console.error('HTTP status:', err.status)
console.error('Request ID:', err.requestId)
}
}dart
try {
final session = await astro.payments.createSession(...);
} on AstroError catch (e) {
print('${e.statusCode}: [${e.code}] ${e.message}');
}kotlin
try {
val session = astro.payments.createSession(...)
} catch (e: AstroRequestException) {
println("${e.status}: [${e.code}] ${e.message}")
println("Request ID: ${e.requestId}")
}swift
do {
let session = try await astro.payments.createSession(...)
} catch let error as AstroError {
print("\(error.statusCode): [\(error.code)] \(error.localizedDescription)")
}Common error codes
| Code | HTTP | Meaning |
|---|---|---|
INVALID_API_KEY | 401 | API key is missing or invalid |
SESSION_NOT_FOUND | 404 | Session ID doesn't exist |
SESSION_EXPIRED | 410 | Session TTL exceeded |
INSUFFICIENT_FUNDS | 422 | Customer has insufficient balance |
ALIAS_NOT_FOUND | 404 | NPT alias not registered |
BANK_UNAVAILABLE | 503 | The target bank is temporarily unreachable |
DUPLICATE_IDEMPOTENCY_KEY | 409 | Same idempotency key used for a different request |
VALIDATION_ERROR | 400 | Request body failed validation |
INVALID_SIGNATURE | 401 | Webhook signature verification failed |
Idempotency
Pass an Idempotency-Key header on write requests. Same key within 24h returns the original response without re-processing:
http
POST /payments/sessions
Idempotency-Key: order_1042_attempt_1