VAT - important change coming on 1/1/2015

General ShopSite user discussion

VAT - important change coming on 1/1/2015

Postby dgray » Fri Oct 18, 2013 10:20 am

On January first, 2015, EU VAT rules change for merchants supplying digital goods and services.

For B2C transactions into the EU, instead of charging tax according to the EU country where the merchant is located or registered, tax will be charged according to the EU country where the customer lives.

So a separate rate of tax will need to be charged, per EU member country.

Is Shopsite planning to update the VAT feature to reflect this?

~ David
dgray
 
Posts: 54
Joined: Fri Sep 08, 2006 9:06 am

Re: VAT - important change coming on 1/1/2015

Postby Jim » Mon Oct 21, 2013 10:09 am

The tax method "Use ZIP Code to determine sales tax" may be able to meet this need since you can set the tax rate for different locations based on the Postal Code of the location where the product is being shipped.

Do you have a link to a site that describes the proposed changes?
Jim
Site Admin
 
Posts: 4953
Joined: Fri Aug 04, 2006 1:42 pm
Location: Utah

Re: VAT - important change coming on 1/1/2015

Postby dgray » Mon Oct 21, 2013 12:15 pm

The option "Use Zip code" is US-centric, but I see it's possible to extend the number of codes. I don't think that can work without also specifying the country, since there would be large numbers of clashes with several countries that use similar 5-digit coding. Besides, I think each country just has one default rate, although some countries also have a few different rates for certain types of products. A simplistic way to do it would be to extend your "Countries" records to include a default tax rate field for each country and somewhere have a global option to say "Choose tax rate based on customer location (B2C) vs. Choose tax rate based on merchant location (B2B)". I only do B2C but any merchants mixing B2C and B2B sales into the EU would need a way to differentiate between the two types of customer.

If you google "VAT 2015 changes" you'll get lots of matches for this. It's EU wide, but all the english results will of course refer to the UK.

A typical overview of the situation is here: www.grant-thornton.co.uk/Global/Publication_pdf/VAT-changes-in-2015.pdf

A statement by the UK HMRC (IRS equivalent) is here: www.hmrc.gov.uk/budget2013/vat-place-supply-rules.pdf

Note that references to "e-Services" include things like apps, e-books, any digital download or online content. The EU-wide changes were allegedly prompted by a certain large online retailer of e-books that does over $5 billion annually in sales in the UK for example, yet pays virtually no corporation tax or VAT there, being headquatered in Luxembourg. So I think in other words, all the tax on all the company's sales in all 28 EU countries ends up going to Luxembourg!
dgray
 
Posts: 54
Joined: Fri Sep 08, 2006 9:06 am

Re: VAT - important change coming on 1/1/2015

Postby Jim » Tue Oct 22, 2013 2:16 pm

I have logged this as an issue to be looked into for a future version of ShopSite.
Jim
Site Admin
 
Posts: 4953
Joined: Fri Aug 04, 2006 1:42 pm
Location: Utah

Re: VAT - important change coming on 1/1/2015

Postby dgray » Mon Oct 20, 2014 3:21 pm

Time's almost out on this issue, do you know if any progress has been made? After 1/1/2015, any business (including US) selling digital goods to someone in the EU has to charge VAT at that customer's country's rate. So if the billing country is one of the 28 EU countries, the VAT rate of that EU country should be charged.
dgray
 
Posts: 54
Joined: Fri Sep 08, 2006 9:06 am

Re: VAT - important change coming on 1/1/2015

Postby dgray » Wed Jun 10, 2015 7:03 am

Since Shopsite hasn't (as yet) added support for the new EU VAT rules on digital goods, here is the tax api script I rolled back in January to cope with the EU VAT changes that came in force then. Thousands of micro businesses are struggling with this ruling, and either forced to stop selling to the EU, pay for an expensive third party solution, or switch to selling only via a marketplace portal, so I hope this helps someone. My implementation is quite limited, as I only sell digital downloads, but I hope it's useful anyhow. Note that to be compliant, you'll need to store and do your own geo-location on the purchaser's IP address, which is fortunately already available in the ShopSite order data. I'm doing the geolocation in my order processing when I download the orders, getting it from ipinfo.io It's an http get with format 'http://ipinfo.io/' + ip + '/country', which returns the 2-character ISO country code. One unexpected bonus of this api script is that the word "Tax" now changes to the more expected word "VAT" in the checkout, just for EU customers.

Note also that this particular script will only be useful to a digital business based in the EU as it only calculates EU VAT. If you are in the US, you'll need something that incorporates this plus your regular US local taxes, and will have to find your own solution. It's a testament to ShopSite's flexible framework that this was straightforward to implement without requiring changes. Here it is anyhow:

Code: Select all
#!/usr/local/bin/php -d max_input_vars=3000
<?php
// DPG: 1/1/2015: Tax API for new EU VAT. Digital B2C sales now require VAT rate per EU country.
// DPG: Based on http://www.sitekickr.com/snippets/php/shopsite-custom-shipping-module
// DPG: Thread http://support.shopsite.com/forums/viewtopic.php?f=1&t=6283&p=27619
// DPG: Put in public_html/cgi-bin/sc directory with 755 access.
// DPG: Specify name of file in ShopSite/Merchandising/Tax API
// DPG: Uses the same techniques as the Order API and Shipping API
// DPG: 4/11/2015 Added support for coupons

    // note - you need a CLI-enabled php binary, the usual /usr/bin/php may not work.
    // Ask your host about this
   
   // Define the EU countries and tax rates. No help from ShopSite here, so we need to
   // keep this updated manually when countries and tax rates change. The supplied country
   // appears to be ISO 2-char codes, not the strings in the "States and Countries" screen.
   // Test e.g. gdatax.php?country=GB&item_total=1&p1item_num=1&p1amount=15
   $euTax_array = array(
'AT' => 20,      // Austria
'BE' => 21,      // Belgium
'BG' => 20,      // Bulgaria
'HR' => 25,      // Croatia
'CY' => 19,      // Cyprus
'CZ' => 21,      // Czech Republic
'DK' => 25,      // Denmark
'EE' => 20,      // Estonia
'FI' => 24,      // Finland
'FR' => 20,      // France
'DE' => 19,      // Germany
'GR' => 23,      // Greece
'HU' => 27,      // Hungary
'IE' => 23,      // Ireland
'IT' => 22,      // Italy
'LV' => 21,      // Latvia
'LT' => 21,      // Lithuania
'LU' => 17,      // Luxembourg
'MT' => 18,      // Malta
'NL' => 21,      // Netherlands
'PL' => 23,      // Poland
'PT' => 23,      // Portugal
'RO' => 24,      // Romania
'SK' => 20,      // Slovakia
'SI' => 22,      // Slovenia
'ES' => 21,      // Spain
'SE' => 25,      // Sweden
'GB' => 20);   // United Kingdom

function MailDebug ()
{   // Function to mail me debug and error messages plus the shopsite params
global $params, $dbgmsg, $errmsg;
   
   $eparams = var_export($params,true);

   $message = "This is a message from the MyCompanyName Tax API script:
   
   Debug:
   $dbgmsg
   
   Errors:
   $errmsg
   
   Shopsite params:
   $eparams
   
   End of message.";   
   mail("MyEmailAddress","Tax API message",$message, "From: MyCompanyName Tax API <MyEmailAddress>");
}

function Dbg ($s)
{   // Function to add a new dbg msg to global $dbgmsg
global $dbgmsg;
   $dbgmsg = $dbgmsg.$s."\n";
}

function Err ($s)
{   // Function to add a new error msg to global $errmsg
global $errmsg;
   $errmsg = $errmsg.$s."\n";
}

   // Following needed whenever outputting data, avoids output compression
    ini_set('zlib.output_compression', 'Off');

    // Here's the difference, we need to pull parameters from STDIN
    $query_string = trim(fgets(STDIN));
    parse_str($query_string, $params);

    // We'll load these into request variables, so we can test this script from a browser
    if (!isset($_REQUEST['country'])) {
      $_REQUEST['country'] = $params['country'];
      $_REQUEST['item_total'] = $params['item_total'];
      $_REQUEST['coupon_total'] = $params['coupon_total'];

      for($i = 1; $i <= $params['item_total']; $i++) {
         $_REQUEST['p' . $i . 'item_num'] = $params['p' . $i . 'item_num'];
         $_REQUEST['p' . $i . 'amount']   = $params['p' . $i . 'amount'];
      }
      for($i = 1; $i <= $params['coupon_total']; $i++) {
         $_REQUEST['c' . $i . 'amount']   = $params['c' . $i . 'amount'];
      }
    }

    // If country is in the EU, use that country's VAT rate, else zero for everyone else
    $taxRate = 0;
   $isEU = array_key_exists($_REQUEST['country'], $euTax_array);
   if ($isEU) {
      $taxRate = $euTax_array[$_REQUEST['country']] / 100.0;
      Dbg ("EU Tax rate set: " . $_REQUEST['country'] . " $taxRate");
   }

   // Calculate the total tax
    $total_tax = 0;
   $tax_name = "";
    $productCount = $_REQUEST['item_total'];
    $couponCount  = $_REQUEST['coupon_total'];
   if ($isEU) {
      $tax_name = "tax_name=VAT\n";      // Change tax name to VAT if EU country
      for($i = 1; $i <= $productCount; $i++) {
         $total_tax += ($_REQUEST['p' . $i . 'amount'] * $taxRate);
      }
      for($i = 1; $i <= $couponCount; $i++) {
         $total_tax += ($_REQUEST['c' . $i . 'amount'] * $taxRate);
      }
    }

   // Return the tax information to ShopSite
   $taxOut =
      "taxapi_status=success\n" .
      sprintf ("total_tax=%0.2f\n", $total_tax) .
      $tax_name .
      "product_count=$productCount\n";
   for($i = 1; $i <= $productCount; $i++) {
      $taxOut = $taxOut . 'p' . $i . 'item_num=' . $_REQUEST["p" . $i . "item_num"] . "\n";
      $taxOut = $taxOut . 'p' . $i . 'tax_rate=' . $taxRate . "\n";
   }
   
//   Dbg ($taxOut);
//   MailDebug ();

   echo $taxOut;
?>
dgray
 
Posts: 54
Joined: Fri Sep 08, 2006 9:06 am


Return to User Forum

Who is online

Users browsing this forum: No registered users and 33 guests

cron