diff --git a/src/Web/Stripe/Card.hs b/src/Web/Stripe/Card.hs
--- a/src/Web/Stripe/Card.hs
+++ b/src/Web/Stripe/Card.hs
@@ -10,7 +10,7 @@
 
 import           Control.Applicative ((<$>), (<*>))
 import           Control.Monad       (mzero)
-import           Data.Aeson          (FromJSON (..), Value (..), (.:))
+import           Data.Aeson          (FromJSON (..), Value (..), (.:), (.:?))
 import qualified Data.ByteString     as B
 import qualified Data.Text           as T
 import           Web.Stripe.Utils    (optionalArgs, showByteString,
@@ -18,12 +18,12 @@
 
 -- | Represents a credit card in the Stripe system.
 data Card = Card
-    { cardType             :: T.Text
-    , cardCountry          :: Maybe T.Text
-    , cardLastFour         :: T.Text
-    , cardExpMonth         :: Int
-    , cardExpYear          :: Int
-    , cardChecks           :: CardChecks
+    { cardType     :: T.Text
+    , cardCountry  :: Maybe T.Text
+    , cardLastFour :: T.Text
+    , cardExpMonth :: Int
+    , cardExpYear  :: Int
+    , cardChecks   :: CardChecks
     } deriving Show
 
 -- | Represents a credit car (with full details) that is used as input to the
@@ -64,8 +64,8 @@
         -- Optional
         md = [ ("card[cvc]",             textToByteString <$> rCardCVC           rc)
              , ("card[name]",            textToByteString <$> rCardFullName      rc)
-             , ("card[address_line1]",  textToByteString <$> rCardAddrLineOne   rc)
-             , ("card[address_line2]",  textToByteString <$> rCardAddrLineTwo   rc)
+             , ("card[address_line1]",   textToByteString <$> rCardAddrLineOne   rc)
+             , ("card[address_line2]",   textToByteString <$> rCardAddrLineTwo   rc)
              , ("card[address_city]",    textToByteString <$> rCardCity   rc)
              , ("card[address_zip]",     textToByteString <$> rCardAddrZip       rc)
              , ("card[address_state]",   textToByteString <$> rCardAddrState     rc)
@@ -79,11 +79,11 @@
 -- | Attempts to parse JSON into a credit 'Card'.
 instance FromJSON Card where
   parseJSON (Object v) = Card
-    <$> v .: "type"
-    <*> v .: "country"
-    <*> v .: "last4"
-    <*> v .: "exp_month"
-    <*> v .: "exp_year"
+    <$> v .:  "type"
+    <*> v .:? "country"
+    <*> v .:  "last4"
+    <*> v .:  "exp_month"
+    <*> v .:  "exp_year"
     <*> (CardChecks
       <$> v .: "cvc_check"
       <*> v .: "address_line1_check"
diff --git a/src/Web/Stripe/Client.hs b/src/Web/Stripe/Client.hs
--- a/src/Web/Stripe/Client.hs
+++ b/src/Web/Stripe/Client.hs
@@ -138,7 +138,7 @@
 -- | Stripe Version
 -- Represents Stripe API Versions
 data StripeVersion = V20110915d
-                   | OtherVersion String -- * "Format: 2011-09-15-d"
+                   | OtherVersion String -- ^ "Format: 2011-09-15-d"
 
 instance Show StripeVersion where
     show V20110915d = "2011-09-15-d"
@@ -226,7 +226,9 @@
 -- >    query baseSReq { sDestination = ["charges"] }
 query :: (MonadIO m, FromJSON a) => StripeRequest -> StripeT m (StripeResponseCode, a)
 query req = query' req >>= \(code, ans) ->
-    either (throwError . strMsg . ("JSON parse error: " ++)) (return . (code, )) $ eitherDecode' ans
+    either (throwError . strMsg .
+               (\msg -> "JSON parse error: " ++ msg ++ ". json: " ++ show ans))
+           (return . (code, )) $ eitherDecode' ans
 
 -- | same as `query` but pulls out the value inside a data field and returns that
 queryData :: (MonadIO m, FromJSON a) => StripeRequest -> StripeT m (StripeResponseCode, a)
diff --git a/src/Web/Stripe/Customer.hs b/src/Web/Stripe/Customer.hs
--- a/src/Web/Stripe/Customer.hs
+++ b/src/Web/Stripe/Customer.hs
@@ -36,9 +36,10 @@
                                       StripeRequest (..), StripeT (..),
                                       baseSReq, query, queryData, runStripeT)
 import           Web.Stripe.Coupon   (CpnId (..))
+import           Web.Stripe.Discount (Discount)
 import           Web.Stripe.Plan     (PlanId (..))
 import           Web.Stripe.Token    (TokenId (..))
-import           Web.Stripe.Utils    (Count (..), Description (..), Offset (..),
+import           Web.Stripe.Utils    (CustomerId(..), Count (..), Description (..), Offset (..),
                                       UTCTime (..), fromSeconds, optionalArgs,
                                       showByteString, textToByteString)
 
@@ -54,11 +55,9 @@
     , custLive        :: Bool
     , custCreated     :: UTCTime
     , custActiveCard  :: Maybe Card
+    , custDiscount    :: Maybe Discount
     } deriving Show
 
--- | Represents a 'Customer'\'s ID in the Stripe system.
-newtype CustomerId = CustomerId { unCustomerId :: T.Text } deriving (Show, Eq)
-
 -- | Represents a standard email address.
 newtype Email = Email { unEmail :: T.Text } deriving (Show, Eq)
 
@@ -178,4 +177,5 @@
         <*>                       o .:  "livemode"
         <*> (fromSeconds      <$> o .:  "created")
         <*>                       o .:? "active_card"
+        <*>                       o .:? "discount"
     parseJSON _ = mzero
diff --git a/src/Web/Stripe/Discount.hs b/src/Web/Stripe/Discount.hs
new file mode 100644
--- /dev/null
+++ b/src/Web/Stripe/Discount.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Web.Stripe.Discount
+    ( Discount(..)
+    ) where
+
+import Web.Stripe.Utils
+
+import Web.Stripe.Coupon
+
+data Discount = Discount {
+    disCustomerId :: CustomerId
+  , disCoupon :: Coupon
+  , disSubscriptionId :: Maybe SubscriptionId
+  , disStart :: Maybe UTCTime
+  , disEnd   :: Maybe UTCTime
+  } deriving (Show)
+
+instance FromJSON Discount where
+    parseJSON = withObject "Discount" $ \o -> Discount
+      <$> (     CustomerId <$> o .: "customer")
+      <*> o .: "coupon"
+      <*> (fmap SubscriptionId <$> o .:? "subscription")
+      <*> (fmap fromSeconds <$> o .:? "start")
+      <*> (fmap fromSeconds <$> o .:? "end")
diff --git a/src/Web/Stripe/Subscription.hs b/src/Web/Stripe/Subscription.hs
--- a/src/Web/Stripe/Subscription.hs
+++ b/src/Web/Stripe/Subscription.hs
@@ -2,12 +2,14 @@
 
 module Web.Stripe.Subscription
     ( Subscription(..)
+    , SubscriptionId(..)
     , SubStatus(..)
     , SubProrate(..)
     , SubTrialEnd(..)
     , SubAtPeriodEnd(..)
     , updateSubRCard
     , updateSubToken
+    , updateSub
     , cancelSub
 
     {- Re-Export -}
@@ -25,14 +27,14 @@
 import           Web.Stripe.Client   (StripeConfig (..), StripeRequest (..),
                                       StripeT (..), baseSReq, query, runStripeT)
 import           Web.Stripe.Coupon   (CpnId (..))
-import           Web.Stripe.Customer (CustomerId (..))
+import           Web.Stripe.Discount (Discount)
 import           Web.Stripe.Plan     (Plan, PlanId (..))
 import           Web.Stripe.Token    (TokenId (..))
-import           Web.Stripe.Utils    (UTCTime (..), fromSeconds, optionalArgs,
+import           Web.Stripe.Utils    (SubscriptionId(..), CustomerId(..), UTCTime (..), fromSeconds, optionalArgs,
                                       showByteString, textToByteString)
 
 import           Control.Applicative ((<$>), (<*>))
-import           Data.Aeson          (FromJSON (..), Value (..), (.:))
+import           Data.Aeson          (FromJSON (..), Value (..), (.:), (.:?))
 import qualified Data.ByteString     as B
 import qualified Data.Text           as T
 
@@ -42,14 +44,16 @@
 
 -- | Represents a subscription in the Stripe API.
 data Subscription = Subscription
-    { subCustomerId  :: CustomerId
+    { subId          :: SubscriptionId
+    , subCustomerId  :: CustomerId
     , subPlan        :: Plan
     , subStatus      :: SubStatus
     , subStart       :: UTCTime
-    , subTrialStart  :: UTCTime
-    , subTrialEnd    :: UTCTime
+    , subTrialStart  :: Maybe UTCTime
+    , subTrialEnd    :: Maybe UTCTime
     , subPeriodStart :: UTCTime -- ^ Current period start
     , subPeriodEnd   :: UTCTime -- ^ Current period end
+    , subDiscount    :: Maybe Discount
     } deriving Show
 
 -- | Describes the various stages that a
@@ -131,12 +135,14 @@
 -- | Attempts to parse JSON into a 'Subscription'.
 instance FromJSON Subscription where
     parseJSON (Object o) = Subscription
-      <$> (CustomerId  <$> o .: "customer")
+      <$> (SubscriptionId <$> o .: "id")
+      <*> (CustomerId     <$> o .: "customer")
       <*> o .: "plan"
-      <*> (toSubStatus <$> o .: "status")
-      <*> (fromSeconds <$> o .: "start")
-      <*> (fromSeconds <$> o .: "trial_start")
-      <*> (fromSeconds <$> o .: "trial_end")
-      <*> (fromSeconds <$> o .: "current_period_start")
-      <*> (fromSeconds <$> o .: "current_period_end")
+      <*> (     toSubStatus <$> o .:  "status")
+      <*> (     fromSeconds <$> o .:  "start")
+      <*> (fmap fromSeconds <$> o .:? "trial_start")
+      <*> (fmap fromSeconds <$> o .:? "trial_end")
+      <*> (     fromSeconds <$> o .:  "current_period_start")
+      <*> (     fromSeconds <$> o .:  "current_period_end")
+      <*> o .:? "discount"
     parseJSON _ = mzero
diff --git a/src/Web/Stripe/Utils.hs b/src/Web/Stripe/Utils.hs
--- a/src/Web/Stripe/Utils.hs
+++ b/src/Web/Stripe/Utils.hs
@@ -1,17 +1,21 @@
 module Web.Stripe.Utils
-    ( Amount(..)
+    ( -- common types
+      CustomerId(..)
+    , SubscriptionId(..)
+    , Amount(..)
     , Count(..)
     , Currency(..)
     , Description(..)
     , Offset(..)
     , optionalArgs
-    {- Re-Export -}
-    , UTCTime(..)
+    -- helper functions
     , fromSeconds
     , toSeconds
     , stringToByteString
     , textToByteString
     , showByteString
+    , module Export
+    {- Re-Export -}
     ) where
 
 import qualified Codec.Binary.UTF8.String as CodecUtf8
@@ -19,11 +23,14 @@
 import qualified Data.ByteString          as B
 import           Data.Maybe               (mapMaybe)
 import qualified Data.Text                as T
-import           Data.Time.Clock          (UTCTime (..))
+import           Data.Time.Clock          as Export (UTCTime (..))
 import           Data.Time.Clock.POSIX    (posixSecondsToUTCTime,
                                            utcTimeToPOSIXSeconds)
 import           Data.Time.Format         ()
 
+import           Data.Aeson as Export     (withObject, FromJSON (..), Value (..), (.:), (.:?))
+import           Control.Applicative      as Export ((<$>), (<*>))
+
 showByteString :: Show a => a -> B.ByteString
 showByteString = stringToByteString . show
 
@@ -36,6 +43,12 @@
 -----------------------
 -- Common Data Types --
 -----------------------
+--
+-- | Represents a 'Customer'\'s ID in the Stripe system.
+newtype CustomerId = CustomerId { unCustomerId :: T.Text } deriving (Show, Eq)
+
+newtype SubscriptionId = SubscriptionId { unSubscriptionId :: T.Text }
+                         deriving (Show, Eq)
 
 -- | Represents an amount in cents in the Stripe system.
 newtype Amount = Amount { unAmount :: Int } deriving (Show, Eq)
diff --git a/stripe.cabal b/stripe.cabal
--- a/stripe.cabal
+++ b/stripe.cabal
@@ -1,12 +1,13 @@
 Name:                stripe
-Version:             0.6.0
+Version:             0.7.0
 Synopsis:            A Haskell implementation of the Stripe API.
 Description:         This is an implementation of the Stripe API as it is
                      documented at https:\/\/stripe.com\/docs\/api
 License:             BSD3
 License-file:        LICENSE
 Author:              Spearhead Development, L.L.C.
-Maintainer:          Michael Schade <m@mschade.me>
+Maintainer:          Michael Schade <m@mschade.me>,
+                     Luke Hoersten <luke@hoersten.org>
 Copyright:           (c) 2011 Spearhead Development, L.L.C.
 Homepage:            https://github.com/michaelschade/hs-stripe
 Category:            Web
@@ -27,6 +28,7 @@
                         , Web.Stripe.Client
                         , Web.Stripe.Connect
                         , Web.Stripe.Coupon
+                        , Web.Stripe.Discount
                         , Web.Stripe.Customer
                         , Web.Stripe.Plan
                         , Web.Stripe.Subscription
