Files
2026-10-19 15:22:52 -07:00

93 lines
3.1 KiB
PHP

<?php
class PayPalClient
{
private string $clientId;
private string $clientSecret;
private string $env; // sandbox|live
private string $baseApi;
public function __construct(array $config)
{
$this->clientId = $config['client_id'] ?? '';
$this->clientSecret = $config['client_secret'] ?? '';
$this->env = $config['env'] ?? 'sandbox';
$this->baseApi = $this->env === 'live'
? 'https://api-m.paypal.com'
: 'https://api-m.sandbox.paypal.com';
if (!$this->clientId || !$this->clientSecret) {
throw new RuntimeException('Missing PayPal client_id/client_secret in config.php');
}
}
public function getAccessToken(): string
{
$url = $this->baseApi . '/v1/oauth2/token';
$headers = [
'Accept: application/json',
'Accept-Language: en_US',
];
$body = 'grant_type=client_credentials';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => $this->clientId . ':' . $this->clientSecret,
]);
$resp = curl_exec($ch);
if ($resp === false) {
throw new RuntimeException('OAuth token request failed: ' . curl_error($ch));
}
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($resp, true);
if ($code < 200 || $code >= 300 || !isset($data['access_token'])) {
throw new RuntimeException('OAuth token response error (' . $code . '): ' . $resp);
}
return $data['access_token'];
}
public function api(string $method, string $path, array $payload = null, array $headers = []): array
{
$url = $this->baseApi . $path;
$accessToken = $this->getAccessToken();
$defaultHeaders = [
'Content-Type: application/json',
'Authorization: Bearer ' . $accessToken,
];
$allHeaders = array_merge($defaultHeaders, $headers);
$ch = curl_init($url);
$opts = [
CURLOPT_HTTPHEADER => $allHeaders,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => strtoupper($method),
];
if ($payload !== null) {
$opts[CURLOPT_POSTFIELDS] = json_encode($payload);
}
curl_setopt_array($ch, $opts);
$resp = curl_exec($ch);
if ($resp === false) {
throw new RuntimeException('API request failed: ' . curl_error($ch));
}
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($resp, true);
if ($data === null && $resp !== '' && $resp !== 'null') {
// not JSON but body present
$data = ['raw' => $resp];
}
return ['status' => $code, 'body' => $data];
}
public function getBaseApi(): string
{
return $this->baseApi;
}
}