# 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/disallow ATM withdrawals - Allow/disallow e-commerce transactions - Allow/disallow 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 2000 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 1000 Euros per hour (or 5 transactions per hour). ```json "limit": { // Object that defines how transactions are limited "type": "MERCHANT_CATEGORY", // Type of transactions that are limited "dimension": [ // Dimension of transactions within the type that are limited "5411" ], "period": "HOURLY", // Time period in which transactions are limited "amount": 10000, // Amount imposed on transactions within time period // OR "count": 5 // Number of limited transactions that may be conducted within time period } ``` #### List of dimensions | Name of the dimension (`type` value) | Content of the dimension (`dimension` values) | | --- | --- | | `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 Please 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](/assets/card-controls-list-diagram.7020af3a1af2bac5b1f022dd50d13875bbc470a305f2b68d8a77c2aaaa069fbf.aebdbb0d.svg) ### 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, then 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 Please note that 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, then the API will return the V1 response. ### V2 spending limit control structure ![V2 Card spending limit control structure](/assets/card-spending-control-limit-diagram_v2.91d55bfcc54b0c8d4cd60c89f0e7f0f1b447a9a6c30e97cc29ed831305cb0636.aebdbb0d.svg) ### V1 spending limit control structure ![V1 Card spending limit control structure](/assets/card-spending-control-limit-diagram_v1.cbc6310fa5d8f54b472074003659762b44aadf1bf7d99e07aee60ab762aea1b5.aebdbb0d.svg) ### 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, then 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, then 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" } } } ``` See the [CARD_AUTHORIZATION_DECLINE_V2 webhook documentation](/api-reference/onboarding/webhooks/#tag/Webhook-events/paths/card_authorization_decline_v2/post) for more information. 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 Click the links below to see the API reference for the endpoints related to card controls lists: - [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 Click the links below to see the API reference for the endpoints related to card spending limit controls: #### 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)