createOrder(['order_id' => '1001', 'amount' => 149.90, 'description' => 'Ürün']); * header('Location: ' . $order['payment_url']); */ class DiscoPay { private string $baseUrl; private string $apiKey; private string $apiSecret; public function __construct(string $baseUrl, string $apiKey, string $apiSecret) { $this->baseUrl = rtrim($baseUrl, '/'); $this->apiKey = $apiKey; $this->apiSecret = $apiSecret; } /** Yeni sipariş oluşturur, ödeme bağlantısını (payment_url) döndürür. */ public function createOrder(array $data): array { return $this->request('POST', '/v1/orders', $data); } /** Sipariş durumunu sorgular. $ref: DP numarası veya kendi sipariş numaranız */ public function getOrder(string $ref): array { return $this->request('GET', '/v1/orders/' . rawurlencode($ref)); } /** Ödenmemiş siparişi iptal eder. */ public function cancelOrder(string $ref): array { return $this->request('POST', '/v1/orders/' . rawurlencode($ref) . '/cancel'); } /** API bilgilerinizin doğru olup olmadığını kontrol eder. */ public function ping(): array { return $this->request('GET', '/v1/ping'); } /** * Webhook isteğini doğrular ve olayı döndürür. Geçersizse null döner. * Kullanım (callback dosyanızda): * $event = $kp->verifyWebhook(); * if (!$event) { http_response_code(400); exit('BAD'); } */ public function verifyWebhook(int $tolerance = 300): ?array { $raw = file_get_contents('php://input'); $ts = $_SERVER['HTTP_X_DISCOPAY_TIMESTAMP'] ?? ''; $sig = $_SERVER['HTTP_X_DISCOPAY_SIGNATURE'] ?? ''; if ($raw === '' || !ctype_digit($ts) || abs(time() - (int)$ts) > $tolerance) { return null; } $expected = hash_hmac('sha256', $ts . '.' . $raw, $this->apiSecret); if (!hash_equals($expected, $sig)) { return null; } $data = json_decode($raw, true); return is_array($data) ? $data : null; } private function request(string $method, string $path, ?array $body = null): array { $json = $body === null ? '' : json_encode($body, JSON_UNESCAPED_UNICODE); $ts = (string)time(); $signature = hash_hmac('sha256', $ts . $method . $path . $json, $this->apiSecret); $ch = curl_init($this->baseUrl . '/api' . $path); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 20, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Accept: application/json', 'X-API-Key: ' . $this->apiKey, 'X-Timestamp: ' . $ts, 'X-Signature: ' . $signature, ], ]); if ($json !== '') { curl_setopt($ch, CURLOPT_POSTFIELDS, $json); } $res = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $err = curl_error($ch); curl_close($ch); if ($res === false) { throw new RuntimeException('DiscoPay bağlantı hatası: ' . $err); } $data = json_decode($res, true); if (!is_array($data) || empty($data['success'])) { $msg = $data['error']['message'] ?? ('HTTP ' . $code); throw new RuntimeException('DiscoPay: ' . $msg, (int)$code); } return $data['data']; } }