Jump to content

Auto Set Clients as Tax Exempt when they fill in a Vat Number/Tax ID


Matt

Recommended Posts

  • WHMCS CEO

Due to a request in a thread yesterday, here is the code needed to automatically set a client to be tax exempt when they provide a VAT Number or Tax ID in a custom field on the signup form. This is needed for companies who need to comply with EU VAT laws.

 

What it does is checks if the user filled out the VAT Number/Tax ID custom field on your signup form and if they did enables the tax exempt setting before generating the invoice for the order they are placing.

 

To install it, simply follow the 3 steps below:

 

1. Open the file "includes/actionhooks.php"

 

2. Find the actionhook_ClientSignup function which gets run after the client signups during the checkout process (lines 15-30 inclusive)

 

3. Replace with the following code:

 

function actionhook_ClientSignup($vars) {
$vatnumber = $_POST["customfield"][1]; # Replace 1 with the ID number of your custom field as in the tblcustomfields table of the database
if ($vatnumber) {
	$table = "tblclients";
	$array = array( "taxexempt" => "on" );
	$where = array( "id" => $_SESSION["uid"] );
	update_query($table,$array,$where);
}
}

 

Regards,

 

Matt

Link to comment
Share on other sites

Matt,

 

correct me if I'm wrong but as far as I know the VAT should be calculated if the company resides in the same country as the hosting provider, so the script should check as well if it the customer is located in a different country then the company that sends out the bills.

 

Our Dutch customers provide us with their VAT number in a custom field which entitles them to request a charge back for the VAT mentioned on payed invoices. If they do not provide a VAT number legally they are not allowed to request a charge back for the VAT paid on invoices.

 

All our prices are shown without VAT, which is clearly stated on each of our hosting pages. On the invoices we send out we add the 19% VAT except for foreign EU customers who provided us with their VAT number. For these customers we set the TAX Exempt status flag.

 

regards

 

Erik

Link to comment
Share on other sites

correct me if I'm wrong but as far as I know the VAT should be calculated if the company resides in the same country as the hosting provider, so the script should check as well if it the customer is located in a different country then the company that sends out the bills.

 

Correct :)

For example Spanish residents pay VAT on spanish purchases

VAT registered Spanish business pay VAT on spanish purchases but can claim it back if the invoice/payment receipt shows their VAT number

English residents pay VAT on spanish purchases

VAT English English business dont pay VAT on spanish purchases as long as a valid UK VAt number is provided to the spanish supplier.

 

So the update of the flag has to be dependant not only on a VAT number completed but also the country not being that of the supplier *and* the country of the client being part of the VAT sharing scheme (CH has VAT and therefore VAt mumbers, but is not art of the UK VAt sharing system, so you still have to charge Swiss business the VAT even if they provide a number for printing on the invoices)

 

Matt

Does this action-hook method also work with the standard orderform method as well as the cart ?

Link to comment
Share on other sites

  • 2 weeks later...
(CH has VAT and therefore VAt mumbers, but is not art of the UK VAt sharing system, so you still have to charge Swiss business the VAT even if they provide a number for printing on the invoices)
I thought we only had to charge VAT to EU member states and the rest we didn't, perhaps I'm confused about this because we have only just become VAT registered. I have just put into whmcs to charge VAT on the 25 member states, is that not right?
Link to comment
Share on other sites

  • 4 weeks later...

I'm also interested in this but as said it does not account for the fact that the client has to be from an EU country other than the businesses own country for reverse charge / charge back VAT to apply.

 

Couldn't the script be extended like so -

 

function actionhook_ClientSignup($vars) {
$vatnumber = $_POST["customfield"][1]; // Replace 1 with the ID number of your custom field as in the tblcustomfields table of the database
$country = $_POST["country"]; // Sorry I dont know the actual post value as i've not installed the software yet

// Check country
if(strtolower($tax_locale)=="it"){
	$isexempt = false; // Italian customers are always charged (My business location)
} elseif (strtolower($country)=="at" ||
	strtolower($country)=="be" ||
	strtolower($country)=="dk" || 
	strtolower($country)=="fi" || 
	strtolower($country)=="fr" || 
	strtolower($country)=="de" || 
	strtolower($country)=="gr" || 
	strtolower($country)=="ie" || 	
	strtolower($country)=="lu" || 
	strtolower($country)=="pt" || 
	strtolower($country)=="es" || 
	strtolower($country)=="se" || 
	strtolower($country)=="nl" || 
	strtolower($country)=="gb" || 
	strtolower($country)=="uk"){
		if ($vatnumber!=""){
			$isexempt = true; // Is exempt, has VAT/IVA number
		}else{
			$isexempt = false;  // No VAT/IVA number, is charged
		}
} else {
	$isexempt = true; // Non-EU customers are always exempt
}

if ($isexempt) {
	$table = "tblclients";
	$array = array( "taxexempt" => "on" );
	$where = "id='".$_SESSION["uid"]."'";
	update_query($table,$array,$where);
}
}

 

The problem I see here is that if the client removes their VAT code or changes there country after sign-up this setting would be invalid would it not? (Or does this check at every change of user details?). Is there not a place where we can do this same check but at Invoice creation so it is always correct? (Thats how AWBS does it)

Link to comment
Share on other sites

This last post seems to be the closest to a perfect VAT calculation as far as companies in the EEC are concerned, with like ServWise.com underlined the need to periodically check if the client changed their VAT status (on every new order they place maybe ?)

 

One rather interesting add-on I could suggest, as mentioned before, is a part of a site I developped, that lets one check if a VAT number is legit - this is originally an open source contribution to OSCommerce @ http://www.oscommerce.com/community/contributions,1848

 

////////////////////////////////////////////////////////////////////////////////////////////////

//

// Function : verif_tva

// Arguments : num_tva VAT INTRACOM number to be checked

// Return : 'true' - valid VAT number

// 'false' - invalid VAT number

// 'no_verif' - problem with the europa server

//

// Description : function for validating VAT INTRACOM number through the europa.eu.int server

// By JeanLuc (February, 5th 2004)

// Updated by JeanLuc (July, 23th 2004)

// Updated by JeanLuc (May, 22th 2006) using europa.eu.int server webservice (SOAP) via nusoap.php class (Dietrich Ayala)

//

// Valid VAT INTRACOM number structure:

// Austria AT + 9 numeric and alphanumeric characters

// Belgium BE + 9 numeric characters

// Denmark DK + 8 numeric characters

// Finland FI + 8 numeric characters

// France FR + 2 chiffres (informatic key) + N° SIREN (9 figures)

// Germany DE + 9 numeric characters

// Greece EL + 9 numeric characters

// Irlande IE + 8 numeric and alphabetic characters

// Italy IT + 11 numeric characters

// Luxembourg LU + 8 numeric characters

// Netherlands NL + 12 alphanumeric characters, one of them a letter

// Portugal PT + 9 numeric characters

// Spain ES + 9 characters

// Sweden SE + 12 numeric characters

// United Kingdom GB + 9 numeric characters

//

// Cyprus CY + 8 numeric characters + 1 alphabetic character

// Estonia EE + 9 numeric characters

// Hungary HU + 8 numeric characters

// Latvia LV + 11 numeric characters

// Lithuania LT + 9 or 12 numeric characters

// Malta MT + 8 numeric characters

// Poland PL + 10 numeric characters

// Slovakia SK + 9 or 10 numeric characters

// Czech Republic CZ + 8 or 9 or 10 numeric characters

// Slovenia SI + 8 numeric characters

//

////////////////////////////////////////////////////////////////////////////////////////////////

function verif_tva($num_tva){

$prefix = substr($num_tva, 0, 2);

$tva = substr($num_tva, 2);

 

if (array_search($prefix, tep_get_tva_intracom_array() ) === false) {

return 'false';

}

 

require_once('inc/classes/nusoap.php');

$param = array('countryCode' => $prefix, 'vatNumber' => $tva );

$client = new soapclient( 'http://ec.europa.eu/taxation_customs/vies/api/checkVatPort' );

$response = $client->call('checkVat', $param);

 

if ($client->fault) {

return 'no_verif';

}elseif ($response['valid']=='true'){

return 'true';

}else{

$myVerif = 'false';

}

return $myVerif;

}

 

 

On my site get a blue or red flag next to the custom VAT field, and VAT is either charged or omitted.

 

Matt could you consider fine-tuning that add-on so that European business can be sure VAT is properly handled by WHMCS ?

 

Regards.

Link to comment
Share on other sites

Due to a request in a thread yesterday, here is the code needed to automatically set a client to be tax exempt when they provide a VAT Number or Tax ID in a custom field on the signup form. This is needed for companies who need to comply with EU VAT laws.

 

What it does is checks if the user filled out the VAT Number/Tax ID custom field on your signup form and if they did enables the tax exempt setting before generating the invoice for the order they are placing.

 

()

 

3. Replace with the following code:

 

function actionhook_ClientSignup($vars) {
$vatnumber = $_POST["customfield"][1];
if ($vatnumber) {
	$table = "tblclients";
	$array = array( "taxexempt" => "on" );
	$where = "id='".$_SESSION["uid"]."'";
	update_query($table,$array,$where);
}
}

 

Regards,

 

Matt

 

I started adding that first code but realize it would create major legal accounting issues for me, as it seems it would prevent any client from France from paying VAT, whereas they must do so even if they are VAT registered - see previous posts.

Could the very good suggestion by ServWise.com be implemented, as I guess all EEC business would have the perfect VAT behavior from WHMCS.

 

Regards.

Link to comment
Share on other sites

  • 2 weeks later...

I went ahead with the scripts above and came up to a working solution.

The only thing i'm going to add in the near future is a check to see wheter the supplied VAT number is valid or not.

Perhaps Matt can look into this also :)

 

1. Create a field called vatnumber in your tblcients table.

2. Edit your orderforms template file and build in a text field with the name vatnumber, and put the data in the table on submission.

3. Edit your actionhooks file with the following code

 

$vatnumber = $_POST["vatnumber"]; // Replace 1 with the ID number of your custom field as in the tblcustomfields table of the database 
$country = $_POST["country"]; // Sorry I dont know the actual post value as i've not installed the software yet 

   // Check country 
   if($country =="NL"){  // fill in the code of your country here!
       $isexempt = false; 
   } elseif (strtolower($country)=="AT" || 
       strtolower($country)=="BE" || 
       strtolower($country)=="DK" ||  
       strtolower($country)=="FI" ||  
       strtolower($country)=="FR" ||  
       strtolower($country)=="DE" ||  
       strtolower($country)=="GR" ||  
       strtolower($country)=="IE" ||      
       strtolower($country)=="LU" ||  
       strtolower($country)=="PT" ||  
       strtolower($country)=="ES" ||  
       strtolower($country)=="SE" ||  
       strtolower($country)=="IT" ||  
       strtolower($country)=="GB" ||  
       strtolower($country)=="UK"){ 
           if ($vatnumber!=""){ 
               $isexempt = true; // Is exempt, has VAT/IVA number 
           }else{ 
               $isexempt = false;  // No VAT/IVA number, is charged 
           } 
   } else { 
       $isexempt = true; // Non-EU customers are always exempt 
   } 

   if ($isexempt) { 
       $table = "tblclients"; 
       $array = array( "taxexempt" => "on" ); 
       $where = "id='".$_SESSION["uid"]."'"; 
       update_query($table,$array,$where); 
   } 
}

Link to comment
Share on other sites

This is what I currenty have working on our site, except the VAT# is not stored the same way. What's needed to check that number is valid is in the function in my message above.

Questions left on that subject now would be to check that number is still there and valid on every order as I guess this only occurs on registration now, and then make it possible for 1 client to have several companies in his contacts and hence different VAT#s ?

Link to comment
Share on other sites

Questions left on that subject now would be to check that number is still there and valid on every order as I guess this only occurs on registration now, and then make it possible for 1 client to have several companies in his contacts and hence different VAT#s ?

Just because of this I suggested that WHMCS track changes of custom fields...

 

http://forum.whmcs.com/showthread.php?t=8051&highlight=custom+fields

 

But nobody second this :( and it would be realy nice that WHMCS keeps track of VAT numbers (custom fields changes) if someone changes company that I can restore old company information, and I can't do that without VAT.

Link to comment
Share on other sites

if someone changes company that I can restore old company information, and I can't do that without VAT.

 

the VAT number you store *probably* shouldnt be edittable by the client, especially as you have a legal responsibility to verify it, and report transactions using it - so having two fields is necessary - the one you actually use, and the one the client tells you ...

 

However yes, I agree, WHMCS should in the changes emails list the custom fields tat have changed as well.

Link to comment
Share on other sites

corrected for typos...

 

make it possible for 1 client to have several companies in his contacts and hence different VAT#s ?

They should be separate "clients" as far as WHMCS is concerned, otherwise you're potentially setting yourself up as a huge centre for VAT-fraud :) A company either is registered for VAT or it's not, it doenst matter how many "contacts" you ave at that company...

Link to comment
Share on other sites

  • 3 months later...

In case anyone is interested here is a working function for checking the validity of a vat number with the EU web service, it's a bit of a mashup of other scripts but it seems to work well.

 



<?php
class checkVat {
 var $countryCode;
 var $vatNumber;
 function __construct($cc, $vat) {
   $this->countryCode = $cc;
   $this->vatNumber = $vat;
   }
}

function checkVat($vat) {
$vat = trim($vat);
$vat = str_replace(" ","",$vat);
$vat = str_replace("-","",$vat);

$vat_prefix = substr($vat, 0, 2);
$vat_num = substr($vat, 2);

$wsdl = 'http://ec.europa.eu/taxation_customs/vies/api/checkVatPort?wsdl';
$vies = new SoapClient($wsdl);
/*
var_dump($vies->__getFunctions());
var_dump($vies->__getTypes());
*/
$nii = new checkVat($vat_prefix, $vat_num);

try {$ret = $vies->checkVat($nii);}
catch (SoapFault $e){
  $ret = $e->faultstring;
  $regex = '/\{ \'([A-Z_]*)\' \}/';
  $n = preg_match($regex, $ret, $matches);
  $ret = $matches[1];
  $faults = array(
	'INVALID_INPUT'       => 'The provided CountryCode is invalid or the VAT number is empty',
	'SERVICE_UNAVAILABLE' => 'The SOAP service is unavailable, try again later',
	'MS_UNAVAILABLE'      => 'The Member State service is unavailable, try again later or with another Member State',
	'TIMEOUT'             => 'The Member State service could not be reached in time, try again later or with another Member State',
	'SERVER_BUSY'         => 'The service cannot process your request. Try again later.'
	);
  $ret = $faults[$ret];
  }


/*
Return results
0 = Invalid VAT number
1 = Valid VAT number
2 = Communication error
*/

if (!is_object($ret)){ // An error occurred
	return 2;  // SOAP ERROR
} else {

	foreach ($ret as $k => $v) {
		if ($k == "valid"){
			if ($v==1){
				return 1; // Valid VAT
			} else {
				return 0; // invalid VAT
			}
		} 
	}
}
}
print_r(checkVat('GB523239269'));
?>


Link to comment
Share on other sites

  • 4 weeks later...
  • 6 months later...
I thought we only had to charge VAT to EU member states and the rest we didn't, perhaps I'm confused about this because we have only just become VAT registered. I have just put into whmcs to charge VAT on the 25 member states, is that not right?

 

I deal with VAT all the time, and my accountants have confirmed with me that all businesses and individuals residing in the EU must pay VAT. If you are from the EU and you purchase a product or service from a company in a particular country, then you must pay the VAT rate of that country.

 

So if you're in the EU and you purchase something from, lets say, Holland, you will pay 19% VAT. If your business purchases something, you will still have to pay VAT unless your business is VAT registered.

 

Important: Do not become VAT registered if your business is not earning £61,000 per year, even if you wish to escape all the VAT on purchases your business will make. You will lose far more money being VAT registered.

 

Obviously, if you reside in the EU and you purchase something from a company outside of the EU, you are not liable to pay for any tax whatsoever.

 

Hopefully that has cleared things up as there are many people who do not understand about taxation.

Link to comment
Share on other sites

  • 3 months later...
Obviously, if you reside in the EU and you purchase something from a company outside of the EU, you are not liable to pay for any tax whatsoever.

 

Hopefully that has cleared things up as there are many people who do not understand about taxation.

 

Let me give you the advise of getting an accountant before you got to go to jail.

 

VAT is always payable but you balance in and outgoing VAT and pay the difference as a company. That why VAT is omitted on intraEU purchases by companies.

Link to comment
Share on other sites

Let me give you the advise of getting an accountant before you got to go to jail.

 

VAT is always payable but you balance in and outgoing VAT and pay the difference as a company. That why VAT is omitted on intraEU purchases by companies.

 

He is totally correct, you do not pay TAX if ordering from outside of the EU, if a member of the EU. Of course you might be subject to customs duty if importing goods, but not on services over the net.

Link to comment
Share on other sites

If you want to get completely confused, look up the recent changes to taxation within the EU, and how it relates to electronically provided services!!!

 

We spent several days trying to fathom it out, and that was with the help of our accountant.

 

Basically, it all boils down to the definition of where the service is delivered... In some instances, the service will be classed as being delivered where you are (or your datacentre is), whilst other services are classed as being 'delivered' where the customer is.

 

And according to the recent changes, you charge tax at the rate applicable in the country where the service is delivered.... yeah, confusion city, lol.

 

The saving grace is down to the fact that it is the CLIENTS responsibility to supply details, such as tax etc, AND to specify whether it is a business or personal account or not.

 

If a client signs up under a personal account, and does not specify a vat number, its tuff luck basically.

Link to comment
Share on other sites

He is totally correct, you do not pay TAX if ordering from outside of the EU, if a member of the EU. Of course you might be subject to customs duty if importing goods, but not on services over the net.

 

No - He is not. Even if not charged you need to account for it.

 

"This means that UK businesses receiving electronically supplied services from non-UK suppliers will have to account for the VAT using the reverse charge procedure.

 

Source - http://customs.hmrc.gov.uk/channelsPortalWebApp/channelsPortalWebApp.portal?_nfpb=true&_pageLabel=pageVAT_ShowContent&id=HMCE_CL_000902&propertyType=document

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated