> ## Documentation Index
> Fetch the complete documentation index at: https://docs.caibo.digital/llms.txt
> Use this file to discover all available pages before exploring further.

# H2H Response Structure

> Understanding Host-to-Host API response format, status codes, and error handling

# H2H Response Structure

Host-to-Host API responses provide essential information for tracking and completing payment processes. This guide covers response formats, status handling, and implementation patterns.

## Response Overview

The API returns a payment response containing essential information for tracking and completing the payment process.

### Response Structure

The payment response includes:

* **Payment Request Identifier**: A unique identifier for the created payment request that can be used to pull payment request status
* **Redirect URL**: A URL to complete the payment if necessary (for payment methods requiring customer interaction)

### Response Fields

| Field              | Description                           | Type           |
| ------------------ | ------------------------------------- | -------------- |
| `paymentRequestId` | Created payment request identifier    | string/integer |
| `redirectUrl`      | URL to complete payment (if required) | string         |
| `status`           | Initial payment status                | string         |

## Response Usage

### 1. Status Tracking

Use the payment request identifier to check payment status via status endpoints:

```javascript theme={null}
// Track payment status
async function checkPaymentStatus(paymentRequestId) {
  const response = await fetch(`/api/payment-status/${paymentRequestId}`, {
    headers: {
      'X-API-Key': apiKey
    }
  });
  
  const status = await response.json();
  return status;
}
```

### 2. Payment Completion

Redirect customers to the provided URL for payment methods requiring user interaction:

```javascript theme={null}
// Handle redirect if required
if (paymentResponse.redirectUrl) {
  // Redirect customer to complete payment
  window.location.href = paymentResponse.redirectUrl;
} else {
  // Payment completed directly
  handlePaymentComplete(paymentResponse);
}
```

### 3. Transaction Management

Store the identifier for future reference and reconciliation:

```javascript theme={null}
// Store payment reference
const paymentRecord = {
  paymentRequestId: paymentResponse.paymentRequestId,
  merchantReference: orderData.referenceId,
  amount: orderData.amount,
  currency: orderData.unit,
  status: paymentResponse.status,
  createdAt: new Date().toISOString()
};

await savePaymentRecord(paymentRecord);
```

## Implementation Examples

### Basic H2H Payment Processing

```javascript theme={null}
// H2H Payment Processing
async function processH2HPayment(paymentData) {
  const apiEndpoint = "https://api.caibo.com/h2h/payments"; // From dashboard
  const apiKey = "your-api-key-from-dashboard";
  
  try {
    const response = await fetch(apiEndpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': apiKey
      },
      body: JSON.stringify({
        amount: paymentData.amount,
        currency: paymentData.currency,
        paymentMethod: {
          type: "credit_card",
          cardNumber: paymentData.cardNumber,
          expiryMonth: paymentData.expiryMonth,
          expiryYear: paymentData.expiryYear,
          cvv: paymentData.cvv,
          cardholderName: paymentData.cardholderName
        },
        customer: {
          email: paymentData.customerEmail,
          phone: paymentData.customerPhone
        },
        billingAddress: paymentData.billingAddress,
        merchantReference: paymentData.orderId,
        notificationUrl: "https://yoursite.com/webhooks/payment-notification"
      })
    });
    
    const result = await response.json();
    
    if (response.ok) {
      console.log('Payment processed successfully:', result);
      return {
        success: true,
        transactionId: result.transactionId,
        status: result.status,
        data: result
      };
    } else {
      console.error('Payment failed:', result);
      return {
        success: false,
        error: result.error,
        message: result.message
      };
    }
  } catch (error) {
    console.error('Network error:', error);
    return {
      success: false,
      error: 'NETWORK_ERROR',
      message: error.message
    };
  }
}
```

### Multiple Provider Handling

```javascript theme={null}
// Handle multiple API endpoints for different providers
const providerEndpoints = {
  'provider1': 'https://api1.caibo.com/h2h/payments',
  'provider2': 'https://api2.caibo.com/h2h/payments',
  'provider3': 'https://api3.caibo.com/h2h/payments'
};

async function processPaymentWithFailover(paymentData, preferredProvider = 'provider1') {
  const providers = [preferredProvider, ...Object.keys(providerEndpoints).filter(p => p !== preferredProvider)];
  
  for (const provider of providers) {
    try {
      const endpoint = providerEndpoints[provider];
      const result = await processH2HPayment({
        ...paymentData,
        endpoint: endpoint
      });
      
      if (result.success) {
        console.log(`Payment successful with ${provider}`);
        return result;
      }
    } catch (error) {
      console.warn(`Provider ${provider} failed, trying next...`);
      continue;
    }
  }
  
  throw new Error('All payment providers failed');
}
```

## Error Handling

### Common Error Codes

* **INVALID\_API\_KEY**: API key is missing or invalid
* **INSUFFICIENT\_FUNDS**: Customer's account has insufficient funds
* **CARD\_DECLINED**: Payment method was declined by issuer
* **INVALID\_CARD**: Card number or details are invalid
* **EXPIRED\_CARD**: Payment method has expired
* **NETWORK\_ERROR**: Communication error with payment provider

### Retry Logic

```javascript theme={null}
async function processPaymentWithRetry(paymentData, maxRetries = 3) {
  let attempt = 0;
  let lastError;
  
  while (attempt < maxRetries) {
    try {
      const result = await processH2HPayment(paymentData);
      
      if (result.success) {
        return result;
      }
      
      // Check if error is retryable
      if (isRetryableError(result.error)) {
        attempt++;
        await delay(Math.pow(2, attempt) * 1000); // Exponential backoff
        continue;
      } else {
        // Non-retryable error, fail immediately
        return result;
      }
    } catch (error) {
      lastError = error;
      attempt++;
      
      if (attempt < maxRetries) {
        await delay(Math.pow(2, attempt) * 1000);
      }
    }
  }
  
  throw new Error(`Payment failed after ${maxRetries} attempts: ${lastError.message}`);
}

function isRetryableError(errorCode) {
  const retryableErrors = [
    'NETWORK_ERROR',
    'TIMEOUT',
    'TEMPORARY_UNAVAILABLE',
    'RATE_LIMITED'
  ];
  
  return retryableErrors.includes(errorCode);
}

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
```

## Status Management

### Payment Status Types

* **pending**: Payment is being processed
* **completed**: Payment was successful
* **failed**: Payment failed
* **cancelled**: Payment was cancelled
* **expired**: Payment request expired

### Status Polling

```javascript theme={null}
async function pollPaymentStatus(paymentRequestId, maxAttempts = 30, interval = 2000) {
  let attempts = 0;
  
  while (attempts < maxAttempts) {
    try {
      const status = await checkPaymentStatus(paymentRequestId);
      
      // Terminal states
      if (['completed', 'failed', 'cancelled', 'expired'].includes(status.status)) {
        return status;
      }
      
      // Continue polling for pending status
      await delay(interval);
      attempts++;
      
    } catch (error) {
      console.error('Status check failed:', error);
      attempts++;
      await delay(interval);
    }
  }
  
  throw new Error('Payment status polling timeout');
}
```

## Response Validation

### Validate Response Structure

```javascript theme={null}
function validatePaymentResponse(response) {
  const requiredFields = ['paymentRequestId', 'status'];
  
  for (const field of requiredFields) {
    if (!response[field]) {
      throw new Error(`Missing required field: ${field}`);
    }
  }
  
  // Validate status values
  const validStatuses = ['pending', 'completed', 'failed', 'cancelled', 'expired'];
  if (!validStatuses.includes(response.status)) {
    throw new Error(`Invalid status: ${response.status}`);
  }
  
  return true;
}
```

### Response Processing

```javascript theme={null}
async function handlePaymentResponse(response) {
  try {
    // Validate response structure
    validatePaymentResponse(response);
    
    // Store payment record
    await savePaymentRecord({
      paymentRequestId: response.paymentRequestId,
      status: response.status,
      redirectUrl: response.redirectUrl,
      timestamp: new Date().toISOString()
    });
    
    // Handle based on status
    switch (response.status) {
      case 'completed':
        await handleSuccessfulPayment(response);
        break;
        
      case 'pending':
        await handlePendingPayment(response);
        break;
        
      case 'failed':
        await handleFailedPayment(response);
        break;
        
      default:
        console.warn('Unexpected payment status:', response.status);
    }
    
    return response;
    
  } catch (error) {
    console.error('Response handling error:', error);
    throw error;
  }
}
```

## Best Practices

### Response Handling

1. **Immediate Validation**: Validate response structure immediately
2. **Status Tracking**: Always track payment status changes
3. **Error Logging**: Log all errors for debugging and monitoring
4. **Timeout Handling**: Implement appropriate timeout values

### Performance

1. **Connection Pooling**: Use HTTP connection pooling for better performance
2. **Async Processing**: Handle responses asynchronously when possible
3. **Caching**: Cache non-sensitive response data appropriately
4. **Monitoring**: Monitor response times and success rates

### Security

1. **Response Validation**: Always validate response data
2. **Sensitive Data**: Never log sensitive payment information
3. **Error Messages**: Sanitize error messages before displaying to users
4. **Audit Trail**: Maintain audit trail of all payment responses

## Next Steps

<Card title="Request Structure" icon="arrow-left" href="/h2h/request-structure">
  Learn about H2H API request format and parameters
</Card>

<Card title="Notifications" icon="bell" href="/h2h/notifications">
  Set up webhook notifications for real-time status updates
</Card>

<Card title="Payment Methods" icon="credit-card" href="/h2h/payment-methods">
  Explore available payment methods and implementations
</Card>
