diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg
index b53e2eae5..c904cc451 100644
--- a/.github/badges/branches.svg
+++ b/.github/badges/branches.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01677ef49..b07c29b42 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ The changelog for `Superwall`. Also see the [releases](https://github.com/superw
## Enhancements
+- Always redeem existing web codes after a successful purchase and on restore.
- Adds `fontScale` and `fontSize` device attributes for the system text size.
- Memoizes the device template used for audience-filter evaluation and paywall templating. The template is now rebuilt only when one of its mutable inputs (identity, entitlements, subscription status, interface style, platform wrapper, etc.) changes, while time-derived fields are recomputed on every read. This removes a full JSON round trip and repeated system lookups from every `register()` call.
diff --git a/superwall/src/main/java/com/superwall/sdk/dependencies/DependencyContainer.kt b/superwall/src/main/java/com/superwall/sdk/dependencies/DependencyContainer.kt
index c453767c0..886f5eca7 100644
--- a/superwall/src/main/java/com/superwall/sdk/dependencies/DependencyContainer.kt
+++ b/superwall/src/main/java/com/superwall/sdk/dependencies/DependencyContainer.kt
@@ -592,6 +592,9 @@ class DependencyContainer(
showRestoreDialogForWeb = {
showWebRestoreSuccesful()
},
+ notifyBackendOfReceipts = {
+ reedemer.redeem(WebPaywallRedeemer.RedeemType.Existing)
+ },
entitlementsById = {
entitlements.byProductId(it)
},
diff --git a/superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt b/superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt
index 53257fa29..465dea6ba 100644
--- a/superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt
+++ b/superwall/src/main/java/com/superwall/sdk/store/transactions/TransactionManager.kt
@@ -79,6 +79,7 @@ class TransactionManager(
Superwall.instance.entitlements.web
},
private val showRestoreDialogForWeb: suspend () -> Unit,
+ private val notifyBackendOfReceipts: suspend () -> Unit = {},
private val refreshReceipt: () -> Unit,
private val updateState: (cacheKey: String, update: PaywallViewState.Updates) -> Unit,
private val notifyOfTransactionComplete: suspend (paywallCacheKey: String, trialEndDate: Long?, productId: String) -> Unit,
@@ -478,6 +479,8 @@ class TransactionManager(
PaywallResult.Restored(),
)
}
+
+ ioScope.launchWithTracking { notifyBackendOfReceipts() }
}
private fun trackFailure(
@@ -657,6 +660,8 @@ class TransactionManager(
storeManager.loadPurchasedProducts(allEntitlementsByProductId())
+ ioScope.launchWithTracking { notifyBackendOfReceipts() }
+
trackTransactionDidSucceed(transaction, product, purchaseSource, didStartFreeTrial)
if (shouldDismiss && factory.makeSuperwallOptions().paywalls.automaticallyDismiss) {
@@ -695,6 +700,8 @@ class TransactionManager(
}
storeManager.loadPurchasedProducts(allEntitlementsByProductId())
+ ioScope.launchWithTracking { notifyBackendOfReceipts() }
+
trackTransactionDidSucceed(transaction, product, purchaseSource, didStartFreeTrial)
}
}