SDK Örnekleri
Resmi bir SDK henüz yayınlanmamıştır. Üç popüler dilde kopyala-yapıştır kullanılabilir istemci sınıfı aşağıda — kendi projenize göre uyarlayın.
Node.js / TypeScript
import crypto from "node:crypto";
export interface EpinparkClientOptions {
baseUrl?: string;
apiKey: string;
secret: string;
fetchImpl?: typeof fetch;
}
export class EpinparkClient {
private baseUrl: string;
private apiKey: string;
private secret: string;
private fetchImpl: typeof fetch;
constructor(options: EpinparkClientOptions) {
this.baseUrl = options.baseUrl ?? "https://public-api.epinpark.com";
this.apiKey = options.apiKey;
this.secret = options.secret;
this.fetchImpl = options.fetchImpl ?? fetch;
}
async request<T>(
method: string,
path: string,
body?: unknown,
extraHeaders?: Record<string, string>
): Promise<{ status: number; headers: Headers; data: T }> {
const ts = Math.floor(Date.now() / 1000).toString();
const nonce = crypto.randomBytes(16).toString("hex");
const bodyText = body ? JSON.stringify(body) : "";
const bodyHash = crypto.createHash("sha256").update(bodyText).digest("hex");
const canonical = [method.toUpperCase(), path, bodyHash, ts, nonce].join("\n");
const signature = crypto
.createHmac("sha256", this.secret)
.update(canonical)
.digest("base64");
const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
method,
headers: {
"X-Api-Key": this.apiKey,
"X-Timestamp": ts,
"X-Nonce": nonce,
"X-Signature": signature,
...(body ? { "Content-Type": "application/json" } : {}),
...extraHeaders,
},
body: bodyText || undefined,
});
const data = res.headers.get("content-type")?.includes("json")
? await res.json()
: (await res.text() as any);
return { status: res.status, headers: res.headers, data };
}
get<T>(path: string) {
return this.request<T>("GET", path);
}
post<T>(path: string, body: unknown, idempotencyKey?: string) {
return this.request<T>("POST", path, body,
idempotencyKey ? { "Idempotency-Key": idempotencyKey } : undefined);
}
patch<T>(path: string, body: unknown) {
return this.request<T>("PATCH", path, body);
}
delete<T>(path: string) {
return this.request<T>("DELETE", path);
}
}Kullanım
const client = new EpinparkClient({
apiKey: process.env.EPINPARK_API_KEY!,
secret: process.env.EPINPARK_SECRET!,
});
const { data } = await client.get<OrderResponse[]>(
"/v1/orders?page=1&pageSize=20&orderBy=CreatedAt&order=Desc"
);Python
import base64
import hashlib
import hmac
import json
import secrets
import time
from typing import Any
import requests
class EpinparkClient:
def __init__(self, api_key: str, secret: str, base_url: str = "https://public-api.epinpark.com"):
self.base_url = base_url
self.api_key = api_key
self.secret = secret
self.session = requests.Session()
def _sign(self, method: str, path: str, body: str) -> dict:
ts = str(int(time.time()))
nonce = secrets.token_hex(16)
body_hash = hashlib.sha256((body or "").encode()).hexdigest()
canonical = f"{method.upper()}\n{path}\n{body_hash}\n{ts}\n{nonce}"
signature = base64.b64encode(
hmac.new(self.secret.encode(), canonical.encode(), hashlib.sha256).digest()
).decode()
return {
"X-Api-Key": self.api_key,
"X-Timestamp": ts,
"X-Nonce": nonce,
"X-Signature": signature,
}
def request(self, method: str, path: str, body: Any = None) -> requests.Response:
body_text = json.dumps(body, separators=(",", ":")) if body is not None else ""
headers = self._sign(method, path, body_text)
if body is not None:
headers["Content-Type"] = "application/json"
return self.session.request(
method=method,
url=f"{self.base_url}{path}",
data=body_text or None,
headers=headers,
)
def get(self, path: str): return self.request("GET", path)
def post(self, path: str, body): return self.request("POST", path, body)
def patch(self, path: str, body): return self.request("PATCH", path, body)
def delete(self, path: str): return self.request("DELETE", path)C# / .NET
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
public sealed class EpinparkClient : IDisposable
{
private readonly HttpClient _http;
private readonly string _apiKey;
private readonly string _secret;
public EpinparkClient(string apiKey, string secret, string baseUrl = "https://public-api.epinpark.com")
{
_http = new HttpClient { BaseAddress = new Uri(baseUrl) };
_apiKey = apiKey;
_secret = secret;
}
public async Task<HttpResponseMessage> SendAsync(
HttpMethod method,
string path,
object? body = null,
string? idempotencyKey = null,
CancellationToken ct = default)
{
string bodyText = body is null ? "" : JsonSerializer.Serialize(body);
string ts = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
string nonce = Convert.ToHexString(RandomNumberGenerator.GetBytes(16)).ToLowerInvariant();
string bodyHash = Convert.ToHexString(
SHA256.HashData(Encoding.UTF8.GetBytes(bodyText))).ToLowerInvariant();
string canonical = $"{method.Method.ToUpperInvariant()}\n{path}\n{bodyHash}\n{ts}\n{nonce}";
string signature = Convert.ToBase64String(
new HMACSHA256(Encoding.UTF8.GetBytes(_secret))
.ComputeHash(Encoding.UTF8.GetBytes(canonical)));
var req = new HttpRequestMessage(method, path);
req.Headers.Add("X-Api-Key", _apiKey);
req.Headers.Add("X-Timestamp", ts);
req.Headers.Add("X-Nonce", nonce);
req.Headers.Add("X-Signature", signature);
if (!string.IsNullOrEmpty(idempotencyKey))
req.Headers.Add("Idempotency-Key", idempotencyKey);
if (body is not null)
req.Content = new StringContent(bodyText, Encoding.UTF8, "application/json");
return await _http.SendAsync(req, ct);
}
public void Dispose() => _http.Dispose();
}Yardımlarınızı bekleriz
Resmî SDK paketlerinin (npm, NuGet, PyPI) yayınlanması için yol haritamızda — gelişmeler için Sürüm Notları sayfasını takip edin. Topluluk SDK'larına da açığız.