Penalties for CD accounts
You can apply penalties to certificate of deposit (CD) accounts when specific withdrawal conditions occur, such as shortly after account opening, during the term, or after multiple withdrawals within a short period.
CD penalty configuration lets you model different withdrawal behaviors across the product lifecycle. You can apply these penalty types individually or combine them to enforce product rules more precisely. Penalties are configured at the deposit product level during its creation, and the Pismo platform evaluates them at withdrawal time.
You can also preview the penalties that would apply to a planned withdrawal, including a full withdrawal of the account balance before executing it. Refer to Simulate penalties.
When designing a penalty strategy, pay close attention to:
- the customer event that triggers the penalty
- whether the penalty should be percentage-based or fixed
- the dependency on the interest plan
- whether multiple penalties may apply together
A CD product can include one or more of these penalty types, refer to the Penalty types section for more details. Depending on the product configuration, you can apply more than one penalty to the same withdrawal.
Supported penalty models
CD account penalties use two main calculation models.
Penalty model | Description |
|---|---|
Percentage-based | Calculates the penalty by applying the equivalent of a configured number of interest days to the withdrawn amount. In a percentage‑based penalty, the Pismo platform calculates the value of X interest days on the withdrawn amount. Percentage‑based penalties require the following interest‑plan values from the product:
|
Fixed amount | Calculates a penalty as the monetary value of forfeited interest days, typically based on the account balance or CD principal. Fixed-amount penalties calculate the monetary value of X forfeited interest days for the account balance. |
Penalty types
Here is a summary table of all penalty types. For the relevant fee IDs and transaction flows, refer to Create deposit product.
| Penalty type | Model | Basis | Main configuration |
|---|---|---|---|
| Early withdrawal after opening | Percentage-based | Withdrawn amount | applicable_within_days, penalty_interest_days |
| Tiered interest forfeiture | Fixed amount | Days held tier | min_days_held, max_days_held, forfeited_interest_days |
| Subsequent withdrawal | Percentage-based | Withdrawn amount | window_behavior, applicable_within_days, penalty_interest_days |
| Grace period | Percentage-based | Withdrawn amount | duration_days, penalty_interest_days |
| Withdrawal fee | Percentage-based or fixed amount | Withdrawn amount or fixed configured value | type, value |
Early withdrawal after opening
This penalty applies to any withdrawal made within a configured number of days after account opening.
How it works
This is how early withdrawal after opening is calculated.
| Calculation factor | Description |
|---|---|
| Type | Percentage-based |
| Basis | Withdrawn amount |
| Equivalent to | penalty_interest_days days of interest |
| Applies within | applicable_within_days after account opening |
Example
"penalties": {
"early_withdrawal_after_opening": {
"applicable_within_days": 10,
"penalty_interest_days": 7
}
}In this example, the Pismo platform applies a penalty equivalent to seven days of simple interest on the withdrawn amount for any withdrawal made within the first ten days after the deposit account opens.
Tiered interest forfeiture
This penalty applies a fixed penalty amount based on how long the funds remained in the account before withdrawal.
How it works
| Calculation factor | Description |
|---|---|
| Type | Fixed amount |
| Basis | A holding‑period tier defined by min_days_held and max_days_held |
| Equivalent to | forfeited_interest_days days of interest, converted into a monetary amount |
Rules
- You can define multiple tiers.
- Tiers must not overlap.
- The last tier’s
max_days_heldmust not exceed the product’smax_term.
Example
"tiered_interest_forfeiture": [
{
"min_days_held": 1,
"max_days_held": 90,
"forfeited_interest_days": 30
},
{
"min_days_held": 91,
"max_days_held": 180,
"forfeited_interest_days": 90
}
]In this example:
- A withdrawal made between day 1 and day 90 forfeits 30 days of interest.
- A withdrawal made between day 91 and day 180 forfeits 90 days of interest.
The Pismo platform converts the forfeited interest days into a fixed monetary penalty amount. The penalty amount remains fixed and does not vary based on the amount withdrawn.
Subsequent withdrawal
This penalty applies when a customer makes subsequent withdrawals within a configured time window.
How it works
| Calculation factor | Description |
|---|---|
| Type | Percentage-based |
| Basis | Withdrawn amount |
| Equivalent to | penalty_interest_days days of interest |
| Window | applicable_within_days |
Window strategies
Window strategies define how the time window is tracked when evaluating whether a penalty applies. The window sets the period in which withdrawals are reviewed, and the strategy determines how that period behaves after each withdrawal.
This penalty supports two window strategies:
ROLLING: the window resets after each withdrawalFIXED: the window starts with the first withdrawal and does not reset
Example
"subsequent_withdrawals": {
"window_behavior": "ROLLING",
"applicable_within_days": 6,
"penalty_interest_days": 7
}In this example, the Pismo platform applies a penalty equivalent to seven days of simple interest to any subsequent withdrawal made within a six-day rolling window. Each qualifying withdrawal resets the window and starts a new six-day period.
Grace period
This penalty applies to withdrawals made during the grace period.
During the grace period, customers can make multiple cash‑out transactions without penalty as long as the total amount withdrawn does not exceed the matured CD balance.
When cumulative withdrawals go beyond the matured CD balance, only the excess amount is classified as an early withdrawal and is subject to the grace‑period penalty defined at the deposit product level.
If a withdrawal reduces the remaining balance below the previous principal amount, the Pismo platform applies the grace‑period penalty.
This behavior is deterministic and evaluated per transaction:
- The penalty applies only to the withdrawal that causes the cumulative amount to exceed the matured balance.
- The penalty is calculated solely on the excess amount and is never applied retroactively.
How it works
| Calculation factor | Description |
|---|---|
| Type | Percentage-based |
| Basis | Withdrawn amount |
| Equivalent to | penalty_interest_days days of interest |
| Duration | duration_days |
Example
"grace_period": {
"duration_days": 10,
"penalty_interest_days": 30
}In this example, a withdrawal made during the ten-day grace period triggers a penalty only if it causes the remaining balance to fall below the previous CD principal. If that happens, the Pismo platform applies a penalty equivalent to 30 days of interest.
NoteThere is an option for you to accrue interest during grace period. Refer to
accrue_during_grace_periodin Create deposit product for more details.
Withdrawal fee
This penalty is a generic withdrawal fee that you can configure as either a percentage-based fee or a fixed amount.
How it works
| Calculation factor | Description |
|---|---|
| Type | Percentage-based or fixed amount |
| Values | The product defines these directly in the withdrawal_fee configuration object |
Example
"withdrawal_fee": {
"type": "PERCENTAGE",
"value": 1.5
}In this example, a 1.5% fee is applied to the withdrawn amount because the penalty is configured using the PERCENTAGE type.
Required accounting configuration
Penalty‑enabled CD accounts rely on accounting components that you must provide before penalty transactions can post. Each penalty type needs a transaction type and a transaction flow, and these objects define how the penalty appears in the ledger and in financial accounting, and how the fee connects to the withdrawal operation.
The four building blocks
These objects work together to support penalty operations. Each one answers a different part of the penalty configuration.
| Object | What it answers | Role |
|---|---|---|
| Fee model | What to charge and how much | Holds a fees[] array. Each fee has an ID and a calculation method (calculation) such as FIXED, PERCENTAGE, GREATER, or DYNAMIC_BY_AMOUNT. Refer to Create fee model for more details. |
| Processing code | When to charge | Identifies the financial operation. The fee is ignored if the operation does not match the processing code linked to the fee. |
| Transaction type | How it appears in the ledger | Defines credit and posted transactions. Custom IDs start at 7000 because lower values are reserved for Pismo internals. |
| Transaction flow | The wiring | Maps one processing code to one transaction type using a key such as PRINCIPAL, INSTALLMENT, CONTRACT, or OTHER. |
What you provide
| Item | Description |
|---|---|
| Transaction type | Defines credit, posted_transaction, and how the entry appears in the ledger and financial accounting. Custom IDs start at 7000 because lower values are reserved for Pismo internals. |
| Transaction flow | Maps one processing code to one transaction type. The mapping uses a key such as PRINCIPAL, INSTALLMENT, CONTRACT, or OTHER. |
| Processing code | Identifies when the penalty is charged. Penalties use Pismo’s standard processing codes: PSM175 for the penalty charge and PSM176 for the reversal. |
How the components work together
A fee model only calculates the penalty amount. It does not create a transaction. To convert a calculated penalty into accounting entries, the fee must land in a transaction type through a transaction flow. Penalty operations need two transaction types mapped to the same processing code. The PRINCIPAL mapping covers the withdrawal operation. The OTHER mapping covers the penalty amount.
When the key is OTHER, the transaction flow must include a custom_key. This value ties the flow to a specific fee inside the fee model. custom_key is the fee ID plus the suffix Amount. For example, if the fee ID is earlyWithdrawalAfterOpeningID, the custom_key is earlyWithdrawalAfterOpeningAmount. Incorrect suffixes or fee IDs prevent the penalty from posting.
Penalty configuration
Example (PRINCIPAL)
PRINCIPAL)This example shows how to configure a penalty that subtracts a principal amount as the deduction method.
curl --request POST \
--url https://sandbox.pismolabs.io/transactions-core/v1/transaction-flow \
--header 'Content-type: application/json' \
--data '{
"key": "PRINCIPAL",
"transaction_type_id": 10000,
"processing_code": "PSM175",
}'Using the example, you
- set the processing code for the penalty. In the example, use
PSM175for debit. - define the transaction type by assigning a transaction type ID supplied by the client.
- map the withdrawal operation to its transaction type using key
PRINCIPAL, which shows that the amount comes from the principal.
Example (OTHER)
OTHER)Besides using principal to cover a penalty, you can set the key OTHER and pass a custom_key value to show that the penalty is paid through an alternative method. In this example, you use PSM175 as the processing code.
curl --request POST \
--url https://sandbox.pismolabs.io/transactions-core/v1/transaction-flow \
--header 'Content-type: application/json' \
--data '{
"key": "OTHER",
"transaction_type_id": 10001,
"processing_code": "PSM175",
"custom_key": "earlyWithdrawalAfterOpeningAmount"
}'- Set the processing code
PSM175for the penalty. - Map the penalty amount to its transaction type using key
OTHERand acustom_keyvalue, wherecustom_keyis the fee ID with the suffixIDreplaced byAmount(for example,earlyWithdrawalAfterOpeningPenaltyIDbecomesearlyWithdrawalAfterOpeningPenaltyAmount). - Upon completion, the Pismo platform attaches the fee model to your organization, program, or account.
For details, refer to Create transaction flow.
Penalty types
| Penalty type | Fee ID | Transaction flow |
|---|---|---|
| Early withdrawal after opening | earlyWithdrawalAfterOpeningPenaltyID | earlyWithdrawalAfterOpeningPenaltyAmount |
| Tiered interest forfeiture | tieredInterestForfeiturePenaltyID | tieredInterestForfeiturePenaltyAmount |
| Grace period | gracePeriodPenaltyID | gracePeriodPenaltyAmount |
| Withdrawal fee | withdrawalFeePenaltyID | withdrawalFeePenaltyAmount |
| Subsequent withdrawal | subsequentWithdrawalPenaltyID | subsequentWithdrawalPenaltyAmount |
For each penalty type, you provide one transaction type for the penalty and one transaction flow that maps the withdrawal or detach processing code to that transaction type. Your custom_key must point to the penalty’s fee ID. The fee model containing these penalty fees must be attached to the account or program. This is handled by the Pismo platform.
NoteThe processing code used in the fee model must match the processing code used in the interest plan. This serves as a precedent for the configuration requirements described here. Refer to Create interest plan and Fee models for more details.
Penalty calculation
Penalty calculation depends on the penalty type.
Percentage-based penalties
This model applies to:
- Early withdrawal after opening
- Subsequent withdrawal
- Grace period
- Withdrawal fee when configured as a percentage
The Pismo platform derives the effective penalty percentage from the product’s interest settings.
Example parameters
The following formula is used to calculate a percentage-based penalty.
| Calculation factor | Value |
|---|---|
fixed_interest_rate | 3% annually |
accrual_basis | 365 |
penalty_interest_days | 7 |
withdrawal_amount | 10,000 |
Step 1: Compute the daily rate
daily_rate = fixed_interest_rate / accrual_basis
daily_rate = 0.03 / 365 ≈ 0.0000822Step 2: Compute the penalty factor for X interest days
penalty_factor = daily_rate * penalty_interest_days
penalty_factor = 0.0000822 * 7 ≈ 0.0005754Step 3: Convert the factor into a percentage
penalty_percent = penalty_factor * 100
penalty_percent ≈ 0.05754 (%)Step 4: Apply the percentage to the withdrawal amount
penalty_amount = withdrawal_amount * (penalty_percent / 100)
penalty_amount = 10,000 * 0.0005754 ≈ 5.75Result
The penalty amount is 5.75.
Fixed-amount penalties
This model applies to:
- Tiered interest forfeiture
- Withdrawal fee when configured as a fixed amount
The Pismo platform computes a monetary penalty based on forfeited interest days.
Example parameters
| Calculation factor | Value |
|---|---|
interest_rate | 3% annually |
accrual_basis | 365 |
forfeited_interest_days | 30 |
| CD principal amount | 500 |
Formula
penalty = (((1 + (interest_rate * n / accrual_basis)) * CD_amount) - CD_amount)Applied example
Note that the subtraction of 500 removes the original principal amount, ensuring the formula returns only the interest portion, which represents the penalty.
penalty = (((1 + (0.03 * 30 / 365)) * 500) - 500)
penalty ≈ 1.23Result
The fixed penalty amount is 1.23. The Pismo platform then uses this monetary value as the fixed amount for the fee model.
Simulate penalties
Before performing an actual withdrawal, you can preview the penalties that would apply by using the Simulate penalty endpoint:
The simulation is read-only and does not modify any data. It evaluates all penalty rules configured for the account's product, including:
- Early withdrawal after opening
- Grace period
- Tiered interest forfeiture
- Withdrawal fee
- Subsequent withdrawal
For details about penalty types, refer to the penalties object in Create deposit product.
Request parameters
| Field | Required | Description |
|---|---|---|
withdrawal_date | Yes | Simulated withdrawal date, in ISO 8601 format. For example, 2026-12-15T00:00:00Z. |
withdrawal_amount | No | The amount the customer intends to withdraw. When passed, it must not exceed the current book balance. When omitted, the Pismo platform simulates a full withdrawal. |
Simulate a full withdrawal
If you omit withdrawal_amount, the Pismo platform fetches the account's current book balance using Get transaction banking account balance and calculates the penalty on that value. This lets you simulate a full withdrawal without having to look up the balance first.
The withdrawal_amount returned in the response shows the value used in the simulation, which equals the book balance when the field was omitted in the request.
Request example for a full-withdrawal simulation:
curl --request POST \
--url https://sandbox.pismolabs.io/savings-products/v1/deposits/accounts/accountId/penalty-simulation \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"withdrawal_date": "2026-12-15T00:00:00Z"
}Response example:
{
"withdrawal_amount": 40667.17,
"withdrawal_date": "2026-12-15T00:00:00Z",
"penalty_rule_applied": [
{
"type": "fixed",
"value": 50.00,
"description": "Withdrawal fee"
},
{
"type": "percentage",
"value": 181.75,
"description": "Early withdrawal after opening penalty"
}
],
"penalty_amount": 231.75,
"penalty_breakdown": {
"fixed_amount": 50.00,
"percentage_amount": 181.75
},
"currency": "BRL",
"gross_amount": 41329.34,
"interest_earned_amount": 667.17,
"net_amount": 41097.59,
"simulation_timestamp": "2026-06-19T19:22:55Z"
}In this example, you can see the results of a withdrawal simulation, including any applicable penalty rules, penalty amounts, and calculated withdrawal values.
Response fields
| Field | Description |
|---|---|
withdrawal_amount | The withdrawal amount used in the simulation. Equals the book balance when omitted in the request. |
withdrawal_date | The withdrawal date used in the simulation, in ISO 8601 format. |
penalty_rule_applied | List of penalty rules that apply to the withdrawal. Each item includes type (percentage or fixed), value, and description. Omitted when no penalties apply. |
penalty_amount | Total penalty amount, combining all relevant penalty rules. |
penalty_breakdown | Total penalty split by calculation type, in fixed_amount and percentage_amount. Omitted when no penalty applies. |
currency | Currency in ISO 4217 alphabetic format. Omitted when no penalty applies. |
gross_amount | Gross amount of the deposit account: total balance without interest plus total interest earned. Always present; 0 when no total record exists. |
interest_earned_amount | Total interest earned (paid or capitalized) on the account. Always present; 0 when no total record exists. |
net_amount | Net amount after deducting penalties: gross_amount - penalty_amount. |
simulation_timestamp | Date and time of the simulation, in ISO 8601 format. |
Simulation rules and errors
- A
withdrawal_dateinside the cool-off period results in no penalties. withdrawal_datemust not be in the past.- A withdrawal_amount of zero or a negative value is rejected.
- A
withdrawal_amountgreater than the current book balance is rejected, and the error details return the available balance. - Simulation is available only for deposit accounts.
Key rules and considerations
- Penalties are evaluated at withdrawal time.
- A single withdrawal can trigger multiple penalties if the product configuration allows it.
- Percentage-based penalties depend on the product’s interest plan to derive the effective rate.
- To preview penalties for a planned withdrawal, including a full withdrawal, use the Simulate penalty endpoint. Refer to Simulate penalties for more information.
- Tiered interest forfeiture tiers must be:
- non-overlapping
- logically ordered
- bounded by the product’s maximum term
Example penalties object
This example shows how a CD product can define multiple penalties.
"penalties": {
"early_withdrawal_after_opening": {
"applicable_within_days": 10,
"penalty_interest_days": 7
},
"tiered_interest_forfeiture": [
{
"min_days_held": 1,
"max_days_held": 90,
"forfeited_interest_days": 30
},
{
"min_days_held": 91,
"max_days_held": 180,
"forfeited_interest_days": 90
}
],
"subsequent_withdrawals": {
"window_behavior": "ROLLING",
"applicable_within_days": 6,
"penalty_interest_days": 7
},
"grace_period": {
"duration_days": 10,
"penalty_interest_days": 30
},
"withdrawal_fee": {
"type": "PERCENTAGE",
"value": 1.5
}Updated 3 days ago