From b91da4ff9624441d769c32978b52de6e1ffe21e7 Mon Sep 17 00:00:00 2001 From: Sam Lown Date: Wed, 5 Aug 2026 10:41:13 +0000 Subject: [PATCH 1/4] Preparing release 0.504.0 --- CHANGELOG.md | 2 ++ data/schemas/head/header.json | 2 +- version.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff38e7c54..838253c84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ## [Unreleased] +## [v0.504.0] + ### Added - `pay`: `IsIBAN` and `IsBIC` rules tests for bank details — the ISO 13616 structure with its ISO 7064 mod 97-10 check digits, and the ISO 9362 structure. Available to rule sets that need them; no core rule applies them. diff --git a/data/schemas/head/header.json b/data/schemas/head/header.json index b2ed6cbb5..632b6ab30 100644 --- a/data/schemas/head/header.json +++ b/data/schemas/head/header.json @@ -53,7 +53,7 @@ "from": { "$ref": "https://gobl.org/draft-0/cbc/uri", "title": "From", - "description": "From is the URI-form transport address of the envelope's issuer,\ne.g. \"gobl:samlown.example.com\" or\n\"iso6523-actorid-upis::9920:b123123123\"." + "description": "From is the URI-form transport address of the envelope's issuer,\ne.g. \"gobl:invoices.example.com\" or\n\"iso6523-actorid-upis::9920:b123123123\"." }, "to": { "$ref": "https://gobl.org/draft-0/cbc/uri", diff --git a/version.go b/version.go index f78297a86..10afd1ad4 100644 --- a/version.go +++ b/version.go @@ -8,7 +8,7 @@ import ( type Version string // VERSION is the current version of the GOBL library -const VERSION Version = "v0.503.0" +const VERSION Version = "v0.504.0" // Semver parses and returns semver func (v Version) Semver() *semver.Version { From fb7fb57497d5eca1d02f275ae325b95fde21e68c Mon Sep 17 00:00:00 2001 From: Sam Lown Date: Wed, 5 Aug 2026 13:47:49 +0000 Subject: [PATCH 2/4] Add credit transfer clearing code --- bill/payment_test.go | 2 +- data/schemas/pay/credit-transfer.json | 13 +++++++++---- pay/instructions.go | 9 ++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/bill/payment_test.go b/bill/payment_test.go index 141347b35..21965fb07 100644 --- a/bill/payment_test.go +++ b/bill/payment_test.go @@ -551,7 +551,7 @@ func TestPaymentLegacyMethodMigration(t *testing.T) { assert.Equal(t, pay.MeansKeyCreditTransfer, pmt.Methods[0].Key) assert.Equal(t, "Wire transfer from BBVA", pmt.Methods[0].Description) require.NotNil(t, pmt.Methods[0].CreditTransfer) - assert.Equal(t, "ES1234567890123456789012", pmt.Methods[0].CreditTransfer.IBAN) + assert.Equal(t, cbc.Code("ES1234567890123456789012"), pmt.Methods[0].CreditTransfer.IBAN) } func TestPaymentFromToEndpoint(t *testing.T) { diff --git a/data/schemas/pay/credit-transfer.json b/data/schemas/pay/credit-transfer.json index 05254051b..4561b0131 100644 --- a/data/schemas/pay/credit-transfer.json +++ b/data/schemas/pay/credit-transfer.json @@ -6,20 +6,25 @@ "pay.CreditTransfer": { "properties": { "iban": { - "type": "string", + "$ref": "https://gobl.org/draft-0/cbc/code", "title": "IBAN", "description": "International Bank Account Number" }, "bic": { - "type": "string", + "$ref": "https://gobl.org/draft-0/cbc/code", "title": "BIC", "description": "Bank Identifier Code used for international transfers." }, "number": { - "type": "string", + "$ref": "https://gobl.org/draft-0/cbc/code", "title": "Number", "description": "Account number, if IBAN not available." }, + "clearing": { + "$ref": "https://gobl.org/draft-0/cbc/code", + "title": "Clearing Code", + "description": "National bank or branch clearing identifier, such as a Danish registration\nnumber, UK sort code, or US routing number." + }, "name": { "type": "string", "title": "Name", @@ -35,4 +40,4 @@ "description": "CreditTransfer contains fields that can be used for making payments via a bank transfer or wire." } } -} \ No newline at end of file +} diff --git a/pay/instructions.go b/pay/instructions.go index 364b8cbe6..aaf4d2830 100644 --- a/pay/instructions.go +++ b/pay/instructions.go @@ -72,11 +72,14 @@ type DirectDebit struct { // a bank transfer or wire. type CreditTransfer struct { // International Bank Account Number - IBAN string `json:"iban,omitempty" jsonschema:"title=IBAN"` + IBAN cbc.Code `json:"iban,omitempty" jsonschema:"title=IBAN"` // Bank Identifier Code used for international transfers. - BIC string `json:"bic,omitempty" jsonschema:"title=BIC"` + BIC cbc.Code `json:"bic,omitempty" jsonschema:"title=BIC"` // Account number, if IBAN not available. - Number string `json:"number,omitempty" jsonschema:"title=Number"` + Number cbc.Code `json:"number,omitempty" jsonschema:"title=Number"` + // National bank or branch clearing identifier, such as a Danish registration + // number, UK sort code, or US routing number. + Clearing cbc.Code `json:"clearing,omitempty" jsonschema:"title=Clearing Code"` // Name of the bank. Name string `json:"name,omitempty" jsonschema:"title=Name"` // Bank office branch address, not normally required. From 7b7779a7bdc8200b90b3fe794e6ee2c20c85740d Mon Sep 17 00:00:00 2001 From: Sam Lown Date: Wed, 5 Aug 2026 13:52:20 +0000 Subject: [PATCH 3/4] Test credit transfer code normalization --- pay/instructions_test.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pay/instructions_test.go b/pay/instructions_test.go index e71025688..e2d26d440 100644 --- a/pay/instructions_test.go +++ b/pay/instructions_test.go @@ -33,6 +33,34 @@ func TestInstructionsNormalize(t *testing.T) { }) } +func TestCreditTransferNormalize(t *testing.T) { + ct := &pay.CreditTransfer{ + IBAN: " DK50 0040 0440 1162 43 ", + BIC: " DABADKKK ", + Number: " 0440-116243 ", + Clearing: " 1234 ", + Name: "Example Bank", + } + + norm.Normalize(ct) + + assert.Equal(t, cbc.Code("DK50 0040 0440 1162 43"), ct.IBAN) + assert.Equal(t, cbc.Code("DABADKKK"), ct.BIC) + assert.Equal(t, cbc.Code("0440-116243"), ct.Number) + assert.Equal(t, cbc.Code("1234"), ct.Clearing) + assert.Equal(t, "Example Bank", ct.Name) + + data, err := json.Marshal(ct) + require.NoError(t, err) + assert.JSONEq(t, `{ + "iban": "DK50 0040 0440 1162 43", + "bic": "DABADKKK", + "number": "0440-116243", + "clearing": "1234", + "name": "Example Bank" + }`, string(data)) +} + func TestOnline(t *testing.T) { instr := &pay.Instructions{ Key: pay.MeansKeyOnline, From 4897d4c425907e8f2bf80e2bfd49a74354629de3 Mon Sep 17 00:00:00 2001 From: Sam Lown Date: Wed, 5 Aug 2026 14:02:34 +0000 Subject: [PATCH 4/4] Document credit transfer clearing codes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff38e7c54..a326accc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Added +- `pay`: `CreditTransfer` now supports a `clearing` code for national bank or branch identifiers such as Danish registration numbers, UK sort codes, and US routing numbers. Its `iban`, `bic`, `number`, and `clearing` identifiers use the flexible `cbc.Code` type; the descriptive bank `name` remains a string. - `pay`: `IsIBAN` and `IsBIC` rules tests for bank details — the ISO 13616 structure with its ISO 7064 mod 97-10 check digits, and the ISO 9362 structure. Available to rule sets that need them; no core rule applies them. - `rules/is`: `AllOf` composes several tests into one that passes only when all of them do, alongside the existing `AnyOf` and `OneOf`. - `fi-finvoice-v3`: approved as an external addon implemented by [`github.com/invopop/gobl.fi.finvoice`](https://github.com/invopop/gobl.fi.finvoice) — Finland's Finvoice 3.0 e-invoicing format. As with other external addons, the module must be imported (`_ "github.com/invopop/gobl.fi.finvoice/addon"`) for documents declaring the key to calculate and validate.