feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: add Paykit subscriptions - #685

Open
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions
Open

feat: add Paykit subscriptions#685
ben-kaufman wants to merge 9 commits into
masterfrom
codex/paykit-subscriptions

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #683.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Linked Issues/Tasks

Screenshot / Video

Final iOS and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise failed and uncertain initial payments and verify retry stays in the same sheet while the first period remains due.
  • Complete Lightning and on-chain subscription payments and verify purple/orange success confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • 97 focused PaykitPaymentRequestServiceTests and PaykitPaymentProofServiceTests
  • E2E regtest Debug build for an arm64 iOS simulator
  • Exact build installed and cold-launched on an iOS simulator
  • SwiftFormat validation for all 13 changed Swift files
  • Localization validation
  • git diff --check

@greptile-apps

This comment has been minimized.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Comment threadBitkit/Services/PaykitPaymentProofService.swift
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from fee8601 to 01c4164CompareAugust 28, 2026 14:13
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from a8d71d0 to 059eb83CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 01c4164 to bcf1d8aCompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 059eb83 to 69a0746CompareAugust 31, 2026 14:25
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 69a0746 to 3a1bcd2CompareAugust 31, 2026 18:22
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked on the updated payment-proof branch at c3f2d8c. The subscription layer is unchanged; all commits remain signed, and the complete payment-proof suite (including recurring periods and uncertain on-chain recovery) passes 22/22.

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from c3f2d8c to 281b865CompareAugust 31, 2026 18:30
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from 3a1bcd2 to cf4cea2CompareAugust 31, 2026 18:30
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked again on the final signed payment-proof hardening head 281b8654; current signed subscriptions head is cf4cea28. Focused PaykitPaymentProofServiceTests: 21/21 passing.

@ben-kaufmanben-kaufman mentioned this pull request Aug 31, 2026
2 tasks

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details OK button dismisses an in-progress subscribe or cancel sheet instead of restoring previousRoute.

Comment threadBitkit/Views/Subscriptions/SubscriptionsView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs branch from 281b865 to e66771bCompareSeptember 1, 2026 12:44
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch 3 times, most recently from d68a602 to c274b0aCompareSeptember 1, 2026 16:38
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The subscriptions branch is now correctly restacked on the current signed #683 head (6bcff553); the subscription-only head is c274b0a4, and every commit is verified. After restacking, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests pass 112/112. The earlier details-flow and payment-sheet sequencing fixes remain present. @ovitrif@jvsena42 please re-review the current head; fresh CI is still running.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RequestOrPayView.payContact() and the subscribe-and-pay launches omit alternativeOnchainBalanceSats, so hardware-wallet funds are ignored.
  • SendSheet.startsOnFailure is introduced and never read.
  • SendConfirmationView copies lifecycle modifiers onto body and leaves the originals on confirmationContent.

Comment threadBitkit/Views/PaymentRequests/CreatePaymentRequestView.swift
Comment threadBitkit/Views/Wallets/Send/SendSheet.swift Outdated
Comment threadBitkit/Views/Wallets/Send/SendConfirmationView.swift Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions branch from c274b0a to e641682CompareSeptember 1, 2026 17:18
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Restacked onto #683 signed head 489b1e61; the new subscriptions head is e6416820. The one conflict was in the shared secondary button and was resolved by keeping the subscriptions/Figma-correct shared height plus #683’s shouldExpand behavior. All five subscriptions commits were re-signed.

Post-restack simulator verification passes 134/134 across HwFundingSignerTests, PaykitPaymentProofServiceTests, PaykitPaymentRequestServiceTests, and PaymentNavigationHelperTests.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three comments from the previous review still apply on this restack.

  • Hardware-wallet funding is still omitted from RequestOrPayView.payContact, SubscriptionSheet.accept, and SendSheet.retryEmbeddedInitialSubscriptionPayment.
  • SendSheet.startsOnFailure is still unused.
  • SendConfirmationView still attaches the same lifecycle modifiers on both body and confirmationContent.

ovitrif
ovitrif previously approved these changes Sep 1, 2026

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Base automatically changed from codex/paykit-payment-proofs to masterSeptember 2, 2026 10:57
@jvsena42
jvsena42 dismissed ovitrif’s stale reviewSeptember 2, 2026 10:57

The base branch was changed.

@ovitrifovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

completeOnchainPayment now requires paymentStarted, but the hardware-wallet path only prepare()s before broadcast, so the txid never attaches and the paid period stays due.

Comment threadBitkit/Services/PaykitPaymentProofService.swift
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@ben-kaufman@ovitrif