badge-service: verify App Store and Google Play purchases (#7654)

This commit is contained in:
spaced4ndy authored and GitHub committed 2026-10-13 15:24:07 +00:00
1 parent 5cddbffaa1
commit 59c588932e
31 files changed
+1574 -79

No files matched your search

@@ -7475,6 +7475,7 @@ sealed class BadgeServiceErrorCode {
object CodeExpired: BadgeServiceErrorCode()
object ReceiptInvalid: BadgeServiceErrorCode()
object ReceiptUsed: BadgeServiceErrorCode()
object TestPurchase: BadgeServiceErrorCode()
object Internal: BadgeServiceErrorCode()
data class Unknown(val code: String): BadgeServiceErrorCode()
@@ -7497,6 +7498,7 @@ sealed class BadgeServiceErrorCode {
is CodeExpired -> "code_expired"
is ReceiptInvalid -> "receipt_invalid"
is ReceiptUsed -> "receipt_used"
is TestPurchase -> "test_purchase"
is Internal -> "internal"
is Unknown -> code
}
@@ -7511,6 +7513,7 @@ fun badgeServiceErrorText(code: BadgeServiceErrorCode): String? = when (code) {
is BadgeServiceErrorCode.UnknownPurchaseKey -> generalGetString(MR.strings.badges_error_unknown_purchase)
is BadgeServiceErrorCode.Internal -> generalGetString(MR.strings.badges_error_service_internal)
is BadgeServiceErrorCode.ReceiptInvalid -> generalGetString(MR.strings.badges_error_receipt_invalid)
is BadgeServiceErrorCode.TestPurchase -> generalGetString(MR.strings.badges_error_test_purchase)
is BadgeServiceErrorCode.ReceiptUsed -> generalGetString(MR.strings.badges_error_receipt_used)
is BadgeServiceErrorCode.PaymentPending -> generalGetString(MR.strings.badges_error_payment_pending)
is BadgeServiceErrorCode.ProviderUnavailable -> generalGetString(MR.strings.badges_error_provider_unavailable)
@@ -7540,6 +7543,7 @@ object BadgeServiceErrorCodeSerializer : KSerializer<BadgeServiceErrorCode> {
"code_expired" -> BadgeServiceErrorCode.CodeExpired
"receipt_invalid" -> BadgeServiceErrorCode.ReceiptInvalid
"receipt_used" -> BadgeServiceErrorCode.ReceiptUsed
"test_purchase" -> BadgeServiceErrorCode.TestPurchase
"internal" -> BadgeServiceErrorCode.Internal
else -> BadgeServiceErrorCode.Unknown(v)
}
@@ -443,5 +443,5 @@ private fun compactPrice(product: BadgeProduct): String {
private fun badgeReceiptRefused(err: ChatError?): Boolean {
val redeemError = ((err as? ChatError.ChatErrorChat)?.errorType as? ChatErrorType.CEBadgeRedeemError)?.badgeRedeemError
val code = (redeemError as? BadgeRedeemError.ServiceError)?.serviceError
return code is BadgeServiceErrorCode.ReceiptInvalid || code is BadgeServiceErrorCode.ReceiptUsed
return code is BadgeServiceErrorCode.ReceiptInvalid || code is BadgeServiceErrorCode.ReceiptUsed || code is BadgeServiceErrorCode.TestPurchase
}
@@ -3230,6 +3230,7 @@
<string name="badges_error_service_internal">The badge service reported an internal error.</string>
<string name="badges_error_receipt_invalid">The store did not confirm this purchase.</string>
<string name="badges_error_receipt_used">This purchase was already credited to a badge on another device or profile.</string>
<string name="badges_error_test_purchase">Test purchases are not credited. Badges can only be bought with a real purchase.</string>
<string name="badges_error_payment_pending">The payment has not been confirmed yet.</string>
<string name="badges_error_provider_unavailable">The store could not be reached.</string>
<string name="badges_error_provider_not_configured">Badges cannot be bought in the app yet.</string>