mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-15 15:30:36 +00:00
core, badge service: share one store transaction reference, and mark a verified transaction as such
This commit is contained in:
@@ -77,6 +77,7 @@ import Simplex.Chat.Messages.CIContent.Events
|
||||
import Simplex.Chat.Operators
|
||||
import Simplex.Chat.Options
|
||||
import Simplex.Chat.PaymentService (ServicePayment (..), appleTransactionId, googlePurchaseRef)
|
||||
import Simplex.Chat.PaymentService.Types (PaymentProvider (..), StoreTransactionRef (..))
|
||||
import Simplex.Chat.ProfileGenerator (generateRandomProfile)
|
||||
import Simplex.Chat.Protocol
|
||||
import Simplex.Chat.Remote
|
||||
@@ -5280,8 +5281,8 @@ purchaseBadge nm presentingUser echoedInvoiceId payment = do
|
||||
-- | The same reference the service claims a transaction by, read without verifying anything.
|
||||
storeTransactionRef :: ServicePayment -> Maybe StoreTransactionRef
|
||||
storeTransactionRef = \case
|
||||
SPApple {jws} -> StoreTransactionRef "apple" <$> appleTransactionId jws
|
||||
SPGoogle {token} -> Just $ StoreTransactionRef "google" $ googlePurchaseRef token
|
||||
SPApple {jws} -> StoreTransactionRef PPApple <$> appleTransactionId jws
|
||||
SPGoogle {token} -> Just $ StoreTransactionRef PPGoogle $ googlePurchaseRef token
|
||||
SPInvoice {} -> Nothing
|
||||
SPReceipt {} -> Nothing
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{-# LANGUAGE CPP #-}
|
||||
{-# LANGUAGE DerivingStrategies #-}
|
||||
{-# LANGUAGE DuplicateRecordFields #-}
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
|
||||
module Simplex.Chat.PaymentService.Types
|
||||
@@ -8,6 +11,7 @@ module Simplex.Chat.PaymentService.Types
|
||||
InvoiceId (..),
|
||||
PaymentId (..),
|
||||
PaymentProvider (..),
|
||||
StoreTransactionRef (..),
|
||||
CardProvider (..),
|
||||
CryptoCurrency (..),
|
||||
ServicePaymentMethod (..),
|
||||
@@ -26,7 +30,16 @@ import Data.ByteString.Char8 (ByteString)
|
||||
import Data.Text (Text)
|
||||
import Data.Time.Clock (UTCTime)
|
||||
import Data.Word (Word32)
|
||||
import Simplex.Messaging.Agent.Store.DB (fromTextField_)
|
||||
import Simplex.Messaging.Encoding.String (TextEncoding (..))
|
||||
import Simplex.Messaging.Parsers (dropPrefix, enumJSON, taggedObjectJSON)
|
||||
#if defined(dbPostgres)
|
||||
import Database.PostgreSQL.Simple.FromField (FromField (..))
|
||||
import Database.PostgreSQL.Simple.ToField (ToField (..))
|
||||
#else
|
||||
import Database.SQLite.Simple.FromField (FromField (..))
|
||||
import Database.SQLite.Simple.ToField (ToField (..))
|
||||
#endif
|
||||
|
||||
-- USD etc. are in minor units, following Stripe etc. convention
|
||||
newtype CurrencyAmount = CurrencyAmount Word32
|
||||
@@ -45,6 +58,32 @@ newtype PaymentId = PaymentId Text
|
||||
data PaymentProvider = PPApple | PPGoogle | PPStripe | PPCrypto | PPCode | PPReceipt
|
||||
deriving (Eq, Show)
|
||||
|
||||
instance TextEncoding PaymentProvider where
|
||||
textEncode = \case
|
||||
PPApple -> "apple"
|
||||
PPGoogle -> "google"
|
||||
PPStripe -> "stripe"
|
||||
PPCrypto -> "crypto"
|
||||
PPCode -> "code"
|
||||
PPReceipt -> "receipt"
|
||||
textDecode = \case
|
||||
"apple" -> Just PPApple
|
||||
"google" -> Just PPGoogle
|
||||
"stripe" -> Just PPStripe
|
||||
"crypto" -> Just PPCrypto
|
||||
"code" -> Just PPCode
|
||||
"receipt" -> Just PPReceipt
|
||||
_ -> Nothing
|
||||
|
||||
instance FromField PaymentProvider where fromField = fromTextField_ textDecode
|
||||
|
||||
instance ToField PaymentProvider where toField = toField . textEncode
|
||||
|
||||
-- | A store and its own id for one transaction. The evidence is not the key: the store may sign it
|
||||
-- again, and a retry of the same purchase has to find the same stash.
|
||||
data StoreTransactionRef = StoreTransactionRef {provider :: PaymentProvider, transactionRef :: Text}
|
||||
deriving (Eq, Show)
|
||||
|
||||
data CardProvider = CPStripe
|
||||
deriving (Eq, Show)
|
||||
|
||||
@@ -100,6 +139,7 @@ data StoredPayment = StoredPayment
|
||||
deriving (Show)
|
||||
|
||||
-- to review
|
||||
-- PFApple and PFGoogle hold much what the service's VerifiedStoreTransaction does; the two are reconciled when this is built out.
|
||||
data PaymentFunding
|
||||
= PFInvoice
|
||||
{ invoiceId :: InvoiceId,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
module Simplex.Chat.Store.Badges
|
||||
( BadgeStash (..),
|
||||
BadgeStashRef (..),
|
||||
StoreTransactionRef (..),
|
||||
UserBadgePurchase (..),
|
||||
getUserBadgePurchase,
|
||||
getBadgePurchase,
|
||||
@@ -52,6 +51,7 @@ import Simplex.Chat.Badges
|
||||
import Simplex.Chat.Badges.Ledger
|
||||
import Simplex.Chat.Badges.Service (StatementCreditType (..), StatementDebitType (..), StatementEntry (..), StatementEntryType (..))
|
||||
import Simplex.Chat.Badges.Types (BadgeAlertKind, BadgeIssueError (..), BadgeIssueFailure, BadgePurchaseStatus (..), OpenStorePurchase (..))
|
||||
import Simplex.Chat.PaymentService.Types (StoreTransactionRef (..))
|
||||
import Simplex.Chat.Store.Shared (insertedRowId)
|
||||
import Simplex.Chat.Types
|
||||
import Simplex.Messaging.Agent.Protocol (UserId)
|
||||
@@ -80,11 +80,6 @@ data BadgeStash = BadgeStash
|
||||
|
||||
data BadgeStashRef = BSRCodeRedemption Int64 | BSRStoreReceipt Int64
|
||||
|
||||
-- | A store and its own id for one transaction. The evidence is not the key: the store may sign it
|
||||
-- again, and a retry of the same purchase has to find the same stash.
|
||||
data StoreTransactionRef = StoreTransactionRef {provider :: Text, transactionRef :: Text}
|
||||
deriving (Eq, Show)
|
||||
|
||||
getBadgeCodeRedemption :: DB.Connection -> User -> Text -> IO (Maybe BadgeStash)
|
||||
getBadgeCodeRedemption db User {userId} code =
|
||||
maybeFirstRow (toBadgeStash BSRCodeRedemption) $
|
||||
|
||||
Reference in New Issue
Block a user