Open API Proxy APIs

add_action(‘wp_ajax_proxy_api’, ‘zeevou_openapi_proxy_api’);
add_action(‘wp_ajax_nopriv_proxy_api’, ‘zeevou_openapi_proxy_api’);

function zeevou_openapi_proxy_api() {
// Map: endpoint key => remote URL
$allowed_endpoints = [
‘integration_partner_types’ => ‘https://sandbox.zeevou.com/apis/integration_partner_types’,
‘integration_partners’ => ‘https://sandbox.zeevou.com/apis/integration_partners’,
‘countries’ => ‘https://sandbox.zeevou.com/apis/countries’,
];

$endpoint_key = isset($_GET[‘endpoint’]) ? sanitize_text_field($_GET[‘endpoint’]) : ”;

if (!isset($allowed_endpoints[$endpoint_key])) {
// Always return consistent JSON error shape + proper status
wp_send_json(
[‘detail’ => ‘Invalid endpoint’, ‘code’ => ‘invalid_endpoint’, ‘source’ => ‘wp_proxy’],
400
);
}

$method = strtoupper($_SERVER[‘REQUEST_METHOD’] ?? ‘GET’);
$url = $allowed_endpoints[$endpoint_key];

// Optional: whitelist methods
if (!in_array($method, [‘GET’, ‘POST’], true)) {
wp_send_json(
[‘detail’ => ‘Method not allowed’, ‘code’ => ‘method_not_allowed’, ‘source’ => ‘wp_proxy’],
405
);
}

// Build request args
$args = [
‘method’ => $method,
‘headers’ => [
‘Content-Type’ => ‘application/json’,
‘Accept’ => ‘application/json’,
],
// ✅ IMPORTANT: set a timeout so “hangs” become timeouts you can handle
‘timeout’ => 15,
];

if ($method === ‘POST’) {
$raw_body = file_get_contents(‘php://input’);
$args[‘body’] = $raw_body !== false ? $raw_body : ”;
}

$response = wp_remote_request($url, $args);

// ———- Transport error (timeout/DNS/connection refused) ———-
if (is_wp_error($response)) {
$msg = $response->get_error_message();

// Try to detect timeout-like errors; otherwise treat as bad gateway
$msg_lower = strtolower($msg);
$status = (strpos($msg_lower, ‘timed out’) !== false || strpos($msg_lower, ‘timeout’) !== false)
? 504
: 502;

wp_send_json(
[
‘detail’ => $msg,
‘code’ => $status === 504 ? ‘upstream_timeout’ : ‘upstream_error’,
‘source’ => ‘wp_proxy’,
‘endpoint’=> $endpoint_key,
],
$status
);
}

// ———- Upstream responded ———-
$status_code = (int) wp_remote_retrieve_response_code($response);
$body = wp_remote_retrieve_body($response);
$content_type = wp_remote_retrieve_header($response, ‘content-type’);

// If upstream gave non-2xx, return a consistent JSON error object to the browser
if ($status_code < 200 || $status_code >= 300) {
$detail = ‘Upstream API error. Please try again.’;

// If upstream returned JSON, attempt to extract a useful message
$json = json_decode($body, true);
if (is_array($json)) {
// Prefer “detail” if exists, otherwise fall back to common keys
if (!empty($json[‘detail’])) $detail = $json[‘detail’];
elseif (!empty($json[‘message’])) $detail = $json[‘message’];
elseif (!empty($json[‘error’])) $detail = $json[‘error’];
} elseif (is_string($body) && trim($body) !== ”) {
// non-JSON body; keep it short
$detail = substr(trim($body), 0, 300);
}

wp_send_json(
[
‘detail’ => $detail,
‘code’ => ‘upstream_http_error’,
‘source’ => ‘upstream_api’,
‘status’ => $status_code,
‘endpoint’ => $endpoint_key,
],
$status_code
);
}

// ———- Success (2xx) ———-
// If upstream returns JSON, pass it through as JSON.
// If not JSON, wrap it.
$decoded = json_decode($body, true);
if (json_last_error() === JSON_ERROR_NONE) {
wp_send_json($decoded, 200);
}

wp_send_json(
[
‘data’ => $body,
‘code’ => ‘ok_non_json’,
‘source’ => ‘upstream_api’,
‘endpoint’=> $endpoint_key,
],
200
);
}

Scroll to Top
Solution lamp for mobile header

Custom Solutions with Zeevou

Discover tailored solutions perfectly suited to your role, business size, and specific use cases.