Membership subscription, change user role when subscription runs out

Presumably you’ve saved an expiration data somewhere, so setup a wp_cron job to run daily. That job should check the expiration dates, and change the roles for users whose dates are past.

if ( ! wp_next_scheduled( 'alter_user_role_hook' ) ) {
  wp_schedule_event( strtotime('tomorrow'), 'daily', 'alter_user_role_hook' );
}
function alter_user_role_function() {
  global $wpdb;
  $today = date('Y-m-d H:i:s',strtotime('today'));
  $expired = $wdpb->get_col("SELECT user_id FROM {$wpdb->usermeta} WHERE expired_key < {$today}");
  if (!empty($expired)) {
    foreach ($expired as $uid) {
      wp_update_user( 
        array ( 
          'ID' => $uid, 
          'role' => 'havent_paid'
        ) 
      );
    }
  }
}
add_action( 'alter_user_role_hook', 'alter_user_role_function' );

I am assuming that the expiration date is stored in user meta and I am guessing at the role slug.

Untested but that should be close. I would alter the time components so that it runs at some low traffic time on your site.