Skip to content

Commit

Permalink
Support 16 digit Indonesian NPWP numbers
Browse files Browse the repository at this point in the history
The Indonesian NPWP is being switched from 15 to 16 digits. The number
is now the NIK for Indonesian citizens and the old format with a leading
0 for others (organisations and non-citizens).

See https://www.grantthornton.co.id/insights/global-insights1/updates-regarding-the-format-of-indonesian-tax-id-numbers/

Closes #432
  • Loading branch information
arthurdejong committed Jun 23, 2024
1 parent 1da003f commit e951dac
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
24 changes: 19 additions & 5 deletions stdnum/id/npwp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# coding: utf-8
#
# Copyright (C) 2020 Leandro Regueiro
# Copyright (C) 2024 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
Expand All @@ -24,11 +25,15 @@
individuals (families) by the Indonesian Tax Office after registration by the
tax payers.
The number consists of 15 digits of which the first 2 denote the type of
The number consists of 16 digits and is either a NIK (Nomor Induk Kependudukan)
or a number that starts with a 0, followed by 2 digits that denote the type of
entity, 6 digits to identify the tax payer, a check digit over the first 8
digits followed by 3 digits to identify the local tax office and 3 digits for
branch code.
This module also accepts the old 15 digit format which is just the 16 digit
format without the starting 0.
More information:
* https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Indonesia-TIN.pdf
Expand All @@ -49,6 +54,7 @@

from stdnum import luhn
from stdnum.exceptions import *
from stdnum.id import nik
from stdnum.util import clean, isdigits


Expand All @@ -64,12 +70,20 @@ def compact(number):
def validate(number):
"""Check if the number is a valid Indonesia NPWP number."""
number = compact(number)
if len(number) != 15:
raise InvalidLength()
if not isdigits(number):
raise InvalidFormat()
luhn.validate(number[:9])
return number
if len(number) == 15:
# Old 15 digit format
luhn.validate(number[:9])
return number
if len(number) == 16:
# New format since 2024: either a NIK (for Indonesian citizens) or
# the old number with a 0 at the beginning
if not number.startswith('0'):
return nik.validate(number)
luhn.validate(number[:10])
return number
raise InvalidLength()


def is_valid(number):
Expand Down
11 changes: 11 additions & 0 deletions tests/test_id_npwp.doctest
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
test_id_npwp.doctest - more detailed doctests for stdnum.id.npwp module

Copyright (C) 2020 Leandro Regueiro
Copyright (C) 2024 Arthur de Jong

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -49,6 +50,16 @@ Traceback (most recent call last):
InvalidChecksum: ...


Since 2024 the numbers have been changed to a 16 digit format. They can
either be a NIK (for Indonesian citizens) or a 0 followed by the original
15-digit number.

>>> npwp.validate('3171011708450001') # NIK
'3171011708450001'
>>> npwp.validate('083.132.665.7-201.000') # extra 0 prepended
'0831326657201000'


These have been found online and should all be valid numbers.

>>> numbers = '''
Expand Down

0 comments on commit e951dac

Please sign in to comment.