core, ios, android: state the real reason in the badge purchase comments

This commit is contained in:
spaced4ndy
2026-10-05 13:10:30 +04:00
parent 4b5b239fdb
commit bdc7c64f97
8 changed files with 23 additions and 19 deletions
+1 -1
View File
@@ -660,7 +660,7 @@ data ChatCommand
| UpdateProfileImageFromFile FilePath -- set profile image from a .png/.jpg/.jpeg file
| AddBadge BadgeCredential -- attach an issued badge credential (testing; credential from `simplex-chat badge sign`)
| APIRedeemBadgeCode {userId :: UserId, code :: Text} -- redeem a badge code with the configured badge service
| APIPurchaseBadge {userId :: UserId, echoedInvoiceId :: Maybe Text, payment :: ServicePayment} -- redeem an App Store or Google Play purchase; without an invoice id, as for one this install did not start, it is credited by transaction reference
| APIPurchaseBadge {userId :: UserId, echoedInvoiceId :: Maybe Text, payment :: ServicePayment} -- redeem an App Store or Google Play purchase; without an invoice id, as for one the app never started, it is credited by transaction reference
| APICreateBadgeInvoice {userId :: UserId} -- the record of a store purchase, created before the store charges; answers the id the store echoes
| APICloseBadgeInvoice {userId :: UserId, invoiceId :: Text} -- a store purchase that came to nothing
| APIGetBadgeState {userId :: UserId} -- the user's badges, their balances and any current alert
-2
View File
@@ -138,8 +138,6 @@ data StoredPayment = StoredPayment
deriving (Show)
-- to review
-- TODO [badges] reconcile PFApple and PFGoogle with the badge service's VerifiedStoreTransaction,
-- which is what a store attested rather than a payment recorded here, when this is built out.
data PaymentFunding
= PFInvoice
{ invoiceId :: InvoiceId,
+2 -2
View File
@@ -123,8 +123,8 @@ attachBadgeStoreReceipt db invoiceId_ txRef@StoreTransactionRef {provider, trans
userId_ <-
maybeFirstRow fromOnly $
DB.query db "SELECT user_id FROM badge_store_receipts WHERE invoice_id = ? AND transaction_ref IS NULL" (Only invoiceId)
-- a closed record is reopened: new keys for a paid transaction would be refused as receipt_used,
-- and the badge the old keys were credited with would be lost
-- a closed record is reopened so the purchase stays on the profile that paid: only a record no
-- receipt has reached can be closed, so its keys were never sent and nothing was credited to them
forM_ userId_ $ \_ ->
DB.execute
db
@@ -6,9 +6,10 @@ module Simplex.Chat.Store.Postgres.Migrations.M20260925_badge_store_receipts whe
import Data.Text (Text)
import Text.RawString.QQ (r)
-- | invoice_id is null for a receipt this install did not start — a reinstall, a restored database, or the
-- same store account on another device. provider and transaction_ref are null until a receipt arrives, and
-- distinct NULLs let several rows await one at once.
-- | invoice_id is null for a purchase the app never started, such as a store offer code, since the stores
-- echo back only an id the app set. A reinstall or another device echoes one this database does not know,
-- and that row is keyed by its transaction instead. provider and transaction_ref are null until a receipt
-- arrives, and distinct NULLs let several rows await one at once.
m20260925_badge_store_receipts :: Text
m20260925_badge_store_receipts =
[r|
@@ -5,9 +5,10 @@ module Simplex.Chat.Store.SQLite.Migrations.M20260925_badge_store_receipts where
import Database.SQLite.Simple (Query)
import Database.SQLite.Simple.QQ (sql)
-- | invoice_id is null for a receipt this install did not start — a reinstall, a restored database, or the
-- same store account on another device. provider and transaction_ref are null until a receipt arrives, and
-- distinct NULLs let several rows await one at once.
-- | invoice_id is null for a purchase the app never started, such as a store offer code, since the stores
-- echo back only an id the app set. A reinstall or another device echoes one this database does not know,
-- and that row is keyed by its transaction instead. provider and transaction_ref are null until a receipt
-- arrives, and distinct NULLs let several rows await one at once.
m20260925_badge_store_receipts :: Query
m20260925_badge_store_receipts =
[sql|