Skip to content

jubin5555/PaymentProcessor

Repository files navigation

Transaction risk Assessment for payment processor (ex Paypal) using Drools

Transaction risk assessment

A payment processor (ex. PayPal) faces several monetary and legal risks. A transaction may be fraudulent, or otherwise illegal, opening them up to legal action. A merchant might not ship a product after accepting money, leading the consumer to demand their money back. And so on. For this reason, risk assessment and management is a big part of payments business. Risk assessment can often be very complex, with many statistical variables as well as hard laws that must be complied with. For this reason, it is often implemented as a combination of a machine learning and rule-based system. In this project, I have implemented an example in which I will weed out transactions that are too risky before adding them. I have used a rule-based programming in Drools to do that.

There are two entities this project :-

Banks

A bank:

  • Can process multiple transactions
  • Is either local or international
  • Can be blacklisted, in which case it can no longer process transactions

Transaction request

This is a representation of a transaction before we have decided if it’s too risky to add to our ontology. A transaction request:

  • Is associated with a single bank
  • Has a specific amount
  • Has a sender and a receiver, identified by their IDs as added to the OWL ontology
  • Has a single category: Medical, Dining, Gambling, Wages, Weapons, Other.
  • Has a timestamp (generated by system)

Assessment rules

We will use our knowledge base about the banks and the incoming transaction request to decide whether we should insert the transaction into our Ontology, or reject it. This should be done according to the following rules:

  1. A bank, once blacklisted, can no longer process any transactions
  2. A transaction request belonging to the category of “Medical”, must go through, regardless of what the following rules evaluate to (unless the bank is blacklisted)
  3. A transaction request with category “Weapons” requires that (necessary, but not sufficient conditions): a. Both the sender and the receiver be trusted (note that only merchants can be trusted, but you just need to check for membership in the class Trusted in your ontology) b. The bank must be local
  4. A transaction request with amount >$100,000 must have at least one of the participants Trusted.
  5. A transaction request with amount >10 times the average amount for the given bank should be rejected (except if it’s the bank’s first transaction).
  6. If <25% of a bank’s past transaction involved a trusted participant, then the bank can no longer process transactions that don’t involve a trusted participant (until the fraction goes up to 25% again).
  7. If a bank suffers 3 transaction rejections in a row, blacklist the bank.

If all the 7 rules are cleared,only then the transaction is added.

Logging

Two log files are maintained, one for accepted transactions, and one for rejected ones. The acceptance log should have the following info per entry:

  • Transaction ID
  • Bank ID
  • Sender ID
  • Receiver ID
  • Amount
  • Category
  • Timestamp The rejection log should have the above, and in addition list the Rule number that it was rejected because of. The rule numbers are as in the above list of rules. These log files are just be txt’s, and should be accessible through the API as detailed in the following section.

Rest API for the Project

Request API Respone Description
POST /addmerchant/:uniqueID { “status”: “success” } Add an individual to Merchant class
POST /addconsumer/:uniqueID { “status”: “success” } Add an individual to Consumer class
POST /addbank/:nationality/:bankID { “status”: “success” } Nationality will be one of “local” or “international”, in lowercase. ID will be unique.
POST/transactionrequest/:senderID/ :receiverID/:bankID/:category/ :amount/:transactionRequestID {“status”: “success”} OR { “status”: “failure”, “reason”: “” } Try to add a transaction. If successful, use the transactionRequestID as the transactionID. If unsuccessful, use the ID in the log anyway. A failure should specify the rule number that caused the failure. Category will be one of the ones listed before, in all lowercase. Amount will be a whole number.
GET /iscommercial/:transactionID { “status”: “success”, “result”: “[true|false]” } or { “status”: “failure”, “reason”: “not a transaction” } Return whether a transaction is commercial.
GET /ispersonal/:transactionID { “status”: “success”, “result”: “[true|false]” } or { “status”: “failure”, “reason”: “not a transaction” } Return whether a transaction is personal.
GET /ispurchase/:transactionID { “status”: “success”, “result”: “[true|false]” } or { “status”: “failure”, “reason”: “not a transaction” } Return whether a transaction is a purchase transaction.
GET /isrefund/:transactionID { “status”: “success”, “result”: “[true|false]” } or { “status”: “failure”, “reason”: “not a transaction” } Return whether a transaction is a refund transaction.
GET /isblacklisted/:bankID { “status”: “success”, “result”: “[true|false]” } or { “status”: “failure”, “reason”: “not a bank” } Returns whether a bank isblacklisted.
GET /bankrejections/:bankID { “status”: “success”, “rejections”: “” } or { “status”: “failure”, “reason”: “not a bank” } Returns the number of rejections suffered by a bank.
POST /reset { “result”: “success” } Reload and start afresh
GET /acceptancelog acceptance log contents Refer to the logging section
GET /rejectionlog rejection log contents Refer to the logging section