1. override
Future<StreamedResponse> send(BaseRequest request)

Sends an HTTP request and asynchronously returns the response.

Implementers should call BaseRequest.finalize to get the body of the request as a ByteStream. They shouldn't make any assumptions about the state of the stream; it could have data written to it asynchronously at a later point, or it could already be closed when it's returned. Any internal HTTP errors should be wrapped as ClientExceptions.

Source

@override
Future<StreamedResponse> send(BaseRequest request) async {
  if (_lastTokenTime != null && credentials != null) {
    var now = new DateTime.now();
    var difference = now.difference(_lastTokenTime);
    if (difference.inSeconds >= credentials.expiresIn) await _fetchToken();
  } else
    await _fetchToken();

  if (credentials != null) {
    request.headers["Authorization"] = "Bearer ${credentials.accessToken}";
  }

  var response = await _inner.send(request);

  if (response.statusCode != 200 && response.statusCode != 201) {
    var out = await Response.fromStream(response);
    throw new PayPalException.fromJson(out.body, statusCode: response.statusCode);
  } else return response;
}