Skip to content

bug: a dismissed payment request comes back after reset and restore #1156

Open

Description

@ovitrif

What happened?

A Payment Request dismissed on the payer comes back as pending after Reset And Restore, and its Payment Request sheet opens again after Get Started.

Seen while running the allowance journeys for #1141 (J3, then J5 restore-keeps-history.xml):

  • A $2 one-time request ("AfterEnd") arrived after the payer's allowance had ended, so it asked as an ordinary Payment Request and waited in the bell.
  • The payer opened the bell and tapped Dismiss on that row (PaymentRequestDismiss-<id>). This is Dismiss in the list, not Decline in the sheet. The request left the list.
  • Later in the run the payer made a $2 automatic payment, waited until Data Backups showed "Boosts & Transfers" backed up after it, then did Reset And Restore from the recovery phrase.
  • After the restore, "AfterEnd" was pending again, and its sheet ($2.00 from Leo) opened right after Get Started.

Leads, on master (85e9d4c)

  • Dismiss on a request that still needs acceptance calls reject(request) (PaykitPaymentRequestManager.dismiss in Bitkit/Services/PaykitPaymentRequestService.swift), so the dismissal is a rejection kept in Paykit SDK state, not an app flag. The restored state brought the request back as pending. It is not confirmed whether the restored SDK snapshot predates the rejection or does not carry it; this is the main open question.
  • The sheet opening again has a separate cause: the ids of requests already presented (PaykitPaymentRequestIdStore with .paykitPresentedPaymentRequests) are not part of the wallet backup. PaykitPaymentStateBackup carries subscriptions, pending proofs, the active on-chain attempt and accepted one-time requests only (PaykitPaymentProofService backup snapshot). A restored wallet therefore treats every pending request as never presented. save() signalling a backup only for .paykitAcceptedPaymentRequests follows from that, rather than causing it.
  • Android, from code: PaykitPaymentRequestPresentationStore.save bumps backupStateVersion only for accepted ids, and BackupRepo backs up subscriptions and acceptedOneTimeRequests, not presented one-time ids. A pending request is presented again after a restore there too. Whether Android keeps the rejection across a restore was not checked.

Expected behavior

A request dismissed before a wallet backup stays dismissed after Reset And Restore, and no sheet opens for it.

Steps to Reproduce

  1. On two instances with each other as linked contacts, have the payee send the payer a one-time Payment Request that asks (for example, with no Active allowance).
  2. On the payer, open the bell and tap Dismiss on the request.
  3. On the payer, make any change that triggers a wallet backup, and wait until Settings › Security › Data Backups shows a backup after the dismissal.
  4. Reset And Restore the payer from its recovery phrase and tap Get Started.
  5. The dismissed request is pending in the bell again, and its Payment Request sheet opens.

Logs / Screenshots / Recordings

The payer's reset, restore and the sheet opening for the dismissed "AfterEnd" request (2x; the recovery phrase entry is cut):

j5b-payer2x-cut.mp4

Bitkit Version

E2E Debug build of #1141 at e71b591 against a local bitkit-docker regtest stack. The code paths above are the same on master (85e9d4c).

Device / OS

Two iPhone 16 simulators, iOS 26.5.

Reproducibility

Seen once; not repeated.

Activity

  1. added this to the 3.2.0 milestone on Oct 27, 2026
  2. ovitrif commented on Oct 27, 2026

    @ovitrif
    CollaboratorAuthor

    Triage: 3.2.0. It only shows after Reset And Restore, isn't a regression, and has no fix before tomorrow's 3.1.0 cut. Android likely has the same gap, to be confirmed with the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions