Skip to content

[MINOR] Add JP Regime#729

Open
rafaharo wants to merge 4 commits intoinvopop:mainfrom
rafaharo:jp_regime
Open

[MINOR] Add JP Regime#729
rafaharo wants to merge 4 commits intoinvopop:mainfrom
rafaharo:jp_regime

Conversation

@rafaharo
Copy link
Copy Markdown

@rafaharo rafaharo commented Feb 24, 2026

Summary

  • Adds a new tax regime for Japan (JP) implementing the Japanese Consumption Tax (JCT), Withholding Income Tax, and the Qualified Invoice System (QIS).
  • Added a new README.md describing a tep by step process to add new regimes

Tax Categories

  • Consumption Tax (JCT) — Standard rate at 10% and reduced rate at 8% (food/beverages, newspapers), with full historical rates back to the original 3% in 1989.
  • Withholding Income Tax (源泉徴収) — Professional rates at 10.21% (includes 2.1% reconstruction surtax) and 20.42% for amounts over ¥1M, with historical rates.

Tax Identity

  • Validates 13-digit Corporate Numbers (法人番号) issued by the National Tax Agency, including check digit verification.

Qualified Invoice System (QIS)

  • Models the Invoice Registration Number (T + 13 digits) as an organization identity (jp-invoice-registration-number), required since October 2023 for input tax credit claims.

Scenarios

  • Reverse Charge (reverse-charge) — Adds legal note for reverse charge mechanism on cross-border B2B services.
  • Simplified Invoice (simplified) — Supports simplified invoices for transactions under ¥10,000.

Corrections

  • Supports credit and debit notes via the credit-note and debit-note extension types.

Examples

  • invoice-jp-jp.yaml — Standard domestic B2B invoice
  • invoice-jp-freelance.yaml — Freelancer invoice with withholding tax
  • invoice-jp-reverse-charge.yaml — Cross-border reverse charge invoice
  • invoice-jp-simplified.yaml — Simplified invoice

Files Added

Path Description
regimes/jp/jp.go Regime definition, init, normalize, validate
regimes/jp/tax_categories.go JCT and withholding tax category definitions
regimes/jp/tax_identity.go Corporate number normalization and validation
regimes/jp/scenarios.go Reverse charge and simplified invoice scenarios
regimes/jp/invoices.go Invoice-level validation
regimes/jp/identities.go Organization identity types (invoice registration number)
regimes/jp/README.md Regime documentation
regimes/jp/*_test.go Tests for all components
examples/jp/*.yaml Example invoices with generated JSON output
data/regimes/jp.json Generated regime data

Test plan

  • go test ./regimes/jp/... passes
  • go test ./... passes (no regressions)
  • Example YAML files calculate and validate correctly
  • Tax identity validation covers valid/invalid corporate numbers
  • Withholding tax applies correctly on freelancer invoices
  • Reverse charge scenario adds appropriate legal notes

Pre-Review Checklist

  • Opened this PR as a draft
  • Read the CONTRIBUTING.md guide.
  • Performed a self-review of my code.
  • Added thorough tests with at least 90% code coverage.
  • Modified or created example GOBL documents to show my changes in use, if appropriate.
  • Added links to the source of the changes in tax regimes or addons, either structured or in the comments.
  • Run go generate . to ensure that the Schemas and Regime data are up to date.
  • Reviewed and fixed all linter warnings.
  • Been obsessive with pointer nil checks to avoid panics.
  • Updated the CHANGELOG.md with an overview of my changes.
  • Requested a review from Copilot and fixed or dismissed (with a reason) all the feedback raised.

Only after checking off all the previous items:

  • Marked this PR as ready for review and requested one from @samlown.

@rafaharo rafaharo marked this pull request as ready for review February 24, 2026 11:42
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 92.92035% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.86%. Comparing base (8ca0f6c) to head (81b4597).

Files with missing lines Patch % Lines
regimes/jp/tax_identity.go 87.87% 2 Missing and 2 partials ⚠️
regimes/jp/identities.go 86.66% 1 Missing and 1 partial ⚠️
regimes/jp/invoices.go 91.30% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main     #729    +/-   ##
========================================
  Coverage   92.86%   92.86%            
========================================
  Files         331      335     +4     
  Lines       17260    17373   +113     
========================================
+ Hits        16029    16134   +105     
- Misses        867      871     +4     
- Partials      364      368     +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Collaborator

@samlown samlown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! Very difficult regime to tackle :-) A few changes requested to be more aligned with existing regimes, or at least, where we want to go. I'd reconsider using the VAT code, it looks like Japan uses something else, and I'd double check the reverse-charge usage.

Comment thread regimes/jp/invoices.go
return validation.ValidateStruct(p,
validation.Field(&p.TaxID,
validation.Required,
tax.RequireIdentityCode,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The simplified tag is normally only used for B2C scenarios and not the type of issuing party. Do Japanese entities need to include some kind of ID in invoices even if not registered for VAT? That determines what validations should take place.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I think enforcing the tax ID could make sense for QIS registered entities, but for a simplified invoice, it probably doesn't make sense to enforce the issuer to have a registration number. So what about having a simplified tag for B2C scenarios and create another custom tag for QIS something like qualified or qis?

Comment thread regimes/jp/jp.go
Comment on lines +25 to +26
TaxRatePro cbc.Key = "pro" // Professional services (≤ ¥1,000,000)
TaxRateProOver cbc.Key = "pro-over" // Professional services (> ¥1,000,000)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did experiment with withholding/retained tax rates, but recently this is something we try to avoid and just let the user put in what makes sense for them. It avoids hard to understand keys like "pro-over", whose meaning is not obvious at first glance.

Comment thread regimes/jp/jp.go
Name: i18n.String{
i18n.EN: "Japan",
i18n.JA: "日本",
},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to have the key details from the README here in the description.

Comment thread regimes/jp/README.md
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think most of the details here can be added to the regime description and comments.

Comment thread regimes/jp/scenarios.go
Note: &tax.ScenarioNote{
Key: org.NoteKeyLegal,
Src: tax.TagReverseCharge,
Text: "Reverse Charge: The recipient is liable for the consumption tax on this transaction",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no JP translation required here? Does JP actually support Reverse Charge? Would be useful to have comments indicating the source of details.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @samlown. Thanks for reviewing the PR!

For this specific scenario, I was trying to understand how they apply at other countries to check if it could be applicable for JP. As far as I understood, Japan does have a reverse charge mechanism, but it's quite limited in scope compared to EU-style reverse charge. It applies specifically to cross-border digital services when a foreign provider sells digital services to a Japanese business.

You are right a source is missing. Not sure if you understand the same than me for example from this link: https://www.nta.go.jp/english/taxes/consumption_tax/cross-kokugai-en.pdf#:~:text=Under%20Consumption%20Tax%20Act%2C%20when%20a%20business,receives%20electronic%20services%20from%20a%20foreign%20business.

These concepts are somehow new to me. To keep it simple I can remove this tag for now. wdyt?

// Consumption Tax (消費税)
//
{
Code: tax.CategoryVAT,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is VAT the correct code here? The key detail with VAT is that expenses can be claimed back, a consumption or sales tax cannot.

URL: "https://taxsummaries.pwc.com/japan/corporate/withholding-taxes",
},
},
Rates: []*tax.RateDef{
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As stated earlier, I don't think I'd worry about the income tax rates, its usually easier just to enter the values manually.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I will remove the support for withholding taxes

Comment thread regimes/README.md
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put this in a separate PR to discuss independently.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive support for the Japanese tax regime (JP) to GOBL, implementing Japan's Consumption Tax (JCT), Withholding Income Tax system, and the Qualified Invoice System (QIS). The implementation follows established GOBL patterns and includes extensive test coverage, documentation, and working examples.

Changes:

  • Added complete Japanese tax regime with Consumption Tax (10% standard, 8% reduced) and Withholding Income Tax (10.21% and 20.42% rates including reconstruction surtax)
  • Implemented Corporate Number validation with checksum verification and Invoice Registration Number support for the Qualified Invoice System
  • Created comprehensive documentation in regimes/README.md providing step-by-step guide for adding new tax regimes

Reviewed changes

Copilot reviewed 21 out of 26 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
regimes/regimes.go Registers JP regime via blank import
regimes/jp/jp.go Main regime definition with Normalize and Validate functions
regimes/jp/tax_categories.go Defines Consumption Tax and Withholding Income Tax categories with historical rates
regimes/jp/tax_identity.go Corporate Number validation with checksum algorithm
regimes/jp/identities.go Invoice Registration Number identity type
regimes/jp/invoices.go Invoice-level validation requiring supplier tax ID (except for simplified invoices)
regimes/jp/scenarios.go Reverse charge and simplified invoice scenarios
regimes/jp/*_test.go Comprehensive test coverage for all components
regimes/jp/README.md Detailed regime documentation with tax system explanations
regimes/README.md New comprehensive guide for creating tax regimes
examples/jp/*.yaml Four example invoices demonstrating standard, freelance, reverse charge, and simplified scenarios
examples/jp/out/*.json Generated JSON output for all example invoices
data/regimes/jp.json Generated regime data
data/schemas/tax/regime-code.json Updated regime code schema
CHANGELOG.md Updated with JP regime addition
.gitignore Added .idea directory for JetBrains IDEs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread regimes/jp/README.md
@@ -0,0 +1,68 @@
# GOBL Japan Tax Regime — `JP`

Japan's tax regime for GOBL covering the Consumption Tax, Withholding Incom and the Qualified Invoice System.
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a typo in "Withholding Incom" which should be "Withholding Income Tax". Also, there are extra spaces before "and".

Suggested change
Japan's tax regime for GOBL covering the Consumption Tax, Withholding Incom and the Qualified Invoice System.
Japan's tax regime for GOBL covering the Consumption Tax, Withholding Income Tax and the Qualified Invoice System.

Copilot uses AI. Check for mistakes.
Comment thread regimes/jp/README.md

- [EU-Japan Centre - Qualified Invoice System](https://www.eu-japan.eu/qualified-invoice-system)
- [Qualified Invoice System Instructions](https://www.nta.go.jp/taxes/shiraberu/zeimokubetsu/shohi/keigenzeiritsu/pdf/0024006-039_01.pdf)
-
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an incomplete bullet point with just a dash and no text. This appears to be an unfinished entry in the reference list.

Suggested change
-

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +20
{name: "valid sony corporate number", code: "5010401067252"}, // https://www.houjin-bangou.nta.go.jp/henkorireki-johoto.html?selHouzinNo=1130001011420
{name: "valid nintendo corporate number", code: "1130001011420"},
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment shows a URL for Nintendo's corporate number (1130001011420) but is placed on the line testing Sony's number (5010401067252). The URL should either be removed or corrected to match the Sony corporate number, or moved to the next line.

Suggested change
{name: "valid sony corporate number", code: "5010401067252"}, // https://www.houjin-bangou.nta.go.jp/henkorireki-johoto.html?selHouzinNo=1130001011420
{name: "valid nintendo corporate number", code: "1130001011420"},
{name: "valid sony corporate number", code: "5010401067252"},
{name: "valid nintendo corporate number", code: "1130001011420"}, // https://www.houjin-bangou.nta.go.jp/henkorireki-johoto.html?selHouzinNo=1130001011420

Copilot uses AI. Check for mistakes.
Comment thread regimes/README.md
Comment on lines +25 to +32
| `it` | Italy |
| `mx` | Mexico |
| `nl` | Netherlands |
| `pl` | Poland |
| `pt` | Portugal |
| `se` | Sweden |
| `sg` | Singapore |
| `us` | United States |
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JP regime should be added to the "Existing Regimes" table in the regimes/README.md file. It should be inserted in alphabetical order between IT (Italy) and MX (Mexico) as: | jp | Japan |

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants