Check if a postcode is in a list
Inside of a function call, avoid echoing.  By hardcoding echoes, you prevent the "silent" usage of the function.  It may be necessary in the future to present the output in more than one format, so use a return inside the function declaration and perform the echo on the function call.

Pay close attention to psr-2's guidelines on control structures.  They will help you (and future developers of your code) to read your code.  Always imagine that the next person to read your code will have a headache, a hatchet, and your home address; don't set them off.

Empty on $_POST is an imprecise way of checking for expected submission data.  

strcmp() provides greater specificity than your condition logic requires.   For your logic, just check if the input is identical to the string without a function call.

Condense conditionals within the same block that have the same outcome.  Multiple conditions lead to $passed = 1 so they can be consolidated. I didn't really bother to understand the conditional logic behind $passed = 1 but it should certainly be refined.

Refine your validation check on $_POST['pc'].  You are checking if is_numeric(), that's fine. Then checking if the value that is cast as (int) is an integer -- um, at this point of course it is, it has no choice.  Better yet, why not just make a single check with ctype_digit()?  You might also like to check that the strlen() is valid (only you will know if/how to design this for your region).  If you want to check the quality and length of the postcode value, perhaps it would be more sensible to use preg_match() where you can design robust/flexible validation with a single function call (again, only you can determine this).

$temp_l and $temp_p are poor variable naming choices.  As a new dev to your script, I don't instantly know what they contains (I can venture a guess, but don't ask devs to do this).  Try to practice a more literal naming convention.  Furthermore, try to avoid declaring single-use variables ($temp_l).  Often, fewer variables will lead to fewer typos/mistakes, concise code, and improved readability.  When data needs some explaining, use commenting. *notes: 1. I have read some cases where declaring a variable prior to a foreach loop can improve performance 2. Some devs don't like to see functions fed to a foreach loop, I can respect this and I don't typically do this in my own projects.

There is no use in checking if the return value from explode() is an array.  It returns an array by design, so you can remove that check.  Even if you explode a empty string with PHP_EOL, you will not get a true evaluation from empty(), so that check is pointless to write.  At the end of the day, if you try to use foreach() on an empty array, it simply won't iterate -- no worries.

If you have no intentions of using $i in your foreach loop, don't bother to declare it.  I don't like single-use variables; I super don't like no-use variables.

How to get the substring before the first occurrence of a character without explode()? strstr() with a true third parameter.  Otherwise, explode has to create an array enroute to delivering the string that you need.  My suggested snippet will attempt to extract the substring before the first colon, if there is no colon the full string will be used.

By storing qualifying matches as an array, you can avoid having to trim any trailing delimiters from your output string.  In fact, return the data without delimiters as an array so that you can easily adjust the way that your qualifying values are delimited.

Strictly speaking, having zero qualifying results from a postcode search doesn't mean that there was an "Error", so just have your function calling script accommodate for "Successful" yet "Empty" results.

I can't imagine a benefit from JSON_FORCE_OBJECT.

die() in nearly every scenario should be avoided.

Suggested Code Overhaul:

function sapc_ajax_check() {
    $checker_defaults = get_option('sapc_checker_settings_options');

    if (!isset($_POST['action']) ||  $_POST['action'] !== 'sapc_ajax_check') {
        $errors[] = 'Missing required submission data';
    }
    if (!isset($_POST['pc'])) {
        $errors[] = 'Missing postcode value';
    }
    if (isset($_POST['verify-int']) &amp;&amp; $_POST['verify-int'] === 'on' &amp;&amp; ctype_digit($_POST['pc'])) {
        $errors[] = 'Invalid postcode value';
    }
    if (isset($errors)) {
        return json_encode(['Error', $errors]);
    }

    $result = [];
    foreach (explode(PHP_EOL, $checker_defaults['postcodes']) as $postcode) {
        $before_colon = strstr($postcode, ':', true);
        $postcode = ($before_colon === false ? $postcode : $before_colon);
        if ($postcode === $_POST['pc'])) {
            $result[] = $postcode;
        }
    }
    return json_encode(['Success', $result]); 
}


Much cleaner right?