Skip to content

Adapters

components.payment_gateway.subcomponents.rules.adapters.adyen

helpers

expense_limit_rule_to_transaction_rule_info

expense_limit_rule_to_transaction_rule_info(
    description,
    reference,
    external_card_id,
    amount,
    currency,
    period,
    criteria,
    first_day=None,
    is_active=True,
    start=None,
    end=None,
)

Convert our expense limit model into an Adyen TransactionRuleInfo for API creation calls.

Source code in components/payment_gateway/subcomponents/rules/adapters/adyen/helpers.py
def expense_limit_rule_to_transaction_rule_info(
    description: str,
    reference: str,
    external_card_id: str,
    amount: int,
    currency: CurrencyCode,
    period: ExpenseLimitPeriod,
    criteria: list[RuleCriterion],
    first_day: int | None = None,
    is_active: bool = True,
    start: datetime | None = None,
    end: datetime | None = None,
) -> TransactionRuleInfo:
    """
    Convert our expense limit model into an Adyen TransactionRuleInfo for API creation calls.
    """
    # TODO @frederic.bonnet 2025-11-01: temporary override until dead code is removed
    is_active = False  # See https://www.notion.so/alaninsurance/Authorization-Relay-Bugsquashing-Plan-1f11426e8be780b496d4f0a428fba808?source=copy_link#1f11426e8be780cabe83f32f85abc67a

    ruleRestrictions = to_transaction_rule_restrictions(criteria)
    # https://docs.adyen.com/api-explorer/balanceplatform/latest/post/transactionRules#request-ruleRestrictions-totalAmount
    ruleRestrictions.totalAmount = TotalAmountRestriction(
        operation="greaterThan",
        value=Amount(
            currency=currency.value,
            value=amount,
        ),
    )
    return TransactionRuleInfo(
        description=description[0:300],
        reference=reference[0:150],
        type="velocity",
        aggregationLevel="paymentInstrument",
        entityKey=TransactionRuleEntityKey(
            entityType="paymentInstrument",
            entityReference=external_card_id,
        ),
        interval=_to_interval(period, first_day),
        ruleRestrictions=ruleRestrictions,
        startDate=start.isoformat() if start else None,
        endDate=end.isoformat() if end else None,
        status="active" if is_active else "inactive",
    )

to_transaction_rule_restrictions

to_transaction_rule_restrictions(criteria)

Convert our criterion model into an Adyen TransactionRuleRestrictions for API creation calls.

Source code in components/payment_gateway/subcomponents/rules/adapters/adyen/helpers.py
def to_transaction_rule_restrictions(
    criteria: list[RuleCriterion],
) -> TransactionRuleRestrictions:
    """
    Convert our criterion model into an Adyen TransactionRuleRestrictions for API creation calls.
    """
    result = TransactionRuleRestrictions()
    for criterion in criteria:
        if isinstance(criterion, CountryCriterion):
            # https://docs.adyen.com/api-explorer/balanceplatform/latest/post/transactionRules#responses-200-ruleRestrictions-countries
            result.countries = CountriesRestriction(
                operation=_list_match_to_operation(criterion.condition),
                value=[c.value for c in criterion.country_codes],
            )
        elif isinstance(criterion, ProcessingTypeCriterion):
            # https://docs.adyen.com/api-explorer/balanceplatform/latest/post/transactionRules#responses-200-ruleRestrictions-processingTypes
            result.processingTypes = ProcessingTypesRestriction(
                operation=_list_match_to_operation(criterion.condition),
                value=[_to_processing_type(pt) for pt in criterion.processing_types],  # type: ignore[misc]
            )
        elif isinstance(criterion, MCCCriterion):
            # https://docs.adyen.com/api-explorer/balanceplatform/latest/post/transactionRules#request-ruleRestrictions-mccs
            result.mccs = MccsRestriction(
                operation=_list_match_to_operation(criterion.condition),
                value=[mcc.value for mcc in criterion.mccs],
            )
        elif isinstance(criterion, MerchantCriterion):
            # https://docs.adyen.com/api-explorer/balanceplatform/latest/post/transactionRules#request-ruleRestrictions-mccs
            result.merchants = MerchantsRestriction(
                operation=_list_match_to_operation(criterion.condition),
                value=[
                    MerchantAcquirerPair(
                        acquirerId=merchant_id.acquirer_id,
                        merchantId=merchant_id.merchant_id,
                    )
                    for merchant_id in criterion.merchants
                ],
            )
        elif isinstance(criterion, CurrencyCriterion):
            # https://docs.adyen.com/api-explorer/balanceplatform/2/post/transactionRules#request-ruleRestrictions-differentCurrencies
            result.differentCurrencies = DifferentCurrenciesRestriction(
                operation="equals",
                value=not criterion.same_as_card,
            )
        else:
            raise NotImplementedError(f"Unknown criterion type {criterion}")
    return result

usage_restriction_rule_to_transaction_rule_info

usage_restriction_rule_to_transaction_rule_info(
    description,
    reference,
    external_account_id,
    criteria,
    is_active=True,
    start=None,
    end=None,
    allow_zero_amount=True,
)

Convert our usage restriction model into an Adyen TransactionRuleInfo for API creation calls.

Source code in components/payment_gateway/subcomponents/rules/adapters/adyen/helpers.py
def usage_restriction_rule_to_transaction_rule_info(
    description: str,
    reference: str,
    external_account_id: str,
    criteria: list[RuleCriterion],
    is_active: bool = True,
    start: datetime | None = None,
    end: datetime | None = None,
    allow_zero_amount: bool = True,
) -> TransactionRuleInfo:
    """
    Convert our usage restriction model into an Adyen TransactionRuleInfo for API creation calls.
    """
    # TODO @frederic.bonnet 2025-11-01: temporary override until dead code is removed
    is_active = False  # See https://www.notion.so/alaninsurance/Authorization-Relay-Bugsquashing-Plan-1f11426e8be780b496d4f0a428fba808?source=copy_link#1f11426e8be780cabe83f32f85abc67a

    ruleRestrictions = to_transaction_rule_restrictions(criteria)
    if allow_zero_amount:
        # Bypass zero-transactions as they are typically pre-authorizations for wallets and in-app card registrations
        ruleRestrictions.totalAmount = TotalAmountRestriction(
            operation="notEquals",
            value=Amount(
                currency="EUR",  # TODO do we need to support other currencies?
                value=0,
            ),
        )

    return TransactionRuleInfo(
        description=description[0:300],
        reference=reference[0:150],
        type="blockList",
        entityKey=TransactionRuleEntityKey(
            entityType="balanceAccount",
            entityReference=external_account_id,
        ),
        interval=TransactionRuleInterval(
            type="perTransaction",
        ),
        ruleRestrictions=ruleRestrictions,
        startDate=start.isoformat() if start else None,
        endDate=end.isoformat() if end else None,
        status="active" if is_active else "inactive",
    )