Stripe New Grad Software Engineer Interview Experience — Four-Part Split Tender Online Assessment

Stripe·Software Engineer·Oct 2026
Online AssessmentNew Gradhard

I converted the screenshot version into text, including some test cases, to help everyone prepare!

Split Tender

Many of Stripe's merchants rely on Stripe Terminal to accept in-person payments at the point of sale. In physical retail, it's common for a customer to cover a purchase with multiple payment methods. For example, they might cover a $100 purchase with a $40 gift card combined with a $60 credit card. This is called a split-tender transaction, and supporting it is a key requirement for retail merchants on Terminal.

For this multi-part question, we will be writing a system to process split-tender payments. When a transaction occurs, the system first deducts from the customer's available gift card balance, then charges the remaining balance to the customer's credit card. Given a chronological stream of payment events, your task is to calculate the correct credit card charge for each transaction. The question is broken down into four parts, each introducing a new event type: gift card expiration, regional credit card surcharges, and complex refund logic.

Function Description

Complete the function process_events in the editor below.

Function Parameters

string events[n]: Lines for each event in chronological order. Lines have a format defined by one of three schemas:

timestamp,ADD_GIFTCARD,customer_id,card_id,amount,valid_before

timestamp,CHARGE,charge_id,customer_id,amount,zip_code

timestamp,REFUND,charge_id,refund_amount

string surcharge_rates[m]: A list of non-overlapping ZIP code ranges mapped to a surcharge percentage in the format start_zip-end_zip:rate, where start and end are inclusive.

Example: 90000-99999:0.05 (representing 5%).

General Constraints and Assumptions

  • Events are in chronological order by timestamp.
  • All event lines are well-formed.
  • charge_id values are unique across CHARGE events.
  • REFUND events always reference a prior CHARGE event.
  • Each charge_id will receive at most one REFUND event.
  • card_id values from ADD_GIFTCARD events are unique.
  • surcharge_rates contains non-overlapping, valid ZIP code ranges.
  • zip_code values are five-digit numeric strings.

Monetary Representation and Precision

  • All monetary amounts in the input and output are represented as non-negative integer numbers of cents. For example, $40.00 is represented as 4000.
  • Surcharge rates are decimal fractions; for example, 0.05 represents 5%.
  • Each surcharge calculation results in a whole number. You don't need to round.

Returns

string[n]: An array of strings, one per input event, in the same order.

For CHARGE events, return the formatted charge string using the schema:

CC_CHARGE_AMOUNT,GIFT_CARD_ID_1:AMOUNT_USED,GIFT_CARD_ID_2:AMOUNT_USED

For all other event types, return an empty string "" unless a later part specifies otherwise.

The length of the output array must exactly match the length of the input events array.

Part 1: Basic Split Tendering

For Part 1, process ADD_GIFTCARD and CHARGE events. All customer balances start at 0.

When an ADD_GIFTCARD event is received, add the specified amount to the designated customer's total gift card balance. Return an empty string "".

When a CHARGE event is received, attempt to cover the transaction cost using the customer's available gift card balance first.

  • If the gift card balance is greater than or equal to the charge amount, deduct the charge amount from their gift card balance. The credit card charge is 0.
  • If the charge amount exceeds the gift card balance, drain the entire gift card balance to 0. The remaining unpaid amount becomes the credit card charge.

Output Format for CHARGE: Return a string starting with the credit card charge, followed by a comma-separated list of the gift cards debited and their amounts (CARD_ID:AMOUNT). If no gift cards were debited, output only the credit card charge.

CC_CHARGE_AMOUNT,GIFT_CARD_ID_1:AMOUNT_USED,GIFT_CARD_ID_2:AMOUNT_USED

Note: In Part 1, each customer will hold at most one active gift card at a time. You do not need to implement card prioritization or sorting logic until Part 2.

Example Input

Suppose we receive the following events in order:

events = [
"1,ADD_GIFTCARD,cust1,gc1,5000,10",  # cust1 gift card gc1 with 5000 cents ($50.00), expiration: t=10
"2,ADD_GIFTCARD,cust2,gc2,2000,15",
"3,CHARGE,chg1,cust2,3000,10000",   # cust2 is charged 3000
"4,CHARGE,chg2,cust1,3000,10000"
]

Example Output

[
"",                  # ADD_GIFTCARD always returns an empty string
"",
"1000,gc2:2000",    # gc2 drained for 2000, remaining 1000 goes to the credit card
"0,gc1:3000"        # gc1 covers the full 3000, so the credit card charge is 0
]

Part 2: Expiration Dates

All constraints from Part 1 still apply. In this part, each gift card has its own individual balance, and a customer may hold multiple gift cards simultaneously, tracked by card_id. Additionally, gift cards have expiration dates: they must be used before their valid_before time.

When a CHARGE event occurs at time T, evaluate the customer's available gift cards:

  • A gift card is valid only if T is strictly less than its valid_before value. If T is at or after valid_before, the gift card is expired and its balance permanently voided.
  • The system must charge valid gift cards by the earliest expiration date first. Completely drain one gift card before moving to the next.
  • Gift cards with no expiration date are considered valid forever and should be used after all valid gift cards with finite expiration timestamps.
  • If multiple gift cards share the exact same expiration timestamp, prioritize the card whose card_id appears first lexicographically.

Output Format for CHARGE: Identical to Part 1. Gift cards must be debited according to the priority rules above. Now that multiple gift cards can be consumed in a single charge, cards must be sorted lexicographically by card_id in the final output string to ensure deterministic matching.

Example Input

events = [
"1,ADD_GIFTCARD,cust1,gc1,5000,10",
"2,ADD_GIFTCARD,cust1,gc2,4000,5",
"3,CHARGE,chg1,cust1,6000,10000",
"11,CHARGE,chg2,cust1,1000,10000"
]

Example Output

[
"",
"",
"0,gc1:2000,gc2:4000",  # cards sorted lexicographically
"1000"
]

Part 3: Surcharges

All constraints from previous parts still apply. Credit card transactions are now subject to regional processing fees using the zip_code and surcharge_rates.

When a CHARGE event occurs, first split the raw charge amount between gift cards and credit card exactly as before. However, our system must now apply a surcharge on the final CC_CHARGE amount according to the following rules:

  • Identify which range in surcharge_rates the event's zip_code falls into. If it does not fall into any range, the rate is 0.
  • Calculate the surcharge strictly on the portion of the bill falling to the credit card. Gift card deductions are not subject to surcharges.
  • The surcharge is calculated as credit_card_portion × rate, then added to the original credit_card_portion to arrive at the final CC_CHARGE. For example, a $100 credit card portion at a 5% surcharge (0.05) yields a final CC_CHARGE of $105.00.

Output Format for CHARGE: Identical to Part 1 and Part 2, but the CC_CHARGE value must reflect the newly calculated total including the surcharge.

Example Input

events = [
"1,ADD_GIFTCARD,cust1,gc1,5000,10",
"2,CHARGE,chg1,cust1,15000,90210"
]
surcharge_rates = [
"80000-89999:0.02",
"90000-99999:0.05"
]

Example Output

[
"",
"10500,gc1:5000"
]

Part 4: Refunds

All constraints from previous parts still apply. You must now handle REFUND events targeting a historical charge_id.

A REFUND event has the following format:

timestamp,REFUND,charge_id,refund_amount

The refund amount represents the total amount to return to the customer, including any refundable credit card surcharge. Refund amounts are guaranteed not to exceed the total amount originally paid for the referenced charge, including surcharge. Each charge_id will receive at most one REFUND event.

When a refund occurs, route the money back to the customer in the following priority:

  • Real dollars: Refund back to the credit card first, up to the amount that was actually charged to the credit card for the referenced charge_id, including surcharge.
  • Store credit second: If refund_amount exceeds the amount refundable to the credit card, refund the remaining amount as store credit by creating a new gift card for the original customer. The new card_id must be formatted as REFUND_{charge_id}. This gift card has no expiration date.

Refund-created gift cards participate in future CHARGE events like any other gift card. Refund-created gift cards never expire. When choosing gift cards for a future charge, non-expiring gift cards are used after all valid gift cards with finite expiration timestamps.

Output Format for REFUND: Return a flat string containing the amount refunded to the credit card and the amount refunded to the store credit gift card, separated by a single comma:

CC_REFUND,GC_REFUND

Example Input

events = [
"1,ADD_GIFTCARD,cust1,gc1,5000,10",
"2,CHARGE,chg1,cust1,15000,90210",
"3,REFUND,chg1,12000"
]
surcharge_rates = [
"90000-99999:0.05"
]

Example Output

[
"",
"10500,gc1:5000",
"10500,1500"  # CC_REFUND, GC_REFUND
]

Appendix: Additional Test Cases

The following test cases were shown in subsequent debugging screenshots. These are separate from the original problem's four example sections.

Test Case 13

Input:

events = [
"1,ADD_GIFTCARD,cust_1,gc_1,5000,10",
"2,CHARGE,chg_1,cust_1,15000,90210",
"3,REFUND,chg_1,12000"
]
surcharge_rates = ["90000-99999:0.05"]

Expected output:

["", "10500,gc_1:5000", "10500,1500"]

Test Case 16

Input:

events = [
"1,ADD_GIFTCARD,cust_1,gc_1,10000,10",
"2,CHARGE,chg_1,cust_1,20000,15000",
"3,REFUND,chg_1,21000",
"15,CHARGE,chg_2,cust_1,5000,15000",
"16,ADD_GIFTCARD,cust_1,gc_2,3000,20",
"17,CHARGE,chg_3,cust_1,9000,15000"
]
surcharge_rates = ["10000-20000:0.10"]

Expected output:

[
"",
"11000,gc_1:10000",
"11000,10000",
"0,REFUND_chg_1:5000",
"",
"1100,REFUND_chg_1:5000,gc_2:3000"
]

Published

Curated and edited by PracHub

Practice the questions from this interview

Discussion

Sign in to join the discussion. The author is notified of every comment.

Loading comments…

Interview at a glance

Company
Stripe
Role
Software Engineer
Level
New Grad
Rounds
Online Assessment
Difficulty
hard
Interview date
Oct 2026
Questions from this interview
1 question

Real Stripe interview experiences

First-hand reports from Stripe candidates — the rounds, the questions they were asked, and how it went.

All 59 Stripe interview experiences