Reported December 2023
Stripestring

Parse and Enrich Imported Card Data

Reported by candidates from Stripe's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Stripe OA. Under 2s to a working solution.
Founder's read

The Stripe OA reported in December 2023 looks like trivial string work, and that's the trap. Parse and Enrich Imported Card Data hands you two CSV strings and asks for a joined, reformatted output. The edge case that breaks a naive solution is sitting in the examples: empty name fields and three-character expirations. If you split on commas without thinking, or slice the expiration from the left, you'll get wrong answers on rows that look fine. You've got a hash map join and careful string slicing. That's it. If you blank mid-assessment, StealthCoder runs invisibly as a safety net and gives you the solution.

The problem

Stripe merchants can import active card data from another payment processor. You are given two valid CSV strings.
cardsCsv has header customer_id,card_id,first_name,last_name,card_number,expiration. The expiration uses MYY or MMYY, with a two-digit year in the 21st century.
usersCsv has header customer_id,email.
For each card row, combine the non-empty first and last names with one space, split the expiration into an unpadded month and a four-digit year, and attach the matching user's email.
Return CSV rows beginning with customer_id,card_id,email,cardholder_name,card_number,exp_month,exp_year. Preserve card input order.

Function
parseAndEnrichCardData(cardsCsv: String, usersCsv: String) → String[]

Examples
Example 1
cardsCsv = "customer_id,card_id,first_name,last_name,card_number,expiration\ncus_100,card_100,John,Doe,4242424242424242,1023\ncus_200,card_200,Jane,Doe,5555555555554444,921\ncus_300,card_300,Roberts,6011111111111117,820"
usersCsv = "customer_id,email\ncus_300,rob@example.com\ncus_100,john@example.com\ncus_200,jane@example.com"
return = ["customer_id,card_id,email,cardholder_name,card_number,exp_month,exp_year","cus_100,card_100,john@example.com,John Doe,4242424242424242,10,2023","cus_200,card_200,jane@example.com,Jane Doe,5555555555554444,9,2021","cus_300,card_300,rob@example.com,Roberts,6011111111111117,8,2020"]
The user rows may arrive in another order. Cards retain their original order, names are combined from non-empty pieces, and each expiration is split into month and four-digit year.
Example 2
cardsCsv = "customer_id,card_id,first_name,last_name,card_number,expiration\nc1,k1,Ada,Lovelace,4000000000000001,125\nc2,k2,Grace,4000000000000002,1128"
usersCsv = "customer_id,email\nc1,ada@pay.test\nc2,grace@pay.test"
return = ["customer_id,card_id,email,cardholder_name,card_number,exp_month,exp_year","c1,k1,ada@pay.test,Ada Lovelace,4000000000000001,1,2025","c2,k2,grace@pay.test,Grace,4000000000000002,11,2028"]
A three-character expiration has a one-digit month. An empty last name contributes no extra space.
Example 3
cardsCsv = "customer_id,card_id,first_name,last_name,card_number,expiration"
usersCsv = "customer_id,email"
return = ["customer_id,card_id,email,cardholder_name,card_number,exp_month,exp_year"]
When there are no card records, return only the output header.

Constraints
Each CSV contains its exact header followed by between 0 and 100000 data rows.
Fields contain no commas, line breaks, or surrounding whitespace.
Customer and card IDs are unique in their respective inputs, and every card customer has exactly one user row.
At least one of first name and last name is non-empty.
Every expiration has length 3 or 4, represents a month from 1 through 12, and ends with a two-digit 21st-century year.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The pattern is a hash join plus string parsing. Build a map from customer_id to email out of usersCsv, then walk cardsCsv in order and emit one row per card. The expiration trick: the last two characters are always the year, and everything before them is the month. So slice from the right, not the left. Parse the month as an integer to drop any padding, and the year is 2000 plus the last two digits. Look at the 921 and 820 cases in the examples. A left-based slice of the first two characters gives you 92 and 82, which is wrong. The name trap is the other one. Filter the non-empty pieces of first and last name and join them with a single space. Watch for the empty-last-name row where the split leaves a blank field. With up to 100000 rows, one pass and a hash map is plenty. If the logic slips on the live OA, StealthCoder is the hedge.

StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.

If this hits your live OA

You can drill Parse and Enrich Imported Card Data cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. If you're reading this with an OA window open, you're who this was built for.

Get StealthCoder

Related leaked OAs

⏵ The honest play

You've seen the question. Make sure you actually pass Stripe's OA.

Stripe reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Parse and Enrich Imported Card Data FAQ

How hard is the Stripe Parse and Enrich Imported Card Data question really?+

It's easy on algorithms and unforgiving on details. There's no clever data structure, just a hash map join and string slicing. Most failures come from the expiration parsing and name handling, not from the join. Read the examples closely and you'll catch both.

What's the trick for splitting the expiration?+

Slice from the right. The last two characters are the year, and whatever remains is the month. Convert the month to an integer so it prints unpadded. Add 2000 to the two-digit year. This handles both the 3-character and 4-character formats with the same code.

How do I handle an empty first or last name?+

Collect the first and last name into a list, drop the empty ones, and join with a single space. That avoids a leading or trailing space. The constraints guarantee at least one name is non-empty, so you never produce an empty cardholder name.

Do I need to worry about CSV quoting or commas in fields?+

No. The constraints say fields contain no commas, line breaks, or surrounding whitespace. A plain split on newline and then on comma is safe. Don't write a full CSV parser. Just handle the header row and the zero-data-rows case.

How should I prepare for this in 48 hours?+

Practice a few string-parsing and hash-join problems that need exact output formatting. Write one solution that reads two CSV strings, joins them by key, and preserves input order. Test the empty input case, since the output must still contain the header line.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Stripe.

OA at Stripe?
Invisible during screen share
Get it