diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -23,3 +23,9 @@
 ## 1.0.0.8 - 2021-03-08
 
 Support cryptonite 0.28
+
+## 1.0.0.10 - 2021-06-05
+
+Support GHC 9.0, `cryptonite` 0.29, `bytestring` 0.11, `memory` 0.16
+
+Switch `base16-bytestring` version from 0.1 to 1.0
diff --git a/library/Stripe/Signature.hs b/library/Stripe/Signature.hs
--- a/library/Stripe/Signature.hs
+++ b/library/Stripe/Signature.hs
@@ -14,11 +14,10 @@
 import qualified Text.Read
 
 -- base16-bytestring
-import qualified Data.ByteString.Base16
+import qualified Data.ByteString.Base16 as Base16
 
 -- bytestring
 import Data.ByteString (ByteString)
-import qualified Data.ByteString
 
 -- cryptonite
 import Crypto.Hash     (SHA256)
@@ -32,8 +31,8 @@
 
 -- text
 import           Data.Text (Text)
-import qualified Data.Text
-import qualified Data.Text.Encoding
+import qualified Data.Text as Text
+import qualified Data.Text.Encoding as Text
 
 isSigValid :: Sig -> WebhookSecretKey -> ByteString -> Bool
 isSigValid x secret body =
@@ -79,13 +78,13 @@
     parts = splitSig txt
   in
     do
-      time <- Data.List.lookup (Data.Text.pack "t") parts
-                    >>= (readNatural . Data.Text.unpack)
+      time <- Data.List.lookup (Text.pack "t") parts
+                    >>= (readNatural . Text.unpack)
 
       let
           v1 = Data.Maybe.mapMaybe
               ( \(k, v) ->
-                  if k == Data.Text.pack "v1"
+                  if k == Text.pack "v1"
                   then decodeHex v
                   else Nothing
               )
@@ -96,16 +95,16 @@
 splitSig :: Text -> [(Text, Text)]
 splitSig =
     Data.Maybe.catMaybes
-    . fmap (split2 (Data.Text.pack "="))
-    . Data.Text.splitOn (Data.Text.pack ",")
+    . fmap (split2 (Text.pack "="))
+    . Text.splitOn (Text.pack ",")
 
 split2 :: Text -> Text -> Maybe (Text, Text)
 split2 pat src =
     let
-        (x, y) = Data.Text.breakOn pat src
-        y' = Data.Text.drop (Data.Text.length pat) y
+        (x, y) = Text.breakOn pat src
+        y' = Text.drop (Text.length pat) y
     in
-        if Data.Text.null y then Nothing else Just (x, y')
+        if Text.null y then Nothing else Just (x, y')
 
 {- | Parse a number consisting of one or more digits 0 through 9. -}
 
@@ -117,9 +116,4 @@
 @0@ through @9@ and letters @a@ through @f@. -}
 
 decodeHex :: Text -> Maybe ByteString
-decodeHex txt =
-    let
-        bs = Data.Text.Encoding.encodeUtf8 txt
-        (x, remainder) = Data.ByteString.Base16.decode bs
-    in
-        if Data.ByteString.null remainder then Just x else Nothing
+decodeHex = either (const Nothing) Just . Base16.decode . Text.encodeUtf8
diff --git a/stripe-signature.cabal b/stripe-signature.cabal
--- a/stripe-signature.cabal
+++ b/stripe-signature.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.0
 
 name: stripe-signature
-version: 1.0.0.8
+version: 1.0.0.10
 
 synopsis: Verification of Stripe webhook signatures
 category: Web
@@ -24,7 +24,8 @@
 license-file: license.txt
 
 build-type: Simple
-tested-with: GHC==8.2.2, GHC==8.4.4, GHC==8.6.3, GHC==8.8.1, GHC==8.10.1
+tested-with: GHC==8.2.2, GHC==8.4.4, GHC==8.6.3, GHC==8.8.1, GHC==8.10.1,
+             GHC==9.0.1
 
 extra-source-files:
     changelog.md
@@ -38,10 +39,12 @@
 
     build-depends:
         base ^>= 4.10 || ^>= 4.11 || ^>= 4.12 || ^>= 4.13 || ^>= 4.14
-      , base16-bytestring ^>= 0.1
-      , bytestring ^>= 0.10
+          || ^>= 4.15
+      , base16-bytestring ^>= 1.0
+      , bytestring ^>= 0.10 || ^>= 0.11
       , cryptonite ^>= 0.25 || ^>= 0.26 || ^>= 0.27 || ^>= 0.28
-      , memory ^>= 0.14 || ^>= 0.15
+                || ^>= 0.29
+      , memory ^>= 0.14 || ^>= 0.15 || ^>= 0.16
       , stripe-concepts ^>= 1.0
       , text ^>= 1.2
 
@@ -54,6 +57,7 @@
 
     build-depends:
         base ^>= 4.10 || ^>= 4.11 || ^>= 4.12 || ^>= 4.13 || ^>= 4.14
-      , bytestring ^>= 0.10
+          || ^>= 4.15
+      , bytestring ^>= 0.10 || ^>= 0.11
       , stripe-signature
       , text ^>= 1.2
