|
|
@@ -0,0 +1,72 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace Controllers;
|
|
|
+
|
|
|
+use Libs\ResponseLib;
|
|
|
+use Psr\Http\Message\ServerRequestInterface;
|
|
|
+use React\Http\Message\Response;
|
|
|
+
|
|
|
+class B3TokenController
|
|
|
+{
|
|
|
+ public function __invoke(ServerRequestInterface $request)
|
|
|
+ {
|
|
|
+ $b3Url = $_ENV['B3_URL'] ?? null;
|
|
|
+ $clientId = $_ENV['CLIENT_ID'] ?? null;
|
|
|
+ $clientSecret = $_ENV['CLIENT_SECRET'] ?? null;
|
|
|
+ $grantType = $_ENV['GRANT_TYPE'] ?? 'client_credentials';
|
|
|
+ $certPass = $_ENV['CERT_PASS'] ?? null;
|
|
|
+
|
|
|
+ if (!$b3Url || !$grantType || !$clientId || !$clientSecret) {
|
|
|
+ return ResponseLib::sendFail('Missing required env vars: B3_URL, GRANT_TYPE, CLIENT_ID, CLIENT_SECRET', [], 'E_VALIDATE')->withStatus(500);
|
|
|
+ }
|
|
|
+
|
|
|
+ $certPath = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.cer';
|
|
|
+ $keyPath = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.key';
|
|
|
+ if (!file_exists($certPath) || !file_exists($keyPath)) {
|
|
|
+ return ResponseLib::sendFail('Client certificate or key not found', ['cert' => $certPath, 'key' => $keyPath], 'E_INTERNAL')->withStatus(500);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Send grant_type + client credentials in body in the same order as the working curl
|
|
|
+ $postFields = 'grant_type=' . ($grantType);
|
|
|
+
|
|
|
+ $ch = curl_init($b3Url);
|
|
|
+ curl_setopt($ch, CURLOPT_POST, true);
|
|
|
+ $headers = [
|
|
|
+ 'Content-Type: application/x-www-form-urlencoded',
|
|
|
+ 'Accept: application/json',
|
|
|
+ ];
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
|
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
+
|
|
|
+ // mTLS client certificate
|
|
|
+ curl_setopt($ch, CURLOPT_SSLCERT, $certPath);
|
|
|
+ curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
|
|
|
+ curl_setopt($ch, CURLOPT_SSLKEY, $keyPath);
|
|
|
+ curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
|
|
|
+ if ($certPass) {
|
|
|
+ curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $certPass);
|
|
|
+ }
|
|
|
+ // Keep verification enabled (recommended)
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
|
|
+
|
|
|
+ $responseBody = curl_exec($ch);
|
|
|
+ $curlErrNo = curl_errno($ch);
|
|
|
+ $curlErr = curl_error($ch);
|
|
|
+ $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ if ($curlErrNo !== 0) {
|
|
|
+ return ResponseLib::sendFail('cURL error during B3 token request', ['error' => $curlErr, 'code' => $curlErrNo], 'E_EXTERNAL')->withStatus(502);
|
|
|
+ }
|
|
|
+
|
|
|
+ $decoded = json_decode($responseBody, true);
|
|
|
+ if ($decoded === null) {
|
|
|
+ // Not a JSON body; return raw text for troubleshooting
|
|
|
+ return Response::json(['raw' => $responseBody, 'status' => $httpCode])->withStatus($httpCode ?: 502);
|
|
|
+ }
|
|
|
+
|
|
|
+ return Response::json($decoded)->withStatus($httpCode ?: 200);
|
|
|
+ }
|
|
|
+}
|