B3TokenController.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. namespace Controllers;
  3. use Libs\ResponseLib;
  4. use Psr\Http\Message\ServerRequestInterface;
  5. use React\Http\Message\Response;
  6. class B3TokenController
  7. {
  8. public function __invoke(ServerRequestInterface $request)
  9. {
  10. $b3Url = $_ENV['B3_URL'] ?? null;
  11. $clientId = $_ENV['CLIENT_ID'] ?? null;
  12. $clientSecret = $_ENV['CLIENT_SECRET'] ?? null;
  13. $grantType = $_ENV['GRANT_TYPE'] ?? 'client_credentials';
  14. $certPass = $_ENV['CERT_PASS'] ?? null;
  15. if (!$b3Url || !$grantType || !$clientId || !$clientSecret) {
  16. return ResponseLib::sendFail('Missing required env vars: B3_URL, GRANT_TYPE, CLIENT_ID, CLIENT_SECRET', [], 'E_VALIDATE')->withStatus(500);
  17. }
  18. $certPath = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.cer';
  19. $keyPath = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.key';
  20. if (!file_exists($certPath) || !file_exists($keyPath)) {
  21. return ResponseLib::sendFail('Client certificate or key not found', ['cert' => $certPath, 'key' => $keyPath], 'E_INTERNAL')->withStatus(500);
  22. }
  23. // Send grant_type + client credentials in body in the same order as the working curl
  24. $postFields = 'grant_type=' . ($grantType);
  25. $ch = curl_init($b3Url);
  26. curl_setopt($ch, CURLOPT_POST, true);
  27. $headers = [
  28. 'Content-Type: application/x-www-form-urlencoded',
  29. 'Accept: application/json',
  30. ];
  31. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  32. curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
  33. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  34. // mTLS client certificate
  35. curl_setopt($ch, CURLOPT_SSLCERT, $certPath);
  36. curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
  37. curl_setopt($ch, CURLOPT_SSLKEY, $keyPath);
  38. curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
  39. if ($certPass) {
  40. curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $certPass);
  41. }
  42. // Keep verification enabled (recommended)
  43. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
  44. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  45. $responseBody = curl_exec($ch);
  46. $curlErrNo = curl_errno($ch);
  47. $curlErr = curl_error($ch);
  48. $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
  49. curl_close($ch);
  50. if ($curlErrNo !== 0) {
  51. return ResponseLib::sendFail('cURL error during B3 token request', ['error' => $curlErr, 'code' => $curlErrNo], 'E_EXTERNAL')->withStatus(502);
  52. }
  53. $decoded = json_decode($responseBody, true);
  54. if ($decoded === null) {
  55. // Not a JSON body; return raw text for troubleshooting
  56. return Response::json(['raw' => $responseBody, 'status' => $httpCode])->withStatus($httpCode ?: 502);
  57. }
  58. return Response::json($decoded)->withStatus($httpCode ?: 200);
  59. }
  60. }