I am trying to grab some data from the struct of the stripe response objects for subscriptions. Here is link to the structure of the response object stribe subscription object
Here is what i have and what am trying to do
type SubscriptionDetails struct {
CustomerId string `json:"customer_id"`
SubscritpionId string `json:"subscritpion_id"`
StartAt time.Time `json:"start_at"`
EndAt time.Time `json:"end_at"`
Interval string `json:"interval"`
Plan string `json:"plan"`
PlanId string `json:"plan_id"`
SeatCount uint8 `json:"seat_count"`
PricePerSeat float64 `json:"price_per_seat"`
}
func CreateStripeSubscription(CustomerId string, planId string) (*SubscriptionDetails, error) {
stripe.Key = StripeKey
params := &stripe.SubscriptionParams{
Customer: stripe.String(CustomerId),
Items: []*stripe.SubscriptionItemsParams{
&stripe.SubscriptionItemsParams{
Price: stripe.String(planId),
},
},
}
result, err := sub.New(params)
if err != nil {
return nil, err
}
data := &SubscriptionDetails{}
data.CustomerId = result.Customer
data.SubscritpionId = result.ID
data.StartAt = result.CurrentPeriodStart
data.EndAt = result.CurrentPeriodEnd
data.Interval = result.Items.Data.Price.Recurring.Interval
data.Plan = result.Items.Data.Price.Nickname
data.SeatCount = result.Items.Data.Quantity
data.PricePerSeat = result.Items.Data.Price.UnitAmount
return data, nil
}
there are some items that are easy to get directly like ID
field i got easily with result.ID
and no complaints but for other items here are the error messages am getting
cannot use result.CurrentPeriodStart (type int64) as type time.Time in assignment
...
cannot use result.Customer (type *stripe.Customer) as type string in assignment
...
result.Items.Data.price undefined (type []*stripe.SubscriptionItem has no field or method price)
So how do i get the data for data.CustomerId
and data.PricePerSeat
?
UPDATE:
here is structure of the subscription object from stripe
type FilesStripeCreateSubscription struct {
ID string `json:"id"`
CancelAt interface{} `json:"cancel_at"`
CancelAtPeriodEnd bool `json:"cancel_at_period_end"`
CanceledAt interface{} `json:"canceled_at"`
CurrentPeriodEnd int64 `json:"current_period_end"`
CurrentPeriodStart int64 `json:"current_period_start"`
Customer string `json:"customer"`
Items struct {
Data []struct {
ID string `json:"id"`
BillingThresholds interface{} `json:"billing_thresholds"`
Created int64 `json:"created"`
Metadata struct {
} `json:"metadata"`
Object string `json:"object"`
Price struct {
ID string `json:"id"`
Active bool `json:"active"`
Currency string `json:"currency"`
CustomUnitAmount interface{} `json:"custom_unit_amount"`
Metadata struct {
} `json:"metadata"`
Nickname string `json:"nickname"`
Object string `json:"object"`
Product string `json:"product"`
Recurring struct {
AggregateUsage interface{} `json:"aggregate_usage"`
Interval string `json:"interval"`
IntervalCount int64 `json:"interval_count"`
UsageType string `json:"usage_type"`
} `json:"recurring"`
TaxBehavior string `json:"tax_behavior"`
TiersMode interface{} `json:"tiers_mode"`
TransformQuantity interface{} `json:"transform_quantity"`
Type string `json:"type"`
UnitAmount int64 `json:"unit_amount"`
UnitAmountDecimal int64 `json:"unit_amount_decimal,string"`
} `json:"price"`
Quantity int64 `json:"quantity"`
Subscription string `json:"subscription"`
TaxRates []interface{} `json:"tax_rates"`
} `json:"data"`
} `json:"items"`
}
Lets first go over the code which works under the hood, what is being returned and then we look at the problems one at a time.
When we call sub.New()
method with params
it returns Subscription
type
Note: I will only show limited definition for types since adding the complete structure will make the answer big and not specific to the question context
Lets Look Subscription
type
type Subscription struct {
...
// Start of the current period that the subscription has been invoiced for.
CurrentPeriodStart int64 `json:"current_period_start"`
// ID of the customer who owns the subscription.
Customer *Customer `json:"customer"`
...
// List of subscription items, each with an attached price.
Items *SubscriptionItemList `json:"items"`
...
}
Let looks over the first error
cannot use result.CurrentPeriodStart (type int64) as type time.Time in assignment
According to the Subscription
type we can see CurrentPeriodStart
is of type int64
while you are trying to set it to StartAt
field of SubscriptionDetails
type which is of type time.Time
since the types are different one type cannot be assigned to other, to solve the issue we need to explicitly convert it to time.Time
which can be done as follows:
data.StartAt = time.Unix(result.CurrentPeriodStart, 0)
time.Unix
method creates time.Time
type from the passed int64
value and return which we can assign to StartAt
field
Now lets move on to the second error
cannot use result.Customer (type *stripe.Customer) as type string in assignment
As we can see from Subscription
definition Customer
field is of type *Customer
it is not string type since you are trying to assign *Customer
type to CustomerId
field of string type which is not possible that causes the above error, referred data is incorrect then where is the correct data the correct data is available inside *Customer
type withing ID
field which can be retrieved as follows
data.CustomerId = result.Customer.ID
Lets go over the last error
result.Items.Data.price undefined (type []*stripe.SubscriptionItem has no field or method price)
Again if we look at Subscription
definition we can see Items
field is of type *SubscriptionItemList
type and if we look at *SubscriptionItemList
definition
type SubscriptionItemList struct {
APIResource
ListMeta
Data []*SubscriptionItem `json:"data"`
}
It contains a field name Data
and Data
is of type []*SubscriptionItem
notice it is slice []
of *SubscriptionItem
, which is the cause of the error since Data
field is slice of *SubscriptionItem
we can solve the problem as below:
data.PricePerSeat = result.Items.Data[0].price.UnitAmount
There are few more errors which can occur that I would like to point out please continue reading below to solve those issue
Now lets look at *SubscriptionItem
definition
type SubscriptionItem struct {
...
Price *Price `json:"price"`
...
}
It contains Price
field notice the name starts with capital letter and in shared code it is referred with small letter which can cause another issue and finally if we look at Price
definition
type Price struct {
...
// The unit amount in %s to be charged, represented as a whole integer if possible. Only set if `billing_scheme=per_unit`.
UnitAmount int64 `json:"unit_amount"`
// The unit amount in %s to be charged, represented as a decimal string with at most 12 decimal places. Only set if `billing_scheme=per_unit`.
UnitAmountDecimal float64 `json:"unit_amount_decimal,string"`
...
}
It contains UnitAmount
field which is what we are using, but there is a catch here UnitAmount
is of type int64
but PricePerSeat
is of type float64
assigning different type to each other will again cause error so either you can convert int64
to float64
or even better you can use UnitAmountDecimal
field available within Price
type containing the same data in float64
format which will reduce the explicit conversion that we would have to do when using UnitAmount
field, so as per the explanation we get below solution
data.PricePerSeat = result.Items.Data[0].Price.UnitAmountDecimal
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With