DEV Community

Alexander Nitrovich
Alexander Nitrovich

Posted on Originally published at blog.eurovalidate.com

Validate IBAN in Go

Introduction

Validating International Bank Account Numbers (IBANs) is crucial for minimizing errors and preventing fraud in financial applications. With strict regulatory standards, IBAN validation ensures the integrity and reliability of transactions. In this guide, we'll walk through validating an IBAN using Go, a language known for its performance and simplicity. We'll also explore integrating an API to further streamline this process.

Understanding IBAN

An International Bank Account Number (IBAN) uniquely identifies an account across borders. It consists of up to 34 alphanumeric characters, including a country code, check digits, and a Basic Bank Account Number (BBAN). Key validation criteria include verifying length and structure according to country-specific rules.

Why Use Go for IBAN Validation

Go is an excellent choice for IBAN validation due to its robust standard libraries, performance, and simplicity. Its built-in concurrency and ease of deployment make it ideal for developing secure, scalable fintech applications.

Setting Up Your Go Project

To begin, ensure Go is installed on your system. You can download the latest version from the official Go website. Initialize your project by creating a directory and running go mod init your-module-name. This sets up a module for managing dependencies.

Implementing IBAN Validation in Go

Below, we explore a basic implementation to validate IBANs, focusing on length and country code checks.

package main

import (
    "fmt"
)

// Basic IBAN check function
func isValidIBAN(iban string) bool {
    if len(iban) < 15 {
        return false
    }
    prefix := iban[:2]
    allowedPrefixes := map[string]bool{"GB": true, "DE": true, "FR": true}
    return allowedPrefixes[prefix]
}

func main() {
    testIBAN := "GB29NWBK60161331926819"
    fmt.Println("Basic validation result:", isValidIBAN(testIBAN))
}
Enter fullscreen mode Exit fullscreen mode

Integrating with a Developer-First API (Optional)

For enhanced validation, integrate with an API like EuroValidate's IBAN endpoint. This allows for automated verification against up-to-date data.

package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
    "encoding/json"
    "errors"
)

// Integrating EuroValidate IBAN validation API
func validateIBANWithAPI(iban string) (bool, error) {
    url := "https://api.eurovalidate.com/v1/iban/" + iban
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return false, err
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return false, err
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return false, errors.New("validation API error")
    }

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return false, err
    }
    var result map[string]interface{}
    json.Unmarshal(body, &result)

    return result["status"].(string) == "valid", nil
}

func main() {
    validIBAN := "DE89370400440532013000"
    invalidIBAN := "FR40303265045"

    fmt.Println("Basic validation result:", isValidIBAN(validIBAN))

    valid, err := validateIBANWithAPI(validIBAN)
    if err != nil {
        fmt.Println("API validation error:", err)
    } else {
        fmt.Println("API validation result:", valid)
    }

    valid, err = validateIBANWithAPI(invalidIBAN)
    if err != nil {
        fmt.Println("API validation error:", err)
    } else {
        fmt.Println("API validation result:", valid)
    }
}
Enter fullscreen mode Exit fullscreen mode

Real API Responses

Valid IBAN Request (GET /v1/iban/DE89370400440532013000):

{
    "vat_number": "DE89370400440532013000",
    "country_code": "DE",
    "status": "valid",
    "company_name": "Example Bank",
    "company_address": "123 Banking St, Berlin, Germany",
    "request_id": "xyz123",
    "meta": {
        "confidence": "high",
        "source": "central_bank",
        "cached": false,
        "response_time_ms": 120
    }
}
Enter fullscreen mode Exit fullscreen mode

Invalid IBAN Request (GET /v1/iban/FR40303265045):

{
    "vat_number": "FR40303265045",
    "country_code": "FR",
    "status": "invalid",
    "request_id": "abc456",
    "meta": {
        "confidence": "low",
        "source": "central_registry",
        "cached": false,
        "response_time_ms": 110
    }
}
Enter fullscreen mode Exit fullscreen mode

Code Walkthrough & Explanation

The basic validation checks the IBAN length and country prefix. The API integration involves making an HTTP GET request to the EuroValidate service. The function handles errors such as network issues or validation failures.

Error Handling and Best Practices

Ensure robust error handling by returning meaningful error messages and using custom error types for specific issues. Proper logging can be achieved by integrating logging libraries like logrus.

Testing Your IBAN Validator

To create reliable applications, it's crucial to write tests. Go's testing package offers powerful tools for this.

package main

import "testing"

func TestIsValidIBAN(t *testing.T) {
    validIBAN := "GB29NWBK60161331926819"
    invalidIBAN := "12345"

    if !isValidIBAN(validIBAN) {
        t.Error("Expected IBAN to be valid")
    }
    if isValidIBAN(invalidIBAN) {
        t.Error("Expected IBAN to be invalid")
    }
}
Enter fullscreen mode Exit fullscreen mode

Example Test Cases

Use a combination of valid and invalid IBANs to ensure all edge cases are covered, providing thorough test coverage for your validation logic.

Conclusion

Implementing IBAN validation in Go allows fintech applications to benefit from improved accuracy and reduced fraud risk. By integrating with EuroValidate's API, developers can achieve enhanced reliability. Explore further options on EuroValidate's Documentation to extend your validation capabilities.

Ready to streamline your financial validations? Sign up for our free trial today and integrate our IBAN validation API into your Go applications.

Top comments (0)