Search by

sugarcommerce / countries

arraypress

ISO 3166-1 country data: codes, names, emoji flags, EU membership, sanctioned and elevated-risk territories. Zero dependencies.

Package info

github.com/SugarCommerce/countries

Homepage

Issues

pkg:composer/sugarcommerce/countries

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

1.2.0 2026-10-22 09:17 UTC

This package is auto-updated.

Last update: 2026-10-22 15:44:05 UTC


README

ISO 3166-1 country data: codes, names, emoji flags, EU membership, and sanctioned or elevated-risk territories. Zero dependencies.

Why

Every commerce application needs a country dropdown, a "is this the EU" check for VAT, and โ€” sooner than most people expect โ€” a sanctions check before taking money. That is usually three separate half-lists scattered across the codebase, each drifting out of date on its own schedule.

All 250 ISO 3166-1 entries live in one class constant, so lookups are array reads with no file I/O and no parsing.

Features

  • ๐ŸŒ All 250 territories โ€” the full ISO 3166-1 alpha-2 list, not the 190-odd everyone remembers.
  • ๐Ÿ‡ช๐Ÿ‡บ EU membership โ€” the 27, post-Brexit, for VAT and reverse-charge decisions.
  • ๐Ÿšซ Sanctions and risk flags โ€” comprehensively-sanctioned territories, and FATF elevated-risk jurisdictions.
  • ๐Ÿณ๏ธ Emoji flags โ€” derived from the code via regional indicators, so no image assets.
  • ๐Ÿ”Ž Search and reverse lookup โ€” name to code, and substring search for a picker.
  • ๐Ÿงผ Input sanitising โ€” normalises casing and rejects anything that isn't a real code.

Requirements

PHP 8.5+

Installation

composer require sugarcommerce/countries

Usage

use SugarCommerce\Countries\Country;

Country::name( 'DE' );          // 'Germany'
Country::code( 'Germany' );     // 'DE'
Country::flag( 'DE' );          // ๐Ÿ‡ฉ๐Ÿ‡ช
Country::exists( 'ZZ' );        // false
Country::sanitize( ' de ' );    // 'DE', or null if not a country

Building a picker

foreach ( Country::all() as $code => $name ) {
    echo '<option value="' . $code . '">' . Country::flag( $code ) . ' ' . $name . '</option>';
}

Country::search( 'ital' );      // [ 'IT' => 'Italy' ]
Country::search( 'united', 3 ); // capped

VAT and the EU

if ( Country::is_eu( $customer_country ) ) {
    // Reverse charge applies when the customer has a VAT number and
    // isn't in your own country.
}

Country::eu();                  // the 27, as code => name

Risk

Country::is_sanctioned( 'KP' );   // comprehensively sanctioned
Country::is_high_risk( 'MM' );    // FATF elevated monitoring

is_sanctioned() covers the territories under comprehensive embargo. It is a coarse first gate for "should this checkout proceed at all", not a compliance product โ€” it does not screen names, and it does not know about sectoral or entity-level restrictions. Where the money moves through Stripe, their own screening still applies on top.

is_high_risk() is the FATF grey and black lists โ€” a signal for elevated fraud scrutiny, not a reason to refuse.

Both are point-in-time lists that change by political decision. Pin the version you have reviewed.

Testing

composer install
composer test

26 tests, 321 assertions โ€” including that every code maps to a name and back, every flag renders as two regional indicators, and the EU list holds exactly 27 members.

License

GPL-2.0-or-later