# Card spending controls

The **spending controls** feature allows your customers to tailor card spending to fit their needs and enjoy a greater degree of security around their spending. To this end, you can institute the following controls:

* **Card controls lists:** Inclusion/exclusion controls that determine how customers' cards can be used. Examples:
  * Including only Germany as an allowed merchant country (i.e., excluding all other countries).
  * Allowing only contactless payment methods (i.e., excluding all other POS entry modes).
* **Card spending limit controls:** These determine how much money can be spent using a customer's card in a certain context or time interval. Examples:
  * Setting a maximum number of daily card transactions at either the individual card level or among all cardholders.
  * Setting a maximum amount that can be spent each month.


For example, customers may use these controls to allow or disallow ATM withdrawals, e-commerce transactions, or internal transactions.

This guide describes how to implement these controls.

Solaris recommends using the [V2 endpoints](/api-reference/digital-banking/cards/#operation/createCardControlSpendingLimitV2) for **card spending limit controls.**

## Common data elements

### Origin

This attribute identifies who created the spending control (either `PARTNER` or `SOLARISBANK`).

You cannot override card spending controls created by Solaris with your own card spending controls.

### Dimensions

When creating a card spending control, you must specify the **dimension** of the control. Dimensions determine what kind of control to impose on spending. The value of the dimension depends on the **type** of card spending control.

**Example (Card controls list)**

In this example, the card controls list will **exclude** all transactions of type `ATM_WITHDRAWAL` for all cards that it applies to.


```json
    "exclusion": {               
      "type": "TRANSACTION_TYPE",
      "dimension": [
        "ATM_WITHDRAWAL"
      ]
    }
```

If you used the `inclusion` object instead of the `exclusion` object, the card controls list would **only allow** transactions of type `ATM_WITHDRAWAL` for all cards that it applies to.

**Example (Card spending limit control, V2)**

When creating a card spending limit control using the **V2 method**, you can create an array of **conditions** to apply to the control. Each condition object contains a transaction type and array of dimensions to either **include** (using the `dimension` array) or **exclude** (using the `excluded_dimension` array).

Note that within a single condition, you may only use one of these arrays. You can use multiple conditions within the same control to create a more precise restriction on the customer's card spending.

In the example below, a daily limit of 2,000 Euro is applied for OCT transactions (specified in the first `condition`) at merchants with all category codes **except** `crypto` (specified in the second `condition`).


```json
"limit": {
        "period": "DAILY",
        "amount": 20000,
        "conditions": [
            {
                "type": "TRANSACTION_TYPE",
                "dimension": [
                    "OCT"
                ]
            },
            {
                "type": "MERCHANT_CATEGORY_CODE",
                "excluded_dimension": [
                    "crypto"
                ]
            }
        ]
    }
```

**Example (Card spending limit control, V1)**

In the example below, spending with merchants with the category `5411` would be limited to 1,000 Euros per hour (or 5 transactions per hour).


```json
    "limit": {
      "type": "MERCHANT_CATEGORY",
      "dimension": [
         "5411"
      ],
      "period": "HOURLY",
      "amount": 10000,
      "count": 5
    }
```

#### List of dimensions

| Name (`type`) | Content (`dimension`) |
|  --- | --- |
| `MERCHANT_CATEGORY` | Array of [4-digit numeric codes](https://www.dm.usda.gov/procurement/card/card_x/mcc.pdf) that correspond with the merchant types to be included or excluded. Examples:- 5814 (Fast Food Restaurants)
- 5912 (Drug Stores and Pharmacies)
- 5977 (Cosmetic Stores)

 |
| `POS_ENTRY_MODE` | Types of POS entry modes for card transactions to be included or excluded. Possible values:- `MANUAL_PAN_ENTRY`
- `MAG_STRIPE`
- `CHIP`
- `ECOMMERCE`
- `CONTACTLESS`
- `CREDENTIAL_ON_FILE`
- `UNKNOWN`

 |
| `TRANSACTION_TYPE` | The types of card transactions to be included or excluded. Possible values:- `PURCHASE`
- `ATM_WITHDRAWAL`

 |
| `MERCHANT_COUNTRY` | A list of [ISO3166 2-character country codes](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) that corresponds with countries whose merchants customers can or cannot complete card transactions with. |
| `ACQUIRER_ID` | An array of identification codes (up to 11 characters) of acquiring institutions for whom card transactions are allowed or denied. |
| `MERCHANT_ID` | An array of card accepter identification codes (up to 15 characters) for whom card transactions are allowed or denied. Solaris does not have a list of these values; you can retrieve them directly from the merchant or from the acquiring bank. |


## Card controls lists

Note the following behaviors of card controls lists:

* Once you create an inclusion, any card transaction that does not match the inclusion will be **excluded.**
  * For example, if you create an **inclusion** with the value of `MERCHANT_COUNTRY` set to `DE`, then cardholders will **only** be able to use their cards for transactions with merchants based in Germany.
  * Conversely, if you create an **exclusion** with the value of `MERCHANT_COUNTRY` set to `DE`, then cardholders will only be able to use their cards for transactions with merchants **not** based in Germany.


### Structure of card controls lists

Card controls list diagram
### Data models

#### Card controls list scopes

While the `type` and `dimension` of the card controls list determine what kind of transaction is included or excluded, the **scope** determines **who** the control applies to.

For each `scope` (possible values listed below), you must specify a `scope_id`. For example, if you want to restrict certain transactions for a business, you must provide the ID of the business as the value of `scope_id`.

| Scope | Definition |
|  --- | --- |
| `PARTNER_CARDS` | The control applies to the Solaris partner (i.e., you) defined in `scope_id`. |
| `PARTNER_CARDHOLDERS` | The control applies to the individual Person specified in `scope_id`. |
| `BUSINESS`, `BUSINESS_CARDS` | The control applies to the business type defined in `scope_id`. |
| `ACCOUNT`, `ACCOUNT_CARDS` | The control applies to the customer bank account to which the card is linked, defined in `scope_id`. |
| `CARDHOLDER`, `CARDHOLDER_CARDS` | The control applies to all cards in the possession of the cardholder defined in `scope_id`. |
| `CARD` | The control applies to a specific card, defined in `scope_id`. |
| `NON_BUSINESS_CARDS` | The control applies to all cards not associated with a `business` resource (e.g., freelancers and sole proprietors). |


## Card spending limit controls

### V2 update

There are currently two versions of the card spending limit controls endpoints: **V1** and **V2.** Solaris recommends implementing the V2 endpoints.

The V2 endpoints introduce the `conditions` array to the card spending control object. This allows you to specify more than one `type` to restrict within a single control, which is not possible with V1. For example, you could create a single control to apply to a transaction type within multiple countries:


```json
"limit": {
        "period": "DAILY",
        "amount": 30000,
        "conditions": [
            {
                "type": "TRANSACTION_TYPE",
                "dimension": [
                    "OCT"
                ]
            },
            {
                "type": "MERCHANT_COUNTRY",
                "excluded_dimension": [
                    "FR",
                    "IT",
                    "ES"
                ]
            }
        ]
    }
```

Additionally, it is possible to define different rules for positive and negative balances. You can use the field `positive_balance_limit` for this purpose. This is particularly useful for products that allow negative balances, such as credit cards.

When using V2 endpoints, you must supply the `api-version` header in the request with a date value (format: YYYY-MM-DD). If you do not, the API will return the V1 response.

### V2 spending limit control structure

V2 Card spending limit control structure
### V1 spending limit control structure

V1 Card spending limit control structure
### Data models

Card spending limits have the following unique data models.

#### Card spending limit control scopes

Note that card spending limit controls use different scopes than card controls lists:

| Scope | Definition |
|  --- | --- |
| `PARTNER_CARDS` | The control applies individually to every card you manage. |
| `PARTNER_CARDHOLDERS` | The control applies to the Person specified in `scope_id`. |
| `BUSINESS` | The control applies to all cards linked to the business defined in `scope_id`. |
| `BUSINESS_CARDS` | The control applies individually to each card linked to the business defined in `scope_id`. |
| `ACCOUNT` | The control applies to all cards linked to the customer bank account defined in `scope_id`. |
| `ACCOUNT_CARDS` | The control applies individually to each card linked to the customer bank account defined in `scope_id`. |
| `CARDHOLDER` | The control applies to all cards in the possession of the cardholder defined in `scope_id`. |
| `CARDHOLDER_CARDS` | The control applies individually to each card in the possession of the cardholder defined in `scope_id`. |
| `CARD` | The control applies to the specific card defined in `scope_id`. |


Solaris could set an additional internal scope for partners: `PARTNER_CARDS_DEFAULT`. With this scope, Solaris can place default limits during onboarding. Please note the following points about this scope:

* This scope can only be set by Solaris and is not accessible to partners.
* This scope acts as the limit for daily and monthly purchases and ATM withdrawals dimensions if neither the partner nor the customer has set any limits.
* This scope will be overwritten if the scope `CARD` is set.


#### Period

You can specify a period of time during which the spending limit applies:

| Period | Description |
|  --- | --- |
| `HOURLY` | Applies to transactions within an hour (e.g., from 15:00 to 16:00). |
| `MINUTES_60` | Applies to transactions within a 60-minute period. |
| `DAILY` | Applies to transactions within a calendar day. |
| `HOURS_24` | Applies to transactions within a 24-hour period. |
| `WEEKLY` | Applies to transactions within a calendar week (i.e., from Sunday through Saturday). |
| `DAYS_7` | Applies to transactions within a 7-day period. |
| `MONTHLY` | Applies to transactions within a calendar month (e.g., in the month of March). |
| `DAYS_30` | Applies to transactions within a 30-day period. |
| `TRANSACTION` | Applies to all transactions. Note that you may only specify an `amount` for this type of limit, not a `count`. |


#### Amount

You can specify an amount (in Euro cents) that may be spent within the context of the limit. Note that you cannot specify both an `amount` and a `count` within the same limit.

#### Count

You can specify the number of transactions that may be conducted within the context of the limit.

## API documentation

### `CARD_AUTHORIZATION_DECLINE_V2` webhook

Subscribe to the `CARD_AUTHORIZATION_DECLINE_V2` webhook to receive notifications whenever a card transaction is declined.

If a card transaction is declined due to a card spending control, the webhook will return the ID for each card spending control responsible for blocking the payment in the `reasons` object along with a description of the control.

For example, if a card controls list restricted the transaction, one of the `reasons` will have a `type` of `LIST_CONTROL`, along with the ID of the card controls list. For card spending limit controls, the `type` will be `SPENDING_LIMIT`.

**Example payload:**


```json
{
   "reasons": [
      { "type": "LIST_CONTROL", "id": "rule-id", "message": "Evaluation fails due to the inclusion scope_type={SCOPE_TYPE}, scope_id={SCOPE_ID}, dimension_type={DIMENSION_TYPE}, dimension={DIMENSION} and requested dimension={DIMENSION_PROVIDED}" },
      { "type": "SPENDING_LIMIT", "id": "rule-id", "message": "Evaluation fails due to the exceeding limit scope_type={SCOPE_TYPE}, scope_id={SCOPE_ID}, dimension_type={DIMENSION_TYPE}, dimension={DIMENSION}, period={PERIOD}, amount={AMOUNT}, count={COUNT}" }
    ],

   "card_transaction":{
      "card_id":"f459e5de647e2909c94a7120c4d03557mcrd",
      "type":"PURCHASE",
      "status":"DECLINED",
      "attempted_at":"2019-04-01T12:23:42+00:00",
      "pos_entry_mode":"CHIP",
      "merchant":{
         "country_code":"DE",
         "category_code":"5999",
         "name":"Shady Bob"
      },
      "amount":{
         "currency":"EUR",
         "value":1540,
         "unit":"cents"
      },
      "original_amount":{
         "currency":"EUR",
         "value":1540,
         "unit":"cents"
      }
   }
}
```

[View CARD_AUTHORIZATION_DECLINE_V2 webhook reference](/api-reference/onboarding/webhooks/webhook-events/paths/card_authorization_decline_v2/post)

See the [transaction declined reasons appendix](/guides/cards/creation-and-servicing#appendix-v-transaction-declined-reasons-v2) in the card servicing guide for a full list of decline reasons.

### Card controls list endpoints

* [POST Create card controls list](/api-reference/digital-banking/cards/#operation/createCardControlList)
* [GET Retrieve a card controls list](/api-reference/digital-banking/cards/#operation/showCardControlList)
* [GET Index card controls lists](/api-reference/digital-banking/cards/#operation/indexCardControlList)
* [DELETE Remove a card controls list](/api-reference/digital-banking/cards/#operation/deleteCardControlList)


### Card spending limit control endpoints

#### V2 endpoints

* [POST Create card spending limit control (V2)](/api-reference/digital-banking/cards/#operation/createCardControlSpendingLimitV2)
* [GET Retrieve a card spending limit control (V2)](/api-reference/digital-banking/cards/#operation/showCardControlSpendingLimitV2)
* [GET Index card spending limit controls (V2)](/api-reference/digital-banking/cards/#operation/indexCardControlSpendingLimitV2)
* [DELETE Remove a card spending limit control (V2)](/api-reference/digital-banking/cards/#operation/deleteCardControlSpendingLimitV2)


#### V1 endpoints

* [POST Create card spending limit control (V1)](/api-reference/digital-banking/cards/#operation/createCardControlSpendingLimit)
* [GET Retrieve a card spending limit control (V1)](/api-reference/digital-banking/cards/#operation/showCardControlSpendingLimit)
* [GET Index card spending limit controls (V1)](/api-reference/digital-banking/cards/#operation/indexCardControlSpendingLimit)
* [DELETE Remove a card spending limit control (V1)](/api-reference/digital-banking/cards/#operation/deleteCardControlSpendingLimit)