protected function genRequest($address, $data = [], $token = null, $get = false) {
		// compose request URL
		if (strstr($address, 'https://'))
			$url = $address;
		else 
			$url = $this->endpoint . '/v1/' . $address;
		
		$method = (is_null($data) || $get) ? 'GET' : 'POST'; 
		
		self::debug("PayPal Auth: " . $token->token_type . ' ' . $token->access_token);
		
		// create HTTP request
		$req = (new Request($url))->method($method)
			->headers('Accept','application/json')
			->headers('Accept-Language', 'en_US')
			->headers('Authorization', is_null($token) ?
				'Basic ' . base64_encode($this->clientID . ":" . $this->secret) :
				$token->token_type . ' ' . $token->access_token)
			->headers('Content-Type', (is_array($data) && $method == 'POST') ?
					'application/x-www-form-urlencoded' : 'application/json');
		
		if (is_null($data)) {
			self::debug("Sending message to $url");
			return $req;
		}
		if (is_array($data)) {
			$req = $req->post($data); // set all fields directly
			self::debug("Sending POST message to $url :", $data);
			return $req; 
		}
		
		if (!is_object($data))
			throw new PayPal_Exception("Invalid data type in PayPal::genRequest");
		
		$data = json_encode($data);
		$req = $req->body($data);
		self::debug("Sending JSON message to $url : $data");
		return $req;
	}