Radar API β Integration Guide
Practical guidance for integrating Radar into your system: real-world examples, validation rules, error handling, and best practices.
Back to: Radar Event API Overview Β· API Reference
Use Cases & Examples
Common integration scenarios across all three event categories, showing the full request payload and the expected response. Use these as a starting point for your own integration.
1. User Login Event
Track a successful user login.
Request:
{
"event": "login_succeeded",
"event_timestamp": 1734523200000,
"ip": "192.168.1.100",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"mobile": "+966501234567"
},
"device": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"os": "Android",
"brand": "Samsung",
"model": "Galaxy S21",
"os_version": "13",
"rooted": false,
"emulator": false
},
"session": {
"id": "770e8400-e29b-41d4-a716-446655440002"
},
"location": {
"latitude": 24.7136,
"longitude": 46.6753,
"mocked": false
}
}
Response:
{
"action_id": "unknown",
"action": "allow",
"state": "unknown"
}
2. Failed Login Attempt
Track a failed login attempt for potential brute-force detection.
Request:
{
"event": "login_failed",
"event_timestamp": 1734523200000,
"ip": "45.33.32.156",
"user": {
"email": "[email protected]"
},
"device": {
"id": "660e8400-e29b-41d4-a716-446655440001",
"os": "Android",
"rooted": true,
"emulator": true
},
"browser": {
"user_agent": "Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36"
}
}
Response (High Risk):
{
"action_id": "unknown",
"action": "block",
"state": "unknown"
}
3. Business Registration
Track a new business registration.
Request:
{
"event": "business_registered",
"event_timestamp": 1734523200000,
"ip": "192.168.1.100",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]"
},
"business": {
"id": "880e8400-e29b-41d4-a716-446655440003",
"registration_number": "1010123456",
"registration_date": "2024-01-15T00:00:00.000Z",
"registration_country": "SA",
"name": "Example Trading Est.",
"type": "LLC",
"category": "Retail",
"tax_id": "300012345600003",
"status": "active",
"owners": [
{
"id": "990e8400-e29b-41d4-a716-446655440004",
"name": "John Doe",
"national_id": "1234567890",
"nationality": "SA"
}
]
}
}
Response:
{
"action_id": "unknown",
"action": "allow",
"state": "unknown"
}
4. Payment Transaction (POS)
Track a point-of-sale purchase transaction.
Request:
{
"event": "payment_completed",
"event_timestamp": 1734523200000,
"ip": "10.0.0.50",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000"
},
"merchant": {
"id": "MID123456789",
"mcc": "5411",
"name": "Grocery Store"
},
"terminal": {
"id": "TID987654321",
"merchant_id": "MID123456789",
"card_acceptor_terminal_id": "12345678",
"lat": 24.7136,
"lon": 46.6753
},
"request": {
"id": "aa0e8400-e29b-41d4-a716-446655440005",
"card_present": true,
"channel": "pos",
"type": "PURCHASE",
"entry_mode": "tapped",
"amount": 150.5,
"currency": "SAR",
"is_3ds": false,
"card": {
"pan": "489537******1234",
"brand": "mada",
"last4": "1234",
"verification": "pin",
"cardholder_verification": "pin"
}
},
"response": {
"auth_code": "123456",
"response_code": "00",
"response_message": "Approved",
"is_approved": true
},
"location": {
"latitude": 24.7136,
"longitude": 46.6753,
"mocked": false
}
}
Response:
{
"action_id": "unknown",
"action": "allow",
"state": "unknown"
}
5. E-Commerce Payment
Track an online card-not-present transaction.
Request:
{
"event": "payment_requested",
"event_timestamp": 1734523200000,
"ip": "203.0.113.50",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]"
},
"merchant": {
"id": "MID123456789",
"mcc": "5399",
"name": "Online Store"
},
"browser": {
"name": "Chrome",
"version": "120.0.0",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"timezone": "Asia/Riyadh",
"fingerprint": "abc123fingerprint",
"screen_resolution": "1920x1080"
},
"domain": {
"name": "onlinestore.com",
"age_days": 365,
"is_new": false,
"is_suspicious": false
},
"request": {
"id": "bb0e8400-e29b-41d4-a716-446655440006",
"card_present": false,
"channel": "e-commerce",
"type": "PURCHASE",
"entry_mode": "entered",
"amount": 299.99,
"currency": "SAR",
"is_3ds": true,
"card": {
"pan": "411111******1111",
"brand": "Visa",
"last4": "1111",
"exp_month": "12",
"exp_year": "2025",
"verification": "3ds",
"cardholder_ip": "203.0.113.50"
}
},
"response": {
"response_code": "00",
"is_approved": true
}
}
Response:
{
"action_id": "unknown",
"action": "allow",
"state": "unknown"
}
6. Payment Refund
Track a refund transaction (requires original transaction reference).
Request:
{
"event": "payment_refunded",
"event_timestamp": 1734609600000,
"ip": "10.0.0.50",
"merchant": {
"id": "MID123456789"
},
"terminal": {
"id": "TID987654321"
},
"request": {
"id": "cc0e8400-e29b-41d4-a716-446655440007",
"type": "REFUND",
"original_transaction_id": "aa0e8400-e29b-41d4-a716-446655440005",
"amount": 150.5,
"currency": "SAR",
"channel": "pos",
"card": {
"pan": "489537******1234"
}
},
"response": {
"auth_code": "654321",
"response_code": "00",
"is_approved": true
}
}
Response:
{
"action_id": "unknown",
"action": "allow",
"state": "unknown"
}
7. High-Risk Transaction (Blocked)
Example of a transaction that triggers a block action.
Request:
{
"event": "payment_requested",
"event_timestamp": 1734523200000,
"ip": "45.33.32.156",
"device": {
"id": "dd0e8400-e29b-41d4-a716-446655440008",
"rooted": true,
"emulator": true,
"hooked": true,
"malware": true
},
"location": {
"latitude": 0,
"longitude": 0,
"mocked": true
},
"request": {
"amount": 50000.0,
"currency": "SAR",
"channel": "e-commerce",
"card": {
"pan": "411111******9999"
}
},
"response": {
"is_approved": false,
"response_code": "51"
}
}
Response:
{
"action_id": "unknown",
"action": "block",
"state": "unknown"
}
Validation Rules
All events are validated before processing. Requests that fail validation return a 400 Bad Request with a message describing the issue.
Global Rules
| Rule | Description |
|---|---|
event_timestamp | Required. Must be a valid number (Unix timestamp in milliseconds). |
event_id | If provided, must be a valid UUID v4. Auto-generated if omitted. |
event | Must be one of the defined event types. |
Financial Event Rules
For all financial events (payment_*), these additional validations apply:
| Rule | Description |
|---|---|
request | Required. Must contain payment request details. |
response | Required. Must contain financial response details. |
request.amount | Required. Must be a number greater than 0.01. |
request.card.pan | Required within card object. Must be a string. |
request.currency | If provided, must match pattern ^[A-Z]{3}$ (ISO 4217). |
UUID Validation
All fields marked as UUID must conform to UUID v4 format:
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
Enum Constraints
| Field | Allowed Values |
|---|---|
user.status | active, inactive |
business.status | active, inactive |
device.install_source | google_play, apple_store, unknown |
request.channel | e-commerce, pos, softpos |
request.type | PURCHASE, REFUND, REVERSAL |
request.entry_mode | swiped, dipped, tapped, entered, apple_pay, google_pay, samsung_pay, mada_pay, tokenized, contactless |
card.verification | cvv, cvc, none, 3ds, cryptogram |
card.cardholder_verification | signature, otp, pin, none, 3ds, cryptogram |
Transform Rules
| Field | Transformation |
|---|---|
| Boolean fields | Accepts: true, false, 1, 0, "true", "false" |
| Date fields | Converted to JavaScript Date objects |
Error Responses
Errors follow a consistent JSON structure with statusCode, message, and error fields. Use the statusCode to distinguish between:
- 401 / 404 β Authentication and account errors
- 400 β Validation errors (missing fields, invalid formats, unknown properties)
- 500 β Unexpected server errors β contact NearPay support
Authentication Errors
401 Unauthorized - Missing or Invalid API Key
{
"statusCode": 401,
"message": "invalid_api_key",
"error": "Unauthorized"
}
Cause: The api-key header is missing or does not match any registered key.
404 Not Found - Client Not Found
{
"statusCode": 404,
"message": "client_not_found",
"error": "Not Found"
}
Cause: No customer account associated with the provided API key.
Validation Errors
400 Bad Request - Missing Required Field
{
"statusCode": 400,
"message": ["event_timestamp must be a number"],
"error": "Bad Request"
}
400 Bad Request - Invalid Event Type
{
"statusCode": 400,
"message": ["Event type must be a valid activity event"],
"error": "Bad Request"
}
400 Bad Request - Invalid UUID
{
"statusCode": 400,
"message": ["User ID must be a valid UUID"],
"error": "Bad Request"
}
400 Bad Request - Invalid Currency Format
{
"statusCode": 400,
"message": ["Currency must be a valid ISO 4217 code"],
"error": "Bad Request"
}
400 Bad Request - Missing Financial Event Fields
{
"statusCode": 400,
"message": [
"Request is required for financial events",
"Response is required for financial events"
],
"error": "Bad Request"
}
400 Bad Request - Invalid Amount
{
"statusCode": 400,
"message": [
"Payment amount must be a number",
"Payment amount must be greater than 0"
],
"error": "Bad Request"
}
400 Bad Request - Non-Whitelisted Properties
{
"statusCode": 400,
"message": ["property unknownField should not exist"],
"error": "Bad Request"
}
Server Errors
500 Internal Server Error
{
"risk": "error",
"score": 0
}
Cause: An unexpected error occurred during event processing. Contact NearPay support.
Best Practices
Follow these guidelines to get the most accurate risk scoring and maintain a reliable integration.
1. Include Complete Context
Provide as much context as possible for accurate risk scoring:
{
"event": "payment_requested",
"event_timestamp": 1734523200000,
"ip": "192.168.1.100",
"device": { ... },
"browser": { ... },
"location": { ... },
"user": { ... },
"merchant": { ... },
"terminal": { ... },
"request": { ... },
"response": { ... }
}
2. Use Consistent Identifiers
- Use the same
user.idfor all events from the same user - Use the same
device.idfor events from the same device - Use the same
session.idwithin a user session
3. Send Events in Real-Time
Send events as they occur for accurate time-based analysis:
payment_requestedβ When payment is initiatedpayment_responsedβ When processor respondspayment_completedβ When transaction finalizes
4. Handle Responses Appropriately
const response = await radarApi.sendEvent(event);
if (response.action === 'block') {
// Block the transaction/action
throw new Error('Transaction blocked by fraud detection');
} else if (response.action === 'allow') {
// Proceed with the transaction
processTransaction();
}
5. Provide Device Trust Signals
For mobile applications, include device attestation:
{
"device": {
"rooted": false,
"emulator": false,
"hooked": false,
"debuggable": false,
"malware": false,
"attestation_passed": true,
"app_verified": true,
"install_source": "google_play"
}
}
6. Track Location Accurately
{
"location": {
"latitude": 24.7136,
"longitude": 46.6753,
"mocked": false
}
}
7. Use Proper Date Formats
All date fields should use ISO 8601 format:
{
"signup_date": "2024-01-15T10:30:00.000Z",
"date_of_birth": "1990-05-20T00:00:00.000Z"
}
8. Reference Original Transactions
For refunds, reversals, and chargebacks:
{
"event": "payment_refunded",
"request": {
"type": "REFUND",
"original_transaction_id": "uuid-of-original-transaction",
"original_event_id": "uuid-of-original-event",
"original_rrn": "123456789012"
}
}