Q:

Installed Package Apex Callout Error

I'm developing an app for the app exchange that requires a callout to an external system. I have a named credential set up to handle the users login information to the external server. While developing the application, when I make a callout to the external server everything works fine. I issue starts after I upload the package to the app exchange. When customers download and install the application they are getting a callout error. I'm not sure what to test for next? I've verified that their login information is correct. I'll attach some screenshots of the error as well as the code I'm using.
Callout Class
/**
* @author       Allen Watson
* @version  1.0
* @since        1.0 
* 
* Used to handle communication with slybroadcast Servers
*/
public with sharing class callout {

public String Username;
public String Password;

public callout(){
    Username = '{!$Credential.UserName}';
    Password = '{!$Credential.Password}';
}

/**
 * Sends a voice message request to slybroadcast
 * 
 * @param   phone - The phone number that is to receive the voice message.
 * @param   audioRecord - The voice message that is to be sent.
 * @param   cdate - The date and time the voice message should be sent.
 * @param   callerID - The phone number that you want to send the voice message from.
 * @param   mobileOnly - Do you want to send the voice message to mobile phones only?
 * @return  Boolean - return value relays success or failure to the parent.
 * @since   1.0
 */
public Boolean sendRequest(String phone, String audioRecord, String cdate, String callerID, String mobileOnly)
{
    // remove username and password as it is handled by named credential
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    Http http = new Http();
    req.setMethod('POST'); // Method Type
    req.setEndpoint('callout:SlyUserCred/vmb.php'); // Server Url
    req.setBody('c_uid='+Username+  
                '&c_password='+Password+ '&c_phone=' + EncodingUtil.urlEncode(phone, 'UTF-8') +
                '&c_record_audio=' + EncodingUtil.urlEncode(audioRecord, 'UTF-8') + '&c_callerID=' + 
                EncodingUtil.urlEncode(callerID,'UTF-8') + '&c_date=' + EncodingUtil.urlEncode(cdate, 'UTF-8') +
                '&c_audio='+ EncodingUtil.urlEncode('wav', 'UTF-8') + '&mobile_only=' + EncodingUtil.urlEncode(mobileOnly, 'UTF-8')); // Request Parameters
    try 
    {
        //processing the response from slybroadcast.
        res = http.send(req);
        system.debug(res.getBody());
        if(res.getBody() != null)
        {
            system.debug(res.getBody());
            return true;
        }
        return true;

    } 
    catch(Exception e) 
    {
        System.debug('error: '+ e);
        return false;
    }
}

/**
 * Use to ask the slybroadcast severs for a list of stored audio file names.
 * 
 * @return  List<String> - returns a list of all the audiofile accociated with a slybroadcast account.
 * @since   1.0
 */
public List<String> getAudioFiles()
{
    // remove username and password as it is handled by named credential
    List<String> rtnString = new List<String>();

    //Creates HttpRequest and builds the request.
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    Http http = new Http();
    req.setMethod('POST'); // Method Type
    req.setEndpoint('callout:SlyUserCred/vmb.aflist.php'); // Server Url
    req.setBody('c_uid='+Username+   
                '&c_password='+Password+
               '&c_method=' + EncodingUtil.urlEncode('get_audio_list', 'UTF-8'));

    try 
    {
        //Processing the response from slybroadcast
        res = http.send(req);
        system.debug(res.getBody());
        if(res.getBody() != null)
        {
            //Splitting up the audioRecords into a list
            String unsplitString = res.getBody();
            List<String> firstSplitString = unsplitString.split('\n');
            List<String> secondSplitString = new List<String>();
            for(String s : firstSplitString)
            {
                secondSplitString = s.split('\\|');
                String temp = secondSplitString[1];
                secondSplitString[1] = temp.remove('\"');
                rtnString.add(secondSplitString[1]);
            }
            return rtnString;
        }
        return rtnString;
    } 
    catch(Exception e) 
    {
        rtnString.add('error: '+ e);
        return rtnString;
    }
}
//used to verify that the slybroadcast account that the user entered is a valid one.
public Boolean validateAccount()
{
    // remove username and password as it is handled by named credential
    Boolean isValid = false;
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    Http http = new Http();
    req.setMethod('POST'); // Method Type
    req.setEndpoint('callout:SlyUserCred/vmb.php'); // Server Url
    req.setBody('c_uid='+Username+   
                '&c_password='+Password+
                '&c_option=user_verify'); // Request Parameters
    system.debug('CAL116: '+req.getBody());
    try 
    {
        res = http.send(req);
        system.debug('Res: '+res.getBody());
        if(res.getBody() == 'OK')
        {
            isValid = true;
        }else
        {
            //throw new CalloutException(res.getBody());
        }

    } 
    catch(Exception e) 
    {
        throw e;
    }
    return isValid;
} 
}

VisualForce Page Controller
public with sharing class WelcomeController {
public callout Broadcaster;

public WelcomeController(){
    Broadcaster = new callout();
    //System.debug('Got Here');
}

public PageReference ValidateSlybroadcastAccount(){
    PageReference ValidationResult = Page.SlybroadcastAcctValidVFP;
    Boolean isValid = Broadcaster.validateAccount();
    if(!isValid) ValidationResult = Page.SlybroadcastAcctInvalidVFP;
    System.debug('Is Slybroadcast Account Valid: '+isValid);
    return ValidationResult;
}

public PageReference ReturnToWelcome(){
    return Page.SlybroadcastWelcomeVFP;
}
}

Visualforce Page
<apex:page controller="WelcomeController">
<apex:pageBlock title="Welcome to Slybroadcast." tabStyle="Message__c">
    <apex:form >
        <apex:pageBlockSection title="Account Validation" collapsible="true">
            <apex:commandLink action="/0XU/e?retURL=%2Fudd%2FExternalDataUserAuth%2FlistExternalDataUserAuth.apexp" value="Add Slybroadcast Credentials to Salesforce."/>
            <apex:commandLink action="{!ValidateSlybroadcastAccount}" value="Validate Slybroadcast Credentials."/>
        </apex:pageBlockSection>
        <apex:pageBlockSection title="More" collapsible="true">
            <apex:commandLink action="https://drive.google.com/drive/folders/11X2d6Ml1249BVFMkPfaPd9VlHs4CgZfG?usp=sharing" value="Visual Aids and more instructions."/>
        </apex:pageBlockSection>
    </apex:form>
</apex:pageBlock>

A:

I also had the same issue today.
Try to prefix the name of your named credential with ".__" as shown in the sample below.
final String DEV_ORG_ID = <my_dev_org_Id>;
String endpointURL = 'callout:.__SlyUserCred/vmb.aflist.php'; 
if(UserInfo.getOrganizationId() == DEV_ORG_ID){ 
    endpointURL = 'callout:SlyUserCred/vmb.aflist.php';
}
req.setEndpoint(endpointURL);

