<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
/**
 * Thin Stripe REST client built on top of the framework's pjHttp component
 * (same approach as pjSmsApi uses for the ClickSend REST API).
 */
class pjStripeApi extends pjAppController
{
	private $secretKey;

	private $apiBase = 'https://api.stripe.com/v1/';

	private $apiVersion = '2022-08-01';

	private $error = NULL;

	/**
	 * Currencies Stripe expects in their base unit (not multiplied by 100).
	 * @link https://stripe.com/docs/currencies#zero-decimal
	 */
	private static $zeroDecimal = array(
		'bif', 'clp', 'djf', 'gnf', 'jpy', 'kmf', 'krw', 'mga',
		'pyg', 'rwf', 'ugx', 'vnd', 'vuv', 'xaf', 'xof', 'xpf'
	);

	public function __construct()
	{

	}

	public function setSecretKey($str)
	{
		$this->secretKey = $str;
		return $this;
	}

	public function getError()
	{
		return $this->error;
	}

	public static function toMinorUnits($amount, $currency)
	{
		if (in_array(strtolower($currency), self::$zeroDecimal))
		{
			return (int) round($amount);
		}
		return (int) round($amount * 100);
	}

	private function call($method, $path, $params=NULL)
	{
		$this->error = NULL;

		$headers = array(
			"Authorization: Bearer " . $this->secretKey,
			"Stripe-Version: " . $this->apiVersion
		);
		if (strtoupper($method) === 'POST')
		{
			$headers[] = "Content-Type: application/x-www-form-urlencoded";
		}

		$http = new pjHttp();
		$http->setHeaders($headers)->setMethod($method);
		if (strtoupper($method) === 'POST' && is_array($params))
		{
			$http->setData($params); // array -> http_build_query (nested keys supported)
		}
		$response = $http->request($this->apiBase . $path)->getResponse();

		$result = json_decode($response, true);
		if (isset($result['error']))
		{
			$this->error = isset($result['error']['message']) ? $result['error']['message'] : 'Stripe API error';
		}

		return $result;
	}

	/**
	 * Create a hosted Checkout Session.
	 * $args: reference_id, amount, currency, description, success_url, cancel_url
	 */
	public function createSession($args)
	{
		$params = array(
			'mode' => 'payment',
			'client_reference_id' => @$args['reference_id'],
			'success_url' => $args['success_url'],
			'cancel_url' => $args['cancel_url'],
			'line_items' => array(
				array(
					'quantity' => 1,
					'price_data' => array(
						'currency' => strtolower($args['currency']),
						'unit_amount' => self::toMinorUnits($args['amount'], $args['currency']),
						'product_data' => array(
							'name' => $args['description'] !== '' ? $args['description'] : 'Payment'
						)
					)
				)
			)
		);

		return $this->call('POST', 'checkout/sessions', $params);
	}

	public function retrieveSession($session_id)
	{
		return $this->call('GET', 'checkout/sessions/' . $session_id);
	}
}
?>
