<?php
namespace App\Library;
use Illuminate\Support\Facades\Cache;
use Psr\SimpleCache\InvalidArgumentException;
class OrangeMoney
{
const BASE_URL = 'https://api.orange.com';
protected string $authorization_header;
protected string $merchant_key;
/**
* The Token will be used for all further API calls.
*
* @var string
*/
protected string $token = '';
/**
* @param string $authorization_header
* @param string $merchant_key
*/
public function __construct(string $authorization_header, string $merchant_key)
{
$this->authorization_header = $authorization_header;
$this->merchant_key = $merchant_key;
}
/**
* Retrieves a token from Orange server, that will be used for all further API calls.
*
* @return array
*/
public function getTokenFromConsumerKey(): array
{
$url = self::BASE_URL.'/oauth/v3/token';
$headers = ['Authorization: '.$this->authorization_header];
$args = ['grant_type' => 'client_credentials'];
$response = $this->callApi($headers, $args, $url, 'POST', 200);
if ( ! empty($response['access_token'])) {
$this->setToken($response['access_token']);
}
return $response;
}
/**
* get payment url generated by orange
*
* @param array $data
*
* @return string[]
* @throws InvalidArgumentException
*/
public function getPaymentUrl(array $data): array
{
$headers = [
'Authorization: Bearer '.$this->getToken(),
'Accept: application/json',
'Content-Type' => 'application/json',
];
return $this->callApi($headers, $data, $data['payment_url'], 'POST', 201, true);
}
/**
* Calls API Endpoints.
*
* @param array $headers An array of HTTP header fields to set
* @param array $args The data to send
* @param string $url The URL to fetch
* @param string $method Whether to do a HTTP POST or a HTTP GET
* @param int $successCode The HTTP code that will be returned on
* success
* @param bool $jsonEncodeArgs Whether or not to json_encode $args
*
* @return array Contains the results returned by the endpoint or an error
* message
*/
public function callApi(array $headers, array $args, string $url, string $method, int $successCode, bool $jsonEncodeArgs = false): array
{
$ch = curl_init();
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
if ( ! empty($args)) {
if ($jsonEncodeArgs === true) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($args));
} else {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($args));
}
}
} else /* $method === 'GET' */ {
if ( ! empty($args)) {
curl_setopt($ch, CURLOPT_URL, $url.'?'.http_build_query($args));
} else {
curl_setopt($ch, CURLOPT_URL, $url);
}
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Make sure we can access the response when we execute the call
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
if ($data === false) {
return ['error' => 'API call failed with cURL error: '.curl_error($ch)];
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$response = json_decode($data, true);
$jsonErrorCode = json_last_error();
if ($jsonErrorCode !== JSON_ERROR_NONE) {
return [
'error' => 'API response not well-formed (json error code: '.$jsonErrorCode.')',
];
}
if ($httpCode !== $successCode) {
$errorMessage = '';
if ( ! empty($response['error_description'])) {
$errorMessage = $response['error_description'];
} elseif ( ! empty($response['error'])) {
$errorMessage = $response['error'];
} elseif ( ! empty($response['description'])) {
$errorMessage = $response['description'];
} elseif ( ! empty($response['message'])) {
$errorMessage = $response['message'];
} elseif ( ! empty($response['requestError']['serviceException'])) {
$errorMessage = $response['requestError']['serviceException']['text'].' '.$response['requestError']['serviceException']['variables'];
} elseif ( ! empty($response['requestError']['policyException'])) {
$errorMessage = $response['requestError']['policyException']['text'].' '.$response['requestError']['policyException']['variables'];
}
return ['error' => $errorMessage];
}
return $response;
}
/**
* Sets the Token value.
*
* @param string $token the token
*/
public function setToken(string $token): void
{
$this->token = $token;
}
/**
* Gets the (local/current) Token.
*
* @return string
* @throws InvalidArgumentException
*/
public function getToken(): string
{
$token = Cache::get('OrangeMoneyAccessToken');
if ( ! $token) {
$this->getTokenFromConsumerKey();
Cache::set('OrangeMoneyAccessToken', $this->token, 3600);
return $this->token;
}
return $token;
}
}