Q:

What is the right ISO8601 format?

Why 
echo date('c');

not equal with 
$datetime = new DateTime();
echo $datetime->format(DateTime::ISO8601); 

The result:
2016-07-07T21:18:22+03:00
2016-07-07T21:18:22+0300

Both must give current time in ISO8601 format. In Wikipedia right format is 2016-07-07T21:18:22+03:00 but some banks use 2016-07-07T21:18:22+0300 format in API. Why?

A:

2016-07-07T21:18:22+03:00

Is the correct ISO 8601:2004 representation.

2016-07-07T21:18:22+0300

Is incorrect, the zone designator may not be in the basic format when the date and time of day is in the extended format.
ISO 8601:2004 4.3 Date and time of day:

[...] the expression shall either be completely in basic format, in
  which case the minimum number of separators necessary for the required
  expression is used, or completely in extended format, in which case
  additional separators shall be used [...]

Update 1:
ISO 8601 specifies three differerent date representations: calendar, ordinal and week dates. Theese can be formatted in either basic format (minimum number of seperators) or extended format (extension of the basic format that includes additional separators). ISO 8601 requires that the resulting expression is either consistently in basic format or consistently in extended format.
Combination of calendar date and time of day in local time with difference from UTC:
2016-07-07T21:18:22+03:00 (extended format)
20160707T211822+0300 (basic format)

Combination of ordinal date and time of day in local time with difference from UTC:
2016-189T21:18:22+03:00 (extended format)
2016189T211822+0300 (basic format)

Combination of week date and time of day in local time with difference from UTC:
2016-W27-4T21:18:22+03:00 (extended format)
2016W274T211822+0300 (basic format)

All of the above representations represent the same date and time of day in local time with difference from UTC (and instant). If an API documents that it accepts an ISO 8601 date with time of day and a zone designator (aka known as a complete representation), it should accept all of the above representations to be compliant with ISO 8601.
Update 2:
Most bugs i have encountered stem from using strftime() to output an ISO 8601 date and time of day in local time with difference from UTC in extended format. The standard strftime() can only output compliant representations in basic format due to the limitations in the z conversion specifier:
Combination of calendar date and time of day in local time with difference from UTC:
Format:          Example:
%Y%m%dT%H%M%S%z  20160707T211822+0300

Combination of ordinal date and time of day in local time with difference from UTC:
Basic format:    Example:
%Y%jT%H%M%S%z    2016189T211822+0300

Combination of week date and time of day in local time with difference from UTC:
Basic format:    Example:
%GW%V%uT%H%M%S%z 2016W274T211822+0300

The GNU strftime implementation supports a : flag between the percent and the z conversion specifier to specify that the zone designator should be formated in extended format:
Combination of calendar date and time of day in local time with difference from UTC:
Format:                Example:
%Y-%m-%dT%H:%M:%S%:z   2016-07-07T21:18:22+03:00

Combination of ordinal date and time of day in local time with difference from UTC:
Format:                Example:
%Y-%jT%H:%M:%S%:z      2016-189T21:18:22+03:00

Combination of week date and time of day in local time with difference from UTC:
Format:                Example:
%G-W%V-%uT%H:%M:%S%:z  2016-W27-4T21:18:22+03:00

