Savings Accounts (Tagesgeld)
Introduction
The Savings Account product enables your customers to open call money (overnight deposit) accounts that earn interest on their end-of-day balances, paid out on a monthly basis. Customers can transfer money to and from their savings account using their existing current account with Solaris. They can also submit a tax exemption order (Freistellungsauftrag) to exclude a certain amount of the interest paid/capital gains from taxation.
This document covers the functional specifications of this product, the process flows involved, and the API references for the relevant endpoints.
Product overview
Key features
The key product features are as follows:
- The Savings Account consists of a call money (overnight deposit) account (Tagesgeld) that accrues interest daily.
- Solaris will automatically pay out the earned interest on a monthly basis. The earned interest is settled on the first day of the following month, with the valuta date set to the last day of the respective month. The interest payouts will be based on the Savings Account balance at the end of the day.
- The account will be linked to the customer's Solaris current account, which will act as the main account. Customers may only use this main account to add or withdraw funds from the Savings Account.
- Customers can submit a Tax Exemption Order (Freistellungsauftrag) for their Savings Account, which will be validated against their tax ID and then passed on to a third-party tax service provider.
- Interest conditions can be customized at the partner level through an interest profile.
- Solaris will define and impose a limit on the balance on which interest can be earned per customer per partner. Any balance beyond that will not earn interest.
Prerequisites
-
This product is available to German (DE) branch customers with a German tax ID registered with Solaris. DE branch customers with non-German tax IDs may not open Savings Accounts.
- Before you can open a Savings Account for your customer, the customer must confirm the validity of their registered German tax ID.
- This product is available to all three customer segments: retail (B2C), business (B2B), and freelancers.
- Each customer can have one active Savings Account per partner.
- Each customer must have an active current account with Solaris before they may open a Savings Account. See the Get Started guides for more information on how to onboard customers with current accounts.
Product flow
The product flow consists of the following steps:
- In your frontend, prompt the customer to validate their tax ID.
-
Call POST Create an account opening request to request a Savings Account on behalf of the customer. In the request body, specify the
product_name
andaccount_type
that correspond with the type of customer.- Solaris will only open the Savings Account once all validations have passed, including a review of the customer's tax ID. If the validations fail, then the API will return an error response.
- You will receive an ACCOUNT_OPENING_REQUEST webhook event notification when the account opening request succeeds or fails.
-
Once the Savings Account has been created, link the new account to the customer's main (current) account by calling POST Map a person's main account to a savings account (for persons) or POST Map a business' main account to a savings account (for businesses). The Savings Account will remain blocked until you complete this step.
- During this asynchronous process, Solaris will map the Savings Account to the customer's main account, attach interest rate conditions, and register the customer/account with a third party tax service provider.
- Subscribe to the DEPOSIT_ACCOUNT_UPDATED webhook event to receive a notification when this process is complete. If the mapping succeeds, then the payload will contain a success message; if not, it will contain an error message.
- Now you can move funds in and out of the Savings Account using the dedicated API endpoints. Funds may only be paid in from, or out to, the customer's mapped main account.
- Once the Savings Account is funded, it will begin to accrue interest on a daily basis based on the end-of-day balance.
-
Solaris will settle the accrued interest on a monthly basis. Interest accrued in a given month will be paid out on the first day of the following month.
- As part of the interest settlement process, Solaris will deduct the applicable tax amount (determined in partnership with a third-party tax service provider) from the final interest amount before crediting it to the customer.
-
Tax exemption order: You must provide an option in your frontend to allow the customer to submit a tax exemption order (Freistellungsauftrag) for their Savings Account. Solaris offers dedicated endpoints for this type of document. See the section below for a description of how they work.
- This will be an asynchronous process. Subscribe to the TAX_EXEMPTION_UPDATED webhook event to receive a notification when this process succeeds or fails.
- Important note: The tax exemption order will apply to all deposit accounts that the customer has with Solaris (which could be across multiple partners). You must inform the customer of this and manage the tax exemption order accordingly. Solaris will match the tax exemption order against the customer's tax ID
- The tax exemption order will be available only at the individual level (i.e., not for spouses or civil partners).
- Annual tax statement: Solaris will send out the annual tax statements for every customer via Postbox at the end of each year.
-
Account closure: Use the existing account closure endpoints for Savings Accounts. In addition to the usual steps, when closing a Savings Account, Solaris will:
- Settle any unsettled interest that is due
- Move any remaining funds on the Savings Account to the customer's main account
Integration steps
note
Before a customer can open a savings account, they must already be onboarded with a current account. See the Get Started guides for instructions on how to implement this process.
Step 1: Validate customer's tax ID
When a customer wishes to open a Savings Account, you must first prompt them in your frontend to confirm the accuracy of their existing tax ID. Call GET Index tax identifications for a person to retrieve this info.
Step 2: Create account opening request
Follow the steps in the account opening guide to create an account opening request for the customer's Savings Account the same way you would for a current account. Please note the following properties and rules specific to Savings Accounts:
Savings Account product_name and account_type values
In your request to the POST Create an account opening request endpoint, supply
the following product_name
and account_type
values based on your customer type:
Type of Customer | product_name | account_type |
---|---|---|
Retail - Consumer | SAVINGS_ACCOUNT_CONSUMER_GERMANY |
SAVINGS_PERSONAL |
Business | SAVINGS_ACCOUNT_BUSINESS_GERMANY |
SAVINGS_BUSINESS |
Freelancer | SAVINGS_ACCOUNT_FREELANCER_GERMANY |
SAVINGS_SOLE_PROPRIETOR |
Rules and validations
In addition to the existing validations for regular account opening, Solaris will perform the following validations for Savings Accounts:
- The customer must have a valid German tax ID registered with Solaris.
- The customer may only have one active Savings Account per partner.
- The customer must have at least one active current account.
Solaris will apply a credit block to the account at the end of the account opening process. This is to ensure that the Savings Account is mapped to the customer's main account before they can fund it.
Step 3: Map main account to Savings Account
Once the Savings Account has been opened, you must map it to the customer's main (current) account. Please note that the customer cannot use their Savings Account until this operation is performed.
Solaris will perform the following steps before returning a success response:
- Map the main current account to the Savings Account
- Register the Savings Account with the third-party tax service provider
- Tag the interest conditions relevant for the account
- Remove the credit block
The diagram below depicts the API request/response process:
POST Create a mapping to a main account
This endpoint creates a mapping between a Savings Account and a main (current) account. This is an asynchronous process; subscribe to the DEPOSIT_ACCOUNT_UPDATED webhook event (described below) to receive notifications when the request succeeds or fails.
Rules and validations
The API will run the following validations on the request:
- Only one mapping per Savings Account: Validates whether the Savings Account already has a mapping to an active current account.
- Only one Savings Account per current account: Validates whether there are any other active Savings Accounts mapped to the current account.
- Main account must be active: Checks whether the current account has a status of ACTIVE and whether it has any blocks.
- Main account belongs to the same person/business ID: Validates whether the current account specified in the request belongs to the same person/business ID initiating the request.
Request parameters
main_account_id
: (required) The account ID of the main (current) account to which the Savings Account will be mapped.deposit_type
: (required) The deposit type to apply to the mapping. For Savings Accounts, use SAVINGS_ACCOUNT.reference
: (required) UUID reference for the request. Used as an idempotency key.
Request URL:
POST /v1/persons/{id}/deposit_accounts/{id}/mappings
POST /v1/businesses/{id}/deposit_accounts/{id}/mappings
Request example:
{
"reference": "73a46685-8ac6-4fff-9d36-55288523d879",
"main_account_id": "148c29b85992b8772eb7ddd518490110cacc",
"deposit_type": "SAVINGS_ACCOUNT"
}
Response example:
// 202: Accepted
{
"id": "d222a0b8-07ea-49be-83c1-68719be286e8",
"reference": "73a46685-8ac6-4fff-9d36-55288523d879",
"main_account_id": "148c29b85992b8772eb7ddd518490110cacc",
"deposit_type": "SAVINGS_ACCOUNT",
"status": "OPENED"
}
Click the links below for the full documentation for this endpoint:
DEPOSIT_ACCOUNT_UPDATED Webhook
The DEPOSIT_ACCOUNT_UPDATED
webhook event will send a notification when there is a status update on the mapping request (i.e., success or failure). The payload will contain a success message or a failure message.
Click here to view the documentation for this webhook event.
Step 4: Pay money into/out of the savings account
This section describes how to add money to, and withdraw money from, a Savings Account..
POST Create a savings account pay-in
This endpoint creates a pay-in transaction from the customer's main account into their Savings Account.
Rules and validations
- Balance check: Checks if the main account has sufficient funds to cover the transaction.
- Block check: Checks if there are any blocks applied on either of the accounts that would prevent the money movement.
- Active accounts check: Checks if both accounts are active.
- Mapping check: Checks if the two accounts have already been mapped to one another using POST Create a mapping to a main account.
Request parameters
main_account_id
: (required) The ID of the customer's main account.-
amount
: (required) The amount to pay into the Savings Account. (Note: The amount must be entered in cents)value
(required)currency
(required)unit
(required)
description
: A text description for the transaction, provided by the customer.reference
: (required) UUID reference for the transaction. Used as an idempotency key.
Request URL:
POST /v1/persons/{id}/deposit_accounts/{id}/payin
POST /v1/businesses/{id}/deposit_accounts/{id}/payin
Request body:
{
"reference": "73a46685-8ac6-4fff-9d36-55288523d879",
"main_account_id": "148c29b85992b8772eb7ddd518490110cacc",
"description": "Example transaction",
"amount": {
"value": 1000,
"currency": "EUR",
"unit":"cents"
}
}
Response example:
// 201: Created
{
"id": "d222a0b8-07ea-49be-83c1-68719be286e8",
"reference": "73a46685-8ac6-4fff-9d36-55288523d879",
"amount": {
"value": 1000,
"unit": "cents",
"currency": "EUR"
},
"main_account_id": "148c29b85992b8772eb7ddd518490110cacc",
"description": "Example transaction",
"created_at": "2023-10-10T16:02:54Z"
}
Click the links below for the full documentation for this endpoint:
POST Create a payout from a savings account
This endpoint creates a payout transaction from the Savings Account to the customer's main account.
Rules and validations:
- Balance check: Checks if the main account has sufficient funds to cover the transaction.
- Block check: Checks if there are any blocks applied on either of the accounts that would prevent the money movement.
- Active accounts check: Checks if both accounts are active.
- Mapping check: Checks if the two accounts have already been mapped to one another using POST Create a mapping to a main account.
Request parameters
main_account_id
: (required) The ID of the customer's main account.-
amount
: (required) The amount to pay out of the Savings Account. (Note: The amount must be entered in cents)value
(required)currency
(required)unit
(required)
description
: (Optional) A text description for the transaction from the customer.reference
: (required) UUID reference for the transaction. Used as an idempotency key.
Request URL:
POST /v1/persons/{id}/deposit_accounts/{id}/payout
POST /v1/businesses/{id}/deposit_accounts/{id}/payout
Request body:
{
"reference": "73a46685-8ac6-4fff-9d36-55288523d879",
"main_account_id": "148c29b85992b8772eb7ddd518490110cacc",
"description": "Example transaction",
"amount": {
"value": 1000,
"currency": "EUR",
"unit":"cents"
}
}
Response example:
// 201: Created
{
"id": "d222a0b8-07ea-49be-83c1-68719be286e8",
"reference": "73a46685-8ac6-4fff-9d36-55288523d879",
"amount": {
"value": 1000,
"unit": "cents",
"currency": "EUR"
},
"main_account_id": "148c29b85992b8772eb7ddd518490110cacc",
"description": "Example transaction",
"created_at": "2023-10-10T16:02:54Z"
}
Click the links below for the full documentation for this endpoint:
Step 5: Create tax exemption order
This section describes the endpoints for creating and managing tax exemption orders. Tax exemption orders are processed asynchronously by Solaris and the third-party tax service provider.
POST Create tax exemption order
This endpoint submits a request to create a tax exemption order. The diagram below depicts the API request-response process flow for this process:
note
When a customer submits a tax exemption order, it will apply to the total banking relationship that the customer has with Solaris (i.e., including savings accounts with other partners). This means that the customer will have only one exemption order with Solaris (across all partner relations that the customer might have). Solaris will use the customer's tax ID as the unique identifier for this purpose.
Currently, the exemption order can be created for one tax resident individual only (single tax allowance)
Rules and validations
- Account check: Checks if the customer has an active Savings Account with the provided account ID.
-
Existing tax exemption order check: Checks if the customer has already registered a tax exemption order with Solaris (based on their tax ID).
- If the customer has an existing tax exemption order, then call GET Retrieve tax exemption order to see the details of the order and PATCH Update tax exemption order to make any changes if necessary.
- Year validation: The
validFromYear
andvalidToYear
properties must contain valid year values and cannot be a past year. - Amount validation: The amount of the exemption may not exceed 1000 EUR.
- Natural person check: Checks if the request is from a person or a business. Only natural persons may submit tax exemption orders.
Request parameters
valid_from_year
: (required) Denotes the calendar year from when the exemption order will come into effect. Must be the current year or later.valid_to_year
: (Optional) Denotes the calendar year when the exemption order will expire. Must be the current year or later.-
amount
: (required) The amount of the tax exemption order. As per current regulation, the maximum permitted amount is 1000 EUR. Note: The amount to be entered in centsvalue
(required)currency
(required)unit
(required)
reference
: (required) UUID reference for the operation. Used as an idempotency key.
Request URL:
POST /v1/persons/{id}/deposit_accounts/{id}/tax_exemptions
Request example:
{
"reference": "7aa04f97-7720-4609-a5c5-d7b0f86e7661",
"valid_from_year": "2023",
"valid_to_year": "2024",
"amount": {
"value": 80000,
"currency": "EUR",
"unit":"cents"
}
}
Response example:
// 202: Accepted
{
"id": "d222a0b8-07ea-49be-83c1-68719be286e8",
"reference": "7aa04f97-7720-4609-a5c5-d7b0f86e7661",
"valid_from_year": "2023",
"valid_to_year": "2024",
"amount": {
"value": 80000,
"currency": "EUR",
"unit":"cents"
}
}
Click here to view the full documentation.
PATCH Update tax exemption order
This endpoint updates the properties of a customer's existing tax exemption order.
Rules and validations
- Account check: Checks if the customer has an active Savings Account with the provided account ID.
-
Existing tax exemption order check: Checks if the customer has already registered a tax exemption order with Solaris (based on their tax ID).
- If the customer has an existing tax exemption order, then call GET Retrieve tax exemption order to see the details of the order and PATCH Update tax exemption order to make any changes if necessary.
- Year validation: The
validFromYear
andvalidToYear
properties must contain valid year values and cannot be a past year. - Amount validation: The amount of the exemption may not exceed 1000 EUR.
Request parameters
valid_from_year
: Denotes the calendar year from when the exemption order will come into effect. Must be the current year or later.valid_to_year
: Denotes the calendar year when the exemption order will expire. Must be the current year or later.-
amount
: The amount of the tax exemption order. As per current regulation, the maximum permitted amount is 1000 EUR. Note: The amount to be entered in centsvalue
(required)currency
(required)unit
(required)
Request URL:
PATCH /v1/persons/{id}/deposit_accounts/{id}/tax_exemptions
Request example:
{
"amount": {
"value": 90000,
"currency": "EUR",
"unit":"cents"
}
}
Response example:
// 202: Accepted
{
"id": "d222a0b8-07ea-49be-83c1-68719be286e8",
"amount": {
"value": 90000,
"currency": "EUR",
"unit":"cents"
},
"valid_from_year": "2023",
"valid_to_year": "2024"
}
Click here to view the full documentation.
GET Retrieve tax exemption order
This endpoint returns the tax exemption order that the customer has registered with Solaris. The API will match this resource against the customer's tax ID.
Note: The status
field in the response will indicate whether the tax exemption
order is active or closed.
Request URL:
GET /v1/persons/{id}/deposit_accounts/{id}/tax_exemptions
Response example:
// 200: OK
{
"id": "018db09f-0a93-7067-a0bf-cd28fcc8ae9f",
"amount": {
"value": 60000,
"currency": "EUR",
"unit":"cents"
},
"valid_from_year": "2024",
"valid_to_year": "2025",
"status": "ACTIVE"
}
Click here to view the full documentation.
PATCH Close tax exemption order
This endpoint closes a customer's tax exemption order.
Use this endpoint if the customer's tax exemption order must be closed within the current year. Once you make this API request, Solaris' third-party tax provider will perform one of the following actions:
- If the tax exemption order has not been used, then the tax-exempt amount will be reduced to 0 and the tax exemption order will be terminated by the end of the year.
- If the tax exemption order has already been partially used, then the tax-exempt amount will be reduced to the used amount and the tax exemption order will be terminated by the end of the year.
- If the tax exemption order has been fully used, then the tax exemption order will be terminated by the end of the year.
Request URL:
PATCH /v1/persons/{person_id}/deposit_accounts/{account_id}/tax_exemptions/close
Response example:
// 202: Accepted
{
"id": "d222a0b8-07ea-49be-83c1-68719be286e8"
}
Click here to view the full documentation.
DELETE Remove tax exemption order
This endpoint deletes a customer's tax exemption order.
note
Only use this endpoint for tax exemption orders that have not been utilized (e.g., if the tax exemption order was submitted in error).
Request URL:
DELETE /v1/persons/{id}/deposit_accounts/{id}/tax_exemptions
Response example:
// 202: Accepted
{
"id": "d222a0b8-07ea-49be-83c1-68719be286e8"
}