Skip to content

Instantly share code, notes, and snippets.

@cesarcneto
Last active May 24, 2022 09:41
Show Gist options
  • Save cesarcneto/d4106117ac773f1c2c83f023dd6bf6b0 to your computer and use it in GitHub Desktop.
Save cesarcneto/d4106117ac773f1c2c83f023dd6bf6b0 to your computer and use it in GitHub Desktop.
Interview Challenge

Objective

Implement a function that authorizes a transaction for a specific account, following some predefined rules.

Input

You'll receive as input:

  • The account data

    • Card status (active or blocked)
    • Current available limit, i.e., the amount available for purchases for the account.
  • Transaction to be authorized

    • Merchant (the name is enough)
    • Amount
    • Time of the transaction
  • List of approved transactions (using the same data model of the transaction to be authorized)

Output

The output should consist of:

  • Whether the purchase was authorized or not
  • The updated available limit for the account
  • All of the reasons why the transaction was denied, when relevant.

Transaction validation rules

  1. The transaction amount should not be above the account limit
  2. No transaction should be approved when the card is blocked
  3. The first transaction shouldn't be above 90% of the limit
  4. There should not be more than 10 transactions for the same merchant
  5. Transactions from a list of denied merchants should not be approved
  6. There should not be more than 3 approved transactions on a 2 minutes interval
  7. There should not be more than 2 similar transactions (same amount and merchant) in a 2 minutes interval

Guidance

Here are some tips that might help you think about the problem and implement the solution:

  • Consider starting by implementing few rules and then expanding your solution to support the rest.
  • Consider designing the solution as if you were implementing the business logic layer of a service/application.
  • The examples below (in Clojure) suggest how the data structures and function signatures could look like. These are just suggestions; you can use modified versions of the schemas.

Schemas

(def Purchase
  {:merchant s/Str
   :amount   s/Num
   :time     s/Inst})

(def Account
  {:card-status    (s/enum :active :blocked)
   :limit          s/Num
   :denylist       [s/Str]
   :allowlisted?   s/Bool
   :last-purchases [Purchase]})

(def AuthorizeResponse
  {:approved?      s/Bool
   :new-limit      s/Num
   :denied-reasons [s/Keyword]})

(s/defn authorize :- AuthorizeResponse
   [account :- Account, purchase :- Purchase]
   ...)

Examples

(def one-account
  {:card-status    :active
   :limit          500
   :denylist       ["MerchantA"]
   :allowlisted?   false
   :last-purchases []})

(def one-purchase
  {:merchant "MerchantB"
   :amount   100
   :time     #inst "2015-10-10T10:10:00Z"})

(authorize one-account one-purchase)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment