iiitl / iiitl/Tap2Eat

[bug]: Prevent double-tap on Checkout "Pay" button from firing multiple payment intents

Open Beginner friendly
#6 1 comment 0 reactions 0 assignees View on GitHub
bug medium
Dominant language
Kotlin
Stars
0
Forks
7
PR merge metrics
No merged PRs in 30d

Description

On the `CheckoutPage`, rapidly tapping the "Continue to Payment" button triggers `getCustomerId()` multiple times before the first call has a chance to complete. Since each call to `getCustomerId()` initiates a new Stripe Payment Intent, a double-tap can silently create duplicate payment intents — leading to potential double charges, corrupted order states, or unpredictable Stripe behavior.

This is a common and critical bug in payment flows. The fix is straightforward: disable the button immediately on the first tap and only re-enable it if the payment process fails, preventing any duplicate calls from ever reaching Stripe.

## Current Behavior

The "Continue to Payment" button at `CheckoutPage.kt` has no debounce or disabled state. Tapping it rapidly fires `getCustomerId()` multiple times in quick succession, creating multiple Stripe Payment Intents for the same order.

## Expected Behavior

The button is disabled immediately after the first tap. If the payment flow succeeds, the user is navigated away and the button state is irrelevant. If the flow fails at any point, the button is re-enabled so the user can try again.

## Acceptance Criteria

- [ ] The "Pay" button is disabled immediately after the first tap inside `setOnClickListener`.
- [ ] `getCustomerId()` is called exactly once per tap — no duplicate Stripe Payment Intents are created on rapid tapping.
- [ ] The button is re-enabled inside every error callback where the payment fails and the user stays on `CheckoutPage`.
- [ ] If the payment succeeds and the user is navigated away, the button state does not need to be restored.
- [ ] The app compiles and runs without crashes after the change.
- [ ] A screen recording demonstrating that rapid tapping no longer triggers multiple payment intents is attached to the PR.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in CheckoutPage.kt at the "Continue to Payment" button's setOnClickListener and trace getCustomerId() through the payment callbacks. Check every error callback that leaves the user on CheckoutPage and verify the button is restored there. Done means rapid tapping causes one call, failures allow retry, and the app compiles and runs without crashes.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin
Domain
mobile, payments
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.