PortaBilling API

Billing extends BillingBase
in package

Billing API wrapper

The class is intended to provide interface to Portaone billing API. It handles authorisation, access token management and API call handling. It needs ConfigInterface object as source of every configuraton aspect

See 'API documentation' section on https://docs.portaone.com

Table of Contents

DATETIME_FORMAT  = 'Y-m-d H:i:s'
Billing API datetime format
__construct()  : mixed
Setup the class, load (if any) saved session state and get it ready to use
call()  : array<string|int, mixed>
Perform billing API call.
callAsync()  : mixed
Performs async call to the billing and returns promise
callConcurrent()  : void
Perform bulk billig call, running multiple concurrent requests at once.
checkSession()  : void
Does active sesson check to billing server, relogin if required
getUsername()  : string|null
Return current user login name
isSessionPresent()  : bool
Returns true if session data exit and not expired
login()  : void
Do login and setup the session.
logout()  : void
Closes the session explicitly.
makeRequest()  : RequestInterface
Creates PSR-7 Request object for API call
processResponse()  : array<string|int, mixed>
Process billing response, given as Response object
timeToBilling()  : string
Return billing API string at UTC fro given Datetime object
timeToLocal()  : DateTime
Convert billing-supplied UTC time string to DateTime object with target timezone

Constants

DATETIME_FORMAT

Billing API datetime format

public mixed DATETIME_FORMAT = 'Y-m-d H:i:s'

Methods

__construct()

Setup the class, load (if any) saved session state and get it ready to use

public __construct(ConfigInterface $config) : mixed

On construct:

  • Check the cached session token expire time within margin or left
  • If token expire soon (within configured margin), try to refresh token
  • If token expired or refresh failed - try to relogin if account data present, throwing exceptions on failures.
  • If no accoount data present, just left the class un-logged-in, then you need login() to get it connected
Parameters
$config : ConfigInterface

Configuration object to run

Return values
mixed

call()

Perform billing API call.

public call(string $endpoint[, array<string|int, mixed> $params = [] ]) : array<string|int, mixed>

Reference to your billing system API docs, located at https://your-billing-sip-host/doc/api/ or API section of Portaone docs site https://docs.portaone.com/. Mind your billing release version.

Parameters
$endpoint : string

API endpoint as per docs, exapmle: '/Customer/get_customer_info'

$params : array<string|int, mixed> = []

API requst params to put into "params" section

Tags
throws
PortaException

on general errors

throws
PortaAuthException

on auth-related errors

throws
PortaApiException

on API returned an error

Return values
array<string|int, mixed>

Billing system answer, converted to associative array. If billing retuns file, returns array with keys:

$returned = [
    'filename' => 'Invoice1234.pdf', // string, returned file name,
    'mime' => 'application/pdf',     // string, MIME file type
    'stream' => Stream               // PSR-7 stream object with file
];

callAsync()

Performs async call to the billing and returns promise

public callAsync(string $endpoint[, array<string|int, mixed> $params = [] ]) : mixed

This method is backend-dependent. In fact, it receives promise from client adapter and wraps it with processResponse() to next promise and returns.

As a result, returned promise will contain processed billing response (array) on fulfilled or throw proper exceptions in failures, behave the same way as method::call() method do.

Parameters
$endpoint : string

API endpoint as per docs, exapmle: '/Customer/get_customer_info'

$params : array<string|int, mixed> = []

API requst params to put into "params" section

Return values
mixed

backend-dependent 'thenable' promise

On fulfill, promise contains Billing system answer, converted to associative array. If billing retuns file, returns array with keys:

$returned = [
    'filename' => 'Invoice1234.pdf', // string, returned file name,
    'mime' => 'application/pdf',     // string, MIME file type
    'stream' => Stream               // PSR-7 stream object with file
];

On reject, it will contain (and throw as unwrapped):

  • PortaException on general errors
  • PortaAuthException on auth-related errors
  • PortaApiException on API returned an error

callConcurrent()

Perform bulk billig call, running multiple concurrent requests at once.

public callConcurrent(iteratable<string|int, mixed> $operations[, int $concurency = 20 ]) : void

Method crawling recursively the traversable given to find all AsyncOperationInterface objects and then process it in parallel with given concurrency (default 20). After run, the objects filled with answers or exceptions depending of each separate call results. it is safe as if there no object, it just do nothing silently, but still do a session check call.

Please, take care to ensure the session is up and warm. If session fail for any reason, this metod will not relogin even credentials set. Therefore, all the bundle of async calls will faile and array be populateed with auth exceptions. If you can't be sure on session state, please use checkSession() before call to ensure session is up and Ok. Do not trust to isSessionPresent(), it only checks token state, it does not means the session OK on the server side.

Parameters
$operations : iteratable<string|int, mixed>

array or any other multi-level iterable, containing objects, implementing AsyncOperationInterface

$concurency : int = 20

how much calls to run in parallel. Default is 20.

WARNING: due of some reasons increasing of concurrency over some empiric value does not decrease overall time to complete all the requests and even make it longer. In fact, PHP does not support async operations, so all the magic comes from cURL multi-call, so it could be combination of limitations: cURL, PortaOne server and PHP itlself. As for me, 20 works fine.

Return values
void

checkSession()

Does active sesson check to billing server, relogin if required

public checkSession() : void

Completes 'Session/ping' call to check session state, then:

  • If session not recognised, and credentials present, trying to relogin
  • If no credentials in config or login failure - throws auth exception
Tags
throws
PortaAuthException

on relogin failed or no credentilas

Return values
void

getUsername()

Return current user login name

public getUsername() : string|null

Returns username taken from access token or null if no session is up

Return values
string|null

isSessionPresent()

Returns true if session data exit and not expired

public isSessionPresent() : bool

Returns true if session data (token) exists and not expired, false if not logged in for any reason.

Does not complete active sesion check to the server. Due of serveer configuratioin issues token may be invalidated for inactivity before it's expire time really has come. So, positive isSessionUp() only means persistent session data loaded,

Return values
bool

login()

Do login and setup the session.

public login(array<string|int, mixed> $account) : void

The session data will be stored if session storage class is supplied

Parameters
$account : array<string|int, mixed>

Account record to login to the billing. Combination of login+password or login+token required

$account = [
    'login' => 'myUserName',    // Mandatory username
    'password' => 'myPassword', // When login with password
    'token' => 'myToken'        // When login with API token
Tags
throws
PortaAuthException
Return values
void

logout()

Closes the session explicitly.

public logout() : void

Will call '/Session/logout' api method. Due of some problems with Portaone resposes, session will considered closed whatever server respond. No server error will be respected, but conenction errors will thrown.

Tags
throws
PortaConnectException
Return values
void

makeRequest()

Creates PSR-7 Request object for API call

public makeRequest(string $endpoint[, array<string|int, mixed> $params = [] ]) : RequestInterface

Creates Request with all necessaly elements could be send to the billing API: endpoint, data, auth headers and all other.

This used for all other functions, but you may also got request, send it with some specific client, async, multitread, wrap or whatever else, and then got Respose object and process the response with static processResponse() method below. all the processing sounds like:

// Creating PSR-7 HTTP Request object
$request = $billing->makeRequest(
                      '/Section/get_something_info', // Endpoint
                      ['i_something' => 42]          // Params
);

// Perform call with PSR-18 HTTP client
$response = $client->sendRequest($request);

// Parse response, extract data or files, handle errors
$result = Billing::processResponse($response);

Reference to your billing system API docs, located at https://your-billing-sip-host/doc/api/ or API section of Portaone docs site https://docs.portaone.com/. Mind your billing release version.

Parameters
$endpoint : string

billing API endpoint

$params : array<string|int, mixed> = []

API request params to put into "params" section

Return values
RequestInterface

processResponse()

Process billing response, given as Response object

public static processResponse(ResponseInterface $response) : array<string|int, mixed>

The full response nadling be provided, includint throwing exceptions on different errors, if any.

Companion function to makeRequest(). All the processing sounds like:

// Creating PSR-7 HTTP Request object
$request = $billing->makeRequest(
                      '/Section/get_something_info', // Endpoint
                      ['i_something' => 42]          // Params
);

// Perform call with PSR-18 HTTP client
$response = $client->sendRequest($request);

// Parse response, extract data or files, handle errors
$result = Billing::processResponse($response);
Parameters
$response : ResponseInterface

object got from the biliing as answer

Tags
throws
PortaException

on general errors

throws
PortaAuthException

on auth-related errors

throws
PortaApiException

on API returned an error

Return values
array<string|int, mixed>

billing answer, converted to associative array

timeToBilling()

Return billing API string at UTC fro given Datetime object

public static timeToBilling(DateTimeInterface $time) : string

The DateTime obhject given will not change.

Parameters
$time : DateTimeInterface

Datetime object to take time from

Return values
string

Billing API-type datetime string, shifted to UTC

timeToLocal()

Convert billing-supplied UTC time string to DateTime object with target timezone

public static timeToLocal(string $billingTime[, string $timezone = 'UTC' ]) : DateTime
Parameters
$billingTime : string
  • datetime string as billing returns
$timezone : string = 'UTC'
  • timezone string like 'Europe/London" or '+3000', as defined at https://www.php.net/manual/en/datetimezone.construct.php
Return values
DateTime

Search results