简体   繁体   English

如何从条带订阅响应 object 中正确获取结构项?

[英]How do i properly get struct items from stripe subscription response object?

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这里是响应结构的链接 object stripe 订阅 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有些项目很容易直接得到,比如我很容易用result.ID得到的ID字段,没有投诉,但对于其他项目,这里是错误消息

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 ?那么如何获取data.CustomerIddata.PricePerSeat的数据呢?

UPDATE:更新:

here is structure of the subscription object from stripe这是来自条带的订阅 object 的结构

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"`
}

Looking at the 3 errors you have mentioned查看您提到的 3 个错误

  1. cannot use result.CurrentPeriodStart (type int64) as type time.Time in assignment

Type of result.CurrentPeriodStart is int64 and you are trying to set it into a field of type time.Time , which will obviously fail. result.CurrentPeriodStart的类型是 int64 并且您试图将其设置为time.Time类型的字段,这显然会失败。 The API is sending the time in unix format , which you need to parse to get it into time.Time. API 以 unix 格式发送时间,您需要将其解析为 time.Time。 Do this for other time fields also也对其他时间字段执行此操作

data.StartAt = time.Unix(result.CurrentPeriodStart, 0)
  1. cannot use result.Customer (type *stripe.Customer) as type string in assignment

Similar issue as above, the field result.Customer is of type *stripe.Customer while you are trying to set it into a field of type string .与上面类似的问题,字段result.Customer*stripe.Customer类型,而您尝试将其设置为string类型的字段。 Customer ID is a field inside the struct Customer客户 ID 是结构Customer中的一个字段

data.CustomerId = result.Customer.ID
  1. result.Items.Data.price undefined (type []*stripe.SubscriptionItem has no field or method price)

stripe.SubscriptionItem struct does not have a field price . stripe.SubscriptionItem结构没有price字段。 I am not sure what you want here.我不确定你想要什么。 I suggest reading the subscriptions object documentation .我建议阅读订阅 object 文档

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.让我们首先 go 了解在后台运行的代码,返回的内容,然后我们一次看一个问题。

When we call sub.New() method with params it returns Subscription type which can be seen here当我们使用params调用sub.New()方法时,它返回Subscription类型,可以在here看到

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 only Look Subscription type让我们只看Subscription类型

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 it is not assignable to solve the issue we need to explicitly convert it to time.Time which can be done as follows:根据Subscription类型,我们可以看到CurrentPeriodStart的类型为int64 ,而您尝试将其设置为SubscriptionDetails类型的StartAt字段,该字段的类型为time.Time ,因为类型不同,因此无法分配以解决我们需要明确的问题将其转换为time.Time可以按如下方式完成:

data.StartAt = time.Unix(result.CurrentPeriodStart, 0)

and then you can assign the return value from time.Unix method to StartAt field然后您可以将time.Unix方法的返回值分配给StartAt字段

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 since we are referring to incorrect data where is the correct data the correct data is available inside *Customer type withing ID field which can be retrieved as follows正如我们从Subscription定义中看到的那样, Customer字段的类型是*Customer ,它不是字符串类型,因为您试图将*Customer类型分配给字符串类型的CustomerId字段,这不可能导致上述错误,因为我们指的是不正确的数据正确的数据在哪里 正确的数据在*Customer type withing ID字段中可用,可以按如下方式检索

data.CustomerId = result.Customer.ID

Lets go over the last error让 go 超过最后一个错误

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 it we look at *SubscriptionItemList definition同样,如果我们查看Subscription定义,我们可以看到Items字段的类型为*SubscriptionItemList类型,我们查看*SubscriptionItemList定义

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 , now lets look at *SubscriptionItem definition它包含一个字段名称Data和 Data 的类型是[]*SubscriptionItem注意它是*SubscriptionItem SubscriptionItem 的 slice [] ,现在让我们看看*SubscriptionItem定义

type SubscriptionItem struct {
  ...
  Price *Price `json:"price"`
  ...
}

It contains Price field notice the name starts with capital letter and finally if we look at Price definition它包含Price字段注意名称以大写字母开头,最后如果我们查看Price定义

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 required, but there is a catch here UnitAmount is of type int64 but PricePerSeat is of type float64 so probably you want UnitAmountDecimal which is float64 type as per requirement, so as per the explanation we can solve the problem as below它包含我们需要的UnitAmount字段,但是这里有一个问题UnitAmountint64类型,但PricePerSeatfloat64类型,所以您可能需要根据要求使用float64类型的UnitAmountDecimal ,因此按照说明我们可以解决问题如下

data.PricePerSeat = result.Items.Data[0].Price.UnitAmountDecimal

To access the price result.Items.Data[0].Price.UnitAmount访问价格result.Items.Data[0].Price.UnitAmount

If you use a debugger, just put a breakpoint after the sub.New line and explore the content of the result variable如果您使用调试器,只需在sub.New行之后放置一个断点并探索结果变量的内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM