apiKey = trim($apiKey); $this->baseUrl = rtrim($baseUrl, '/'); $this->timeout = $timeout; } /** * Create a new hosted checkout payment session * * @param array $params Required keys: amount, currency, success_url, cancel_url, brand_id. Optional: cus_name, cus_email, cus_phone, webhook_url, metadata. * @return array Decoded JSON API response * @throws Exception On cURL error or network failure */ public function createPayment(array $params): array { $payload = array_merge([ 'api_key' => $this->apiKey, ], $params); return $this->request('/api/create-payment', $payload); } /** * Verify payment status by Transaction Reference ID * * @param string $transactionId FuturePay Transaction ID (e.g. FPTRX...) * @return array Decoded JSON API response * @throws Exception */ public function verifyPayment(string $transactionId): array { $payload = [ 'api_key' => $this->apiKey, 'transaction_id' => $transactionId, ]; return $this->request('/api/verify-payment', $payload); } /** * Helper to verify and decode incoming webhook notification * * @return array|null Decoded payload or null if invalid */ public static function readWebhookPayload(): ?array { $raw = file_get_contents('php://input'); if (empty($raw)) { return null; } $data = json_decode($raw, true); return is_array($data) ? $data : null; } /** * Execute internal HTTP POST request using cURL */ private function request(string $endpoint, array $data): array { $url = $this->baseUrl . $endpoint; $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Accept: application/json', 'X-API-KEY: ' . $this->apiKey, ], CURLOPT_SSL_VERIFYPEER => true, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); curl_close($ch); if ($curlError) { throw new Exception("FuturePay cURL Error: " . $curlError); } $decoded = json_decode($response, true); if ($decoded === null) { return [ 'status' => 'error', 'http_code' => $httpCode, 'raw_body' => $response, ]; } return $decoded; } }