Are you using IPN if yes then, when a subscription is cancelled paypal returns $_POST['txn_type'] = subscr_cancel
along with subscr_date = subscription date, subscr_id = subscription ID, etc now you can process cancel request for the returned subscription id.
similarly you get $_POST['txn_type'] = subscr_eot
when subscription ends.
Once you have setup IPN url in the paypal settings it will always call your ipn handler.
use switch case to handle different requests like so,
switch ($_POST['txn_type']) {
case 'cart':
//for products without subscription
break;
case 'subscr_payment':
//subscription payment recieved
break;
case 'subscr_signup':
//subscription bought payment pending
break;
case 'subscr_eot':
//subscription end of term
break;
case 'subscr_cancel':
//subscription canceled
break;
}