Presentations
Templates
Features
Teams
Pricing
Log in
Sign up
Log in
Sign up
Menu
Refactoring monthly fees (card.com)
Ashok Modi
About CARD.com
Offered debit cards with vanity branding
~5 million cardholders
~3-4 million active
2 plans
Single cardholder ($6-10 per month depending on bank)
Waived fees if direct deposits
Family of cards ($20 per month)
About engineering team
8 people
2 lead, 3 senior, 3 mid
Primary monolith codebase
Drupal (PHP CMS/Framework)
2 microservices
Email validation
Image derivative generation
History
Company reorg
Engineering team given responsibilities of Data Eng team
Sep data eng codebases
R Scripts
Charge customers fees
History (cont'd)
Feature request
Add new waivers for users that don't get charged
"Shouldn't take more than a week"
Review old code
1000+ line R script
No separated functions
No real error handling
Not processing cardholders in parallel
Took over 24h to run
Results of review
Made more sense to rewrite code
Bring into monolith
Utilize existing classes around CardHolder
Figure out plans
Figure out waivers
Full test framework
Utilize queueing libraries
Requirements
Fee Schedules
Easy way to have a cardholder get billed on a given date
Support different fees for different products/banks
Fee waivers
Staff
Matched deposit amounts
Inactive accounts
Nice-to-haves
Track history
Know full history when a card was charged/credited monthly fees
Overall idea
Card acquired
Card added to a fee schedule in pending state
Have a scheduled job to check new cards with deposits
Once added, add card to first-fee-queue
Put card on a fee schedule to be charged every 30 days
Overall Idea (cont'd)
Recurring fee
Check cards that are active and have a past 'next_charge_date'
Add them to queue for processing
Queue runner processes card and updates 'next_charge_date' to 30 days from current date
Create new revision of fee schedule row for card
DB Structure (models)
card_fee
Amount proposed/waived/charged/collected
card_fee_(charge_allocation)
Corresponding tables logging and having auditable history
card_fee_schedule
Schedule of fees for cards
Associated revision table for tracking when data is updated
Core classes
AbstractFeeInvoice
Gets proposed amounts, schedules
AbstractFeeWaiver
Gets all credits to be applied to proposed fees
AbstractFeeAllocation
Allocates fees to be collected
AbstractFeeDriver
Makes API calls to charge customer
Code (Runners)
lib/cli
Set of cli entrypoints for running various tasks
queue-first-fees (every 5 minutes)
process-first-fees (background runner)
queue-recurring-fees (every 2 hours)
process-recurring-fees (background runner)
Queues
First Fee queue
When a customer was going to be charged the first time
Would later get added to the recurring fee queue
Recurring Fee queue
When a customer with a scheduled date gets charged
Examples
Show how config variables were set / tables were defined
Show code in lib
Show runner code
Show some of the tests
Outcome
15% revenue increase per month
All cards slated for processing completed within few hours
Slower processing of individual cardholder
Running in queue allowed proper parallelizing
More accurate
Everything validated via testing
Actually easier to add new functionality
Questions?
Thank you
Refactoring MMF
By btmash
Refactoring MMF
528
btmash
Blob of contradictions
btmash.com
btmash
More from
btmash