### C# PassimPay API client example Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client.md C# example of a PassimPay client that reads platform ID and API key from environment variables, reads request fields from a JSON file, and posts a request. It prints the result or an error message and returns exit code 0 or 1. ```csharp public static class Program { public static async Task Main(string[] args) { try { if (args.Length != 2) throw new ArgumentException("Invalid arguments"); using var client = new PassimPay(int.Parse(Environment.GetEnvironmentVariable("PASSIMPAY_PLATFORM_ID")!), Environment.GetEnvironmentVariable("PASSIMPAY_API_KEY")!); var fields = JsonNode.Parse(await File.ReadAllTextAsync(args[1]))!.AsObject(); var result = await client.PostAsync(args[0], fields); Console.WriteLine("PassimPay request result=" + result["result"]!.GetValue()); return 0; } catch (Exception) { Console.Error.WriteLine("PassimPay request failed; check configuration and reconcile before retrying"); return 1; } } } ``` -------------------------------- ### Successful response (200) example Source: https://passimpay.gitbook.io/passimpay-api/fiat/supported-currencies Example response showing a subset of returned currencies. The response includes a list of currency objects with fields id, name, sign, currency, and rateUsd. Exchange rates may change. ```json { "list": [ { "id": 1, "name": "United States Dollar", "sign": "$", "currency": "USD", "rateUsd": "1" }, { "id": 10, "name": "Euro", "sign": "€", "currency": "EUR", "rateUsd": "0.877381" } ], "result": 1 } ``` -------------------------------- ### Signature Verification Example (PHP) Source: https://passimpay.gitbook.io/passimpay-api/webhook-1.md PHP example of verifying the HMAC-SHA256 signature for the withdraw webhook. It shows how to generate the signature contract and compare it with the 'x-signature' header. ```APIDOC ## Signature Verification Example (PHP) ### Description PHP example of verifying the HMAC-SHA256 signature for the withdraw webhook. It shows how to generate the signature contract and compare it with the 'x-signature' header. ### Code ```php notificationWebHook(@RequestBody Map body, @RequestHeader HttpHeaders headers) throws NoSuchAlgorithmException, InvalidKeyException, JsonProcessingException { // Signature Verification ObjectMapper objectMapper = new ObjectMapper(); String sortedBodyJson = objectMapper.writeValueAsString(body); // Generate the signature contract string String signatureContract = PLATFORM_ID + ";" + sortedBodyJson + ";" + SECRET; // Generate HMAC-SHA256 signature String signature = generateSignature(signatureContract, SECRET); // Get the signature from the headers String receivedSignature = headers.getFirst("x-signature"); // Compare the generated signature with the received signature if (StringUtils.hasText(receivedSignature) && signature.equals(receivedSignature)) { return ResponseEntity.ok("Signature is valid"); } else { return ResponseEntity.status(400).body("Invalid signature"); } } } ``` ``` -------------------------------- ### Go: POST /v2/currencies and /v2/balance Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Uses the shared signed client to POST empty fields to /v2/currencies and /v2/balance, printing the result. Requires the shared client from the signature and API client example. ```go fields1 := map[string]any{ } result1, err := client.Post("/v2/currencies", fields1) if err != nil { return err } fmt.Printf("PassimPay request result=%v\n", result1["result"]) fields2 := map[string]any{ } result2, err := client.Post("/v2/balance", fields2) if err != nil { return err } fmt.Printf("PassimPay request result=%v\n", result2["result"]) ``` -------------------------------- ### Signature Verification Example (Python) Source: https://passimpay.gitbook.io/passimpay-api/webhook-1.md Python example of verifying the HMAC-SHA256 signature for the withdraw webhook. It shows how to generate the signature contract and compare it with the 'x-signature' header. ```APIDOC ## Signature Verification Example (Python) ### Description Python example of verifying the HMAC-SHA256 signature for the withdraw webhook. It shows how to generate the signature contract and compare it with the 'x-signature' header. ### Code ```python body = request.get_json() # Platform and secret keys (example placeholders) platform_id = 'your-platform-id' secret = 'your-api-key' # Generate the signature contract string signature_contract = f'{platform_id};{body};{secret}' # Generate HMAC-SHA256 signature signature = hmac.new(secret.encode(), signature_contract.encode(), hashlib.sha256).hexdigest() # Get the signature from the headers received_signature = request.headers.get('x-signature', '') # Compare the generated signature with the received signature if signature == received_signature: return 'Signature is valid', 200 else: return 'Invalid signature', 400 ``` ``` -------------------------------- ### Request example: curl https://api.passimpay.io/v2/fiats Source: https://passimpay.gitbook.io/passimpay-api/fiat/supported-currencies Use this curl command to retrieve the list of supported fiat currencies. No authentication or request parameters are required. ```bash curl https://api.passimpay.io/v2/fiats ``` -------------------------------- ### Signature Verification Examples Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/webhooks-and-payment-accounting Code examples for verifying webhook signatures in various programming languages. These functions are also included in the shared client. ```APIDOC ## Signature Verification Examples ### Description These functions are also included in the shared client. They demonstrate how to verify webhook signatures. ### Languages Go, PHP, Java, Python, JavaScript, C# ### Usage Refer to the shared client for the actual implementation. The examples are provided in the source documentation. ``` -------------------------------- ### Java API Client Example Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client.md Java client that reads platform ID and API key from environment variables, reads a JSON file for request fields, and posts to the PassimPay API. It prints the result code and exits with an error message on failure. ```java public static void main(String[] args) { try { if (args.length != 2) throw new IllegalArgumentException("Invalid arguments"); PassimPay client = new PassimPay(Integer.parseInt(System.getenv("PASSIMPAY_PLATFORM_ID")), System.getenv("PASSIMPAY_API_KEY"), "https://api.passimpay.io"); ObjectNode fields = (ObjectNode) JSON.readTree(Files.readString(Path.of(args[1]))); JsonNode result = client.post(args[0], fields); System.out.println("PassimPay request result=" + result.path("result").intValue()); } catch (Exception error) { System.err.println("PassimPay request failed; check configuration and reconcile before retrying"); System.exit(1); } } ``` -------------------------------- ### C#: Execute Passimpay API request with x-signature Source: https://passimpay.gitbook.io/passimpay-api/example-of-a-signature.md C# example using HttpClient. Sends a POST request to https://api.passimpay.io/v2/currencies with the x-signature header and JSON content. Deserializes the response and prints it with indentation. Replace 'signature' with the actual signature. ```csharp using var httpClient = new HttpClient(); try { httpClient.DefaultRequestHeaders.Add("x-signature", signature); httpClient.Timeout = TimeSpan.FromSeconds(10); var content = new StringContent(jsonBody, Encoding.UTF8, "application/json"); HttpResponseMessage response = await httpClient.PostAsync("https://api.passimpay.io/v2/currencies", content); int httpCode = (int)response.StatusCode; string resultContent = await response.Content.ReadAsStringAsync(); var result = JsonSerializer.Deserialize(resultContent); Console.WriteLine($"HTTP Code: {httpCode}"); Console.WriteLine("Response:"); Console.WriteLine(JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true })); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } ``` -------------------------------- ### Run PassimPay request commands for currency list Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client.md Commands to run a PassimPay request for the platform currency list from the source archive root. Each command uses the respective language's example file and the request JSON file. ```bash cd examples/go && go run . /v2/currencies ../requests/currencies.json ``` ```bash php examples/php/passimpay.php /v2/currencies examples/requests/currencies.json ``` ```bash mvn -q -f examples/java/pom.xml compile exec:java -Dexec.mainClass=PassimPay -Dexec.args="/v2/currencies examples/requests/currencies.json" ``` ```bash python3 examples/python/passimpay.py /v2/currencies examples/requests/currencies.json ``` ```bash node examples/javascript/passimpay.mjs /v2/currencies examples/requests/currencies.json ``` ```bash dotnet run --project examples/csharp -- /v2/currencies examples/requests/currencies.json ``` -------------------------------- ### Python: POST /v2/currencies and /v2/balance Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Uses the shared signed client to POST empty dicts to /v2/currencies and /v2/balance, printing the result. Requires the shared client from the signature and API client example. ```python fields1 = {} result1 = client.post("/v2/currencies", fields1) print("PassimPay request result=", result1["result"]) fields2 = {} result2 = client.post("/v2/balance", fields2) print("PassimPay request result=", result2["result"]) ``` -------------------------------- ### Calling record_verified_deposit after verification Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/webhooks-and-payment-accounting.md Initializes the database and calls record_verified_deposit with a two-confirmation policy for a BTC example. Must be called after IP and signature verification and loading the saved order. Outcomes are durably stored. ```python from deposit_store import init_database, record_verified_deposit init_database("payments.sqlite3") # Use a schema migration in production. outcome = record_verified_deposit( "payments.sqlite3", event, platform_id=platform_id, expected_order_id=order["orderId"], expected_payment_id=order["paymentId"], expected_address=order["address"], expected_tag=order.get("destinationTag"), minimum_confirmations=2, ) # After return, pending, credited and duplicate outcomes are durably stored. ``` -------------------------------- ### Create Withdrawal (C#) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/cryptocurrency-withdrawals.md C# example that creates a withdrawal via /v2/withdraw. It uses the shared client and requires a valid recipient address and local order ID. Replace the placeholder BTC address before sending. ```csharp var fields1 = JsonNode.Parse(""" { "paymentId": 10, "orderId": "payout-1001", "addressTo": "REPLACE_BTC_ADDRESS", "amount": "0.00100000" } """)!.AsObject(); var result1 = await client.PostAsync("/v2/withdraw", fields1); Console.WriteLine("PassimPay request result=" + result1["result"]!.GetValue()); ``` -------------------------------- ### Create Withdrawal (Go) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/cryptocurrency-withdrawals.md Go example that creates a withdrawal via /v2/withdraw. It uses the shared client and requires a valid recipient address and local order ID. Replace the placeholder BTC address before sending. ```go fields1 := map[string]any{ "paymentId": 10, "orderId": "payout-1001", "addressTo": "REPLACE_BTC_ADDRESS", "amount": "0.00100000", } result1, err := client.Post("/v2/withdraw", fields1) if err != nil { return err } fmt.Printf("PassimPay request result=%v\n", result1["result"]) ``` -------------------------------- ### Python: Execute Passimpay API request with x-signature Source: https://passimpay.gitbook.io/passimpay-api/example-of-a-signature.md Python example using requests library. Sends a POST request to https://api.passimpay.io/v2/currencies with the x-signature header and JSON body. Prints the response or an error message on exception. Replace 'your_signature' with the actual signature. ```python import json import requests body_json = json.dumps(body) headers = { 'Content-Type': 'application/json', 'x-signature': 'your_signature', # Replace with the actual signature } # Send the POST request url = 'https://api.passimpay.io/v2/currencies' try: response = requests.post(url, headers=headers, data=body_json, timeout=10) # Get the HTTP status code http_code = response.status_code # Parse the JSON response result = response.json() print(f'Response: {result}') except requests.exceptions.RequestException as e: print(f'An error occurred: {e}') ``` -------------------------------- ### Create Withdrawal (Java) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/cryptocurrency-withdrawals.md Java example that creates a withdrawal via /v2/withdraw. It uses the shared client and requires a valid recipient address and local order ID. Replace the placeholder BTC address before sending. ```java ObjectNode fields1 = new ObjectMapper().createObjectNode(); fields1.put("paymentId", 10); fields1.put("orderId", "payout-1001"); fields1.put("addressTo", "REPLACE_BTC_ADDRESS"); fields1.put("amount", "0.00100000"); JsonNode result1 = client.post("/v2/withdraw", fields1); System.out.println("PassimPay request result=" + result1.path("result").intValue()); ``` -------------------------------- ### C#: POST /v2/currencies and /v2/balance Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Uses the shared signed client to POST empty JSON objects to /v2/currencies and /v2/balance, printing the result. Requires the shared client from the signature and API client example. ```csharp var fields1 = JsonNode.Parse(""" {} """)!.AsObject(); var result1 = await client.PostAsync("/v2/currencies", fields1); Console.WriteLine("PassimPay request result=" + result1["result"]!.GetValue()); var fields2 = JsonNode.Parse(""" {} """)!.AsObject(); var result2 = await client.PostAsync("/v2/balance", fields2); Console.WriteLine("PassimPay request result=" + result2["result"]!.GetValue()); ``` -------------------------------- ### Create Withdrawal (Python) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/cryptocurrency-withdrawals.md Python example that creates a withdrawal via /v2/withdraw. It uses the shared client and requires a valid recipient address and local order ID. Replace the placeholder BTC address before sending. ```python fields1 = { "paymentId": 10, "orderId": "payout-1001", "addressTo": "REPLACE_BTC_ADDRESS", "amount": "0.00100000" } result1 = client.post("/v2/withdraw", fields1) print("PassimPay request result=", result1["result"]) ``` -------------------------------- ### Java: POST /v2/currencies and /v2/balance Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Uses the shared signed client to POST empty ObjectNode to /v2/currencies and /v2/balance, printing the result. Requires the shared client from the signature and API client example. ```java ObjectNode fields1 = new ObjectMapper().createObjectNode(); JsonNode result1 = client.post("/v2/currencies", fields1); System.out.println("PassimPay request result=" + result1.path("result").intValue()); ObjectNode fields2 = new ObjectMapper().createObjectNode(); JsonNode result2 = client.post("/v2/balance", fields2); System.out.println("PassimPay request result=" + result2.path("result").intValue()); ``` -------------------------------- ### Java: Execute Passimpay API request with x-signature Source: https://passimpay.gitbook.io/passimpay-api/example-of-a-signature.md Java example for Step 2 - Execution of the Request. Opens an HttpURLConnection, sets the x-signature header, sends a JSON body, reads the response (handling both OK and error streams), and parses the JSON response with ObjectMapper. Replace 'your-signature' with the generated signature. ```java String signature = "your-signature"; // Replace with the generated signature // Open connection HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(10000); // 10 seconds timeout conn.setReadTimeout(10000); conn.setDoOutput(true); // Allow sending data // Set headers conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("x-signature", signature); // Send the request body try (OutputStream os = conn.getOutputStream()) { byte[] input = jsonBody.getBytes(StandardCharsets.UTF_8); os.write(input, 0, input.length); } // Get response code int responseCode = conn.getResponseCode(); // Read the response BufferedReader br; if (responseCode == HttpURLConnection.HTTP_OK) { br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); } else { br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8)); } StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } // Close connection conn.disconnect(); // Parse JSON response (if needed) Map result = objectMapper.readValue(response.toString(), Map.class); // Print result System.out.println(result); ``` -------------------------------- ### Create Withdrawal (PHP) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/cryptocurrency-withdrawals.md PHP example that creates a withdrawal via /v2/withdraw. It uses the shared client and requires a valid recipient address and local order ID. Replace the placeholder BTC address before sending. ```php $fields1 = [ "paymentId" => 10, "orderId" => "payout-1001", "addressTo" => "REPLACE_BTC_ADDRESS", "amount" => "0.00100000", ]; $result1 = $client->post("/v2/withdraw", $fields1); echo "PassimPay request result=", $result1["result"], PHP_EOL; ``` -------------------------------- ### PHP: POST /v2/currencies and /v2/balance Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Uses the shared signed client to POST empty arrays to /v2/currencies and /v2/balance, echoing the result. Requires the shared client from the signature and API client example. ```php $fields1 = [ ]; $result1 = $client->post("/v2/currencies", $fields1); echo "PassimPay request result=", $result1["result"], PHP_EOL; $fields2 = [ ]; $result2 = $client->post("/v2/balance", $fields2); echo "PassimPay request result=", $result2["result"], PHP_EOL; ``` -------------------------------- ### Create Withdrawal (JavaScript) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/cryptocurrency-withdrawals.md JavaScript example that creates a withdrawal via /v2/withdraw. It uses the shared client and requires a valid recipient address and local order ID. Replace the placeholder BTC address before sending. ```javascript const fields1 = { "paymentId": 10, "orderId": "payout-1001", "addressTo": "REPLACE_BTC_ADDRESS", "amount": "0.00100000" }; const result1 = await client.post("/v2/withdraw", fields1); console.log("PassimPay request result=", result1.result); ``` -------------------------------- ### Python API Client Example Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client.md Python 3.10+ server-side client with no automatic retries. Includes signature generation, verification, request serialization, and a PassimPay class for posting to the API. Handles errors and exits with a failure message. ```python """Python 3.10+. Server-side client; no automatic retries.""" import hashlib import hmac import json import os import re import sys import urllib.error import urllib.request def signature(platform_id, secret, signature_body): contract = str(platform_id).encode() + b";" + signature_body + b";" + secret.encode() return hmac.new(secret.encode(), contract, hashlib.sha256).hexdigest() def verify_signature(platform_id, secret, signature_body, received): return isinstance(received, str) and bool(re.fullmatch(r"[0-9a-fA-F]{64}", received)) and hmac.compare_digest( signature(platform_id, secret, signature_body), received.lower() ) def serialize_request(fields): """Prepare the JSON request body.""" if not isinstance(fields, dict) or any(not isinstance(key, str) for key in fields): raise ValueError("Request must be an object with string keys") for value in fields.values(): if type(value) not in (str, int, bool, type(None)): raise ValueError("Use decimal strings for amounts; nested fields are unsupported") if type(value) is int and not -(2**63) <= value < 2**63: raise ValueError("Integer outside the supported 64-bit range") raw = json.dumps(fields, ensure_ascii=False, separators=(",", ":"), allow_nan=False) escaped = [] for char in raw: point = ord(char) if 0xD800 <= point <= 0xDFFF: raise ValueError("Invalid Unicode surrogate") if point > 0xFFFF: point -= 0x10000 escaped.append(f"\\u{0xD800 + (point >> 10):04x}\\u{0xDC00 + (point & 1023):04x}") elif point >= 0x80: escaped.append(f"\\u{point:04x}") else: escaped.append(char) return "".join(escaped).replace("/", "\\/").encode("utf-8") class NoRedirect(urllib.request.HTTPRedirectHandler): def redirect_request(self, req, fp, code, msg, headers, newurl): return None class PassimPay: def __init__(self, platform_id, secret, base_url="https://api.passimpay.io"): if type(platform_id) is not int or platform_id <= 0 or not isinstance(secret, str) or not secret: raise ValueError("Platform ID and API key are required") self.platform_id, self.secret = platform_id, secret self.base_url = base_url.rstrip("/") self.opener = urllib.request.build_opener(NoRedirect()) def post(self, path, fields): if not re.fullmatch(r"/v[23]/[a-z]+", path): raise ValueError("Invalid endpoint path") if not isinstance(fields, dict): raise ValueError("Request must be an object") body = dict(fields) body["platformId"] = self.platform_id raw = serialize_request(body) req = urllib.request.Request(self.base_url + path, data=raw, method="POST", headers={ "Content-Type": "application/json", "x-signature": signature(self.platform_id, self.secret, raw), }) # HTTP errors, redirects and timeouts propagate to the caller. with self.opener.open(req, timeout=15) as response: try: result = json.load(response) except (ValueError, UnicodeError): raise RuntimeError("Invalid PassimPay JSON response; reconcile before retrying") from None if not isinstance(result, dict) or type(result.get("result")) is not int or result["result"] != 1: raise RuntimeError("PassimPay rejected the request; reconcile before retrying") return result if __name__ == "__main__": try: if len(sys.argv) != 3: raise ValueError("Invalid arguments") client = PassimPay(int(os.environ["PASSIMPAY_PLATFORM_ID"]), os.environ["PASSIMPAY_API_KEY"]) with open(sys.argv[2], encoding="utf-8") as file: fields = json.load(file) result = client.post(sys.argv[1], fields) print("PassimPay request result=", result["result"]) except Exception: print("PassimPay request failed; check configuration and reconcile before retrying", file=sys.stderr) sys.exit(1) ``` -------------------------------- ### Validate Address and Get Fees (C#) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/cryptocurrency-withdrawals.md C# example that validates a recipient address via /v2/validateaddress and retrieves fees via /v2/fees. It throws an InvalidOperationException if the address is invalid. Replace the placeholder BTC address before use. ```csharp var fields1 = JsonNode.Parse(""" { "paymentId": 10, "address": "REPLACE_BTC_ADDRESS" } """)!.AsObject(); var result1 = await client.PostAsync("/v2/validateaddress", fields1); Console.WriteLine("PassimPay request result=" + result1["result"]!.GetValue()); if (result1["validate"]?.GetValue() != 1) throw new InvalidOperationException("Invalid recipient address"); var fields2 = JsonNode.Parse(""" { "paymentId": 10, "addressTo": "REPLACE_BTC_ADDRESS", "amount": "0.00100000" } """)!.AsObject(); var result2 = await client.PostAsync("/v2/fees", fields2); Console.WriteLine("PassimPay request result=" + result2["result"]!.GetValue()); ``` -------------------------------- ### Successful response (200) for GET /v2/currencies Source: https://passimpay.gitbook.io/passimpay-api/list-of-cryptocurrencies Example JSON response returned by the PassimPay API when the request succeeds. The response includes a result field (1 for success) and a list of cryptocurrency objects with fields such as id, name, currency, network, rateUsd, minDep, minWithdraw, feeNetwork, and decimals. ```json { "result":1, "list":[ { "id":10, "name":"Bitcoin", "currency":"BTC", "network":"Bitcoin", "rateUsd":"56990.50450929", "minDep":null, "minWithdraw":null, "feeNetwork":null, "decimals":8 }, ... ] } ``` -------------------------------- ### Run request in Go Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client Command to run the Go client from the source archive root to request the platform currency list. ```bash cd examples/go && go run . /v2/currencies ../requests/currencies.json ``` -------------------------------- ### Run request in C# Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client Command to run the C# client from the source archive root to request the platform currency list. ```bash dotnet run --project examples/csharp -- /v2/currencies examples/requests/currencies.json ``` -------------------------------- ### GET /v2/currencies Source: https://passimpay.gitbook.io/passimpay-api/list-of-cryptocurrencies Retrieves a list of cryptocurrencies, their exchange rates against the US dollar, and the minimum deposit amount required. This endpoint is used to get an up-to-date list of supported cryptocurrencies and their details. ```APIDOC ## GET /v2/currencies ### Description Retrieves a list of cryptocurrencies, their exchange rates against the US dollar, and the minimum deposit amount required. ### Method GET ### Endpoint `https://api.passimpay.io/v2/currencies` ### Parameters No parameters required. ### Request Example No request body required. ### Response #### Success Response (200) - **result** (integer) - Request result: `1`: success - **list** (array) - List of cryptocurrencies Each item in the list contains: - **id** (integer) - Currency ID - **name** (string) - The name of the cryptocurrency (e.g., Bitcoin, Ethereum). - **currency** (string) - The unique identifier for the cryptocurrency, typically represented in the form of an acronym (e.g., BTC for Bitcoin, ETH for Ethereum). - **network** (string) - The blockchain network on which the cryptocurrency operates (e.g., Bitcoin network, Ethereum network). - **rateUsd** (string) - The current exchange rate of the cryptocurrency against the US dollar. - **minDep** (string or null) - The minimum deposit amount required to use the specified cryptocurrency. - **minWithdraw** (string or null) - The minimum withdrawal amount required to use the specified cryptocurrency. - **feeNetwork** (string or null) - Transaction fee charged by the blockchain network (e.g., `1.63`). For Bitcoin, fetch fees using the `/fees` method. - **decimals** (integer) - The number of decimal places used to represent the smallest divisible unit of a cryptocurrency (e.g., Bitcoin uses 8 decimals where 1 satoshi = 0.00000001 BTC). #### Response Example ```json { "result":1, "list":[ { "id":10, "name":"Bitcoin", "currency":"BTC", "network":"Bitcoin", "rateUsd":"56990.50450929", "minDep":null, "minWithdraw":null, "feeNetwork":null, "decimals":8 } ] } ``` #### Error Response (400) - **result** (integer) - Request result: `0`: error - **message** (string) - Error description ``` -------------------------------- ### Run request in Java Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client Command to run the Java client from the source archive root to request the platform currency list. ```bash mvn -q -f examples/java/pom.xml compile exec:java -Dexec.mainClass=PassimPay -Dexec.args="/v2/currencies examples/requests/currencies.json" ``` -------------------------------- ### curl: GET /v2/currencies and /v2/fiats Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Public catalogs use GET rather than the shared signed POST client. These curl commands fetch the currency and fiat lists with fail, silent, show-error, and max-time options. ```sh curl --fail --silent --show-error --max-time 15 https://api.passimpay.io/v2/currencies curl --fail --silent --show-error --max-time 15 https://api.passimpay.io/v2/fiats ``` -------------------------------- ### Run request in PHP Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client Command to run the PHP client from the source archive root to request the platform currency list. ```bash php examples/php/passimpay.php /v2/currencies examples/requests/currencies.json ``` -------------------------------- ### GET /v2/currencies Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Retrieves the public cryptocurrency catalog. No authentication required. ```APIDOC ## GET /v2/currencies ### Description Retrieves the public cryptocurrency catalog. No authentication required. ### Method GET ### Endpoint /v2/currencies ### Parameters None ### Response #### Success Response (200) - **list** (array) - Cryptocurrency catalog. #### Response Example { "list": [ { "currencyId": 1, "ticker": "BTC", "network": "Bitcoin" } ] } ``` -------------------------------- ### GET /v2/currencies Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/currencies-and-balance.md Public catalog endpoint to retrieve available currencies without authentication. ```APIDOC ## GET /v2/currencies ### Description Public catalog endpoint to retrieve available currencies without authentication. ### Method GET ### Endpoint https://api.passimpay.io/v2/currencies ### Parameters None ### Request Example ```sh curl --fail --silent --show-error --max-time 15 https://api.passimpay.io/v2/currencies ``` ### Response #### Success Response (200) - `result` - The result of the request, typically an array of currency objects. #### Response Example ```json { "result": [] } ``` ``` -------------------------------- ### Go API Client for PassimPay Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/signature-and-api-client.md Complete Go client for the PassimPay API. Requires Go 1.22+. It includes signature generation, request serialization, signature verification, and a POST method. The client reads platform ID and API key from environment variables PASSIMPAY_PLATFORM_ID and PASSIMPAY_API_KEY. It uses a 15-second timeout and does not follow redirects. Errors indicate to reconcile before retrying. ```go // Go 1.22+. Server-side client; no automatic retries. package main import ( "bytes" "crypto/hmac" "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "io" "net/http" "os" "regexp" "strconv" "time" "unicode/utf16" "unicode/utf8" ) func Signature(platformID int, secret string, signatureBody []byte) string { mac := hmac.New(sha256.New, []byte(secret)) fmt.Fprintf(mac, "%d;", platformID) mac.Write(signatureBody) mac.Write([]byte(";" + secret)) return hex.EncodeToString(mac.Sum(nil)) } func SerializeRequest(fields map[string]any) ([]byte, error) { normalized := make(map[string]any, len(fields)) for key, value := range fields { if !utf8.ValidString(key) { return nil, fmt.Errorf("invalid Unicode key") } switch v := value.(type) { case string: if !utf8.ValidString(v) { return nil, fmt.Errorf("invalid Unicode string") } case json.Number: integer, err := strconv.ParseInt(string(v), 10, 64) if err != nil { return nil, fmt.Errorf("use integer values and decimal strings for amounts") } value = integer case int, int8, int16, int32, int64, bool, nil: default: return nil, fmt.Errorf("use scalar fields and decimal strings for amounts") } normalized[key] = value } var buffer bytes.Buffer encoder := json.NewEncoder(&buffer) encoder.SetEscapeHTML(false) if err := encoder.Encode(normalized); err != nil { return nil, err } raw := bytes.TrimSuffix(buffer.Bytes(), []byte("\n")) var escaped bytes.Buffer for _, point := range string(raw) { if point > 0xFFFF { high, low := utf16.EncodeRune(point) fmt.Fprintf(&escaped, `\u%04x\u%04x`, high, low) } else if point >= 0x80 { fmt.Fprintf(&escaped, `\u%04x`, point) } else { escaped.WriteRune(point) } } return bytes.ReplaceAll(escaped.Bytes(), []byte("/"), []byte(`\/`)), nil } func VerifySignature(platformID int, secret string, signatureBody []byte, received string) bool { actual, err := hex.DecodeString(received) if err != nil || len(actual) != sha256.Size { return false } expected, _ := hex.DecodeString(Signature(platformID, secret, signatureBody)) return hmac.Equal(expected, actual) } type Client struct { PlatformID int Secret string BaseURL string HTTP *http.Client } func NewClient(platformID int, secret string, baseURL string) (*Client, error) { if platformID <= 0 || secret == "" { return nil, fmt.Errorf("platform ID and API key are required") } return &Client{platformID, secret, baseURL, &http.Client{ Timeout: 15 * time.Second, CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, }}, nil } func (c *Client) Post(path string, fields map[string]any) (map[string]any, error) { if !regexp.MustCompile(`^/v[23]/[a-z]+$`).MatchString(path) { return nil, fmt.Errorf("invalid endpoint path") } body := make(map[string]any, len(fields)+1) for key, value := range fields { body[key] = value } body["platformId"] = c.PlatformID raw, err := SerializeRequest(body) if err != nil { return nil, err } req, err := http.NewRequest(http.MethodPost, c.BaseURL+path, bytes.NewReader(raw)) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/json") req.Header.Set("x-signature", Signature(c.PlatformID, c.Secret, raw)) response, err := c.HTTP.Do(req) if err != nil { return nil, err } defer response.Body.Close() if response.StatusCode < 200 || response.StatusCode >= 300 { return nil, fmt.Errorf("PassimPay HTTP %d; reconcile before retrying", response.StatusCode) } var result map[string]any decoder := json.NewDecoder(response.Body) decoder.UseNumber() if err := decoder.Decode(&result); err != nil { return nil, err } var trailing any if err := decoder.Decode(&trailing); err != io.EOF { return nil, fmt.Errorf("invalid trailing JSON response") } if result["result"] != json.Number("1") { return nil, fmt.Errorf("PassimPay rejected the request; reconcile before retrying") } return result, nil } func run() error { if len(os.Args) != 3 { return fmt.Errorf("usage: passimpay /v2/method request.json") } platformID, err := strconv.Atoi(os.Getenv("PASSIMPAY_PLATFORM_ID")) if err != nil { return err } client, err := NewClient(platformID, os.Getenv("PASSIMPAY_API_KEY"), "https://api.passimpay.io") if err != nil { return err } file, err := os.Open(os.Args[2]) if err != nil { return err } defer file.Close() decoder := json.NewDecoder(file) decoder.UseNumber() var fields map[string]any if err := decoder.Decode(&fields); err != nil { return err } result, err := client.Post(os.Args[1], fields) if err != nil { return err } fmt.Printf("PassimPay request result=%v\n", result["result"]) return nil } func main() { if err := run(); err != nil { fmt.Fprintln(os.Stderr, "PassimPay request failed; check configuration and reconcile before retrying") os.Exit(1) } } ``` -------------------------------- ### Durable H2H accounting example (deposit_store.py) Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/webhooks-and-payment-accounting.md Python example for durable SQLite accounting of a verified H2H event. It checks saved recipient details, stores amounts as decimal strings, and creates one accounting entry in a database transaction. The credit policy uses amountReceive after deductions. Call only after IP, signature, and order checks. ```python """Durable H2H accounting example. Call only after IP, signature and order checks. Invoice and static-address deposits require their own reconciliation rules. This example accounts for one deposit per transaction, recipient, tag and asset. Adapt the duplicate check if your application needs to track separate outputs. """ import json import re import sqlite3 from decimal import Decimal def init_database(path): with sqlite3.connect(path) as db: db.executescript(""" CREATE TABLE IF NOT EXISTS deposits ( event_key TEXT PRIMARY KEY, order_id TEXT NOT NULL, amount TEXT NOT NULL, amount_receive TEXT NOT NULL, confirmations INTEGER NOT NULL, credited INTEGER NOT NULL DEFAULT 0 ); CREATE TABLE IF NOT EXISTS ledger ( event_key TEXT PRIMARY KEY REFERENCES deposits(event_key), order_id TEXT NOT NULL, payment_id INTEGER NOT NULL, amount TEXT NOT NULL ); """) def decimal_amount(value): if not isinstance(value, str) or not re.fullmatch(r"[0-9]+(?:\.[0-9]+)?", value): raise ValueError("Amount must be a decimal string") amount = Decimal(value) if not amount.is_finite() or amount < 0: raise ValueError("Invalid amount") return amount def record_verified_deposit(path, event, platform_id, expected_order_id, expected_payment_id, expected_address, expected_tag=None, minimum_confirmations=None): """Returns 'pending', 'credited' or 'duplicate' after committing the transaction. ``` -------------------------------- ### Go: Create payment address with /v2/address Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/h2h-payment-integration.md Uses the shared client to post a request to /v2/address with paymentId and orderId. The order must be saved before sending; there is no amount field. ```go fields1 := map[string]any{ "paymentId": 10, "orderId": "h2h-1001", } result1, err := client.Post("/v2/address", fields1) if err != nil { return err } fmt.Printf("PassimPay request result=%v\n", result1["result"]) ``` -------------------------------- ### Create cryptocurrency invoice in Go Source: https://passimpay.gitbook.io/passimpay-api/integration-examples/invoice-link-and-on-ramp.md Uses the shared client to POST to /v2/createorder with invoice fields. Replace the demonstration order ID with your saved order ID. The response result field is printed. ```go fields1 := map[string]any{ "orderId": "invoice-1001", "amount": "100.00", "symbol": "USD", "type": 1, "currencies": "10", } result1, err := client.Post("/v2/createorder", fields1) if err != nil { return err } fmt.Printf("PassimPay request result=%v\n", result1["result"]) ``` -------------------------------- ### GET /v2/currencies Source: https://passimpay.gitbook.io/passimpay-api/list-of-cryptocurrencies.md Fetches the list of cryptocurrencies, their exchange rates against the US dollar, and the minimum deposit amount required. ```APIDOC ## GET /v2/currencies ### Description Retrieves a list of cryptocurrencies, their exchange rates against the US dollar, and the minimum deposit amount required. ### Method GET ### Endpoint https://api.passimpay.io/v2/currencies ### Response #### Success Response (200) - **result** (integer) - Request result: `1` for success. - **list** (array) - List of cryptocurrencies. Each item in the list contains: - **id** (integer) - Currency ID. - **name** (string) - The name of the cryptocurrency (e.g., Bitcoin, Ethereum). - **currency** (string) - The unique identifier for the cryptocurrency, typically an acronym (e.g., BTC, ETH). - **network** (string) - The blockchain network on which the cryptocurrency operates. - **rateUsd** (string) - The current exchange rate of the cryptocurrency against the US dollar. - **minDep** (string/null) - The minimum deposit amount required. - **minWithdraw** (string/null) - The minimum withdrawal amount required. - **feeNetwork** (string/null) - Transaction fee charged by the blockchain network. For Bitcoin, fetch fees using the `/fees` method. - **decimals** (integer) - The number of decimal places used to represent the smallest divisible unit. #### Response Example ```json { "result":1, "list":[ { "id":10, "name":"Bitcoin", "currency":"BTC", "network":"Bitcoin", "rateUsd":"56990.50450929", "minDep":null, "minWithdraw":null, "feeNetwork":null, "decimals":8 } ] } ``` #### Error Response (400) - **result** (integer) - Request result: `0` for error. - **message** (string) - Error description. ``` -------------------------------- ### Withdrawal Response Format Source: https://passimpay.gitbook.io/passimpay-api/preparation-for-integration.md Example response received upon requesting a withdrawal, including paymentId, addressTo, amount, and transactionId. ```APIDOC ## Withdrawal Response ### Description Response received when initiating a withdrawal request. ### Response Example ```json { "result": 1, "paymentId": 71, "addressTo": "TLBQDMM3zSLr2Tm88iujny5hBX5G7mS1Jd", "amount": "31.42", "transactionId": "Nzc2OTc0Njg2NDcyNjE3NzVmMzEzOTM4MzkzMjM2" } ``` ### Fields - **result** (integer) - Indicates success (1). - **paymentId** (integer) - Unique identifier for the payment. - **addressTo** (string) - Cryptocurrency address to send funds to. - **amount** (string) - Amount in cryptocurrency. - **transactionId** (string) - Internal transaction hash, usable with the `/withdrawstatus` endpoint. ```