diff --git a/README.md b/README.md
index f651dc80a07b76adc2f7a9d2c1fd9c121a0374e1..3fcd7606354ef9799f2a92f26b9be1d92d67514f 100644
--- a/README.md
+++ b/README.md
@@ -372,7 +372,7 @@ Please see the [source code for each lookup](https://github.com/alexreisner/geoc
 Or, to search within a particular region with Google:
 
     Geocoder.search("...", :params => {:region => "..."})
-    
+
 Or, to use parameters in your model:
 
     class Venue
@@ -382,7 +382,7 @@ Or, to use parameters in your model:
 
       # store the fetched address in the full_address attribute
       reverse_geocoded_by :latitude, :longitude, :address => :full_address, :params => {:region => "..."}
-    end 
+    end
 
 
 ### Configure Multiple Services
@@ -852,6 +852,16 @@ This uses the PostcodeAnywhere UK Geocode service, this will geocode any string
 * **Documentation**: http://ip-api.com/docs/
 * **Terms of Service**: https://signup.ip-api.com/terms
 
+#### DB-IP.com (`:db_ip_com`)
+
+* **API key**: required
+* **Quota**: 2,500/day (with free API Key, 50,000/day and up for paid API keys)
+* **Region**: world
+* **SSL support**: yes (with paid API keys - see https://db-ip.com/api/)
+* **Languages**: English (English with free API key, multiple languages with paid API keys)
+* **Documentation**: https://db-ip.com/api/doc.php
+* **Terms of Service**: https://db-ip.com/tos.php
+
 ### IP Address Local Database Services
 
 #### MaxMind Local (`:maxmind_local`) - EXPERIMENTAL
diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb
index bc0882652a4ae0e62c97baeeb4954c915c07921e..2d71041905c289b5990bfe0b3fa4b4b335a3d28a 100644
--- a/lib/geocoder/lookup.rb
+++ b/lib/geocoder/lookup.rb
@@ -70,7 +70,8 @@ module Geocoder
         :pointpin,
         :maxmind_geoip2,
         :ipinfo_io,
-        :ipapi_com
+        :ipapi_com,
+        :db_ip_com
       ]
     end
 
diff --git a/lib/geocoder/lookups/db_ip_com.rb b/lib/geocoder/lookups/db_ip_com.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8a03215757ead93bba3a68e1e49877fc47162189
--- /dev/null
+++ b/lib/geocoder/lookups/db_ip_com.rb
@@ -0,0 +1,45 @@
+require 'geocoder/lookups/base'
+require 'geocoder/results/db_ip_com'
+
+module Geocoder::Lookup
+  class DbIpCom < Base
+
+    def name
+      'DB-IP.com'
+    end
+
+    def supported_protocols
+      [:https, :http]
+    end
+
+    def required_api_key_parts
+      ['api_key']
+    end
+
+    def query_url(query)
+      query_params = if query.options[:params]
+        "?#{url_query_string(query)}"
+      end
+
+      "#{protocol}://api.db-ip.com/v2/#{configuration.api_key}/#{query.sanitized_text}#{query_params}"
+    end
+
+    private
+
+    def results(query)
+      return [] unless doc = fetch_data(query)
+
+      if doc['error']
+        if doc['error'] == 'invalid API key'
+          raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, 'Invalid DB-IP API key.')
+        else
+          Geocoder.log(:warn, "DB-IP Geocoding API error: #{doc['error']}.")
+        end
+
+        return []
+      else
+        return [ doc ]
+      end
+    end
+  end
+end
diff --git a/lib/geocoder/results/db_ip_com.rb b/lib/geocoder/results/db_ip_com.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2328bd0dd9b2d1dc69029f134557744900ffc9cc
--- /dev/null
+++ b/lib/geocoder/results/db_ip_com.rb
@@ -0,0 +1,63 @@
+require 'geocoder/results/base'
+
+module Geocoder::Result
+  class DbIpCom < Base
+
+    def coordinates
+      ['latitude', 'longitude'].map{ |coordinate_name| @data[coordinate_name] }
+    end
+
+    def address(format = :full)
+      s = state_code.to_s == "" ? "" : ", #{state_code}"
+      "#{city}#{s} #{zip_code}, #{country_name}".sub(/^[ ,]*/, "")
+    end
+
+    def city
+      @data['city']
+    end
+
+    def district
+      @data['district']
+    end
+
+    def state_code
+      @data['stateProv']
+    end
+    alias_method :state, :state_code
+
+    def zip_code
+      @data['zipCode']
+    end
+    alias_method :postal_code, :zip_code
+
+    def country_name
+      @data['countryName']
+    end
+    alias_method :country, :country_name
+
+    def country_code
+      @data['countryCode']
+    end
+
+    def continent_name
+      @data['continentName']
+    end
+    alias_method :continent, :continent_name
+
+    def continent_code
+      @data['continentCode']
+    end
+
+    def time_zone
+      @data['timeZone']
+    end
+
+    def gmt_offset
+      @data['gmtOffset']
+    end
+
+    def currency_code
+      @data['currencyCode']
+    end
+  end
+end
diff --git a/test/fixtures/db_ip_com_23_255_240_0 b/test/fixtures/db_ip_com_23_255_240_0
new file mode 100644
index 0000000000000000000000000000000000000000..035da4234b2890b73c7e307c7cc73ed1fc8c4a1e
--- /dev/null
+++ b/test/fixtures/db_ip_com_23_255_240_0
@@ -0,0 +1,27 @@
+{
+  "ipAddress": "23.255.240.0",
+  "continentCode": "NA",
+  "continentName": "North America",
+  "countryCode": "US",
+  "countryName": "United States",
+  "currencyCode": "USD",
+  "phonePrefix": "1",
+  "languages": [
+    "en-US",
+    "es-US",
+    "haw",
+    "fr"
+  ],
+  "stateProv": "California",
+  "district": "Santa Clara County",
+  "city": "Mountain View",
+  "geonameId": 5375480,
+  "zipCode": "94043",
+  "latitude": 37.3861,
+  "longitude": -122.084,
+  "gmtOffset": -7,
+  "timeZone": "America\/Los_Angeles",
+  "isp": "Google Fiber Inc.",
+  "linkType": "fttx",
+  "organization": "Google Fiber Inc."
+}
\ No newline at end of file
diff --git a/test/fixtures/db_ip_com_invalid_key b/test/fixtures/db_ip_com_invalid_key
new file mode 100644
index 0000000000000000000000000000000000000000..91cab5ee4f73a4ccd51b3d3a7f6528d37038ca6e
--- /dev/null
+++ b/test/fixtures/db_ip_com_invalid_key
@@ -0,0 +1 @@
+{"error":"invalid API key"}
\ No newline at end of file
diff --git a/test/fixtures/db_ip_com_no_results b/test/fixtures/db_ip_com_no_results
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/test/test_helper.rb b/test/test_helper.rb
index b51b77ea9053748a04a8cb7f6d84afcc557b06c3..55978055c8d8e55ce18fc692e4d933ad09f762c6 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -161,6 +161,14 @@ module Geocoder
       end
     end
 
+    require 'geocoder/lookups/db_ip_com'
+    class DbIpCom
+      private
+      def default_fixture_filename
+        "db_ip_com_23_255_240_0"
+      end
+    end
+
     require 'geocoder/lookups/google_premier'
     class GooglePremier
       private
diff --git a/test/unit/lookup_test.rb b/test/unit/lookup_test.rb
index 4fa3a28daa49bb1e427f3e7e5548094f4201cb98..8dcaf8047fa61f1d239a10d50eae2c63a5ba0571 100644
--- a/test/unit/lookup_test.rb
+++ b/test/unit/lookup_test.rb
@@ -117,6 +117,12 @@ class LookupTest < GeocoderTestCase
     assert_match "ak=MY_KEY", g.query_url(Geocoder::Query.new("Madison Square Garden, New York, NY  10001, United States"))
   end
 
+  def test_db_ip_com_api_key
+    Geocoder.configure(:api_key => "MY_KEY")
+    g = Geocoder::Lookup::DbIpCom.new
+    assert_match "\/MY_KEY\/", g.query_url(Geocoder::Query.new("232.65.123.94"))
+  end
+
   def test_pointpin_api_key
     Geocoder.configure(:api_key => "MY_KEY")
     g = Geocoder::Lookup::Pointpin.new
diff --git a/test/unit/lookups/db_ip_com_test.rb b/test/unit/lookups/db_ip_com_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..47fc26e68f3b3207628979e143451edf56359fa0
--- /dev/null
+++ b/test/unit/lookups/db_ip_com_test.rb
@@ -0,0 +1,64 @@
+# encoding: utf-8
+require 'test_helper'
+
+class DbIpComTest < GeocoderTestCase
+
+  def configure_for_free_api_access
+    Geocoder.configure(ip_lookup: :db_ip_com, db_ip_com: { api_key: 'MY_API_KEY' })
+    set_api_key!(:db_ip_com)
+  end
+
+  def configure_for_paid_api_access
+    Geocoder.configure(ip_lookup: :db_ip_com, db_ip_com: { api_key: 'MY_API_KEY', use_https: true })
+    set_api_key!(:db_ip_com)
+  end
+
+  def teardown
+    Geocoder::Configuration.instance.set_defaults
+  end
+
+  def test_no_results
+    configure_for_free_api_access
+    results = Geocoder.search('no results')
+    assert_equal 0, results.length
+  end
+
+  def test_result_on_ip_address_search
+    configure_for_free_api_access
+    result = Geocoder.search('23.255.240.0').first
+    assert result.is_a?(Geocoder::Result::DbIpCom)
+  end
+
+  def test_result_components
+    configure_for_free_api_access
+    result = Geocoder.search('23.255.240.0').first
+
+    assert_equal [37.3861, -122.084], result.coordinates
+    assert_equal 'Mountain View, California 94043, United States', result.address
+    assert_equal 'Mountain View', result.city
+    assert_equal 'Santa Clara County', result.district
+    assert_equal 'California', result.state_code
+    assert_equal '94043', result.zip_code
+    assert_equal 'United States', result.country_name
+    assert_equal 'US', result.country_code
+    assert_equal 'North America', result.continent_name
+    assert_equal 'NA', result.continent_code
+    assert_equal 'America/Los_Angeles', result.time_zone
+    assert_equal(-7, result.gmt_offset)
+    assert_equal 'USD', result.currency_code
+  end
+
+  def test_free_host_config
+    configure_for_free_api_access
+    lookup = Geocoder::Lookup::DbIpCom.new
+    query = Geocoder::Query.new("23.255.240.0")
+    assert_match 'http://api.db-ip.com/v2/MY_API_KEY/23.255.240.0', lookup.query_url(query)
+  end
+
+  def test_paid_host_config
+    configure_for_paid_api_access
+    lookup = Geocoder::Lookup::DbIpCom.new
+    query = Geocoder::Query.new("23.255.240.0")
+    assert_match 'https://api.db-ip.com/v2/MY_API_KEY/23.255.240.0', lookup.query_url(query)
+  end
+end