feat: correct subscription response and statuses - #10566
Merged
Merged
Conversation
Member
Author
|
@metamaskbot publish-previews |
lwin-kyaw
approved these changes
Sep 29, 2026
Contributor
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
tanguyenvn
approved these changes
Sep 29, 2026
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.
Explanation
The crypto subscription start flow and
getSubscriptionswere both failing on successful API responses because our response structs did not match what the Subscription API actually returns.Crypto start response shape
SubscriptionService:startSubscriptionWithCryptovalidated thePOST /subscriptions/cryptoresponse againstStartCryptoSubscriptionResponseStruct({ subscriptionId, status }). The API actually returns the full createdSubscriptionobject (crypto subscriptions are created immediately, unlike card checkout which returns a checkout session URL). Because the response never had asubscriptionIdfield,create()threw on every successful call, so the crypto start flow always failed after the API had already created the subscription.This PR:
StartCryptoSubscriptionResponseStructand validates the response againstSubscriptionStructinstead.StartCryptoSubscriptionResponseas an alias ofSubscription. This is BREAKING for consumers readingresponse.subscriptionId; they should readresponse.idinstead.response.statusis unchanged. This affectsSubscriptionService:startSubscriptionWithCrypto,SubscriptionController:startSubscriptionWithCrypto, andSubscriptionDelegationService:startSubscriptionWithDelegation.Optional fields on
SubscriptionSubscriptionStructrequiredlastInvoice.updatedAtandpaymentMethod.card.displayBrand, but both are optional in the API. Any subscription with alastInvoice(i.e. anything that has been billed at least once) failed validation andgetSubscriptionsthrew. Both fields are now optional in the struct and on theSubscriptionInvoice/SubscriptionCardPaymentMethodtypes.awaiting_fundsstatusThe API returns an
awaiting_fundsstatus for crypto subscriptions that were created but whose first invoice has not been funded yet. This status was not inSUBSCRIPTION_STATUSES, so such subscriptions also failed validation. This PR addsSUBSCRIPTION_STATUSES.awaitingFundsand teachesSubscriptionController:submitSubscriptionCryptoApprovalto treat it likepast_due/unpaid: submitting a new approval for a subscription in this state updates the existing subscription's payment method instead of attempting to start a new one.Tests
SubscriptionService.test.ts: crypto start tests now use full subscription fixtures; added cases for a missingupdatedAt, a missingdisplayBrand, theawaiting_fundsstatus, pass-through of additional subscription fields, and rejection of a non-subscription response.SubscriptionController.test.tsandSubscriptionDelegationService.test.ts: updated to the new response shape and added coverage for theawaiting_fundsbranch insubmitSubscriptionCryptoApproval.References
Checklist
Note
Medium Risk
Breaking return type on crypto subscription start affects all consumers; changes subscription status handling and crypto approval routing for payment recovery.
Overview
Fixes crypto subscription and
getSubscriptionsflows that threw on successful API responses because client validation did not match the Subscription API.Breaking:
StartCryptoSubscriptionResponseis now the full createdSubscription(validated withSubscriptionStruct), not{ subscriptionId, status }. Callers must useresponse.idinstead ofresponse.subscriptionIdonstartSubscriptionWithCryptoand delegation start paths.Validation fixes:
lastInvoice.updatedAtand carddisplayBrandare optional so billed subscriptions and card payment methods no longer failgetSubscriptions. AddsSUBSCRIPTION_STATUSES.awaitingFundsfor crypto subs waiting on first-invoice funding.Behavior:
submitSubscriptionCryptoApprovaltreatsawaiting_fundslikepast_due/unpaid—a new approval updates the existing subscription’s payment method instead of starting a new subscription.Tests and changelog updated for the new response shape, optional fields, and the awaiting-funds approval branch.
Reviewed by Cursor Bugbot for commit 82a2b98. Bugbot is set up for automated code reviews on this repo. Configure here.