Repository navigation
Carry main into redesign/main: 3D Secure checkout and the challenge and accountability removal (#746) - #785
Merged
thomasluizon merged 2 commits intoOct 19, 2026
Conversation
* fix(billing): request 3D Secure for subscription checkout * fix(billing): key checkout retries by the 3D Secure policy A checkout request with the new card authentication option must not reuse an idempotency key that a request without it created, because Stripe rejects changed parameters for a retained key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 46e3aac)
* feat: remove challenge and accountability endpoints (ORB-212) * fix: exclude removed achievements from earned totals (ORB-212) (cherry picked from commit c75ab1b)
|
There was a problem hiding this comment.
No new issues found.
Reviewed changes Reviewed both carried commits against redesign/main, including the full diff, surviving backend consumers, and the sibling client's removal of these features.
- Checkout authentication: Requests card 3D Secure with
anyand distinguishes the new policy in checkout idempotency keys without changing subscription, coupon, or return-URL options. - Feature retirement: Removes challenge/accountability endpoints, application logic, registrations, rate policies, and agent catalog actions while retaining friends and unrelated authentication challenges.
- Historical data: Filters removed achievement definitions from returned badges and totals without deleting stored unlocks or XP; retains feature tables, account-reset cleanup, and friend-profile compatibility fields for later contraction.
- Verification: All 428 tests in three focused local runs passed, covering checkout, habit logging, gamification, profile reads, selected redesign agent flows, and retained persistence behavior. CI Build and the OpenAPI Breaking-Change Gate also passed; the full CI test run was still in progress when checked.
The Android release/version-floor gate and hosted 3DS acceptance checks remain the documented release prerequisites. This review did not verify production fleet state or perform browser payment checks.
gpt-6.1-sol | 𝕏
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Carries the two requested main commits onto redesign/main, preserving the redesign API behavior and retaining the challenge and accountability tables for the later contraction.
Refs thomasluizon/orbit-tickets#746
Refs thomasluizon/orbit-tickets#208
Refs thomasluizon/orbit-tickets#218
Carries and resolution
46e3aac4cec26b1368c4df054cd89f691980143f(ORB-202: request 3D Secure for subscription checkout #780): checkout requests card 3D Secure withany; the idempotency key includes the authentication policy. Source and regression tests carried together in60e0a55a, without conflicts.c75ab1bd10044e020295df012022596d3c60091f(Remove challenge and accountability endpoints (ORB-212) #779), carried as749e56bb: removes challenge and accountability controllers, handlers, validators, DI, rate policies, catalog actions, and feature tests; filters removed achievement unlocks from returned badges and totals while retaining stored XP and unlocks. Retains entities, tables, DbSets, mappings, account-reset cleanup, and friend-profile reads for thomasluizon/orbit-tickets#1555.Both carried commits retain the same stable patch IDs as their main originals:
46e3aac4and60e0a55aboth producecb84a51ddbc4e0757b29a9b36a8721b3fee7dd8d;c75ab1bdand749e56bbboth produce23855fe527f21555cd77efa57fd4c636b0519cb4(git show <commit> | git patch-id --stable).Neither commit was skipped. Before each carry, redesign/main had no corresponding cherry-pick trailer and still contained the pre-change implementation. The Stripe checkout lacked PaymentMethodOptions and its policy key; both feature controllers, catalog actions, and feature handlers remained present.
Conflicted paths by redesign commit
5d9ff03e(feat: connect Notion tasks to Astra #732, Notion tasks):src/Orbit.Api/openapi.jsonconflicted where the redesign'sCallbackRequestschema adjoined main's deletedChallengeType. Read both sides and regenerated the document throughdotnet build; the callback schema stays, and the unused challenge schema is removed.7d85e55c(Carry main fixes into redesign main (#746) #756, v2 contract regeneration carrying the Notion schema from feat: connect Notion tasks to Astra #732):src/Orbit.Api/openapi_v2.jsonhad the same conflict. Regenerated throughdotnet buildwith the same result. Neither generated document was hand-merged.All C# merges were automatic and reviewed against both branches. The Astra block error mapping, ask and block stores, pending-write service wiring, proactive catalog entries, Notion catalog entries, and account-reset dependencies retain their redesign additions. No additional redesign-only consumer served the removed features. No migrations or snapshot edits are required, and there is no migration ordering question.
External interface evidence
Source PR #780 records the installed Stripe.net 52.4.2 manifest/source evidence for
SessionCreateOptions.PaymentMethodOptions,SessionPaymentMethodOptionsOptions.Card, andSessionPaymentMethodOptionsCardOptions.RequestThreeDSecure, the serialized field names, supportedanyvalue, and the supplied test-mode acceptance probe. This carry introduces exactly those same SDK option reads and assertions. Re-derive from the package manifest's source commitf4f1c8ce704825d7d7f00b4c9d848a2d028757eband its three linked Checkout option source files.Test evidence
Before the checkout implementation changed,
env -u LANG dotnet test tests/Orbit.Infrastructure.Tests --filter FullyQualifiedName~StripeBillingServiceTestsexited 0 with 38 existing tests passing while the 3D Secure option was absent.With the carried tests present and the original checkout implementation restored, forced a rebuild with
dotnet build src/Orbit.Infrastructure --no-incremental(exit 0), then ran:Exit 1: all five cases failed for the missing options and unchanged pre-policy key. After restoring the carried implementation, the original checkout-suite command exited 0 with all 43 tests passing.
Before the removal, the unchanged existing tests passed 186 cases (exit 0):
With the removed definitions and the original unfiltered query implementations, the carried
Handle_RemovedAchievementEarned_OmitsBadgeAndPreservesXpAndLevelregressions failed all four cases (exit 1), exposing the orphaned unlock in counts and returned profile IDs:env -u LANG dotnet test tests/Orbit.Application.Tests --filter FullyQualifiedName~Handle_RemovedAchievementEarned_OmitsBadgeAndPreservesXpAndLevelAfter restoring both carried query implementations, focused application coverage passed 732 tests and focused infrastructure coverage passed 280 tests, each exit 0. These include habit logging, gamification and historical badges, public profiles, Astra asks and block answers, held writes, the proactive engine, removed routes and policies, content moderation registration, agent catalog and step-up, account reset, retained accountability deletion, idempotency, and snapshot consistency.
Semantic comparison of both regenerated contracts against the branch base confirms exactly ten removed challenge/accountability paths and nine unused schemas per document, zero changed surviving paths or schemas, and the unchanged Notion
CallbackRequestschema. The retained domain entities, DbSets, model configuration, and migration snapshot have no diff.Final verification after both commits, all exit codes read directly:
env -u LANG dotnet build Orbit.slnxLC_ALL=en_US.UTF-8 dotnet build Orbit.slnxenv -u LANG dotnet test tests/Orbit.Domain.Testsenv -u LANG dotnet test tests/Orbit.Application.Testsenv -u LANG dotnet test tests/Orbit.Infrastructure.Testsenv -u LANG dotnet testLC_ALL=en_US.UTF-8 dotnet testFrom
src/Orbit.Infrastructure,env -u LANG dotnet ef migrations has-pending-model-changes --project . --startup-project ../Orbit.Api --no-buildexited 0 and reported: "No changes have been made to the model since the last migration." It used the design-time factory without opening a database connection. The full runs include all 32 analyzer tests.Builds retain warnings from existing dependencies and obsolete APIs. EF reports tool 10.0.12 versus runtime 10.0.13. No suppressions were added. Both commit hooks, generated-contract regeneration, whitespace checks, and the PR prose dash check passed. The working tree is clean. No browser, server, release, database change, or other repository was used.
Manual steps
The following steps are copied unchanged from the source PRs. They remain release prerequisites; this carry performs no release or floor change.
Source #780
.github/workflows/release.yml), dispatched frommain, withenvironment=stagingandbranch=thomasluizon/ticket-208-stripe-3ds. Use the staging web checkout with Stripe test credentials and the published 3DS-required card4000000000003220. Observe the hosted challenge, complete it, inspect the resulting Stripe test subscription for active status, and readGET /api/subscriptions/statusfor the same Orbit user to confirm the paid plan and interval. Repeat with a fresh checkout and fail or abandon authentication: verify no paid Orbit subscription and no successful charge, and a usable return path. These browser checks were not run by this worker, as prohibited by the work order.4000000000003055to confirm the explicit request applies beyond cards already requiring 3DS. Do not expect4242424242424242to display a challenge: Stripe documents it as unenrolled. Withany, frictionless authentication is allowed.environment=productionandbranch=main. Verify the release commit, observe the next real checkouts, and read the existing subscriber's next recurring invoice/subscription state to confirm renewal succeeds. No live release, renewal or payment was performed here. A report that a customer cannot pay is a rollback trigger.PaymentMethodOptions.Card.RequestThreeDSecureor set it toautomaticinStripeBillingService.CreateCheckoutSessionAsync, then release the API through the same workflow. Confirm newly created sessions use the default orautomaticpolicy. No Dashboard rule needs changing.Source #779
release.yml, confirm in Google Play Console that an Android build without challenge and accountability screens is live in the fleet. Complete the owner-approvedMinSupportedVersiongate in thomasluizon/orbit-tickets#1531, including the exactMinSupportedVersionrow in production SupabaseAppConfigs, the RenderAPP_VERSIONpreconditions, readback, and cache activation evidence described inAGENTS.md. This PR does not raise the floor. Merging to main itself deploys nothing.release.ymland production drain evidence exists.AccountResetRepositorycleanup andGetFriendProfileQueryremain table consumers in this PR; remove or retire those consumers in a compatible production release before recording a contract barrier. Record Render service/deploy/commit identifiers and web, hosted-service, Hangfire, retry, queued-job, and in-flight-work drain evidence as required bytests/Orbit.Infrastructure.Tests/Persistence/RollingMigrations.md, then contract in a later PR and release with.github/migration-contracts.jsonevidence. No table drop is authorized by this PR alone.