Since no one was able to answer my question, I will do so myself since I found the answer this morning.
When executing the API call for fetching plugin information, the response object must contain a banners array:
$response->banners = [
'low' => 'http://yourdomain.com/banner_772x250.png',
'high' => 'http://yourdomain.com/banner_1544x500.png',
];
Images need to be called “low” (exactly 772×250 pixels) and/or “high” (1544×500 pixels). Only one of both needs to be set. I recommend the “low” one, since the “high” one seems to be only needed for retina displays (can’t find source anymore).
I found the answer to this question early in the morning today by looking at the file
wp-admin/include/plugin-install.php
lines 526+ (WP version 4.9.6):
if ( ! empty( $api->banners ) && ( ! empty( $api->banners['low'] ) || ! empty( $api->banners['high'] ) ) ) {
$_with_banner="with-banner";
$low = empty( $api->banners['low'] ) ? $api->banners['high'] : $api->banners['low'];
$high = empty( $api->banners['high'] ) ? $api->banners['low'] : $api->banners['high'];
?>
<style type="text/css">
#plugin-information-title.with-banner {
background-image: url( <?php echo esc_url( $low ); ?> );
}
@media only screen and ( -webkit-min-device-pixel-ratio: 1.5 ) {
#plugin-information-title.with-banner {
background-image: url( <?php echo esc_url( $high ); ?> );
}
}
</style>
<?php
}
I hope this is helpful to somebody. It certainly was for me.