n26

package module
v0.0.0-...-8b2f156 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 10, 2023 License: MIT Imports: 13 Imported by: 0

README

Go Report Card

n26

Go API and CLI to get information of your N26 account

Installation

  • macOS: Available via Homebrew. Just run brew install guitmz/tools/n26
  • Linux: You can manually build this project or download a binary release.

You can also install with go get -u github.com/guitmz/n26/cmd/n26 (make sure you have your Go env setup correctly).

Docker

A Dockerfile is also provided and the prebuilt image is available for pulling: docker pull guitmz/n26 or docker pull guitmz/n26:DESIRED_TAG

You can run it like:

$ docker run -e N26_USERNAME="username" -e N26_PASSWORD="password" -e N26_DEVICE_TOKEN="device_token_uuid" guitmz/n26

or if you want to be asked for your credentials:

$ docker run -ti -e N26_DEVICE_TOKEN="device_token_uuid" guitmz/n26

Authentication

Since 14th of September 2019, N26 requires a login confirmation (2 factor authentication) from the paired phone N26 application to login on devices that are not paired (more details here). This means you will receive a notification on your phone when you start using this library to request data. This tool checks for your login confirmation every 5 seconds. If you fail to approve the login request within 60 seconds an exception is raised.

Device Token

Since 17th of June 2020, N26 requires a device_token to differentiate clients. This requires you to specify the N26_DEVICE_TOKEN environment variable with an UUID of your choice. Feel free to use any proper UUID generator like https://www.uuidgenerator.net to generate the token.

Usage

NAME:
   N26 - your N26 Bank financial information on the command line

USAGE:
   n26 command [json|csv|statement ID]

VERSION:
   1.5.0

AUTHOR:
   Guilherme Thomazi <thomazi@linux.com>

COMMANDS:
     addresses     addresses linked to your account
     balance       your balance information
     block         blocks a card
     cards         list your cards information
     contacts      your saved contacts
     info          personal information
     limits        your account limits
     spaces        your spaces
     statements    your statements. Passing the statement ID as argument, downloads the PDF to the current directory
     status        general status of your account
     transactions  list your past transactions. Supports CSV output
     unblock       unblocks a card
     help, h       Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version

You can have the N26_USERNAME and N26_PASSWORD environment variables set to your N26 user email and password. If you don't, you will be prompt for this information, so it's not mandatory. Example of getting your account balance:

$ n26 balance
+------------------------+-------------+-------------------+----------------+
|          IBAN          |     BIC     | AVAILABLE BALANCE | USABLE BALANCE |
+------------------------+-------------+-------------------+----------------+
| DE74100XXXXXXXXXXXXXXX | NTSXXXXXXXX |              88.8 |           88.8 |
+------------------------+-------------+-------------------+----------------+

You can also use the json option to output it as JSON with more information:

$ n26 balance json
N26 password: ********
{
  "availableBalance": 107.5,
  "usableBalance": 107.5,
  "iban": "DEXXXXXXXXXXXXXX",
  "bic": "NTXXXXXXXXXXX",
  "bankName": "N26 Bank",
  "seized": false,
  "id": "11111-1scasda-1112312-adasdasdasdas"
}

And csv for transactions.

You can run n26 help for usage description.

Missing features

  • Improve MFA flow, for now it works but is not really informative
  • Make a transfer
  • Set card limit
  • API docs
  • Better error handling
  • A terminal UI could also be implemented
  • ?

References

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Addresses

type Addresses struct {
	Paging struct {
		TotalResults int `json:"totalResults"`
	} `json:"paging"`
	Data []struct {
		AddressLine1     string `json:"addressLine1"`
		StreetName       string `json:"streetName"`
		HouseNumberBlock string `json:"houseNumberBlock"`
		ZipCode          string `json:"zipCode"`
		CityName         string `json:"cityName"`
		CountryName      string `json:"countryName"`
		Type             string `json:"type"`
		ID               string `json:"id"`
	} `json:"data"`
}

type Auth

type Auth struct {
	UserName    string
	Password    string
	DeviceToken string
}

type Balance

type Balance struct {
	AvailableBalance float64 `json:"availableBalance"`
	UsableBalance    float64 `json:"usableBalance"`
	IBAN             string  `json:"iban"`
	BIC              string  `json:"bic"`
	BankName         string  `json:"bankName"`
	Seized           bool    `json:"seized"`
	ID               string  `json:"id"`
}

type Barzahlen

type Barzahlen struct {
	DepositAllowance           string `json:"depositAllowance"`
	WithdrawAllowance          string `json:"withdrawAllowance"`
	RemainingAmountMonth       string `json:"remainingAmountMonth"`
	FeeRate                    string `json:"feeRate"`
	Cash26WithdrawalsCount     string `json:"cash26WithdrawalsCount"`
	Cash26WithdrawalsSum       string `json:"cash26WithdrawalsSum"`
	AtmWithdrawalsCount        string `json:"atmWithdrawalsCount"`
	AtmWithdrawalsSum          string `json:"atmWithdrawalsSum"`
	MonthlyDepositFeeThreshold string `json:"monthlyDepositFeeThreshold"`
	Success                    bool   `json:"success"`
}

type Cards

type Cards []struct {
	ID                                  string      `json:"id"`
	PublicToken                         interface{} `json:"publicToken"`
	Pan                                 interface{} `json:"pan"`
	MaskedPan                           string      `json:"maskedPan"`
	ExpirationDate                      TimeStamp   `json:"expirationDate"`
	CardType                            string      `json:"cardType"`
	Status                              string      `json:"status"`
	CardProduct                         interface{} `json:"cardProduct"`
	CardProductType                     string      `json:"cardProductType"`
	PinDefined                          TimeStamp   `json:"pinDefined"`
	CardActivated                       TimeStamp   `json:"cardActivated"`
	UsernameOnCard                      string      `json:"usernameOnCard"`
	ExceetExpressCardDelivery           interface{} `json:"exceetExpressCardDelivery"`
	Membership                          interface{} `json:"membership"`
	ExceetActualDeliveryDate            interface{} `json:"exceetActualDeliveryDate"`
	ExceetExpressCardDeliveryEmailSent  interface{} `json:"exceetExpressCardDeliveryEmailSent"`
	ExceetCardStatus                    interface{} `json:"exceetCardStatus"`
	ExceetExpectedDeliveryDate          interface{} `json:"exceetExpectedDeliveryDate"`
	ExceetExpressCardDeliveryTrackingID interface{} `json:"exceetExpressCardDeliveryTrackingId"`
	CardSettingsID                      interface{} `json:"cardSettingsId"`
	MptsCard                            bool        `json:"mptsCard"`
}

type Client

type Client http.Client

func NewClient

func NewClient(a Auth) (*Client, error)

func (*Client) BlockCard

func (auth *Client) BlockCard(ID string)

func (*Client) GetAddresses

func (auth *Client) GetAddresses(retType string) (string, *Addresses)

func (*Client) GetBalance

func (auth *Client) GetBalance(retType string) (string, *Balance)

func (*Client) GetCards

func (auth *Client) GetCards(retType string) (string, *Cards)

func (*Client) GetContacts

func (auth *Client) GetContacts(retType string) (string, *Contacts)

func (*Client) GetInfo

func (auth *Client) GetInfo(retType string) (string, *PersonalInfo)

func (*Client) GetLastTransactions

func (auth *Client) GetLastTransactions(limit string) (*Transactions, error)

func (*Client) GetLimits

func (auth *Client) GetLimits(retType string) (string, *Limits)

func (*Client) GetSmartStatementCsv

func (auth *Client) GetSmartStatementCsv(from, to TimeStamp, reader func(io.Reader) error) error

Get transactions for the given time window as N26 CSV file. Stored as 'smrt_statement.csv'

func (*Client) GetSpaces

func (auth *Client) GetSpaces(retType string) (string, *Spaces)

func (*Client) GetStatementPDF

func (auth *Client) GetStatementPDF(ID string)

func (*Client) GetStatements

func (auth *Client) GetStatements(retType string) (string, *Statements)

func (*Client) GetStatus

func (auth *Client) GetStatus(retType string) (string, *Statuses)

func (*Client) GetTransactions

func (auth *Client) GetTransactions(from, to TimeStamp, limit string) (*Transactions, error)

Get transactions for the given time window. Use the zero values for the time stamps if no restrictions are desired (use the defaults on the server)

func (*Client) UnblockCard

func (auth *Client) UnblockCard(ID string)

type Contacts

type Contacts []struct {
	UserID   string `json:"userId"`
	ID       string `json:"id"`
	Name     string `json:"name"`
	Subtitle string `json:"subtitle"`
	Account  struct {
		AccountType string `json:"accountType"`
		Iban        string `json:"iban"`
		Bic         string `json:"bic"`
	} `json:"account"`
}

type Limits

type Limits []struct {
	Limit  string  `json:"limit"`
	Amount float64 `json:"amount"`
}

type PersonalInfo

type PersonalInfo struct {
	ID                        string `json:"id"`
	Email                     string `json:"email"`
	FirstName                 string `json:"firstName"`
	LastName                  string `json:"lastName"`
	KycFirstName              string `json:"kycFirstName"`
	KycLastName               string `json:"kycLastName"`
	Title                     string `json:"title"`
	Gender                    string `json:"gender"`
	BirthDate                 int64  `json:"birthDate"`
	SignupCompleted           bool   `json:"signupCompleted"`
	Nationality               string `json:"nationality"`
	MobilePhoneNumber         string `json:"mobilePhoneNumber"`
	ShadowUserID              string `json:"shadowUserId"`
	TransferWiseTermsAccepted bool   `json:"transferWiseTermsAccepted"`
	IDNowToken                string `json:"idNowToken"`
}

type Spaces

type Spaces struct {
	Spaces []struct {
		Balance struct {
			AvailableBalance float64     `json:"availableBalance"`
			OverdraftAmount  interface{} `json:"overdraftAmount"`
		} `json:"balance"`
		Color          string      `json:"color"`
		Goal           interface{} `json:"goal"`
		ID             string      `json:"id"`
		ImageURL       string      `json:"imageUrl"`
		IsCardAttached bool        `json:"isCardAttached"`
		IsPrimary      bool        `json:"isPrimary"`
		Name           string      `json:"name"`
	} `json:"spaces"`
	TotalBalance float64 `json:"totalBalance"`
	UserFeatures struct {
		AvailableSpaces int  `json:"availableSpaces"`
		CanUpgrade      bool `json:"canUpgrade"`
	} `json:"userFeatures"`
}

type Statements

type Statements []struct {
	ID        string `json:"id"`
	URL       string `json:"url"`
	VisibleTS int64  `json:"visibleTS"`
	Month     int    `json:"month"`
	Year      int    `json:"year"`
}

type Statuses

type Statuses struct {
	ID                           string `json:"id"`
	Created                      int64  `json:"created"`
	Updated                      int64  `json:"updated"`
	SingleStepSignup             int64  `json:"singleStepSignup"`
	EmailValidationInitiated     int64  `json:"emailValidationInitiated"`
	EmailValidationCompleted     int64  `json:"emailValidationCompleted"`
	ProductSelectionCompleted    int64  `json:"productSelectionCompleted"`
	PhonePairingInitiated        int64  `json:"phonePairingInitiated"`
	PhonePairingCompleted        int64  `json:"phonePairingCompleted"`
	KycInitiated                 int64  `json:"kycInitiated"`
	KycCompleted                 int64  `json:"kycCompleted"`
	KycWebIDInitiated            int64  `json:"kycWebIDInitiated"`
	KycWebIDCompleted            int64  `json:"kycWebIDCompleted"`
	CardActivationCompleted      int64  `json:"cardActivationCompleted"`
	PinDefinitionCompleted       int64  `json:"pinDefinitionCompleted"`
	BankAccountCreationInitiated int64  `json:"bankAccountCreationInitiated"`
	BankAccountCreationSucceded  int64  `json:"bankAccountCreationSucceded"`
	FlexAccount                  bool   `json:"flexAccount"`
}

type TimeStamp

type TimeStamp struct {
	time.Time
}

func (*TimeStamp) AsMillis

func (ts *TimeStamp) AsMillis() int64

convert the timestamp to an integer - millis since epoch

func (*TimeStamp) UnmarshalJSON

func (ts *TimeStamp) UnmarshalJSON(b []byte) (err error)

type Token

type Token struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	MfaToken     string `json:"mfaToken"`
}

func (*Token) CompleteMfaApproval

func (t *Token) CompleteMfaApproval(deviceToken string) int

func (*Token) GetMFAToken

func (t *Token) GetMFAToken(username, password, deviceToken string) error

type TokenSource

type TokenSource struct {
	AccessToken string
}

func (*TokenSource) Token

func (t *TokenSource) Token() (*oauth2.Token, error)

type Transactions

type Transactions []struct {
	ID                   string    `json:"id"`
	UserID               string    `json:"userId"`
	Type                 string    `json:"type"`
	Amount               float64   `json:"amount"`
	CurrencyCode         string    `json:"currencyCode"`
	OriginalAmount       float64   `json:"originalAmount,omitempty"`
	OriginalCurrency     string    `json:"originalCurrency,omitempty"`
	ExchangeRate         float64   `json:"exchangeRate,omitempty"`
	MerchantCity         string    `json:"merchantCity,omitempty"`
	VisibleTS            TimeStamp `json:"visibleTS"`
	Mcc                  int       `json:"mcc,omitempty"`
	MccGroup             int       `json:"mccGroup,omitempty"`
	MerchantName         string    `json:"merchantName,omitempty"`
	Recurring            bool      `json:"recurring"`
	AccountID            string    `json:"accountId"`
	Category             string    `json:"category"`
	CardID               string    `json:"cardId,omitempty"`
	UserCertified        TimeStamp `json:"userCertified"`
	Pending              bool      `json:"pending"`
	TransactionNature    string    `json:"transactionNature"`
	CreatedTS            TimeStamp `json:"createdTS"`
	MerchantCountry      int       `json:"merchantCountry,omitempty"`
	SmartLinkID          string    `json:"smartLinkId"`
	LinkID               string    `json:"linkId"`
	Confirmed            TimeStamp `json:"confirmed"`
	PartnerBic           string    `json:"partnerBic,omitempty"`
	PartnerBcn           string    `json:"partnerBcn,omitempty"`
	PartnerAccountIsSepa bool      `json:"partnerAccountIsSepa,omitempty"`
	PartnerName          string    `json:"partnerName,omitempty"`
	PartnerIban          string    `json:"partnerIban,omitempty"`
	PartnerAccountBan    string    `json:"partnerAccountBan,omitempty"`
	ReferenceText        string    `json:"referenceText,omitempty"`
	UserAccepted         int64     `json:"userAccepted,omitempty"`
	SmartContactID       string    `json:"smartContactId,omitempty"`
}

Directories

Path Synopsis
cmd
n26

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL