# Account Opening

Opening a bank account is the final step in the customer onboarding journey. After you have collected the required data, identified the customer, and performed necessary compliance checks, you can request a new account.

Asynchronous Process
This guide describes the **asynchronous** approach (Account Opening Request - AOR).
Solaris performs background validation checks *after* you submit the request. You will not receive an account ID immediately; you must listen for the webhook result.

## How it works

The account creation process involves creating an **Account Opening Request (AOR)**. This request acts as an application that triggers Solaris' internal validation engine.

The AOR must include:

* **Customer:** The `person_id` or `business_id`.
* **Product:** The specific Solaris product (e.g., `CURRENT_ACCOUNT_CONSUMER_GERMANY`).
* **Branch:** The target IBAN country (DE, FR, IT, ES).


Solaris will **only** open the account if **all validations** (KYC, CDD, Credit Standing, Fraud) are successful.

### Supported products

This process applies to the following account types:

B2C Checking
Retail current accounts.

B2B Checking
Business current accounts.

Freelancer
Freelancer accounts.

Restricted
Limited functionality accounts.

Sub-accounts
Pockets/Wallets.

Prepaid Cards
Accounts linked to prepaid cards.

## Prerequisites

To avoid automatic rejection, ensure the customer meets these criteria before sending the request:

1. **Data Completeness:** All mandatory fields in the `person` or `business` resource are populated.
2. **Identity:** The customer has a `successful` identification status.
3. **Compliance:** The customer has passed all **Customer Due Diligence (CDD)** checks.


## Integration flow

1. **Submit Request:** Call `POST /v1/accounts/opening_requests` with the customer and product details.
2. **Processing:** Solaris runs internal rules (Tax ID validation, Age check, Garnishment check, Sanctions screening).
3. **Webhook Notification:** Solaris sends an event to your `ACCOUNT_OPENING_REQUEST` webhook subscription.
4. **Result:**
  * **Success:** The webhook payload contains the new `account_id`.
  * **Failure:** The webhook payload contains an `error` object with the rejection details.



```mermaid
sequenceDiagram
    participant F as Your frontend
    participant B as Your backend
    participant S as Solaris

    B->>S: POST Create an account opening request<br/>(customer_id, customer_type, product_name, account_type)
    
    Note right of S: id: account opening request
    S-->>B: 201 Created
    
    Note right of S: AOR status: INITIATED
    Note right of S: AOR status: IN_PROGRESS (Validations running)
    
    alt AOR successful
        Note right of S: AOR status: COMPLETED
        Note over B,S: Webhook event: ACCOUNT_OPENING_REQUEST
        S-->>B: status: COMPLETED, account_id
        B-->>F: Success notification (Continue customer onboarding)
    else AOR failed
        Note right of S: AOR status: REJECTED
        Note over B,S: Webhook event: ACCOUNT_OPENING_REQUEST
        S-->>B: status: REJECTED, rejection_reason
        B-->>F: Rejection notification (Abort customer onboarding)
    end
```

### Validation logic

Solaris applies specific rule sets based on the **Product** + **Branch** + **Customer Type** combination.

Common validation checks include:

* **Age:** Customer must be 18+ (Retail).
* **Account Limit:** Customer has not exceeded the maximum allowed number of accounts.
* **Seizures:** Customer has no active account seizures or garnishments with *any* Solaris partner.
* **Data Integrity:**
  * **Person:** `first_name`, `last_name`, `address`, `city`, `country`, `birth_date`, `birth_city`, `nationality`.
  * **Business:** `name`, `sector`, `legal_form`.


User Experience
If an AOR is rejected, display a clear message to the user:
*"Unfortunately, you did not meet the onboarding criteria. If you believe this is an error, contact Customer Support."*

### Status lifecycle

The AOR transitions through the following statuses:

| Status | Description |
|  --- | --- |
| `INITIATED` | The request has been received and persisted. |
| `IN_PROGRESS` | Solaris is running internal validation rules. |
| `COMPLETED` | **Success.** The account is open. A webhook notification is triggered. |
| `REJECTED` | **Failure.** The request was denied. A webhook notification is triggered. You may need to restart the onboarding flow. |


## Testing

You can trigger specific validation failures in the **Sandbox** environment to test your error handling.

### Test case: Missing data

Create a person and omit the `birth_city` field. Submit an AOR.
**Expected Result:** `REJECTED` (Validation Error).

### Test case: Seizure check

To simulate a rejection due to an existing seizure (Pfändung), use these specific test values:

**Person (Retail/Freelance)**


```json
{
  "first_name": "Joshua",
  "last_name": "Seized",
  "birth_date": "1972-12-24",
  "birth_city": "Berlin"
}
```

**Business (B2B)**


```json
{
  "name": "Seized Company GmbH",
  "legal_form": "GMBH",
  "address": {
    "postal_code": "10409"
  },
  "tax_information": {
    "registration_number": "HRB 12345"
  }
}
```

## API Reference

### POST Create request

Initiate the opening process. Ensure your request body handles the dependencies between customer type and product.

| Field | Logic & Description |
|  --- | --- |
| `customer_id` | **Mandatory.** The unique ID of the applicant. Use `person_id` for Retail/Freelancers or `business_id` for B2B. |
| `customer_type` | **Mandatory.** `Person` (Retail/Freelancers) or `Business` (B2B). Must match the ID type above. |
| `product_name` | **Mandatory.** The commercial product ID (e.g., `CURRENT_ACCOUNT_CONSUMER_GERMANY`). See configuration below. |
| `account_type` | **Mandatory.** The technical ledger type (e.g., `CHECKING_PERSONAL`). |
| `account_purpose` | **Conditional.** Required ONLY if the customer holds multiple accounts. Default is `primary`. |
| `account_bic` | **Mandatory.** The BIC of the target branch (DE, FR, IT, ES). See configuration below. |
| `account_currency` | **Mandatory.** The 3-letter currency code (e.g., `EUR`, `GBP`, `USD`). |



```json
// POST /v1/accounts/opening_requests
{
  "customer_id": "b109ee6f66d2a061e006bd31c6455df2cper",
  "customer_type": "Person",
  "product_name": "CURRENT_ACCOUNT_CONSUMER_GERMANY",
  "account_type": "CHECKING_PERSONAL",
  "account_bic": "SOBKDEB2XXX",
  "account_currency": "EUR"
}
```

Create AOR Endpoint
View full technical specification and error codes.

### Webhooks

Subscribe to the `ACCOUNT_OPENING_REQUEST` event to receive the final decision.

**Success Payload:** Contains `account_id` and `status: "COMPLETED"`.
**Failure Payload:** Contains an `error` object.


```json
// Example Failure Payload
{
  "account_opening_request_id": "...",
  "status": "REJECTED",
  "error": {
    "code": "green_person_vetting",
    "detail": "CustomerVettingStatus for person has to be 'green' to open an account."
  }
}
```

Webhook Reference
View the event payload schema.

## Configuration reference

Your Partner Manager will provide the exact values for your specific product setup. Use the detailed definitions below to construct your API requests.

Diagram: Fields mapping example
### Customer Type

The `customer_type` field defines the legal nature of the applicant.

* **Person:** Use for Retail (B2C) and Freelancers.
* **Business:** Use for Legal Entities (B2B).


### Product Name

The `product_name` identifies the commercial package. It is typically a concatenation of the **product**, **customer type**, and **branch**.

* *Example:* `CURRENT_ACCOUNT_CONSUMER_GERMANY`


### Account Types

The `account_type` maps to the technical ledger type.

* **Note:** Only accounts that can be opened via the API are listed in the reference. Internal Solaris accounts are excluded.


### Branch BICs

Use the correct BIC for the target country.

| Branch | Allowed BICs |
|  --- | --- |
| **Germany** | `SOBKDEBBXXX`, `SOBKDEB2XXX` |
| **France** | `SOBKFRP2XXX` |
| **Italy** | `SOBKITM2XXX` |
| **Spain** | `SOBKESM2XXX` |