github.com/stripe/stripe-go/v76@v76.25.0/customer.go (about)

     1  //
     2  //
     3  // File generated from our OpenAPI spec
     4  //
     5  //
     6  
     7  package stripe
     8  
     9  import "encoding/json"
    10  
    11  // Surfaces if automatic tax computation is possible given the current customer location information.
    12  type CustomerTaxAutomaticTax string
    13  
    14  // List of values that CustomerTaxAutomaticTax can take
    15  const (
    16  	CustomerTaxAutomaticTaxFailed               CustomerTaxAutomaticTax = "failed"
    17  	CustomerTaxAutomaticTaxNotCollecting        CustomerTaxAutomaticTax = "not_collecting"
    18  	CustomerTaxAutomaticTaxSupported            CustomerTaxAutomaticTax = "supported"
    19  	CustomerTaxAutomaticTaxUnrecognizedLocation CustomerTaxAutomaticTax = "unrecognized_location"
    20  )
    21  
    22  // The data source used to infer the customer's location.
    23  type CustomerTaxLocationSource string
    24  
    25  // List of values that CustomerTaxLocationSource can take
    26  const (
    27  	CustomerTaxLocationSourceBillingAddress      CustomerTaxLocationSource = "billing_address"
    28  	CustomerTaxLocationSourceIPAddress           CustomerTaxLocationSource = "ip_address"
    29  	CustomerTaxLocationSourcePaymentMethod       CustomerTaxLocationSource = "payment_method"
    30  	CustomerTaxLocationSourceShippingDestination CustomerTaxLocationSource = "shipping_destination"
    31  )
    32  
    33  // Describes the customer's tax exemption status, which is `none`, `exempt`, or `reverse`. When set to `reverse`, invoice and receipt PDFs include the following text: **"Reverse charge"**.
    34  type CustomerTaxExempt string
    35  
    36  // List of values that CustomerTaxExempt can take
    37  const (
    38  	CustomerTaxExemptExempt  CustomerTaxExempt = "exempt"
    39  	CustomerTaxExemptNone    CustomerTaxExempt = "none"
    40  	CustomerTaxExemptReverse CustomerTaxExempt = "reverse"
    41  )
    42  
    43  // Permanently deletes a customer. It cannot be undone. Also immediately cancels any active subscriptions on the customer.
    44  type CustomerParams struct {
    45  	Params `form:"*"`
    46  	// The customer's address.
    47  	Address *AddressParams `form:"address"`
    48  	// An integer amount in cents (or local equivalent) that represents the customer's current balance, which affect the customer's future invoices. A negative amount represents a credit that decreases the amount due on an invoice; a positive amount increases the amount due on an invoice.
    49  	Balance *int64 `form:"balance"`
    50  	// Balance information and default balance settings for this customer.
    51  	CashBalance *CustomerCashBalanceParams `form:"cash_balance"`
    52  	Coupon      *string                    `form:"coupon"`
    53  	// If you are using payment methods created via the PaymentMethods API, see the [invoice_settings.default_payment_method](https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method) parameter.
    54  	//
    55  	// Provide the ID of a payment source already attached to this customer to make it this customer's default payment source.
    56  	//
    57  	// If you want to add a new payment source and make it the default, see the [source](https://stripe.com/docs/api/customers/update#update_customer-source) property.
    58  	DefaultSource *string `form:"default_source"`
    59  	// An arbitrary string that you can attach to a customer object. It is displayed alongside the customer in the dashboard.
    60  	Description *string `form:"description"`
    61  	// Customer's email address. It's displayed alongside the customer in your dashboard and can be useful for searching and tracking. This may be up to *512 characters*.
    62  	Email *string `form:"email"`
    63  	// Specifies which fields in the response should be expanded.
    64  	Expand []*string `form:"expand"`
    65  	// The prefix for the customer used to generate unique invoice numbers. Must be 3–12 uppercase letters or numbers.
    66  	InvoicePrefix *string `form:"invoice_prefix"`
    67  	// Default invoice settings for this customer.
    68  	InvoiceSettings *CustomerInvoiceSettingsParams `form:"invoice_settings"`
    69  	// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to `metadata`.
    70  	Metadata map[string]string `form:"metadata"`
    71  	// The customer's full name or business name.
    72  	Name *string `form:"name"`
    73  	// The sequence to be used on the customer's next invoice. Defaults to 1.
    74  	NextInvoiceSequence *int64  `form:"next_invoice_sequence"`
    75  	PaymentMethod       *string `form:"payment_method"`
    76  	// The customer's phone number.
    77  	Phone *string `form:"phone"`
    78  	// Customer's preferred languages, ordered by preference.
    79  	PreferredLocales []*string `form:"preferred_locales"`
    80  	// The ID of a promotion code to apply to the customer. The customer will have a discount applied on all recurring payments. Charges you create through the API will not have the discount.
    81  	PromotionCode *string `form:"promotion_code"`
    82  	// The customer's shipping information. Appears on invoices emailed to this customer.
    83  	Shipping *CustomerShippingParams `form:"shipping"`
    84  	Source   *string                 `form:"source"`
    85  	// Tax details about the customer.
    86  	Tax *CustomerTaxParams `form:"tax"`
    87  	// The customer's tax exemption. One of `none`, `exempt`, or `reverse`.
    88  	TaxExempt *string `form:"tax_exempt"`
    89  	// The customer's tax IDs.
    90  	TaxIDData []*CustomerTaxIDDataParams `form:"tax_id_data"`
    91  	// ID of the test clock to attach to the customer.
    92  	TestClock *string `form:"test_clock"`
    93  	Validate  *bool   `form:"validate"`
    94  }
    95  
    96  // AddExpand appends a new field to expand.
    97  func (p *CustomerParams) AddExpand(f string) {
    98  	p.Expand = append(p.Expand, &f)
    99  }
   100  
   101  // AddMetadata adds a new key-value pair to the Metadata.
   102  func (p *CustomerParams) AddMetadata(key string, value string) {
   103  	if p.Metadata == nil {
   104  		p.Metadata = make(map[string]string)
   105  	}
   106  
   107  	p.Metadata[key] = value
   108  }
   109  
   110  // Settings controlling the behavior of the customer's cash balance,
   111  // such as reconciliation of funds received.
   112  type CustomerCashBalanceSettingsParams struct {
   113  	// Controls how funds transferred by the customer are applied to payment intents and invoices. Valid options are `automatic`, `manual`, or `merchant_default`. For more information about these reconciliation modes, see [Reconciliation](https://stripe.com/docs/payments/customer-balance/reconciliation).
   114  	ReconciliationMode *string `form:"reconciliation_mode"`
   115  }
   116  
   117  // Balance information and default balance settings for this customer.
   118  type CustomerCashBalanceParams struct {
   119  	// Settings controlling the behavior of the customer's cash balance,
   120  	// such as reconciliation of funds received.
   121  	Settings *CustomerCashBalanceSettingsParams `form:"settings"`
   122  }
   123  
   124  // The list of up to 4 default custom fields to be displayed on invoices for this customer. When updating, pass an empty string to remove previously-defined fields.
   125  type CustomerInvoiceSettingsCustomFieldParams struct {
   126  	// The name of the custom field. This may be up to 40 characters.
   127  	Name *string `form:"name"`
   128  	// The value of the custom field. This may be up to 140 characters.
   129  	Value *string `form:"value"`
   130  }
   131  
   132  // Default options for invoice PDF rendering for this customer.
   133  type CustomerInvoiceSettingsRenderingOptionsParams struct {
   134  	// How line-item prices and amounts will be displayed with respect to tax on invoice PDFs. One of `exclude_tax` or `include_inclusive_tax`. `include_inclusive_tax` will include inclusive tax (and exclude exclusive tax) in invoice PDF amounts. `exclude_tax` will exclude all tax (inclusive and exclusive alike) from invoice PDF amounts.
   135  	AmountTaxDisplay *string `form:"amount_tax_display"`
   136  }
   137  
   138  // Default invoice settings for this customer.
   139  type CustomerInvoiceSettingsParams struct {
   140  	// The list of up to 4 default custom fields to be displayed on invoices for this customer. When updating, pass an empty string to remove previously-defined fields.
   141  	CustomFields []*CustomerInvoiceSettingsCustomFieldParams `form:"custom_fields"`
   142  	// ID of a payment method that's attached to the customer, to be used as the customer's default payment method for subscriptions and invoices.
   143  	DefaultPaymentMethod *string `form:"default_payment_method"`
   144  	// Default footer to be displayed on invoices for this customer.
   145  	Footer *string `form:"footer"`
   146  	// Default options for invoice PDF rendering for this customer.
   147  	RenderingOptions *CustomerInvoiceSettingsRenderingOptionsParams `form:"rendering_options"`
   148  }
   149  
   150  // The customer's shipping information. Appears on invoices emailed to this customer.
   151  type CustomerShippingParams struct {
   152  	// Customer shipping address.
   153  	Address *AddressParams `form:"address"`
   154  	// Customer name.
   155  	Name *string `form:"name"`
   156  	// Customer phone (including extension).
   157  	Phone *string `form:"phone"`
   158  }
   159  
   160  // Tax details about the customer.
   161  type CustomerTaxParams struct {
   162  	// A recent IP address of the customer used for tax reporting and tax location inference. Stripe recommends updating the IP address when a new PaymentMethod is attached or the address field on the customer is updated. We recommend against updating this field more frequently since it could result in unexpected tax location/reporting outcomes.
   163  	IPAddress *string `form:"ip_address"`
   164  	// A flag that indicates when Stripe should validate the customer tax location. Defaults to `deferred`.
   165  	ValidateLocation *string `form:"validate_location"`
   166  }
   167  
   168  // Removes the currently applied discount on a customer.
   169  type CustomerDeleteDiscountParams struct {
   170  	Params `form:"*"`
   171  }
   172  
   173  // Returns a list of your customers. The customers are returned sorted by creation date, with the most recent customers appearing first.
   174  type CustomerListParams struct {
   175  	ListParams `form:"*"`
   176  	// Only return customers that were created during the given date interval.
   177  	Created *int64 `form:"created"`
   178  	// Only return customers that were created during the given date interval.
   179  	CreatedRange *RangeQueryParams `form:"created"`
   180  	// A case-sensitive filter on the list based on the customer's `email` field. The value must be a string.
   181  	Email *string `form:"email"`
   182  	// Specifies which fields in the response should be expanded.
   183  	Expand []*string `form:"expand"`
   184  	// Provides a list of customers that are associated with the specified test clock. The response will not include customers with test clocks if this parameter is not set.
   185  	TestClock *string `form:"test_clock"`
   186  }
   187  
   188  // AddExpand appends a new field to expand.
   189  func (p *CustomerListParams) AddExpand(f string) {
   190  	p.Expand = append(p.Expand, &f)
   191  }
   192  
   193  // The customer's tax IDs.
   194  type CustomerTaxIDDataParams struct {
   195  	// Type of the tax ID, one of `ad_nrt`, `ae_trn`, `ar_cuit`, `au_abn`, `au_arn`, `bg_uic`, `bo_tin`, `br_cnpj`, `br_cpf`, `ca_bn`, `ca_gst_hst`, `ca_pst_bc`, `ca_pst_mb`, `ca_pst_sk`, `ca_qst`, `ch_vat`, `cl_tin`, `cn_tin`, `co_nit`, `cr_tin`, `do_rcn`, `ec_ruc`, `eg_tin`, `es_cif`, `eu_oss_vat`, `eu_vat`, `gb_vat`, `ge_vat`, `hk_br`, `hu_tin`, `id_npwp`, `il_vat`, `in_gst`, `is_vat`, `jp_cn`, `jp_rn`, `jp_trn`, `ke_pin`, `kr_brn`, `li_uid`, `mx_rfc`, `my_frp`, `my_itn`, `my_sst`, `no_vat`, `no_voec`, `nz_gst`, `pe_ruc`, `ph_tin`, `ro_tin`, `rs_pib`, `ru_inn`, `ru_kpp`, `sa_vat`, `sg_gst`, `sg_uen`, `si_tin`, `sv_nit`, `th_vat`, `tr_tin`, `tw_vat`, `ua_vat`, `us_ein`, `uy_ruc`, `ve_rif`, `vn_tin`, or `za_vat`
   196  	Type *string `form:"type"`
   197  	// Value of the tax ID.
   198  	Value *string `form:"value"`
   199  }
   200  
   201  // Returns a list of PaymentMethods for a given Customer
   202  type CustomerListPaymentMethodsParams struct {
   203  	ListParams `form:"*"`
   204  	Customer   *string `form:"-"` // Included in URL
   205  	// Specifies which fields in the response should be expanded.
   206  	Expand []*string `form:"expand"`
   207  	// An optional filter on the list, based on the object `type` field. Without the filter, the list includes all current and future payment method types. If your integration expects only one type of payment method in the response, make sure to provide a type value in the request.
   208  	Type *string `form:"type"`
   209  }
   210  
   211  // AddExpand appends a new field to expand.
   212  func (p *CustomerListPaymentMethodsParams) AddExpand(f string) {
   213  	p.Expand = append(p.Expand, &f)
   214  }
   215  
   216  // Retrieves a PaymentMethod object for a given Customer.
   217  type CustomerRetrievePaymentMethodParams struct {
   218  	Params   `form:"*"`
   219  	Customer *string `form:"-"` // Included in URL
   220  	// Specifies which fields in the response should be expanded.
   221  	Expand []*string `form:"expand"`
   222  }
   223  
   224  // AddExpand appends a new field to expand.
   225  func (p *CustomerRetrievePaymentMethodParams) AddExpand(f string) {
   226  	p.Expand = append(p.Expand, &f)
   227  }
   228  
   229  // Search for customers you've previously created using Stripe's [Search Query Language](https://stripe.com/docs/search#search-query-language).
   230  // Don't use search in read-after-write flows where strict consistency is necessary. Under normal operating
   231  // conditions, data is searchable in less than a minute. Occasionally, propagation of new or updated data can be up
   232  // to an hour behind during outages. Search functionality is not available to merchants in India.
   233  type CustomerSearchParams struct {
   234  	SearchParams `form:"*"`
   235  	// Specifies which fields in the response should be expanded.
   236  	Expand []*string `form:"expand"`
   237  	// A cursor for pagination across multiple pages of results. Don't include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results.
   238  	Page *string `form:"page"`
   239  }
   240  
   241  // AddExpand appends a new field to expand.
   242  func (p *CustomerSearchParams) AddExpand(f string) {
   243  	p.Expand = append(p.Expand, &f)
   244  }
   245  
   246  // Configuration for eu_bank_transfer funding type.
   247  type CustomerCreateFundingInstructionsBankTransferEUBankTransferParams struct {
   248  	// The desired country code of the bank account information. Permitted values include: `BE`, `DE`, `ES`, `FR`, `IE`, or `NL`.
   249  	Country *string `form:"country"`
   250  }
   251  
   252  // Additional parameters for `bank_transfer` funding types
   253  type CustomerCreateFundingInstructionsBankTransferParams struct {
   254  	// Configuration for eu_bank_transfer funding type.
   255  	EUBankTransfer *CustomerCreateFundingInstructionsBankTransferEUBankTransferParams `form:"eu_bank_transfer"`
   256  	// List of address types that should be returned in the financial_addresses response. If not specified, all valid types will be returned.
   257  	//
   258  	// Permitted values include: `sort_code`, `zengin`, `iban`, or `spei`.
   259  	RequestedAddressTypes []*string `form:"requested_address_types"`
   260  	// The type of the `bank_transfer`
   261  	Type *string `form:"type"`
   262  }
   263  
   264  // Retrieve funding instructions for a customer cash balance. If funding instructions do not yet exist for the customer, new
   265  // funding instructions will be created. If funding instructions have already been created for a given customer, the same
   266  // funding instructions will be retrieved. In other words, we will return the same funding instructions each time.
   267  type CustomerCreateFundingInstructionsParams struct {
   268  	Params `form:"*"`
   269  	// Additional parameters for `bank_transfer` funding types
   270  	BankTransfer *CustomerCreateFundingInstructionsBankTransferParams `form:"bank_transfer"`
   271  	// Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase. Must be a [supported currency](https://stripe.com/docs/currencies).
   272  	Currency *string `form:"currency"`
   273  	// Specifies which fields in the response should be expanded.
   274  	Expand []*string `form:"expand"`
   275  	// The `funding_type` to get the instructions for.
   276  	FundingType *string `form:"funding_type"`
   277  }
   278  
   279  // AddExpand appends a new field to expand.
   280  func (p *CustomerCreateFundingInstructionsParams) AddExpand(f string) {
   281  	p.Expand = append(p.Expand, &f)
   282  }
   283  
   284  // Default custom fields to be displayed on invoices for this customer.
   285  type CustomerInvoiceSettingsCustomField struct {
   286  	// The name of the custom field.
   287  	Name string `json:"name"`
   288  	// The value of the custom field.
   289  	Value string `json:"value"`
   290  }
   291  
   292  // Default options for invoice PDF rendering for this customer.
   293  type CustomerInvoiceSettingsRenderingOptions struct {
   294  	// How line-item prices and amounts will be displayed with respect to tax on invoice PDFs.
   295  	AmountTaxDisplay string `json:"amount_tax_display"`
   296  }
   297  type CustomerInvoiceSettings struct {
   298  	// Default custom fields to be displayed on invoices for this customer.
   299  	CustomFields []*CustomerInvoiceSettingsCustomField `json:"custom_fields"`
   300  	// ID of a payment method that's attached to the customer, to be used as the customer's default payment method for subscriptions and invoices.
   301  	DefaultPaymentMethod *PaymentMethod `json:"default_payment_method"`
   302  	// Default footer to be displayed on invoices for this customer.
   303  	Footer string `json:"footer"`
   304  	// Default options for invoice PDF rendering for this customer.
   305  	RenderingOptions *CustomerInvoiceSettingsRenderingOptions `json:"rendering_options"`
   306  }
   307  
   308  // The customer's location as identified by Stripe Tax.
   309  type CustomerTaxLocation struct {
   310  	// The customer's country as identified by Stripe Tax.
   311  	Country string `json:"country"`
   312  	// The data source used to infer the customer's location.
   313  	Source CustomerTaxLocationSource `json:"source"`
   314  	// The customer's state, county, province, or region as identified by Stripe Tax.
   315  	State string `json:"state"`
   316  }
   317  type CustomerTax struct {
   318  	// Surfaces if automatic tax computation is possible given the current customer location information.
   319  	AutomaticTax CustomerTaxAutomaticTax `json:"automatic_tax"`
   320  	// A recent IP address of the customer used for tax reporting and tax location inference.
   321  	IPAddress string `json:"ip_address"`
   322  	// The customer's location as identified by Stripe Tax.
   323  	Location *CustomerTaxLocation `json:"location"`
   324  }
   325  
   326  // This object represents a customer of your business. Use it to create recurring charges and track payments that belong to the same customer.
   327  //
   328  // Related guide: [Save a card during payment](https://stripe.com/docs/payments/save-during-payment)
   329  type Customer struct {
   330  	APIResource
   331  	// The customer's address.
   332  	Address *Address `json:"address"`
   333  	// The current balance, if any, that's stored on the customer. If negative, the customer has credit to apply to their next invoice. If positive, the customer has an amount owed that's added to their next invoice. The balance only considers amounts that Stripe hasn't successfully applied to any invoice. It doesn't reflect unpaid invoices. This balance is only taken into account after invoices finalize.
   334  	Balance int64 `json:"balance"`
   335  	// The current funds being held by Stripe on behalf of the customer. You can apply these funds towards payment intents when the source is "cash_balance". The `settings[reconciliation_mode]` field describes if these funds apply to these payment intents manually or automatically.
   336  	CashBalance *CashBalance `json:"cash_balance"`
   337  	// Time at which the object was created. Measured in seconds since the Unix epoch.
   338  	Created int64 `json:"created"`
   339  	// Three-letter [ISO code for the currency](https://stripe.com/docs/currencies) the customer can be charged in for recurring billing purposes.
   340  	Currency Currency `json:"currency"`
   341  	// ID of the default payment source for the customer.
   342  	//
   343  	// If you use payment methods created through the PaymentMethods API, see the [invoice_settings.default_payment_method](https://stripe.com/docs/api/customers/object#customer_object-invoice_settings-default_payment_method) field instead.
   344  	DefaultSource *PaymentSource `json:"default_source"`
   345  	Deleted       bool           `json:"deleted"`
   346  	// Tracks the most recent state change on any invoice belonging to the customer. Paying an invoice or marking it uncollectible via the API will set this field to false. An automatic payment failure or passing the `invoice.due_date` will set this field to `true`.
   347  	//
   348  	// If an invoice becomes uncollectible by [dunning](https://stripe.com/docs/billing/automatic-collection), `delinquent` doesn't reset to `false`.
   349  	//
   350  	// If you care whether the customer has paid their most recent subscription invoice, use `subscription.status` instead. Paying or marking uncollectible any customer invoice regardless of whether it is the latest invoice for a subscription will always set this field to `false`.
   351  	Delinquent bool `json:"delinquent"`
   352  	// An arbitrary string attached to the object. Often useful for displaying to users.
   353  	Description string `json:"description"`
   354  	// Describes the current discount active on the customer, if there is one.
   355  	Discount *Discount `json:"discount"`
   356  	// The customer's email address.
   357  	Email string `json:"email"`
   358  	// Unique identifier for the object.
   359  	ID string `json:"id"`
   360  	// The current multi-currency balances, if any, that's stored on the customer. If positive in a currency, the customer has a credit to apply to their next invoice denominated in that currency. If negative, the customer has an amount owed that's added to their next invoice denominated in that currency. These balances don't apply to unpaid invoices. They solely track amounts that Stripe hasn't successfully applied to any invoice. Stripe only applies a balance in a specific currency to an invoice after that invoice (which is in the same currency) finalizes.
   361  	InvoiceCreditBalance map[string]int64 `json:"invoice_credit_balance"`
   362  	// The prefix for the customer used to generate unique invoice numbers.
   363  	InvoicePrefix   string                   `json:"invoice_prefix"`
   364  	InvoiceSettings *CustomerInvoiceSettings `json:"invoice_settings"`
   365  	// Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode.
   366  	Livemode bool `json:"livemode"`
   367  	// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object. This can be useful for storing additional information about the object in a structured format.
   368  	Metadata map[string]string `json:"metadata"`
   369  	// The customer's full name or business name.
   370  	Name string `json:"name"`
   371  	// The suffix of the customer's next invoice number (for example, 0001).
   372  	NextInvoiceSequence int64 `json:"next_invoice_sequence"`
   373  	// String representing the object's type. Objects of the same type share the same value.
   374  	Object string `json:"object"`
   375  	// The customer's phone number.
   376  	Phone string `json:"phone"`
   377  	// The customer's preferred locales (languages), ordered by preference.
   378  	PreferredLocales []string `json:"preferred_locales"`
   379  	// Mailing and shipping address for the customer. Appears on invoices emailed to this customer.
   380  	Shipping *ShippingDetails   `json:"shipping"`
   381  	Sources  *PaymentSourceList `json:"sources"`
   382  	// The customer's current subscriptions, if any.
   383  	Subscriptions *SubscriptionList `json:"subscriptions"`
   384  	Tax           *CustomerTax      `json:"tax"`
   385  	// Describes the customer's tax exemption status, which is `none`, `exempt`, or `reverse`. When set to `reverse`, invoice and receipt PDFs include the following text: **"Reverse charge"**.
   386  	TaxExempt CustomerTaxExempt `json:"tax_exempt"`
   387  	// The customer's tax IDs.
   388  	TaxIDs *TaxIDList `json:"tax_ids"`
   389  	// ID of the test clock that this customer belongs to.
   390  	TestClock *TestHelpersTestClock `json:"test_clock"`
   391  }
   392  
   393  // CustomerList is a list of Customers as retrieved from a list endpoint.
   394  type CustomerList struct {
   395  	APIResource
   396  	ListMeta
   397  	Data []*Customer `json:"data"`
   398  }
   399  
   400  // CustomerSearchResult is a list of Customer search results as retrieved from a search endpoint.
   401  type CustomerSearchResult struct {
   402  	APIResource
   403  	SearchMeta
   404  	Data []*Customer `json:"data"`
   405  }
   406  
   407  // UnmarshalJSON handles deserialization of a Customer.
   408  // This custom unmarshaling is needed because the resulting
   409  // property may be an id or the full struct if it was expanded.
   410  func (c *Customer) UnmarshalJSON(data []byte) error {
   411  	if id, ok := ParseID(data); ok {
   412  		c.ID = id
   413  		return nil
   414  	}
   415  
   416  	type customer Customer
   417  	var v customer
   418  	if err := json.Unmarshal(data, &v); err != nil {
   419  		return err
   420  	}
   421  
   422  	*c = Customer(v)
   423  	return nil
   424  }