Epinpark

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

epinpark-client.ts
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

epinpark_client.py
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

EpinparkClient.cs
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.