Set next month payment date (with PHP Carbon)

You should not use last payment date, but keep the first date and calculate all the other date from the first, not the previous one:

Carbon::create(2018, 1, 31, 0, 0, 0)
Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(1)
Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(2)
Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(3)

Supposing you don't have this data, you still can:

$day = 31;
$date = Carbon::create(2018, 1, 28, 0, 0, 0);
$date->addMonthsNoOverflow(1);
$date->day(min($day, $date->daysInMonth));