# Java Example for Calling API

**Prerequisites**

* [You must have a valid API Key and API Secret](/en/getting-started/buy-energy-via-api-on-catfee/api-overview.md#apply-api-info).
* Ensure your environment has Java 8 or higher installed and includes the following dependencies:

```java
java.net.http.HttpClient  
java.security.MessageDigest  
javax.crypto.Mac  
javax.crypto.spec.SecretKeySpec
```

***

#### Example Code

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class CatFeeAPIExample {

    private static final String API_KEY = "your_api_key"; // Replace with your API Key
    private static final String API_SECRET = "your_api_secret"; // Replace with your API Secret
    private static final String BASE_URL = "https://api.catfee.io";

    public static void main(String[] args) throws Exception {
        // HTTP method
        String method = "POST"; // Change to "GET", "PUT", or "DELETE" as needed

        // Example: Create a buy energy order
        String path = "/v1/order";
        Map<String, String> queryParams = new HashMap<>();
        queryParams.put("quantity", "65000");
        queryParams.put("receiver", "TRON_ADDRESS");
        queryParams.put("duration", "1h");

        // Generate headers
        String timestamp = generateTimestamp();
        String requestPath = buildRequestPath(path, queryParams);
        String signature = generateSignature(timestamp, method, requestPath);

        // Create HTTP request
        String url = BASE_URL + requestPath;
        HttpRequest request = createRequest(url, method, timestamp, signature);

        // Send the request and get the response
        HttpClient client = HttpClient.newHttpClient();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // Print response
        System.out.println("Response Code: " + response.statusCode());
        System.out.println("Response Body: " + response.body());

        // Handle potential error messages
        if (response.statusCode() != 200) {
            System.out.println("Error: " + response.body());
        }
    }

    // Generate current UTC timestamp in ISO 8601 format
    public static String generateTimestamp() {
        return Instant.now().toString();
    }

    // Build request path with query parameters
    public static String buildRequestPath(String path, Map<String, String> queryParams) {
        if (queryParams == null || queryParams.isEmpty()) {
            return path;
        }
        String queryString = queryParams.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&", "?", ""));
        return path + queryString;
    }

    // Generate signature
    public static String generateSignature(String timestamp, String method, String requestPath) throws Exception {
        String signString = timestamp + method + requestPath;
        return hmacSHA256(signString, API_SECRET);
    }

    // HMAC-SHA256 signature generation
    public static String hmacSHA256(String data, String secret) throws Exception {
        Mac sha256Hmac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256Hmac.init(secretKey);
        byte[] hash = sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(hash);
    }

    // Create HTTP request supporting GET, POST, PUT, DELETE
    public static HttpRequest createRequest(String url, String method, String timestamp, String signature) {
        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .header("CF-ACCESS-KEY", API_KEY)
                .header("CF-ACCESS-SIGN", signature)
                .header("CF-ACCESS-TIMESTAMP", timestamp);

        switch (method.toUpperCase()) {
            case "POST":
                requestBuilder.POST(HttpRequest.BodyPublishers.noBody());
                break;
            case "PUT":
                requestBuilder.PUT(HttpRequest.BodyPublishers.noBody());
                break;
            case "DELETE":
                requestBuilder.DELETE();
                break;
            case "GET":
                requestBuilder.GET();
                break;
            default:
                throw new UnsupportedOperationException("Unsupported HTTP method: " + method);
        }

        return requestBuilder.build();
    }
}
```

***

#### Code Explanation

* **`method` Variable**:\
  The `method` in the `main()` function is defined as `"POST"`, which can be changed to `"GET"`, `"PUT"`, or `"DELETE"` as needed.
* **Generate Current Timestamp**:\
  The `generateTimestamp()` function returns the current UTC time in ISO 8601 format using `Instant.now().toString()`.
* **Build Request Path**:\
  The `buildRequestPath()` function takes query parameters and appends them to the path to form the full request path.
* **Generate Signature**:\
  The `generateSignature()` function creates the string to be signed by concatenating `timestamp + method + requestPath`, and uses the `hmacSHA256()` method with the API Secret to generate the signature.
* **HMAC-SHA256 Signing**:\
  The `hmacSHA256()` function implements HMAC-SHA256 signing and returns a Base64-encoded result.
* **Create Request**:\
  The `createRequest()` function dynamically builds the HTTP request based on the specified method (GET, POST, PUT, DELETE). For POST and PUT requests, it uses `HttpRequest.BodyPublishers.noBody()`.
* **Send Request and Handle Response**:\
  It uses `HttpClient` to send the HTTP request and prints the response status and body. If the response status is not 200, it logs an error.

***

#### Notes

* **API Key & Secret**:\
  Make sure to replace `API_KEY` and `API_SECRET` with the actual values obtained from CatFee.IO.
* **Purpose of the Signature**:\
  The signature ensures the integrity and authenticity of the request. It is generated using the combination of timestamp, HTTP method, request path, and query parameters.
* **Query Parameter Order**:\
  There is no need to sort query parameters. Use them in their original order.
* **HTTP Methods**:\
  The sample supports POST, PUT, GET, and DELETE methods. All parameters are passed through the URL query string.
* **Handling Response**:\
  The sample prints the response directly. You can parse the body as JSON or other formats for further processing.

***

#### Summary

This example demonstrates how to securely interact with CatFee.IO Rest API in Java. By using HMAC-SHA256 signatures and proper query handling, it ensures each request is valid and protected. You can customize this code to perform different operations and HTTP methods as needed.

For any questions or further assistance, feel free to contact the CatFee.IO support team.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.catfee.io/en/getting-started/buy-energy-via-api-on-catfee/java.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
