CodeIgniter Controller and Library for Address Verification using USPS Web Tools API

Living in Canada has its advantages – we get a lot of free stuff, like healthcare and… maple syrup. Ok, maybe not the syrup. But when it comes to entertainment and a good number of services emanating from south of the border, we really got the short end of the stick. Picture Netflix (kinda), Hulu, and many other services that only show love to Americans.

I’m going to go ahead and sort of blow the whistle on myself here, but I’ve always wondered how out of my buddies, I was able to sign up for (insert name of service that shows us Canadians no love) while they couldn’t. The only difference between us was the time we registered. I had several months head start and by the time they went ahead with registering, they couldn’t. My only guess was that they began verifying addresses during sign up. The good news is, there is always a way around it, but I’ll leave that for another post.

So what’s the big deal here? Why is it important to make sure you live where you say you live? For one, outside of this entertainment theme I have going, is taxes. Not all states pay tax for some services and products. For those states that do, the actual tax amount varies from state to state – and in some cases, county to county. So it’s important that your street and city and zip code match up, otherwise we would all live on 123 Main Street – and well the government will be short on some green (that may or may not be a good thing).

CodeIgniter Library for verifying a US Address

We’ll first begin by creating a library within our CodeIgniter application folder. You’ll want this as a library so you can reuse this anywhere else in your web application. Essentially, this library simply communicates with USPS and returns the result of your query. One thing to keep in mind is that the main street address according to USPS is defined by the Address2 field. For instance, seeing as I live on 123 Main Street, Address1 is blank while Address2 is my ever so popular street address.

class AddressVerify {
	public $usps_endpoint;
	public $usps_userid;
	public $contact_address1;
	public $contact_address2;
	public $contact_city;
	public $contact_state;
	public $contact_zip5;
	public $contact_zip4;
	function verifyAddress() {
		$ch = curl_init($this->usps_endpoint);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, "API=Verify&XML=".$this->processAddress());
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		return curl_exec($ch);
	function processAddress() {
		$address = '<AddressValidateRequest USERID="'.$this->usps_userid.'"><Address>';
		$address .= '<Address1>'.$this->contact_address1.'</Address1>';
		$address .= '<Address2>'.$this->contact_address2.'</Address2>';
		$address .= '<City>'.$this->contact_city.'</City>';
		$address .= '<State>'.$this->contact_state.'</State>';
		$address .= '<Zip5>'.$this->contact_zip5.'</Zip5>';
		$address .= '<Zip4>'.$this->contact_zip4.'</Zip4>';
		$address .= '</Address></AddressValidateRequest>';
 		return $address;

Get it all running with your controller or callback

This is where all the magic happens. The example I’m going to show below is for callbacks used during form validation. Here you’ll load the AddressVerify library and pass in the user’s input. You can control the various error messages to display based on the input received.

function us_address_verify() {
	//Check to see if the ZIP Code is in correct format
	if (preg_match("/^[0-9]{5,5}([- ]?[0-9]{4,4})?$/",$this->zip)) {
		//Loading the Library for address verification
		//USPS Account Information
		$uspsEndpoint = '';
		$uspsUsername = 'ENTER_USPS_USERNAME';
		//Connecting to USPS and verifying address
		$addressVerification = new AddressVerify();
		$addressVerification->usps_endpoint = $uspsEndpoint;
		$addressVerification->usps_userid = $uspsUsername;
		$addressVerification->contact_address1 = $this->address1;
		$addressVerification->contact_address2 = $this->address2;
		$addressVerification->contact_city = $this->city;
		$addressVerification->contact_state = $this->state;
		$addressVerification->contact_zip5 = substr($this->zip, 0, 5);
		$addressVerification->contact_zip4 = substr($this->zip, -4);
		$result = $addressVerification->verifyAddress();
		//Validation Steps
		if (!empty($result)){
			$response = new SimpleXMLElement($result);
			if ($response->Address->City != strtoupper($this->city)) {
				$this->form_validation->set_message('us_address_verify', 'We were unable to verify your address. Please check your city.');
    			return FALSE;
			} else if ( $response->Address->State != $this->state) {
				$this->form_validation->set_message('us_address_verify', 'We were unable to verify your address. Please check your state.');
    			return FALSE;
			} else if ($response->Address->Zip5 != substr($this->zip, 0, 5)) {
				$this->form_validation->set_message('us_address_verify', 'We were unable to verify your address. Please check your postal code.');
    			return FALSE;
			} else if ($response->Address->Zip4 != substr($this->zip, -4)) {
				$this->form_validation->set_message('us_address_verify', 'We were unable to verify your address. Please check your postal code.');
    			return FALSE;
			} else {
				return TRUE;
		} else {
			$this->form_validation->set_message('us_address_verify', 'We were unable to verify your address. Please contact support.');
			return FALSE;
	} else {
		$this->form_validation->set_message('us_address_verify', 'You have provided an invalid zip code.');
		return FALSE;

Now that you have the whole address thing working, you can focus on creating the next best service and of course, only make it available to Americans… cause we got the whole maple syrup thing going.

1 Comment

  1. Kasey

    Very nice! Took me 5 min to set up and works perfectly!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>