fix(shopinbit): back off the real-car-ticket adoption retries
What changed, and why it matters
This change adjusts how the app waits for a car-purchase ticket to become available. Instead of asking the server every 3 seconds for 36 seconds (12 tries), it now asks fewer times and waits longer between each try. This is a reliability and politeness fix that reduces unnecessary load on the server and the user's device; it does not appear to be a security patch.
No security action required. Treat as a normal reliability/usability improvement. If desired, verify the total timeout still meets user-experience expectations.
Security signals we found
No security-relevant code paths modified
Retry/backoff change only
No input validation, auth, crypto, or network trust changes
Evidence from the diff
The patch replaces a fixed 3-second retry loop (12 attempts, ~36 s total) with an exponential-backoff loop (8 attempts, delays 2, 4, 8, 15, 15, 15, 15 s, ~74 s total) when polling the by-customer endpoint to adopt a real car ticket. The goal is to avoid hammering the endpoint while waiting for the ticket to appear. No authentication, authorization, cryptographic, or input-validation logic is changed.
Changed components
lib/pages/shopinbit/shopinbit_car_research_payment_view.dartShopInBit car research payment flowReal car ticket adoption polling loopInspect captured patch +12 / −5
diff --git a/lib/pages/shopinbit/shopinbit_car_research_payment_view.dart b/lib/pages/shopinbit/shopinbit_car_research_payment_view.dart
index 285e96c..7f34843 100644
--- a/lib/pages/shopinbit/shopinbit_car_research_payment_view.dart
+++ b/lib/pages/shopinbit/shopinbit_car_research_payment_view.dart
@@ -352,13 +352,20 @@ class _ShopInBitCarResearchPaymentViewState
// log-payment gives us the fee receipt id, which the customer key can't
// poll; the real car ticket is a separate id. Find and open it, retrying
- // every 3s for a while since it can take a beat to show up in
- // by-customer.
+ // for a while since it can take a beat to show up in by-customer. Back
+ // off between tries (2s, 4s, 8s... capped at 15s) so we don't hammer the
+ // by-customer endpoint while we wait.
int? realId;
- for (int attempt = 0; attempt < 12 && realId == null; attempt++) {
+ const int maxAttempts = 8;
+ for (
+ int attempt = 0;
+ attempt < maxAttempts && realId == null;
+ attempt++
+ ) {
realId = await service.adoptRealCarTicket(result.ticketId);
- if (realId == null && attempt < 11) {
- await Future<void>.delayed(const Duration(seconds: 3));
+ if (realId == null && attempt < maxAttempts - 1) {
+ final int seconds = (1 << (attempt + 1)).clamp(2, 15).toInt();
+ await Future<void>.delayed(Duration(seconds: seconds));
}
}
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.