Skip to main content

IDs, Reference IDs, and Idempotency

Understanding how NextAPI handles identification and ensures data consistency across your payment operations.

ID Types in NextAPI

System-Generated IDs

NextAPI generates unique IDs for all major entities:

// Payout ID
"payout_1234567890abcdef"

// Wallet ID
"wallet_abcdef1234567890"

// Payment Link ID
"plink_1234abcdef567890"

// Transaction ID
"txn_5678901234abcdef"

// Event ID
"evt_9012345678abcdef"

Reference IDs

Client-provided identifiers for your tracking:

// Your reference
{
"reference_id": "your-order-12345",
"metadata": {
"invoice_number": "INV-2024-001",
"customer_id": "cust-789"
}
}

ID Formats and Validation

Format Structure

  • Prefix: Entity type (payout_, wallet_, etc.)
  • Length: 24-32 characters total
  • Charset: Hexadecimal (0-9, a-f)
  • Uniqueness: Globally unique across NextAPI

Validation Patterns

// Payout ID validation
const payoutIdPattern = /^payout_[a-f0-9]{16,24}$/;

// Wallet ID validation
const walletIdPattern = /^wallet_[a-f0-9]{16,24}$/;

// Reference ID validation
const referenceIdPattern = /^[a-zA-Z0-9_-]{1,100}$/;

Idempotency

What is Idempotency?

Idempotency ensures that making the same request multiple times produces the same result as making it once. This prevents duplicate operations when network issues cause retries.

Idempotency Keys

Include an idempotency key in your requests:

const response = await fetch('https://api.nextapi.com/v1/payouts', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
'Idempotency-Key': 'unique-key-for-this-operation'
},
body: JSON.stringify({
amount: 10000,
currency: 'PHP',
recipient: { type: 'wallet', id: 'wallet_123' }
})
});

Key Requirements

  • Uniqueness: Must be unique per operation
  • Format: String, up to 255 characters
  • Scope: Per API endpoint and method
  • Duration: Keys expire after 24 hours

Generating Idempotency Keys

// Using UUID
import { v4 as uuidv4 } from 'uuid';
const idempotencyKey = uuidv4();

// Using timestamp and random
const idempotencyKey = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;

// Using business identifiers
const idempotencyKey = `order-${orderId}-${timestamp}`;

Reference ID Best Practices

Choosing Reference IDs

  1. Business Meaning: Use meaningful identifiers
  2. Uniqueness: Ensure uniqueness within your scope
  3. Consistency: Follow consistent naming patterns
  4. Length: Keep under 100 characters
  5. Characters: Use alphanumeric, hyphens, underscores

Examples

// Good examples
"ORDER-2024-001"
"CUST-789-PAYMENT-001"
"INV-20240115-001"
"PAYROLL-JAN-2024-EMP-123"

// Bad examples
"payment" // Too generic
"a very long reference id that exceeds reasonable limits" // Too long
"payment@#$%" // Invalid characters

Error Handling

Duplicate Reference IDs

// Response when reference ID already exists
{
"error": {
"code": "DUPLICATE_REFERENCE",
"message": "Reference ID already exists",
"existing_id": "payout_123",
"reference_id": "ORDER-2024-001"
}
}

Idempotency Conflicts

// Response when idempotency key was used with different parameters
{
"error": {
"code": "IDEMPOTENCY_KEY_CONFLICT",
"message": "Idempotency key was used with different parameters",
"idempotency_key": "key-123",
"existing_request_id": "req_456"
}
}

Tracking and Reconciliation

Storing Mappings

Maintain mappings between your IDs and NextAPI IDs:

// Database schema example
CREATE TABLE payout_mappings (
id SERIAL PRIMARY KEY,
your_reference_id VARCHAR(100) UNIQUE NOT NULL,
nextapi_payout_id VARCHAR(50) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);

Reconciliation Process

async function reconcilePayouts() {
// Get your recent orders
const yourOrders = await getYourRecentOrders();

for (const order of yourOrders) {
// Find corresponding payout
const payout = await findPayoutByReference(order.reference_id);

if (!payout) {
// Handle missing payout
console.log(`Missing payout for order: ${order.reference_id}`);
} else if (payout.status !== 'completed') {
// Handle incomplete payout
console.log(`Incomplete payout: ${payout.id}`);
}
}
}

API Usage

Query by Reference ID

GET /v1/payouts?reference_id=ORDER-2024-001

Query by Multiple References

GET /v1/payouts?reference_id[]=ORDER-2024-001&reference_id[]=ORDER-2024-002

Include in Requests

POST /v1/payouts
{
"amount": 10000,
"currency": "PHP",
"reference_id": "ORDER-2024-001",
"metadata": {
"invoice_number": "INV-2024-001"
}
}

Best Practices

  1. Always use idempotency keys for POST/PUT operations
  2. Store reference ID mappings in your database
  3. Implement reconciliation processes
  4. Use meaningful reference IDs for business tracking
  5. Handle duplicate errors gracefully
  6. Log ID mappings for debugging
  7. Validate ID formats before using
  • [The Lifecycle of a Payout](./the-lifecycle-of-a-payout
  • [Understanding Webhooks](./understanding-webhooks
  • [Security & Compliance](./security-compliance