WebOrbiton
v1.0.0.0

StocketBase

100 lines · 2.8 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. require_once __DIR__ . '/../config.php';
  6. require_once __DIR__ . '/../site-front.php';
  7. ​
  8. final class PolarClient
  9. {
  10. private const API_BASE = 'https://api.polar.sh/v1';
  11. ​
  12. private string $accessToken;
  13. ​
  14. public function __construct(?string $accessToken = null)
  15. {
  16. $this->accessToken = $accessToken ?? (string) (SiteFront::settings()['payment_polar_access_token'] ?? '');
  17. }
  18. ​
  19. public function createCheckoutSession(
  20. string $polarProductId,
  21. string $successUrl,
  22. ?string $customerEmail,
  23. array $metadata = []
  24. ): ?array {
  25. if ($this->accessToken === '') {
  26. error_log('PolarClient: cannot create checkout session, no access token configured.');
  27. ​
  28. return null;
  29. }
  30. ​
  31. if ($polarProductId === '') {
  32. error_log('PolarClient: cannot create checkout session, no Polar product ID given.');
  33. ​
  34. return null;
  35. }
  36. ​
  37. $payload = [
  38. 'products' => [$polarProductId],
  39. 'success_url' => $successUrl,
  40. ];
  41. ​
  42. if ($customerEmail !== null && $customerEmail !== '') {
  43. $payload['customer_email'] = $customerEmail;
  44. }
  45. ​
  46. if (!empty($metadata)) {
  47. $payload['metadata'] = $metadata;
  48. }
  49. ​
  50. [$status, $body] = $this->post('/checkouts/', $payload);
  51. ​
  52. if ($status < 200 || $status >= 300 || !isset($body['url'])) {
  53. error_log('PolarClient: checkout session creation failed with HTTP ' . $status . ' — ' . (string) json_encode($body));
  54. ​
  55. return null;
  56. }
  57. ​
  58. return $body;
  59. }
  60. ​
  61. private function post(string $path, array $payload): array
  62. {
  63. $url = self::API_BASE . $path;
  64. $body = (string) json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  65. ​
  66. if (!function_exists('curl_init')) {
  67. error_log('PolarClient: cURL extension is not available.');
  68. ​
  69. return [0, []];
  70. }
  71. ​
  72. $curl = curl_init($url);
  73. curl_setopt_array($curl, [
  74. CURLOPT_POST => true,
  75. CURLOPT_POSTFIELDS => $body,
  76. CURLOPT_HTTPHEADER => [
  77. 'Authorization: Bearer ' . $this->accessToken,
  78. 'Content-Type: application/json',
  79. ],
  80. CURLOPT_RETURNTRANSFER => true,
  81. CURLOPT_CONNECTTIMEOUT => 10,
  82. CURLOPT_TIMEOUT => 20,
  83. ]);
  84. $response = curl_exec($curl);
  85. $status = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
  86. $curlError = curl_error($curl);
  87. curl_close($curl);
  88. ​
  89. if ($response === false) {
  90. error_log('PolarClient: request failed — ' . $curlError);
  91. ​
  92. return [0, []];
  93. }
  94. ​
  95. $decoded = json_decode($response, true);
  96. ​
  97. return [$status, is_array($decoded) ? $decoded : []];
  98. }
  99. }
  100. ​