Skip to content

Commit ee7721f

Browse files
Fix line item unit amount parsing from price field. (#13187)
* Fix line item unit amount parsing from price field. * Add another tests.
1 parent 0da09d6 commit ee7721f

3 files changed

Lines changed: 109 additions & 4 deletions

File tree

paymentsheet/src/main/java/com/stripe/android/paymentsheet/repositories/CheckoutSessionResponseJsonParser.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,10 @@ internal object CheckoutSessionResponseJsonParser : ModelJsonParser<CheckoutSess
424424
val quantity = obj.optInt(FIELD_QUANTITY, -1).takeIf { it > 0 } ?: return@mapNotNull null
425425
val subtotal = obj.optLong(FIELD_SUBTOTAL, -1).takeIf { it >= 0 } ?: return@mapNotNull null
426426
val total = obj.optLong(FIELD_TOTAL, -1).takeIf { it >= 0 } ?: return@mapNotNull null
427-
val unitAmount = if (quantity > 0) total / quantity else null
427+
val unitAmount = obj.optLong(FIELD_UNIT_AMOUNT_OVERRIDE, -1).takeIf { it >= 0 }
428+
?: obj.optJSONObject(FIELD_PRICE)
429+
?.optLong(FIELD_UNIT_AMOUNT, -1)
430+
?.takeIf { it >= 0 }
428431
CheckoutSessionResponse.LineItem(
429432
id = id,
430433
name = name,
@@ -525,6 +528,9 @@ internal object CheckoutSessionResponseJsonParser : ModelJsonParser<CheckoutSess
525528
private const val FIELD_LINE_ITEMS = "line_items"
526529
private const val FIELD_ID = "id"
527530
private const val FIELD_QUANTITY = "quantity"
531+
private const val FIELD_PRICE = "price"
532+
private const val FIELD_UNIT_AMOUNT = "unit_amount"
533+
private const val FIELD_UNIT_AMOUNT_OVERRIDE = "unit_amount_override"
528534
private const val FIELD_ADAPTIVE_PRICING_INFO = "adaptive_pricing_info"
529535
private const val FIELD_ACTIVE_PRESENTMENT_CURRENCY = "active_presentment_currency"
530536
private const val FIELD_INTEGRATION_AMOUNT = "integration_amount"

paymentsheet/src/test/java/com/stripe/android/paymentsheet/repositories/CheckoutSessionFixtures.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ internal object CheckoutSessionFixtures {
2929
"name": "Llama Figure",
3030
"quantity": 1,
3131
"subtotal": 999,
32-
"total": 999
32+
"total": 999,
33+
"price": {
34+
"unit_amount": 999
35+
}
3336
}
3437
]
3538
},
@@ -578,15 +581,21 @@ internal object CheckoutSessionFixtures {
578581
"name": "Llama Figure",
579582
"quantity": 2,
580583
"subtotal": 1998,
581-
"total": 1998
584+
"total": 1998,
585+
"price": {
586+
"unit_amount": 999
587+
}
582588
},
583589
{
584590
"id": "li_item2",
585591
"object": "item",
586592
"name": "Alpaca Plushie",
587593
"quantity": 1,
588594
"subtotal": 2499,
589-
"total": 2499
595+
"total": 2499,
596+
"price": {
597+
"unit_amount": 2499
598+
}
590599
}
591600
]
592601
},

paymentsheet/src/test/java/com/stripe/android/paymentsheet/repositories/CheckoutSessionResponseJsonParserTest.kt

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,96 @@ class CheckoutSessionResponseJsonParserTest {
9696
assertThat(lineItems[1].unitAmount).isEqualTo(2499L)
9797
}
9898

99+
@Test
100+
fun `parse line item unitAmount from unit_amount_override`() {
101+
val json = JSONObject(
102+
"""
103+
{
104+
"session_id": "cs_test_override",
105+
"ui_mode": "custom",
106+
"currency": "usd",
107+
"total_summary": { "due": 7000, "subtotal": 7000, "total": 7000 },
108+
"line_item_group": {
109+
"currency": "usd",
110+
"total": 7000,
111+
"subtotal": 7000,
112+
"due": 7000,
113+
"line_items": [
114+
{
115+
"id": "li_override_item",
116+
"object": "item",
117+
"name": "Widget",
118+
"quantity": 2,
119+
"subtotal": 7000,
120+
"total": 7000,
121+
"unit_amount_override": 3500,
122+
"price": {
123+
"unit_amount": 2999
124+
}
125+
}
126+
]
127+
}
128+
}
129+
""".trimIndent()
130+
)
131+
val result = CheckoutSessionResponseJsonParser.parse(json)
132+
133+
assertThat(result).isNotNull()
134+
val lineItems = result!!.lineItems
135+
assertThat(lineItems).hasSize(1)
136+
assertThat(lineItems[0].id).isEqualTo("li_override_item")
137+
assertThat(lineItems[0].name).isEqualTo("Widget")
138+
assertThat(lineItems[0].quantity).isEqualTo(2)
139+
assertThat(lineItems[0].unitAmount).isEqualTo(3500L)
140+
assertThat(lineItems[0].subtotal).isEqualTo(7000L)
141+
assertThat(lineItems[0].total).isEqualTo(7000L)
142+
}
143+
144+
@Test
145+
fun `parse line item unitAmount from price when total includes tax`() {
146+
val json = JSONObject(
147+
"""
148+
{
149+
"session_id": "cs_test_tax",
150+
"ui_mode": "custom",
151+
"currency": "usd",
152+
"total_summary": { "due": 11034, "subtotal": 10198, "total": 11034 },
153+
"line_item_group": {
154+
"currency": "usd",
155+
"total": 11034,
156+
"subtotal": 10198,
157+
"due": 11034,
158+
"line_items": [
159+
{
160+
"id": "li_tax_item",
161+
"object": "item",
162+
"name": "Classic T-Shirt",
163+
"quantity": 2,
164+
"subtotal": 10198,
165+
"total": 11034,
166+
"unit_amount_override": null,
167+
"price": {
168+
"unit_amount": 5099
169+
}
170+
}
171+
]
172+
}
173+
}
174+
""".trimIndent()
175+
)
176+
val result = CheckoutSessionResponseJsonParser.parse(json)
177+
178+
assertThat(result).isNotNull()
179+
val lineItems = result!!.lineItems
180+
assertThat(lineItems).hasSize(1)
181+
assertThat(lineItems[0].id).isEqualTo("li_tax_item")
182+
assertThat(lineItems[0].name).isEqualTo("Classic T-Shirt")
183+
assertThat(lineItems[0].quantity).isEqualTo(2)
184+
assertThat(lineItems[0].unitAmount).isEqualTo(5099L)
185+
assertThat(lineItems[0].subtotal).isEqualTo(10198L)
186+
assertThat(lineItems[0].total).isEqualTo(11034L)
187+
}
188+
99189
@Test
100190
fun `parse returns empty line items when no line_item_group`() {
101191
val json = JSONObject(

0 commit comments

Comments
 (0)