Skip to main content
Controls are optional mandate_options fields that govern how and when payments are executed under a mandate. They sit alongside the consent bounds the customer agreed to but do not change them. Use them when you need to enforce period caps, restrict payment timing, or define retry behaviour after a failure.
These fields are ceilings and constraints, not instructions for when or how often to collect.All constraints are cumulative: a payment must satisfy every active constraint simultaneously.The platform will not execute a payment that would violate any one of them.

Period Limits

Applies rolling caps within a defined time window, useful for preventing over-collection within a billing period. Period limits apply to scheduled and on_demand mandates. They do not apply to installment mandates, where total_amount and terms.max_occurrences serve as the aggregate consent ceiling. No more than 2 payments per month, capped at 500.00 ZAR total within the window:
{
  "mandate_options": {
    "type": "on_demand",
    "period_limits": {
      "period": "month",
      "max_count": 2,
      "max_amount": 50000
    }
  }
}
You can also control how the window is aligned using the window field. By default, windows align to calendar boundaries (e.g. the 1st of each month). Use cycle mode with an anchor to align to a specific date instead. The same limits, with the monthly window resetting on the 15th:
{
  "mandate_options": {
    "type": "scheduled",
    "period_limits": {
      "period": "month",
      "max_count": 2,
      "max_amount": 50000,
      "window": {
        "mode": "cycle",
        "anchor": {
          "type": "day_of_month",
          "day": 15
        }
      }
    }
  }
}
When period_limits.max_amount is set, it must be greater than or equal to amount.max, since it represents a cumulative ceiling across multiple payments within the window.Setting max_amount lower than the per-payment cap is a contradiction and will be rejected.
Provider mapping behavior When period_limits.max_amount is set, providers receive it as the collection ceiling for the period. The platform enforces the per-payment amount.max constraint independently before submitting to the provider. When period_limits is not set, some providers derive the collection ceiling from the consented amount (fixed) or amount.max (variable), using the recurrence interval as the implicit period window. When recurrence is also absent, providers derive the ceiling from amount only, with no period anchor.
validity_period and period_limits are independent constraints, both evaluated separately and both must pass for a payment to be permitted.validity_period controls whether the mandate is active at all.period_limits controls how much or how often within a window.Neither overrides the other.
Calendar windows are fixed to calendar boundaries regardless of when the mandate becomes active. The window does not start from the mandate active date.
The first period window may be partial.A mandate active from March 28th with max_count: 1 per month permits one charge in the remainder of March and another on April 1st, just 4 days later, because they fall in different calendar windows. This applies even when start_date is omitted, since the mandate becomes active on the day of creation.The same applies in cycle mode.A mandate active from March 28th with a cycle anchor on the 15th runs its first window from March 15th to April 14th. Charges before March 28th are blocked by the validity constraint, but the window itself started on the 15th, so the usable portion of the first window is only March 28th to April 14th.
Set validity_period.start_date explicitly and align it with the period boundary.This ensures the mandate becomes active exactly when the first window opens, giving the integrator and the customer a clean, predictable first period.
Calendar mode: start date aligned to the 1st of the month start_date is set to April 1st, which coincides with the calendar month boundary. The first window runs from April 1st to April 30th in full:
{
  "mandate_options": {
    "type": "scheduled",
    "validity_period": {
      "start_date": "2026-04-01"
    },
    "period_limits": {
      "period": "month",
      "max_count": 2,
      "max_amount": 50000
    }
  }
}
Cycle mode: start date aligned to the anchor day start_date is set to April 15th, matching the cycle anchor. The first window runs from April 15th to May 14th in full:
{
  "mandate_options": {
    "type": "scheduled",
    "validity_period": {
      "start_date": "2026-04-15"
    },
    "period_limits": {
      "period": "month",
      "max_count": 2,
      "max_amount": 50000,
      "window": {
        "mode": "cycle",
        "anchor": {
          "type": "day_of_month",
          "day": 15
        }
      }
    }
  }
}

Spacing

Controls the minimum and maximum number of calendar days allowed between successful payments. Useful for preventing payments from landing too close together or drifting too far apart. Spacing applies to on_demand mandates. Payments no sooner than 7 days apart and no later than 31 days apart:
{
  "mandate_options": {
    "type": "on_demand",
    "spacing": {
      "min_interval_days": 7,
      "max_interval_days": 31
    }
  }
}
If not specified, no spacing constraints are enforced.

Allowed Days

Restricts payments to specific days within a given time scope. Use this on on_demand mandates when collections must land on predictable, well-defined dates (for example, always on the 1st and 15th of the month, every Monday, or on a specific date each year). For scheduled mandates, use recurrence.on instead. Four constraint types are supported: Day of month (monthly billing): payments only on specific calendar days each month. Payments permitted on the 1st and 15th of each month, adjusted to the nearest weekday if they fall on a weekend:
{
  "mandate_options": {
    "type": "on_demand",
    "allowed_days": {
      "type": "day_of_month",
      "days": [1, 15],
      "adjustment": "nearest_weekday"
    }
  }
}
Day of week (weekly billing): payments only on specific days of the week. Payments permitted on Mondays, Wednesdays, and Fridays only:
{
  "mandate_options": {
    "type": "on_demand",
    "allowed_days": {
      "type": "day_of_week",
      "days": ["mon", "wed", "fri"]
    }
  }
}
Day of year (annual billing): payments only on specific dates each year. Payments permitted on January 15th each year:
{
  "mandate_options": {
    "type": "on_demand",
    "allowed_days": {
      "type": "day_of_year",
      "dates": [
        { "month": 1, "day": 15 }
      ]
    }
  }
}
Multiple dates are also supported. For example, to allow payments on both January 15th and July 1st each year:
{
  "mandate_options": {
    "type": "on_demand",
    "allowed_days": {
      "type": "day_of_year",
      "dates": [
        { "month": 1, "day": 15 },
        { "month": 7, "day": 1 }
      ]
    }
  }
}
Nth day of month (specific occurrence billing): payments only on a specific day occurrence each month. Payments permitted on the second Monday of each month:
{
  "mandate_options": {
    "type": "on_demand",
    "allowed_days": {
      "type": "nth_day_of_month",
      "day": "mon",
      "occurrence": 2
    }
  }
}
The adjustment field on day_of_month and day_of_year controls what happens when a scheduled day falls on a weekend.Defaults to nearest_weekday if not specified:
  • nearest_weekday (default): shifts to the closest weekday, either forward or backward.
  • next_weekday: always shifts forward to the next Monday.
  • previous_weekday: always shifts backward to the preceding Friday.
  • none: no adjustment is applied. The payment is scheduled on the weekend day as defined.

Recovery

These fields define how the merchant may handle failed payments, controlling retry behaviour under the mandate.

Retry Policy

Defines how failed collections may be retried via new next_in_series payments. Retries are business retries, not automatic re-attempts, but explicit new payment sessions initiated by the merchant at a later time. Retry policy applies to scheduled, on_demand, and installment mandates. Up to 3 retries, at least 3 days apart, permitted within 30 days of the original failure:
{
  "mandate_options": {
    "type": "on_demand",
    "retry_policy": {
      "max_retries": 3,
      "min_days_between_retries": 3,
      "max_days_since_failure": 30
    }
  }
}
  • max_retries: maximum number of retry attempts after a failed payment. If not specified, unlimited.
  • min_days_between_retries: minimum gap between retry attempts. If not specified, no minimum is enforced.
  • max_days_since_failure: how long after the original failure retries are still permitted. If not specified, retries may occur indefinitely.