/
15 minute read
June 24, 2022

Tutorial: Defining Rules in Real-Time Decisioning (Beta)

Hidden
Note
This feature is currently in beta and subject to change. It also requires additional activation steps. To learn more about the Beta program for this feature and about activating it for your program, contact your Marqeta representative.

This tutorial leads you through the basics of defining and testing business rules using ARIC Model Definition Language (AMDL™). For more information on how to use the Real-Time Decisioning dashboard, see Real-Time Decisioning in the Dashboard. For detailed information on AMDL, see Using AMDL and AMDL Reference.

Access the Real-Time Decisioning dashboard

Rules are defined and tested in the Analytics area of the Marqeta Real-Time Decisioning dashboard. To access the dashboard:

  • Log in to Marqeta Dashboard and select RiskControl > Real-Time Decisioning from the sidebar.
    The Welcome screen appears with your profile, including your permissions.

    Welcome

    Is this helpful?

    Yes
    No
  • From the main menu, select Analytics.
    This is where most of your time will be spent—defining analytics workflows by writing rules and analyzing their impact.

View the current status

When you open Analytics, the Staging Status section is displayed at the top. As you develop a rule or set of rules, the progress is tracked here, including when the rule set was created, what changes were applied, who made the changes, who approved the changes, and when the changes went into live production.

Status

Is this helpful?

Yes
No

See a version history

Analytics includes a version history of your rule set. To view the history:

  • In the upper-left corner, select Version History.
    The versions are listed with the most recent at the top, along with who submitted the rule set, who approved it, when it was created, its current status, and any comments.

  • Select Status in the left pane to close the history.

Create a rule

Real-Time Decisioning is an event-driven system. A rule tracks changes to metadata such as business information, cards, deposit accounts, or users by tracking real-time events. Rules use a real-time event—typically a card transaction—to determine if their logic will or will not trigger and flag a transaction as suspicious. A real-time event in the Marqeta schema is appended with _RT.

When you want to create a rule, first evaluate what you will need to implement and then translate that into a rule written in the AMDL language:

  • Are any variables needed to track user behavior.

  • What logic is required for that behavior.

The following example shows how to create a rule for force post transactions over $100. Your rule will need to determine the following:

  • Is the transaction amount greater than 100?

  • Is this a force post transaction?

  • What action to take when the rule evaluates to true or false?

The following steps and those in later sections show how to implement the above requirements:

  • Make sure that Staging is displayed in the box to the right of Version History in the upper left corner. If not, select Staging. Staging allows you to write and test a rule offline before pushing it live.

  • In the left panel, select Rules. A set of directories where rules are organized by entity is displayed in the work area.

    Create definition

    Is this helpful?

    Yes
    No
  • Select Create Definition.

  • In the popup pane, select Acting User for the directory and then select Create.
    Acting User is the person using the card, making the swipe or chip transaction. Most rules you define will be based on the acting user.

  • Select AMDL Generator from the dropdown list and then select Rule.

  • Name the variable to create—in this example, forcePostTXN100.

  • Deselect Trigger Alert.

  • In Event type select TRANSACTION_RT. The TRANSACTION_RT event is a transaction real-time event. This is the most common event for triggering a rule. It represents a card transaction, a card swipe, a chip transaction that requires an authorization decision in real time.

  • Select transaction.amount for the left operand, Is Greater Than for the operator, and then enter 100 for the right operand.

  • Select Add Rule.

  • Select Match ALL of the following rules.

  • Select transaction.is_force_post for the left operand, Is for the operator, and True for the right operand.

    Submit variable

    Is this helpful?

    Yes
    No
  • Select Submit.
    The AMDL Generator automatically adds the additional AMDL details required for a valid definition.

    Define a rule

    Is this helpful?

    Yes
    No

Define the action

Based on the outcome of the logic you’ve defined, you can specify the action that should be taken. In this example, the rule will decline the transaction if both conditions defined above are met‐that is, the transaction is a force post and is for an amount greater than $100.

  • Add the tag @tag(risk = "true") at the top of the definition. The @tag tells Real-Time Decisioning to decline any transaction that triggers this rule. The tag can be interpreted for downstream actions, such as sending a push notification or SMS to the cardholder or generating a case for your Risk Operations team to investigate.

  • Below that add a comment explaining your rule:
    @comment("This rule triggers when a force post txn greater than 100 occurs")

    Add tag and comment

    Is this helpful?

    Yes
    No
  • Select Save.
    The rule is saved to the Acting User directory.

More about tags

You can use a @tag to send a message that drives any functionality your company has implemented for downstream use, such as @tag(review) or @tag(suspicious). This allows you to append metadata to transactions to be evaluated in real-time, such as sending an SMS message to a cardholder for them that they meant to make a transaction. You could also use a tag to make a downstream API call.

Test your rule

Unit tests allow you to validate your rules to ensure that they function as planned before your submit them for review or push them live. Whenever you introduce a new rule, you should perform unit testing to be sure they are valid and that you are not introducing friction for your cardholders.

To test a rule, create a positive test to determine its behavior when the rule evaluates to true, and a negative test to determine its behavior when the rule evaluates to false. For a positive test, you expect the rule to trigger; for the negative test, you expect the test not to trigger.

The following steps show how to create a positive test and a negative test to validate a rule:

  • Select Tests to open the testing window.

    Create test

    Is this helpful?

    Yes
    No
  • Select the + icon, then select the I cursor icon and rename New Test to Positive.

    Create positive test

    Is this helpful?

    Yes
    No
  • Add a value for the Input.Event (JSON) to represent the transaction. This will be a JSON payload from the Transactions endpoint. When you do your own testing, use test transactions from your integration with the Marqeta Core API. For this example, copy and paste the following code into the Input.Event pane:

    JSON
    Copied

    Is this helpful?

    Yes
    No
  • For this positive test, the JSON above includes "amount": 200, which is over 100 and "is_force_post": "True", which should cause the test to evaluate to true, and for the rule to trigger.

  • Select Save, then select Run Tests

  • Use the Results tab to view the details of the test.

    Debug

    Is this helpful?

    Yes
    No

    The window should display Positive, indicating that the rule evaluated to true.

  • Select the arrow in the Results pane to display all of the results.

  • Scroll down to see all of the results. You should see the following three lines interspersed among the others:
    expressionEvaluation event.transaction.amount > 100.0 true
    expressionEvaluation event.transaction.is_force_post true
    ruleTrigger forcePostTXN100 true
    These indicate that the two tests evaluated to true, and that the rule evaluates and triggers as designed.

  • To test the negative case, copy the code in the Input.Event (JSON) pane. and paste it in for the negative test and save it as Negative.

  • Select the + icon, then select the I cursor icon and rename New Test to Negative.

  • Paste the code you copied for the positive test into the Input.Event (JSON) pane for the negative test.

  • To set the test not to trigger, in the JSON code, set "amount": 90, which is under 100, and "is_force_post": "False", which should cause the test to evaluate to false, and for the rule not to trigger.

  • Select Save and then select Run tests. The combination expression evaluates to false, so the rule will not be triggered. You should see the following three lines in the result:

    expressionEvaluation event.transaction.amount > 100.0 false
    expressionEvaluation event.transaction.is_force_post false
    ruleTrigger forcePostTXN100 false

    In this example both conditions are not met, but the rule would have evaluated to negative if one of either of the two conditions had evaluated to false.

Submit your rule for review

After you save your rule, the Submit for review button at the top of the work area is enabled and you can start the review process. The rule can be directly reviewed or submitted to the sandbox replay. Sandbox replay allows you to use historical transactions to compare the performance of a previous rule set with how your new rule set would have performed.

To submit the rule and run a sandbox replay:

  • Select the Submit for review button in the upper-left corner. The Staging Status is redisplayed, showing that the rule has moved along the timeline into the Review stage.

  • Select Comment and enter a comment for the audit trail. In this example, enter <Your name> has submitted a new rule for review.

  • Under Sandbox Replay, select Start.

  • Set the period of time—for this example, 1 month.

  • In the Run Sandbox Replay window, enter a name—for this example, forcePostTXN100Replay.

  • Select the date range—in this case, Last 24 Hours.

  • For Sampling Type, select Live.

  • For Entity type, and select Acting User.

    Sandbox replay

    Is this helpful?

    Yes
    No
  • Select Run Sandbox Replay.

    The replay compares how often fraudulent transactions over the selected period in the past were being caught by rules and with how the new rule set would have caught them, allowing you to see if your new rule set improves performance. You can use this information to determine whether or not to push the new rule set to live.

Approve the new rule set

When the new rule set’s performance is determined to behave as expected, the rule set can be pushed to live production. Approval is typically done by another user, who must have approval privileges. For the new rule set to go live, the user must approve and push the rule set to live operation.

  • In Analytics > Status, select Approve.

  • Select Comment and enter a comment for the audit trail, in this case <your_name> pushed one rule to production. Real-Time Decisioning processes the submission and pushes the new rule set into live operation.

Update a rule set during a fraud attack

If your company is a fraud attack, you can define a set of rules, and put those rules into effect instantaneously. In this case, you can simply update a rule as necessary and push the change directly live in the Status window.

Another example: deny a fraudulent merchant

If a merchant exhibits fraudulent behavior—for example, spoofing a legitimate website and attempting to perform fraudulent transactions—you may need to deny all transactions from that merchant. To deny a merchant by MCC codes or Merchant ID, you can send a POST to the Authorization Controls endpoint in the Core API to specifically disable a merchant scope. However, using Real-Time Decisioning you can deny service for a single merchant.

The following example shows how to deny service for a fraudulent merchant. In this example, the merchant is using the name GOGLE to spoof the Google website:

  • In Analytics > Rules, select Create definition.

  • In the dropdown panel, select the Merchant directory, and then select Create.

  • Select AMDL Generator and then select Rule.

  • Enter a name for the definition—in this example, MerchantDenyList.

  • Deselect Trigger Alert.

  • For Event Type, select TRANSACTION_RT.

  • Select transaction.card_acceptor.name for the left operand, select Is for the operator, and enter the name of the merchant for the right operand—for this example, enter GOGLE.

    Deny merchant

    Is this helpful?

    Yes
    No
  • Select Submit.

    Deny merchant

    Is this helpful?

    Yes
    No
  • To be more scalable, instead of specifying a single merchant, you could modify rule using the Contains collection membership operator (~#) to test a list of merchants:

    @eventType(TRANSACTION_RT)
    rules.merchantDenyList: [GOGLE, GOGL, GOOG, GGL) ~# event.transaction.card_acceptor.name

    Deny merchant list

    Is this helpful?

    Yes
    No

    You could then update this list over time as necessary. Note that the ~# operator requires a direct match.

  • Select Save.

Use a data list

As you use a rule is used over time, you may need to add additional entities—in this case, additional merchants. Instead of maintaining the list of by updating the rule and pushing the changes through the review process, you can create a data list that can be accessed by the rule and more easily managed.

To create the data list:

  • Select Settings in the main menu, then select Data Lists from the left panel.

  • Select Create Data List.

  • For List name, enter DenyListMerchants.

    Create data list

    Is this helpful?

    Yes
    No
  • Select Create.

  • In Data Lists, select DenyListMerchants.

  • Select Add items manually.

  • In the Add Item window, enter GOGLE as the identifier and Looks like Google but is a fraudulent merchant as the comment.

  • Select Add Item.

    Add list item

    Is this helpful?

    Yes
    No
  • Add the other items to the list—GOGL, GOOG, and GGL.

  • Select Analytics > Rules, open the rule definition that you created above, and delete the AMDL code.

  • Select AMDL Generator.

  • In the AMDL Generator popup window, enter useDenyListMerchants as the name, select transaction.card_acceptor.name as the left operand, In List for the operator, and DenyListMerchants as the right operand.

    Insert data list

    Is this helpful?

    Yes
    No
  • Select Submit.

    Data list

    Is this helpful?

    Yes
    No

    Now the data list has replaced the array. Whenever the data list is updated, it will be automatically applied in the rule.

  • Now enter a line space at the top, and enter @tag(risk = "true") to indicate that the rule will decline the transaction if the condition is met.

Example Three: Track card history

This example shows how to maintain a cardholder history using state, which allows you to track behavior over time—in this case, to determine if a card has been used in two different countries within the space of an hour. In this example you will use state to track card use, and reference one definition from another.

  • In Analytics > Rules, select Create Definition, then select Merchant and Create.

  • Select AMDL Generator, and then select State.

  • In the AMDL Generator popup window, name the rule TXNCountries1Hour.

  • For Event Type, select TRANSACTION_RT.

  • For Schema Property, select transaction.card_acceptor.country_code.

    Last hour

    Is this helpful?

    Yes
    No
  • Select Submit.

  • At the top of the ADML code, add a comment:
    @comment("This state stores the cardholder’s transacting countries in the last hour")

    Add comment

    Is this helpful?

    Yes
    No
  • Now add the logic to track the card over a period of one hour. First, at the top of the definition, enter a line space and enter @. A list of entities, such as lists, sets, tags, are displayed in a dropdown list.

  • In this case, you want to specify that the rule will check within the current one hour period, so select set, enter (1h).

    Logic for one hour

    Is this helpful?

    Yes
    No
  • Select Save.

This definition creates the set of countries where the card has been used in the space of one hour, and will be referenced from another definition that will provide the logic to count the countries in the set.

Count the countries

This definition will reference the definition created in the previous section and count the number of countries where the card has been used in the space of the last hour. The rule will be set to trigger if the card is used in more than two countries within the space of an hour.

  • Select Create definition for Acting User and then select AMDL Generator.

  • For the name, enter CardholderTXNCountries1Hour.

  • Deselect Trigger alert and choose TRANSACTION_RT event.

  • For the left operand, select TXNCountries1Hr that you created in the previous section.

  • For the operator select SizeIsGreaterThan and for the right operand enter 2.

    Check the number of countries

    Is this helpful?

    Yes
    No
  • Select Submit.

    Number of codes in set

    Is this helpful?

    Yes
    No

    The code will now look at every individual cardholder for how many country codes are contained in the set over the last one hour. The rule triggers whenever that count is greater than 2.

  • At the top, add the tag and comment as follows:
    @tag(risk="true")
    @comment("Subsequent transactions over 2 are made in different countries within 1 hour.")

  • Select Save.

Because rules are evaluated before states, this definition needs some adjustment to ensure that the state is updated before the rule is evaluated.

Use the State scope

By modifying the logic, you can ensure that the state is evaluated before the rule. For more on how states are evaluated, see State in workflows.

For this example, when an incoming transaction is received the rule must determine whether that country code already exists in this state. The state must then be updated before the rule is evaluated. When a transaction is received, the country code is evaluated to determine if it already exists in the set in the last hour:

  • If it does not already exist, it receives a value of 1.

  • If it does exist, it receives a value of 0.

To implement this in AMDL, replace the current rule logic as follows:

  • Delete the following code:
    'rules.CardholderTXNCountries1Hour: state.TXNCountries1Hour.size() > 2'

  • Now add the following:
    state.CardholderTXNCountries1Hour: (state.TXNCountries1Hour !# event.transaction.card_acceptor.country_code > 1; 0) + state.TXNCountries1Hour.Size()) > 2

    Order of operations

    Is this helpful?

    Yes
    No

    This rule now tracks for new country codes that arrive over the last hour. If the code is new, it is added to the size and compared to determine if the total is greater than 2. Because of the order of operations, you must be sure to count the incoming transactions in addition to the data you are storing in the state.

  • Select Save.

Join our developer newsletter