// File generated from our OpenAPI spec
package com.stripe.model;

import com.google.gson.annotations.SerializedName;
import com.stripe.exception.StripeException;
import com.stripe.net.ApiMode;
import com.stripe.net.ApiRequestParams;
import com.stripe.net.ApiResource;
import com.stripe.net.BaseAddress;
import com.stripe.net.RequestOptions;
import com.stripe.net.StripeResponseGetter;
import com.stripe.param.PaymentIntentApplyCustomerBalanceParams;
import com.stripe.param.PaymentIntentCancelParams;
import com.stripe.param.PaymentIntentCaptureParams;
import com.stripe.param.PaymentIntentConfirmParams;
import com.stripe.param.PaymentIntentCreateParams;
import com.stripe.param.PaymentIntentIncrementAuthorizationParams;
import com.stripe.param.PaymentIntentListParams;
import com.stripe.param.PaymentIntentRetrieveParams;
import com.stripe.param.PaymentIntentSearchParams;
import com.stripe.param.PaymentIntentUpdateParams;
import com.stripe.param.PaymentIntentVerifyMicrodepositsParams;
import java.util.List;
import java.util.Map;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

/**
 * A PaymentIntent guides you through the process of collecting a payment from your customer. We
 * recommend that you create exactly one PaymentIntent for each order or customer session in your
 * system. You can reference the PaymentIntent later to see the history of payment attempts for a
 * particular session.
 *
 * <p>A PaymentIntent transitions through <a
 * href="https://stripe.com/docs/payments/intents#intent-statuses">multiple statuses</a> throughout
 * its lifetime as it interfaces with Stripe.js to perform authentication flows and ultimately
 * creates at most one successful charge.
 *
 * <p>Related guide: <a href="https://stripe.com/docs/payments/payment-intents">Payment Intents
 * API</a>
 */
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
public class PaymentIntent extends ApiResource implements HasId, MetadataStore<PaymentIntent> {
  /**
   * Amount intended to be collected by this PaymentIntent. A positive integer representing how much
   * to charge in the <a href="https://stripe.com/docs/currencies#zero-decimal">smallest currency
   * unit</a> (e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal currency). The
   * minimum amount is $0.50 US or <a
   * href="https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts">equivalent in
   * charge currency</a>. The amount value supports up to eight digits (e.g., a value of 99999999
   * for a USD charge of $999,999.99).
   */
  @SerializedName("amount")
  Long amount;

  /** Amount that can be captured from this PaymentIntent. */
  @SerializedName("amount_capturable")
  Long amountCapturable;

  @SerializedName("amount_details")
  AmountDetails amountDetails;

  /** Amount that was collected by this PaymentIntent. */
  @SerializedName("amount_received")
  Long amountReceived;

  /** ID of the Connect application that created the PaymentIntent. */
  @SerializedName("application")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<Application> application;

  /**
   * The amount of the application fee (if any) that will be requested to be applied to the payment
   * and transferred to the application owner's Stripe account. The amount of the application fee
   * collected will be capped at the total payment amount. For more information, see the
   * PaymentIntents <a href="https://stripe.com/docs/payments/connected-accounts">use case for
   * connected accounts</a>.
   */
  @SerializedName("application_fee_amount")
  Long applicationFeeAmount;

  /**
   * Settings to configure compatible payment methods from the <a
   * href="https://dashboard.stripe.com/settings/payment_methods">Stripe Dashboard.</a>
   */
  @SerializedName("automatic_payment_methods")
  AutomaticPaymentMethods automaticPaymentMethods;

  /**
   * Populated when {@code status} is {@code canceled}, this is the time at which the PaymentIntent
   * was canceled. Measured in seconds since the Unix epoch.
   */
  @SerializedName("canceled_at")
  Long canceledAt;

  /**
   * Reason for cancellation of this PaymentIntent, either user-provided ({@code duplicate}, {@code
   * fraudulent}, {@code requested_by_customer}, or {@code abandoned}) or generated by Stripe
   * internally ({@code failed_invoice}, {@code void_invoice}, or {@code automatic}).
   *
   * <p>One of {@code abandoned}, {@code automatic}, {@code duplicate}, {@code failed_invoice},
   * {@code fraudulent}, {@code requested_by_customer}, or {@code void_invoice}.
   */
  @SerializedName("cancellation_reason")
  String cancellationReason;

  /**
   * Controls when the funds will be captured from the customer's account.
   *
   * <p>One of {@code automatic}, {@code automatic_async}, or {@code manual}.
   */
  @SerializedName("capture_method")
  String captureMethod;

  /**
   * The client secret of this PaymentIntent. Used for client-side retrieval using a publishable
   * key.
   *
   * <p>The client secret can be used to complete a payment from your frontend. It should not be
   * stored, logged, or exposed to anyone other than the customer. Make sure that you have TLS
   * enabled on any page that includes the client secret.
   *
   * <p>Refer to our docs to <a
   * href="https://stripe.com/docs/payments/accept-a-payment?ui=elements">accept a payment</a> and
   * learn about how {@code client_secret} should be handled.
   */
  @SerializedName("client_secret")
  String clientSecret;

  @SerializedName("confirmation_method")
  String confirmationMethod;

  /** Time at which the object was created. Measured in seconds since the Unix epoch. */
  @SerializedName("created")
  Long created;

  /**
   * Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency code</a>,
   * in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported currency</a>.
   */
  @SerializedName("currency")
  String currency;

  /**
   * ID of the Customer this PaymentIntent belongs to, if one exists.
   *
   * <p>Payment methods attached to other Customers cannot be used with this PaymentIntent.
   *
   * <p>If present in combination with <a
   * href="https://stripe.com/docs/api#payment_intent_object-setup_future_usage">setup_future_usage</a>,
   * this PaymentIntent's payment method will be attached to the Customer after the PaymentIntent
   * has been confirmed and any required actions from the user are complete.
   */
  @SerializedName("customer")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<Customer> customer;

  /** An arbitrary string attached to the object. Often useful for displaying to users. */
  @SerializedName("description")
  String description;

  /** Unique identifier for the object. */
  @Getter(onMethod_ = {@Override})
  @SerializedName("id")
  String id;

  /** ID of the invoice that created this PaymentIntent, if it exists. */
  @SerializedName("invoice")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<Invoice> invoice;

  /**
   * The payment error encountered in the previous PaymentIntent confirmation. It will be cleared if
   * the PaymentIntent is later updated for any reason.
   */
  @SerializedName("last_payment_error")
  StripeError lastPaymentError;

  /** The latest charge created by this payment intent. */
  @SerializedName("latest_charge")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<Charge> latestCharge;

  /**
   * Has the value {@code true} if the object exists in live mode or the value {@code false} if the
   * object exists in test mode.
   */
  @SerializedName("livemode")
  Boolean livemode;

  /**
   * Set of <a href="https://stripe.com/docs/api/metadata">key-value pairs</a> that you can attach
   * to an object. This can be useful for storing additional information about the object in a
   * structured format. For more information, see the <a
   * href="https://stripe.com/docs/payments/payment-intents/creating-payment-intents#storing-information-in-metadata">documentation</a>.
   */
  @Getter(onMethod_ = {@Override})
  @SerializedName("metadata")
  Map<String, String> metadata;

  /**
   * If present, this property tells you what actions you need to take in order for your customer to
   * fulfill a payment using the provided source.
   */
  @SerializedName("next_action")
  NextAction nextAction;

  /**
   * String representing the object's type. Objects of the same type share the same value.
   *
   * <p>Equal to {@code payment_intent}.
   */
  @SerializedName("object")
  String object;

  /**
   * The account (if any) for which the funds of the PaymentIntent are intended. See the
   * PaymentIntents <a href="https://stripe.com/docs/payments/connected-accounts">use case for
   * connected accounts</a> for details.
   */
  @SerializedName("on_behalf_of")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<Account> onBehalfOf;

  /** ID of the payment method used in this PaymentIntent. */
  @SerializedName("payment_method")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<PaymentMethod> paymentMethod;

  /** Payment-method-specific configuration for this PaymentIntent. */
  @SerializedName("payment_method_options")
  PaymentMethodOptions paymentMethodOptions;

  /** The list of payment method types (e.g. card) that this PaymentIntent is allowed to use. */
  @SerializedName("payment_method_types")
  List<String> paymentMethodTypes;

  /** If present, this property tells you about the processing state of the payment. */
  @SerializedName("processing")
  Processing processing;

  /**
   * Email address that the receipt for the resulting payment will be sent to. If {@code
   * receipt_email} is specified for a payment in live mode, a receipt will be sent regardless of
   * your <a href="https://dashboard.stripe.com/account/emails">email settings</a>.
   */
  @SerializedName("receipt_email")
  String receiptEmail;

  /** ID of the review associated with this PaymentIntent, if any. */
  @SerializedName("review")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<Review> review;

  /**
   * Indicates that you intend to make future payments with this PaymentIntent's payment method.
   *
   * <p>Providing this parameter will <a
   * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a> to
   * the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any required
   * actions from the user are complete. If no Customer was provided, the payment method can still
   * be <a href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer
   * after the transaction completes.
   *
   * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to dynamically
   * optimize your payment flow and comply with regional legislation and network rules, such as <a
   * href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
   *
   * <p>One of {@code off_session}, or {@code on_session}.
   */
  @SerializedName("setup_future_usage")
  String setupFutureUsage;

  /** Shipping information for this PaymentIntent. */
  @SerializedName("shipping")
  ShippingDetails shipping;

  /**
   * This is a legacy field that will be removed in the future. It is the ID of the Source object
   * that is associated with this PaymentIntent, if one was supplied.
   */
  @SerializedName("source")
  @Getter(lombok.AccessLevel.NONE)
  @Setter(lombok.AccessLevel.NONE)
  ExpandableField<PaymentSource> source;

  /**
   * For non-card charges, you can use this value as the complete description that appears on your
   * customers’ statements. Must contain at least one letter, maximum 22 characters.
   */
  @SerializedName("statement_descriptor")
  String statementDescriptor;

  /**
   * Provides information about a card payment that customers see on their statements. Concatenated
   * with the prefix (shortened descriptor) or statement descriptor that’s set on the account to
   * form the complete statement descriptor. Maximum 22 characters for the concatenated descriptor.
   */
  @SerializedName("statement_descriptor_suffix")
  String statementDescriptorSuffix;

  /**
   * Status of this PaymentIntent, one of {@code requires_payment_method}, {@code
   * requires_confirmation}, {@code requires_action}, {@code processing}, {@code requires_capture},
   * {@code canceled}, or {@code succeeded}. Read more about each PaymentIntent <a
   * href="https://stripe.com/docs/payments/intents#intent-statuses">status</a>.
   */
  @SerializedName("status")
  String status;

  /**
   * The data with which to automatically create a Transfer when the payment is finalized. See the
   * PaymentIntents <a href="https://stripe.com/docs/payments/connected-accounts">use case for
   * connected accounts</a> for details.
   */
  @SerializedName("transfer_data")
  TransferData transferData;

  /**
   * A string that identifies the resulting payment as part of a group. See the PaymentIntents <a
   * href="https://stripe.com/docs/payments/connected-accounts">use case for connected accounts</a>
   * for details.
   */
  @SerializedName("transfer_group")
  String transferGroup;

  /** Get ID of expandable {@code application} object. */
  public String getApplication() {
    return (this.application != null) ? this.application.getId() : null;
  }

  public void setApplication(String id) {
    this.application = ApiResource.setExpandableFieldId(id, this.application);
  }

  /** Get expanded {@code application}. */
  public Application getApplicationObject() {
    return (this.application != null) ? this.application.getExpanded() : null;
  }

  public void setApplicationObject(Application expandableObject) {
    this.application = new ExpandableField<Application>(expandableObject.getId(), expandableObject);
  }

  /** Get ID of expandable {@code customer} object. */
  public String getCustomer() {
    return (this.customer != null) ? this.customer.getId() : null;
  }

  public void setCustomer(String id) {
    this.customer = ApiResource.setExpandableFieldId(id, this.customer);
  }

  /** Get expanded {@code customer}. */
  public Customer getCustomerObject() {
    return (this.customer != null) ? this.customer.getExpanded() : null;
  }

  public void setCustomerObject(Customer expandableObject) {
    this.customer = new ExpandableField<Customer>(expandableObject.getId(), expandableObject);
  }

  /** Get ID of expandable {@code invoice} object. */
  public String getInvoice() {
    return (this.invoice != null) ? this.invoice.getId() : null;
  }

  public void setInvoice(String id) {
    this.invoice = ApiResource.setExpandableFieldId(id, this.invoice);
  }

  /** Get expanded {@code invoice}. */
  public Invoice getInvoiceObject() {
    return (this.invoice != null) ? this.invoice.getExpanded() : null;
  }

  public void setInvoiceObject(Invoice expandableObject) {
    this.invoice = new ExpandableField<Invoice>(expandableObject.getId(), expandableObject);
  }

  /** Get ID of expandable {@code latestCharge} object. */
  public String getLatestCharge() {
    return (this.latestCharge != null) ? this.latestCharge.getId() : null;
  }

  public void setLatestCharge(String id) {
    this.latestCharge = ApiResource.setExpandableFieldId(id, this.latestCharge);
  }

  /** Get expanded {@code latestCharge}. */
  public Charge getLatestChargeObject() {
    return (this.latestCharge != null) ? this.latestCharge.getExpanded() : null;
  }

  public void setLatestChargeObject(Charge expandableObject) {
    this.latestCharge = new ExpandableField<Charge>(expandableObject.getId(), expandableObject);
  }

  /** Get ID of expandable {@code onBehalfOf} object. */
  public String getOnBehalfOf() {
    return (this.onBehalfOf != null) ? this.onBehalfOf.getId() : null;
  }

  public void setOnBehalfOf(String id) {
    this.onBehalfOf = ApiResource.setExpandableFieldId(id, this.onBehalfOf);
  }

  /** Get expanded {@code onBehalfOf}. */
  public Account getOnBehalfOfObject() {
    return (this.onBehalfOf != null) ? this.onBehalfOf.getExpanded() : null;
  }

  public void setOnBehalfOfObject(Account expandableObject) {
    this.onBehalfOf = new ExpandableField<Account>(expandableObject.getId(), expandableObject);
  }

  /** Get ID of expandable {@code paymentMethod} object. */
  public String getPaymentMethod() {
    return (this.paymentMethod != null) ? this.paymentMethod.getId() : null;
  }

  public void setPaymentMethod(String id) {
    this.paymentMethod = ApiResource.setExpandableFieldId(id, this.paymentMethod);
  }

  /** Get expanded {@code paymentMethod}. */
  public PaymentMethod getPaymentMethodObject() {
    return (this.paymentMethod != null) ? this.paymentMethod.getExpanded() : null;
  }

  public void setPaymentMethodObject(PaymentMethod expandableObject) {
    this.paymentMethod =
        new ExpandableField<PaymentMethod>(expandableObject.getId(), expandableObject);
  }

  /** Get ID of expandable {@code review} object. */
  public String getReview() {
    return (this.review != null) ? this.review.getId() : null;
  }

  public void setReview(String id) {
    this.review = ApiResource.setExpandableFieldId(id, this.review);
  }

  /** Get expanded {@code review}. */
  public Review getReviewObject() {
    return (this.review != null) ? this.review.getExpanded() : null;
  }

  public void setReviewObject(Review expandableObject) {
    this.review = new ExpandableField<Review>(expandableObject.getId(), expandableObject);
  }

  /** Get ID of expandable {@code source} object. */
  public String getSource() {
    return (this.source != null) ? this.source.getId() : null;
  }

  public void setSource(String id) {
    this.source = ApiResource.setExpandableFieldId(id, this.source);
  }

  /** Get expanded {@code source}. */
  public PaymentSource getSourceObject() {
    return (this.source != null) ? this.source.getExpanded() : null;
  }

  public void setSourceObject(PaymentSource expandableObject) {
    this.source = new ExpandableField<PaymentSource>(expandableObject.getId(), expandableObject);
  }

  /** Manually reconcile the remaining amount for a customer_balance PaymentIntent. */
  public PaymentIntent applyCustomerBalance() throws StripeException {
    return applyCustomerBalance((Map<String, Object>) null, (RequestOptions) null);
  }

  /** Manually reconcile the remaining amount for a customer_balance PaymentIntent. */
  public PaymentIntent applyCustomerBalance(RequestOptions options) throws StripeException {
    return applyCustomerBalance((Map<String, Object>) null, options);
  }

  /** Manually reconcile the remaining amount for a customer_balance PaymentIntent. */
  public PaymentIntent applyCustomerBalance(Map<String, Object> params) throws StripeException {
    return applyCustomerBalance(params, (RequestOptions) null);
  }

  /** Manually reconcile the remaining amount for a customer_balance PaymentIntent. */
  public PaymentIntent applyCustomerBalance(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path =
        String.format(
            "/v1/payment_intents/%s/apply_customer_balance", ApiResource.urlEncodeId(this.getId()));
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /** Manually reconcile the remaining amount for a customer_balance PaymentIntent. */
  public PaymentIntent applyCustomerBalance(PaymentIntentApplyCustomerBalanceParams params)
      throws StripeException {
    return applyCustomerBalance(params, (RequestOptions) null);
  }

  /** Manually reconcile the remaining amount for a customer_balance PaymentIntent. */
  public PaymentIntent applyCustomerBalance(
      PaymentIntentApplyCustomerBalanceParams params, RequestOptions options)
      throws StripeException {
    String path =
        String.format(
            "/v1/payment_intents/%s/apply_customer_balance", ApiResource.urlEncodeId(this.getId()));
    ApiResource.checkNullTypedParams(path, params);
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * A PaymentIntent object can be canceled when it is in one of these statuses: {@code
   * requires_payment_method}, {@code requires_capture}, {@code requires_confirmation}, {@code
   * requires_action} or, <a href="https://stripe.com/docs/payments/intents">in rare cases</a>,
   * {@code processing}.
   *
   * <p>Once canceled, no additional charges will be made by the PaymentIntent and any operations on
   * the PaymentIntent will fail with an error. For PaymentIntents with a {@code status} of {@code
   * requires_capture}, the remaining {@code amount_capturable} will automatically be refunded.
   *
   * <p>You cannot cancel the PaymentIntent for a Checkout Session. <a
   * href="https://stripe.com/docs/api/checkout/sessions/expire">Expire the Checkout Session</a>
   * instead.
   */
  public PaymentIntent cancel() throws StripeException {
    return cancel((Map<String, Object>) null, (RequestOptions) null);
  }

  /**
   * A PaymentIntent object can be canceled when it is in one of these statuses: {@code
   * requires_payment_method}, {@code requires_capture}, {@code requires_confirmation}, {@code
   * requires_action} or, <a href="https://stripe.com/docs/payments/intents">in rare cases</a>,
   * {@code processing}.
   *
   * <p>Once canceled, no additional charges will be made by the PaymentIntent and any operations on
   * the PaymentIntent will fail with an error. For PaymentIntents with a {@code status} of {@code
   * requires_capture}, the remaining {@code amount_capturable} will automatically be refunded.
   *
   * <p>You cannot cancel the PaymentIntent for a Checkout Session. <a
   * href="https://stripe.com/docs/api/checkout/sessions/expire">Expire the Checkout Session</a>
   * instead.
   */
  public PaymentIntent cancel(RequestOptions options) throws StripeException {
    return cancel((Map<String, Object>) null, options);
  }

  /**
   * A PaymentIntent object can be canceled when it is in one of these statuses: {@code
   * requires_payment_method}, {@code requires_capture}, {@code requires_confirmation}, {@code
   * requires_action} or, <a href="https://stripe.com/docs/payments/intents">in rare cases</a>,
   * {@code processing}.
   *
   * <p>Once canceled, no additional charges will be made by the PaymentIntent and any operations on
   * the PaymentIntent will fail with an error. For PaymentIntents with a {@code status} of {@code
   * requires_capture}, the remaining {@code amount_capturable} will automatically be refunded.
   *
   * <p>You cannot cancel the PaymentIntent for a Checkout Session. <a
   * href="https://stripe.com/docs/api/checkout/sessions/expire">Expire the Checkout Session</a>
   * instead.
   */
  public PaymentIntent cancel(Map<String, Object> params) throws StripeException {
    return cancel(params, (RequestOptions) null);
  }

  /**
   * A PaymentIntent object can be canceled when it is in one of these statuses: {@code
   * requires_payment_method}, {@code requires_capture}, {@code requires_confirmation}, {@code
   * requires_action} or, <a href="https://stripe.com/docs/payments/intents">in rare cases</a>,
   * {@code processing}.
   *
   * <p>Once canceled, no additional charges will be made by the PaymentIntent and any operations on
   * the PaymentIntent will fail with an error. For PaymentIntents with a {@code status} of {@code
   * requires_capture}, the remaining {@code amount_capturable} will automatically be refunded.
   *
   * <p>You cannot cancel the PaymentIntent for a Checkout Session. <a
   * href="https://stripe.com/docs/api/checkout/sessions/expire">Expire the Checkout Session</a>
   * instead.
   */
  public PaymentIntent cancel(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path =
        String.format("/v1/payment_intents/%s/cancel", ApiResource.urlEncodeId(this.getId()));
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * A PaymentIntent object can be canceled when it is in one of these statuses: {@code
   * requires_payment_method}, {@code requires_capture}, {@code requires_confirmation}, {@code
   * requires_action} or, <a href="https://stripe.com/docs/payments/intents">in rare cases</a>,
   * {@code processing}.
   *
   * <p>Once canceled, no additional charges will be made by the PaymentIntent and any operations on
   * the PaymentIntent will fail with an error. For PaymentIntents with a {@code status} of {@code
   * requires_capture}, the remaining {@code amount_capturable} will automatically be refunded.
   *
   * <p>You cannot cancel the PaymentIntent for a Checkout Session. <a
   * href="https://stripe.com/docs/api/checkout/sessions/expire">Expire the Checkout Session</a>
   * instead.
   */
  public PaymentIntent cancel(PaymentIntentCancelParams params) throws StripeException {
    return cancel(params, (RequestOptions) null);
  }

  /**
   * A PaymentIntent object can be canceled when it is in one of these statuses: {@code
   * requires_payment_method}, {@code requires_capture}, {@code requires_confirmation}, {@code
   * requires_action} or, <a href="https://stripe.com/docs/payments/intents">in rare cases</a>,
   * {@code processing}.
   *
   * <p>Once canceled, no additional charges will be made by the PaymentIntent and any operations on
   * the PaymentIntent will fail with an error. For PaymentIntents with a {@code status} of {@code
   * requires_capture}, the remaining {@code amount_capturable} will automatically be refunded.
   *
   * <p>You cannot cancel the PaymentIntent for a Checkout Session. <a
   * href="https://stripe.com/docs/api/checkout/sessions/expire">Expire the Checkout Session</a>
   * instead.
   */
  public PaymentIntent cancel(PaymentIntentCancelParams params, RequestOptions options)
      throws StripeException {
    String path =
        String.format("/v1/payment_intents/%s/cancel", ApiResource.urlEncodeId(this.getId()));
    ApiResource.checkNullTypedParams(path, params);
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Capture the funds of an existing uncaptured PaymentIntent when its status is {@code
   * requires_capture}.
   *
   * <p>Uncaptured PaymentIntents will be canceled a set number of days after they are created (7 by
   * default).
   *
   * <p>Learn more about <a href="https://stripe.com/docs/payments/capture-later">separate
   * authorization and capture</a>.
   */
  public PaymentIntent capture() throws StripeException {
    return capture((Map<String, Object>) null, (RequestOptions) null);
  }

  /**
   * Capture the funds of an existing uncaptured PaymentIntent when its status is {@code
   * requires_capture}.
   *
   * <p>Uncaptured PaymentIntents will be canceled a set number of days after they are created (7 by
   * default).
   *
   * <p>Learn more about <a href="https://stripe.com/docs/payments/capture-later">separate
   * authorization and capture</a>.
   */
  public PaymentIntent capture(RequestOptions options) throws StripeException {
    return capture((Map<String, Object>) null, options);
  }

  /**
   * Capture the funds of an existing uncaptured PaymentIntent when its status is {@code
   * requires_capture}.
   *
   * <p>Uncaptured PaymentIntents will be canceled a set number of days after they are created (7 by
   * default).
   *
   * <p>Learn more about <a href="https://stripe.com/docs/payments/capture-later">separate
   * authorization and capture</a>.
   */
  public PaymentIntent capture(Map<String, Object> params) throws StripeException {
    return capture(params, (RequestOptions) null);
  }

  /**
   * Capture the funds of an existing uncaptured PaymentIntent when its status is {@code
   * requires_capture}.
   *
   * <p>Uncaptured PaymentIntents will be canceled a set number of days after they are created (7 by
   * default).
   *
   * <p>Learn more about <a href="https://stripe.com/docs/payments/capture-later">separate
   * authorization and capture</a>.
   */
  public PaymentIntent capture(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path =
        String.format("/v1/payment_intents/%s/capture", ApiResource.urlEncodeId(this.getId()));
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Capture the funds of an existing uncaptured PaymentIntent when its status is {@code
   * requires_capture}.
   *
   * <p>Uncaptured PaymentIntents will be canceled a set number of days after they are created (7 by
   * default).
   *
   * <p>Learn more about <a href="https://stripe.com/docs/payments/capture-later">separate
   * authorization and capture</a>.
   */
  public PaymentIntent capture(PaymentIntentCaptureParams params) throws StripeException {
    return capture(params, (RequestOptions) null);
  }

  /**
   * Capture the funds of an existing uncaptured PaymentIntent when its status is {@code
   * requires_capture}.
   *
   * <p>Uncaptured PaymentIntents will be canceled a set number of days after they are created (7 by
   * default).
   *
   * <p>Learn more about <a href="https://stripe.com/docs/payments/capture-later">separate
   * authorization and capture</a>.
   */
  public PaymentIntent capture(PaymentIntentCaptureParams params, RequestOptions options)
      throws StripeException {
    String path =
        String.format("/v1/payment_intents/%s/capture", ApiResource.urlEncodeId(this.getId()));
    ApiResource.checkNullTypedParams(path, params);
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Confirm that your customer intends to pay with current or provided payment method. Upon
   * confirmation, the PaymentIntent will attempt to initiate a payment. If the selected payment
   * method requires additional authentication steps, the PaymentIntent will transition to the
   * {@code requires_action} status and suggest additional actions via {@code next_action}. If
   * payment fails, the PaymentIntent transitions to the {@code requires_payment_method} status or
   * the {@code canceled} status if the confirmation limit is reached. If payment succeeds, the
   * PaymentIntent will transition to the {@code succeeded} status (or {@code requires_capture}, if
   * {@code capture_method} is set to {@code manual}). If the {@code confirmation_method} is {@code
   * automatic}, payment may be attempted using our <a
   * href="https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment">client SDKs</a>
   * and the PaymentIntent’s <a
   * href="https://stripe.com/docs/api#payment_intent_object-client_secret">client_secret</a>. After
   * {@code next_action}s are handled by the client, no additional confirmation is required to
   * complete the payment. If the {@code confirmation_method} is {@code manual}, all payment
   * attempts must be initiated using a secret key. If any actions are required for the payment, the
   * PaymentIntent will return to the {@code requires_confirmation} state after those actions are
   * completed. Your server needs to then explicitly re-confirm the PaymentIntent to initiate the
   * next payment attempt. Read the <a
   * href="https://stripe.com/docs/payments/payment-intents/web-manual">expanded documentation</a>
   * to learn more about manual confirmation.
   */
  public PaymentIntent confirm() throws StripeException {
    return confirm((Map<String, Object>) null, (RequestOptions) null);
  }

  /**
   * Confirm that your customer intends to pay with current or provided payment method. Upon
   * confirmation, the PaymentIntent will attempt to initiate a payment. If the selected payment
   * method requires additional authentication steps, the PaymentIntent will transition to the
   * {@code requires_action} status and suggest additional actions via {@code next_action}. If
   * payment fails, the PaymentIntent transitions to the {@code requires_payment_method} status or
   * the {@code canceled} status if the confirmation limit is reached. If payment succeeds, the
   * PaymentIntent will transition to the {@code succeeded} status (or {@code requires_capture}, if
   * {@code capture_method} is set to {@code manual}). If the {@code confirmation_method} is {@code
   * automatic}, payment may be attempted using our <a
   * href="https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment">client SDKs</a>
   * and the PaymentIntent’s <a
   * href="https://stripe.com/docs/api#payment_intent_object-client_secret">client_secret</a>. After
   * {@code next_action}s are handled by the client, no additional confirmation is required to
   * complete the payment. If the {@code confirmation_method} is {@code manual}, all payment
   * attempts must be initiated using a secret key. If any actions are required for the payment, the
   * PaymentIntent will return to the {@code requires_confirmation} state after those actions are
   * completed. Your server needs to then explicitly re-confirm the PaymentIntent to initiate the
   * next payment attempt. Read the <a
   * href="https://stripe.com/docs/payments/payment-intents/web-manual">expanded documentation</a>
   * to learn more about manual confirmation.
   */
  public PaymentIntent confirm(RequestOptions options) throws StripeException {
    return confirm((Map<String, Object>) null, options);
  }

  /**
   * Confirm that your customer intends to pay with current or provided payment method. Upon
   * confirmation, the PaymentIntent will attempt to initiate a payment. If the selected payment
   * method requires additional authentication steps, the PaymentIntent will transition to the
   * {@code requires_action} status and suggest additional actions via {@code next_action}. If
   * payment fails, the PaymentIntent transitions to the {@code requires_payment_method} status or
   * the {@code canceled} status if the confirmation limit is reached. If payment succeeds, the
   * PaymentIntent will transition to the {@code succeeded} status (or {@code requires_capture}, if
   * {@code capture_method} is set to {@code manual}). If the {@code confirmation_method} is {@code
   * automatic}, payment may be attempted using our <a
   * href="https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment">client SDKs</a>
   * and the PaymentIntent’s <a
   * href="https://stripe.com/docs/api#payment_intent_object-client_secret">client_secret</a>. After
   * {@code next_action}s are handled by the client, no additional confirmation is required to
   * complete the payment. If the {@code confirmation_method} is {@code manual}, all payment
   * attempts must be initiated using a secret key. If any actions are required for the payment, the
   * PaymentIntent will return to the {@code requires_confirmation} state after those actions are
   * completed. Your server needs to then explicitly re-confirm the PaymentIntent to initiate the
   * next payment attempt. Read the <a
   * href="https://stripe.com/docs/payments/payment-intents/web-manual">expanded documentation</a>
   * to learn more about manual confirmation.
   */
  public PaymentIntent confirm(Map<String, Object> params) throws StripeException {
    return confirm(params, (RequestOptions) null);
  }

  /**
   * Confirm that your customer intends to pay with current or provided payment method. Upon
   * confirmation, the PaymentIntent will attempt to initiate a payment. If the selected payment
   * method requires additional authentication steps, the PaymentIntent will transition to the
   * {@code requires_action} status and suggest additional actions via {@code next_action}. If
   * payment fails, the PaymentIntent transitions to the {@code requires_payment_method} status or
   * the {@code canceled} status if the confirmation limit is reached. If payment succeeds, the
   * PaymentIntent will transition to the {@code succeeded} status (or {@code requires_capture}, if
   * {@code capture_method} is set to {@code manual}). If the {@code confirmation_method} is {@code
   * automatic}, payment may be attempted using our <a
   * href="https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment">client SDKs</a>
   * and the PaymentIntent’s <a
   * href="https://stripe.com/docs/api#payment_intent_object-client_secret">client_secret</a>. After
   * {@code next_action}s are handled by the client, no additional confirmation is required to
   * complete the payment. If the {@code confirmation_method} is {@code manual}, all payment
   * attempts must be initiated using a secret key. If any actions are required for the payment, the
   * PaymentIntent will return to the {@code requires_confirmation} state after those actions are
   * completed. Your server needs to then explicitly re-confirm the PaymentIntent to initiate the
   * next payment attempt. Read the <a
   * href="https://stripe.com/docs/payments/payment-intents/web-manual">expanded documentation</a>
   * to learn more about manual confirmation.
   */
  public PaymentIntent confirm(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path =
        String.format("/v1/payment_intents/%s/confirm", ApiResource.urlEncodeId(this.getId()));
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Confirm that your customer intends to pay with current or provided payment method. Upon
   * confirmation, the PaymentIntent will attempt to initiate a payment. If the selected payment
   * method requires additional authentication steps, the PaymentIntent will transition to the
   * {@code requires_action} status and suggest additional actions via {@code next_action}. If
   * payment fails, the PaymentIntent transitions to the {@code requires_payment_method} status or
   * the {@code canceled} status if the confirmation limit is reached. If payment succeeds, the
   * PaymentIntent will transition to the {@code succeeded} status (or {@code requires_capture}, if
   * {@code capture_method} is set to {@code manual}). If the {@code confirmation_method} is {@code
   * automatic}, payment may be attempted using our <a
   * href="https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment">client SDKs</a>
   * and the PaymentIntent’s <a
   * href="https://stripe.com/docs/api#payment_intent_object-client_secret">client_secret</a>. After
   * {@code next_action}s are handled by the client, no additional confirmation is required to
   * complete the payment. If the {@code confirmation_method} is {@code manual}, all payment
   * attempts must be initiated using a secret key. If any actions are required for the payment, the
   * PaymentIntent will return to the {@code requires_confirmation} state after those actions are
   * completed. Your server needs to then explicitly re-confirm the PaymentIntent to initiate the
   * next payment attempt. Read the <a
   * href="https://stripe.com/docs/payments/payment-intents/web-manual">expanded documentation</a>
   * to learn more about manual confirmation.
   */
  public PaymentIntent confirm(PaymentIntentConfirmParams params) throws StripeException {
    return confirm(params, (RequestOptions) null);
  }

  /**
   * Confirm that your customer intends to pay with current or provided payment method. Upon
   * confirmation, the PaymentIntent will attempt to initiate a payment. If the selected payment
   * method requires additional authentication steps, the PaymentIntent will transition to the
   * {@code requires_action} status and suggest additional actions via {@code next_action}. If
   * payment fails, the PaymentIntent transitions to the {@code requires_payment_method} status or
   * the {@code canceled} status if the confirmation limit is reached. If payment succeeds, the
   * PaymentIntent will transition to the {@code succeeded} status (or {@code requires_capture}, if
   * {@code capture_method} is set to {@code manual}). If the {@code confirmation_method} is {@code
   * automatic}, payment may be attempted using our <a
   * href="https://stripe.com/docs/stripe-js/reference#stripe-handle-card-payment">client SDKs</a>
   * and the PaymentIntent’s <a
   * href="https://stripe.com/docs/api#payment_intent_object-client_secret">client_secret</a>. After
   * {@code next_action}s are handled by the client, no additional confirmation is required to
   * complete the payment. If the {@code confirmation_method} is {@code manual}, all payment
   * attempts must be initiated using a secret key. If any actions are required for the payment, the
   * PaymentIntent will return to the {@code requires_confirmation} state after those actions are
   * completed. Your server needs to then explicitly re-confirm the PaymentIntent to initiate the
   * next payment attempt. Read the <a
   * href="https://stripe.com/docs/payments/payment-intents/web-manual">expanded documentation</a>
   * to learn more about manual confirmation.
   */
  public PaymentIntent confirm(PaymentIntentConfirmParams params, RequestOptions options)
      throws StripeException {
    String path =
        String.format("/v1/payment_intents/%s/confirm", ApiResource.urlEncodeId(this.getId()));
    ApiResource.checkNullTypedParams(path, params);
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Creates a PaymentIntent object.
   *
   * <p>After the PaymentIntent is created, attach a payment method and <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm</a> to continue the payment.
   * You can read more about the different payment flows available via the Payment Intents API <a
   * href="https://stripe.com/docs/payments/payment-intents">here</a>.
   *
   * <p>When {@code confirm=true} is used during creation, it is equivalent to creating and
   * confirming the PaymentIntent in the same call. You may use any parameters available in the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> when {@code
   * confirm=true} is supplied.
   */
  public static PaymentIntent create(Map<String, Object> params) throws StripeException {
    return create(params, (RequestOptions) null);
  }

  /**
   * Creates a PaymentIntent object.
   *
   * <p>After the PaymentIntent is created, attach a payment method and <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm</a> to continue the payment.
   * You can read more about the different payment flows available via the Payment Intents API <a
   * href="https://stripe.com/docs/payments/payment-intents">here</a>.
   *
   * <p>When {@code confirm=true} is used during creation, it is equivalent to creating and
   * confirming the PaymentIntent in the same call. You may use any parameters available in the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> when {@code
   * confirm=true} is supplied.
   */
  public static PaymentIntent create(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path = "/v1/payment_intents";
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Creates a PaymentIntent object.
   *
   * <p>After the PaymentIntent is created, attach a payment method and <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm</a> to continue the payment.
   * You can read more about the different payment flows available via the Payment Intents API <a
   * href="https://stripe.com/docs/payments/payment-intents">here</a>.
   *
   * <p>When {@code confirm=true} is used during creation, it is equivalent to creating and
   * confirming the PaymentIntent in the same call. You may use any parameters available in the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> when {@code
   * confirm=true} is supplied.
   */
  public static PaymentIntent create(PaymentIntentCreateParams params) throws StripeException {
    return create(params, (RequestOptions) null);
  }

  /**
   * Creates a PaymentIntent object.
   *
   * <p>After the PaymentIntent is created, attach a payment method and <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm</a> to continue the payment.
   * You can read more about the different payment flows available via the Payment Intents API <a
   * href="https://stripe.com/docs/payments/payment-intents">here</a>.
   *
   * <p>When {@code confirm=true} is used during creation, it is equivalent to creating and
   * confirming the PaymentIntent in the same call. You may use any parameters available in the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> when {@code
   * confirm=true} is supplied.
   */
  public static PaymentIntent create(PaymentIntentCreateParams params, RequestOptions options)
      throws StripeException {
    String path = "/v1/payment_intents";
    ApiResource.checkNullTypedParams(path, params);
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Perform an incremental authorization on an eligible <a
   * href="https://stripe.com/docs/api/payment_intents/object">PaymentIntent</a>. To be eligible,
   * the PaymentIntent’s status must be {@code requires_capture} and <a
   * href="https://stripe.com/docs/api/charges/object#charge_object-payment_method_details-card_present-incremental_authorization_supported">incremental_authorization_supported</a>
   * must be {@code true}.
   *
   * <p>Incremental authorizations attempt to increase the authorized amount on your customer’s card
   * to the new, higher {@code amount} provided. As with the initial authorization, incremental
   * authorizations may be declined. A single PaymentIntent can call this endpoint multiple times to
   * further increase the authorized amount.
   *
   * <p>If the incremental authorization succeeds, the PaymentIntent object is returned with the
   * updated <a
   * href="https://stripe.com/docs/api/payment_intents/object#payment_intent_object-amount">amount</a>.
   * If the incremental authorization fails, a <a
   * href="https://stripe.com/docs/error-codes#card-declined">card_declined</a> error is returned,
   * and no fields on the PaymentIntent or Charge are updated. The PaymentIntent object remains
   * capturable for the previously authorized amount.
   *
   * <p>Each PaymentIntent can have a maximum of 10 incremental authorization attempts, including
   * declines. Once captured, a PaymentIntent can no longer be incremented.
   *
   * <p>Learn more about <a
   * href="https://stripe.com/docs/terminal/features/incremental-authorizations">incremental
   * authorizations</a>.
   */
  public PaymentIntent incrementAuthorization(Map<String, Object> params) throws StripeException {
    return incrementAuthorization(params, (RequestOptions) null);
  }

  /**
   * Perform an incremental authorization on an eligible <a
   * href="https://stripe.com/docs/api/payment_intents/object">PaymentIntent</a>. To be eligible,
   * the PaymentIntent’s status must be {@code requires_capture} and <a
   * href="https://stripe.com/docs/api/charges/object#charge_object-payment_method_details-card_present-incremental_authorization_supported">incremental_authorization_supported</a>
   * must be {@code true}.
   *
   * <p>Incremental authorizations attempt to increase the authorized amount on your customer’s card
   * to the new, higher {@code amount} provided. As with the initial authorization, incremental
   * authorizations may be declined. A single PaymentIntent can call this endpoint multiple times to
   * further increase the authorized amount.
   *
   * <p>If the incremental authorization succeeds, the PaymentIntent object is returned with the
   * updated <a
   * href="https://stripe.com/docs/api/payment_intents/object#payment_intent_object-amount">amount</a>.
   * If the incremental authorization fails, a <a
   * href="https://stripe.com/docs/error-codes#card-declined">card_declined</a> error is returned,
   * and no fields on the PaymentIntent or Charge are updated. The PaymentIntent object remains
   * capturable for the previously authorized amount.
   *
   * <p>Each PaymentIntent can have a maximum of 10 incremental authorization attempts, including
   * declines. Once captured, a PaymentIntent can no longer be incremented.
   *
   * <p>Learn more about <a
   * href="https://stripe.com/docs/terminal/features/incremental-authorizations">incremental
   * authorizations</a>.
   */
  public PaymentIntent incrementAuthorization(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path =
        String.format(
            "/v1/payment_intents/%s/increment_authorization",
            ApiResource.urlEncodeId(this.getId()));
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Perform an incremental authorization on an eligible <a
   * href="https://stripe.com/docs/api/payment_intents/object">PaymentIntent</a>. To be eligible,
   * the PaymentIntent’s status must be {@code requires_capture} and <a
   * href="https://stripe.com/docs/api/charges/object#charge_object-payment_method_details-card_present-incremental_authorization_supported">incremental_authorization_supported</a>
   * must be {@code true}.
   *
   * <p>Incremental authorizations attempt to increase the authorized amount on your customer’s card
   * to the new, higher {@code amount} provided. As with the initial authorization, incremental
   * authorizations may be declined. A single PaymentIntent can call this endpoint multiple times to
   * further increase the authorized amount.
   *
   * <p>If the incremental authorization succeeds, the PaymentIntent object is returned with the
   * updated <a
   * href="https://stripe.com/docs/api/payment_intents/object#payment_intent_object-amount">amount</a>.
   * If the incremental authorization fails, a <a
   * href="https://stripe.com/docs/error-codes#card-declined">card_declined</a> error is returned,
   * and no fields on the PaymentIntent or Charge are updated. The PaymentIntent object remains
   * capturable for the previously authorized amount.
   *
   * <p>Each PaymentIntent can have a maximum of 10 incremental authorization attempts, including
   * declines. Once captured, a PaymentIntent can no longer be incremented.
   *
   * <p>Learn more about <a
   * href="https://stripe.com/docs/terminal/features/incremental-authorizations">incremental
   * authorizations</a>.
   */
  public PaymentIntent incrementAuthorization(PaymentIntentIncrementAuthorizationParams params)
      throws StripeException {
    return incrementAuthorization(params, (RequestOptions) null);
  }

  /**
   * Perform an incremental authorization on an eligible <a
   * href="https://stripe.com/docs/api/payment_intents/object">PaymentIntent</a>. To be eligible,
   * the PaymentIntent’s status must be {@code requires_capture} and <a
   * href="https://stripe.com/docs/api/charges/object#charge_object-payment_method_details-card_present-incremental_authorization_supported">incremental_authorization_supported</a>
   * must be {@code true}.
   *
   * <p>Incremental authorizations attempt to increase the authorized amount on your customer’s card
   * to the new, higher {@code amount} provided. As with the initial authorization, incremental
   * authorizations may be declined. A single PaymentIntent can call this endpoint multiple times to
   * further increase the authorized amount.
   *
   * <p>If the incremental authorization succeeds, the PaymentIntent object is returned with the
   * updated <a
   * href="https://stripe.com/docs/api/payment_intents/object#payment_intent_object-amount">amount</a>.
   * If the incremental authorization fails, a <a
   * href="https://stripe.com/docs/error-codes#card-declined">card_declined</a> error is returned,
   * and no fields on the PaymentIntent or Charge are updated. The PaymentIntent object remains
   * capturable for the previously authorized amount.
   *
   * <p>Each PaymentIntent can have a maximum of 10 incremental authorization attempts, including
   * declines. Once captured, a PaymentIntent can no longer be incremented.
   *
   * <p>Learn more about <a
   * href="https://stripe.com/docs/terminal/features/incremental-authorizations">incremental
   * authorizations</a>.
   */
  public PaymentIntent incrementAuthorization(
      PaymentIntentIncrementAuthorizationParams params, RequestOptions options)
      throws StripeException {
    String path =
        String.format(
            "/v1/payment_intents/%s/increment_authorization",
            ApiResource.urlEncodeId(this.getId()));
    ApiResource.checkNullTypedParams(path, params);
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /** Returns a list of PaymentIntents. */
  public static PaymentIntentCollection list(Map<String, Object> params) throws StripeException {
    return list(params, (RequestOptions) null);
  }

  /** Returns a list of PaymentIntents. */
  public static PaymentIntentCollection list(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path = "/v1/payment_intents";
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.GET,
            path,
            params,
            PaymentIntentCollection.class,
            options,
            ApiMode.V1);
  }

  /** Returns a list of PaymentIntents. */
  public static PaymentIntentCollection list(PaymentIntentListParams params)
      throws StripeException {
    return list(params, (RequestOptions) null);
  }

  /** Returns a list of PaymentIntents. */
  public static PaymentIntentCollection list(PaymentIntentListParams params, RequestOptions options)
      throws StripeException {
    String path = "/v1/payment_intents";
    ApiResource.checkNullTypedParams(path, params);
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.GET,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntentCollection.class,
            options,
            ApiMode.V1);
  }

  /**
   * Retrieves the details of a PaymentIntent that has previously been created.
   *
   * <p>Client-side retrieval using a publishable key is allowed when the {@code client_secret} is
   * provided in the query string.
   *
   * <p>When retrieved with a publishable key, only a subset of properties will be returned. Please
   * refer to the <a href="https://stripe.com/docs/api#payment_intent_object">payment intent</a>
   * object reference for more details.
   */
  public static PaymentIntent retrieve(String intent) throws StripeException {
    return retrieve(intent, (Map<String, Object>) null, (RequestOptions) null);
  }

  /**
   * Retrieves the details of a PaymentIntent that has previously been created.
   *
   * <p>Client-side retrieval using a publishable key is allowed when the {@code client_secret} is
   * provided in the query string.
   *
   * <p>When retrieved with a publishable key, only a subset of properties will be returned. Please
   * refer to the <a href="https://stripe.com/docs/api#payment_intent_object">payment intent</a>
   * object reference for more details.
   */
  public static PaymentIntent retrieve(String intent, RequestOptions options)
      throws StripeException {
    return retrieve(intent, (Map<String, Object>) null, options);
  }

  /**
   * Retrieves the details of a PaymentIntent that has previously been created.
   *
   * <p>Client-side retrieval using a publishable key is allowed when the {@code client_secret} is
   * provided in the query string.
   *
   * <p>When retrieved with a publishable key, only a subset of properties will be returned. Please
   * refer to the <a href="https://stripe.com/docs/api#payment_intent_object">payment intent</a>
   * object reference for more details.
   */
  public static PaymentIntent retrieve(
      String intent, Map<String, Object> params, RequestOptions options) throws StripeException {
    String path = String.format("/v1/payment_intents/%s", ApiResource.urlEncodeId(intent));
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.GET,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Retrieves the details of a PaymentIntent that has previously been created.
   *
   * <p>Client-side retrieval using a publishable key is allowed when the {@code client_secret} is
   * provided in the query string.
   *
   * <p>When retrieved with a publishable key, only a subset of properties will be returned. Please
   * refer to the <a href="https://stripe.com/docs/api#payment_intent_object">payment intent</a>
   * object reference for more details.
   */
  public static PaymentIntent retrieve(
      String intent, PaymentIntentRetrieveParams params, RequestOptions options)
      throws StripeException {
    String path = String.format("/v1/payment_intents/%s", ApiResource.urlEncodeId(intent));
    ApiResource.checkNullTypedParams(path, params);
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.GET,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Search for PaymentIntents you’ve previously created using Stripe’s <a
   * href="https://stripe.com/docs/search#search-query-language">Search Query Language</a>. Don’t
   * use search in read-after-write flows where strict consistency is necessary. Under normal
   * operating conditions, data is searchable in less than a minute. Occasionally, propagation of
   * new or updated data can be up to an hour behind during outages. Search functionality is not
   * available to merchants in India.
   */
  public static PaymentIntentSearchResult search(Map<String, Object> params)
      throws StripeException {
    return search(params, (RequestOptions) null);
  }

  /**
   * Search for PaymentIntents you’ve previously created using Stripe’s <a
   * href="https://stripe.com/docs/search#search-query-language">Search Query Language</a>. Don’t
   * use search in read-after-write flows where strict consistency is necessary. Under normal
   * operating conditions, data is searchable in less than a minute. Occasionally, propagation of
   * new or updated data can be up to an hour behind during outages. Search functionality is not
   * available to merchants in India.
   */
  public static PaymentIntentSearchResult search(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path = "/v1/payment_intents/search";
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.GET,
            path,
            params,
            PaymentIntentSearchResult.class,
            options,
            ApiMode.V1);
  }

  /**
   * Search for PaymentIntents you’ve previously created using Stripe’s <a
   * href="https://stripe.com/docs/search#search-query-language">Search Query Language</a>. Don’t
   * use search in read-after-write flows where strict consistency is necessary. Under normal
   * operating conditions, data is searchable in less than a minute. Occasionally, propagation of
   * new or updated data can be up to an hour behind during outages. Search functionality is not
   * available to merchants in India.
   */
  public static PaymentIntentSearchResult search(PaymentIntentSearchParams params)
      throws StripeException {
    return search(params, (RequestOptions) null);
  }

  /**
   * Search for PaymentIntents you’ve previously created using Stripe’s <a
   * href="https://stripe.com/docs/search#search-query-language">Search Query Language</a>. Don’t
   * use search in read-after-write flows where strict consistency is necessary. Under normal
   * operating conditions, data is searchable in less than a minute. Occasionally, propagation of
   * new or updated data can be up to an hour behind during outages. Search functionality is not
   * available to merchants in India.
   */
  public static PaymentIntentSearchResult search(
      PaymentIntentSearchParams params, RequestOptions options) throws StripeException {
    String path = "/v1/payment_intents/search";
    ApiResource.checkNullTypedParams(path, params);
    return getGlobalResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.GET,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntentSearchResult.class,
            options,
            ApiMode.V1);
  }

  /**
   * Updates properties on a PaymentIntent object without confirming.
   *
   * <p>Depending on which properties you update, you may need to confirm the PaymentIntent again.
   * For example, updating the {@code payment_method} will always require you to confirm the
   * PaymentIntent again. If you prefer to update and confirm at the same time, we recommend
   * updating properties via the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> instead.
   */
  @Override
  public PaymentIntent update(Map<String, Object> params) throws StripeException {
    return update(params, (RequestOptions) null);
  }

  /**
   * Updates properties on a PaymentIntent object without confirming.
   *
   * <p>Depending on which properties you update, you may need to confirm the PaymentIntent again.
   * For example, updating the {@code payment_method} will always require you to confirm the
   * PaymentIntent again. If you prefer to update and confirm at the same time, we recommend
   * updating properties via the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> instead.
   */
  @Override
  public PaymentIntent update(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path = String.format("/v1/payment_intents/%s", ApiResource.urlEncodeId(this.getId()));
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /**
   * Updates properties on a PaymentIntent object without confirming.
   *
   * <p>Depending on which properties you update, you may need to confirm the PaymentIntent again.
   * For example, updating the {@code payment_method} will always require you to confirm the
   * PaymentIntent again. If you prefer to update and confirm at the same time, we recommend
   * updating properties via the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> instead.
   */
  public PaymentIntent update(PaymentIntentUpdateParams params) throws StripeException {
    return update(params, (RequestOptions) null);
  }

  /**
   * Updates properties on a PaymentIntent object without confirming.
   *
   * <p>Depending on which properties you update, you may need to confirm the PaymentIntent again.
   * For example, updating the {@code payment_method} will always require you to confirm the
   * PaymentIntent again. If you prefer to update and confirm at the same time, we recommend
   * updating properties via the <a
   * href="https://stripe.com/docs/api/payment_intents/confirm">confirm API</a> instead.
   */
  public PaymentIntent update(PaymentIntentUpdateParams params, RequestOptions options)
      throws StripeException {
    String path = String.format("/v1/payment_intents/%s", ApiResource.urlEncodeId(this.getId()));
    ApiResource.checkNullTypedParams(path, params);
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /** Verifies microdeposits on a PaymentIntent object. */
  public PaymentIntent verifyMicrodeposits() throws StripeException {
    return verifyMicrodeposits((Map<String, Object>) null, (RequestOptions) null);
  }

  /** Verifies microdeposits on a PaymentIntent object. */
  public PaymentIntent verifyMicrodeposits(RequestOptions options) throws StripeException {
    return verifyMicrodeposits((Map<String, Object>) null, options);
  }

  /** Verifies microdeposits on a PaymentIntent object. */
  public PaymentIntent verifyMicrodeposits(Map<String, Object> params) throws StripeException {
    return verifyMicrodeposits(params, (RequestOptions) null);
  }

  /** Verifies microdeposits on a PaymentIntent object. */
  public PaymentIntent verifyMicrodeposits(Map<String, Object> params, RequestOptions options)
      throws StripeException {
    String path =
        String.format(
            "/v1/payment_intents/%s/verify_microdeposits", ApiResource.urlEncodeId(this.getId()));
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            params,
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  /** Verifies microdeposits on a PaymentIntent object. */
  public PaymentIntent verifyMicrodeposits(PaymentIntentVerifyMicrodepositsParams params)
      throws StripeException {
    return verifyMicrodeposits(params, (RequestOptions) null);
  }

  /** Verifies microdeposits on a PaymentIntent object. */
  public PaymentIntent verifyMicrodeposits(
      PaymentIntentVerifyMicrodepositsParams params, RequestOptions options)
      throws StripeException {
    String path =
        String.format(
            "/v1/payment_intents/%s/verify_microdeposits", ApiResource.urlEncodeId(this.getId()));
    ApiResource.checkNullTypedParams(path, params);
    return getResponseGetter()
        .request(
            BaseAddress.API,
            ApiResource.RequestMethod.POST,
            path,
            ApiRequestParams.paramsToMap(params),
            PaymentIntent.class,
            options,
            ApiMode.V1);
  }

  @Getter
  @Setter
  @EqualsAndHashCode(callSuper = false)
  public static class AmountDetails extends StripeObject {
    @SerializedName("tip")
    Tip tip;

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Tip extends StripeObject {
      /** Portion of the amount that corresponds to a tip. */
      @SerializedName("amount")
      Long amount;
    }
  }

  @Getter
  @Setter
  @EqualsAndHashCode(callSuper = false)
  public static class AutomaticPaymentMethods extends StripeObject {
    /**
     * Controls whether this PaymentIntent will accept redirect-based payment methods.
     *
     * <p>Redirect-based payment methods may require your customer to be redirected to a payment
     * method's app or site for authentication or additional steps. To <a
     * href="https://stripe.com/docs/api/payment_intents/confirm">confirm</a> this PaymentIntent,
     * you may be required to provide a {@code return_url} to redirect customers back to your site
     * after they authenticate or complete the payment.
     *
     * <p>One of {@code always}, or {@code never}.
     */
    @SerializedName("allow_redirects")
    String allowRedirects;

    /** Automatically calculates compatible payment methods. */
    @SerializedName("enabled")
    Boolean enabled;
  }

  @Getter
  @Setter
  @EqualsAndHashCode(callSuper = false)
  public static class NextAction extends StripeObject {
    @SerializedName("alipay_handle_redirect")
    AlipayHandleRedirect alipayHandleRedirect;

    @SerializedName("boleto_display_details")
    BoletoDisplayDetails boletoDisplayDetails;

    @SerializedName("card_await_notification")
    CardAwaitNotification cardAwaitNotification;

    @SerializedName("cashapp_handle_redirect_or_display_qr_code")
    CashappHandleRedirectOrDisplayQrCode cashappHandleRedirectOrDisplayQrCode;

    @SerializedName("display_bank_transfer_instructions")
    DisplayBankTransferInstructions displayBankTransferInstructions;

    @SerializedName("konbini_display_details")
    KonbiniDisplayDetails konbiniDisplayDetails;

    @SerializedName("oxxo_display_details")
    OxxoDisplayDetails oxxoDisplayDetails;

    @SerializedName("paynow_display_qr_code")
    PaynowDisplayQrCode paynowDisplayQrCode;

    @SerializedName("pix_display_qr_code")
    PixDisplayQrCode pixDisplayQrCode;

    @SerializedName("promptpay_display_qr_code")
    PromptpayDisplayQrCode promptpayDisplayQrCode;

    @SerializedName("redirect_to_url")
    RedirectToUrl redirectToUrl;

    /**
     * Type of the next action to perform, one of {@code redirect_to_url}, {@code use_stripe_sdk},
     * {@code alipay_handle_redirect}, {@code oxxo_display_details}, or {@code
     * verify_with_microdeposits}.
     */
    @SerializedName("type")
    String type;

    /**
     * When confirming a PaymentIntent with Stripe.js, Stripe.js depends on the contents of this
     * dictionary to invoke authentication flows. The shape of the contents is subject to change and
     * is only intended to be used by Stripe.js.
     */
    @SerializedName("use_stripe_sdk")
    Map<String, Object> useStripeSdk;

    @SerializedName("verify_with_microdeposits")
    VerifyWithMicrodeposits verifyWithMicrodeposits;

    @SerializedName("wechat_pay_display_qr_code")
    WechatPayDisplayQrCode wechatPayDisplayQrCode;

    @SerializedName("wechat_pay_redirect_to_android_app")
    WechatPayRedirectToAndroidApp wechatPayRedirectToAndroidApp;

    @SerializedName("wechat_pay_redirect_to_ios_app")
    WechatPayRedirectToIosApp wechatPayRedirectToIosApp;

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class AlipayHandleRedirect extends StripeObject {
      /**
       * The native data to be used with Alipay SDK you must redirect your customer to in order to
       * authenticate the payment in an Android App.
       */
      @SerializedName("native_data")
      String nativeData;

      /**
       * The native URL you must redirect your customer to in order to authenticate the payment in
       * an iOS App.
       */
      @SerializedName("native_url")
      String nativeUrl;

      /**
       * If the customer does not exit their browser while authenticating, they will be redirected
       * to this specified URL after completion.
       */
      @SerializedName("return_url")
      String returnUrl;

      /** The URL you must redirect your customer to in order to authenticate the payment. */
      @SerializedName("url")
      String url;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class BoletoDisplayDetails extends StripeObject {
      /** The timestamp after which the boleto expires. */
      @SerializedName("expires_at")
      Long expiresAt;

      /**
       * The URL to the hosted boleto voucher page, which allows customers to view the boleto
       * voucher.
       */
      @SerializedName("hosted_voucher_url")
      String hostedVoucherUrl;

      /** The boleto number. */
      @SerializedName("number")
      String number;

      /** The URL to the downloadable boleto voucher PDF. */
      @SerializedName("pdf")
      String pdf;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class CardAwaitNotification extends StripeObject {
      /**
       * The time that payment will be attempted. If customer approval is required, they need to
       * provide approval before this time.
       */
      @SerializedName("charge_attempt_at")
      Long chargeAttemptAt;

      /**
       * For payments greater than INR 15000, the customer must provide explicit approval of the
       * payment with their bank. For payments of lower amount, no customer action is required.
       */
      @SerializedName("customer_approval_required")
      Boolean customerApprovalRequired;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class CashappHandleRedirectOrDisplayQrCode extends StripeObject {
      /**
       * The URL to the hosted Cash App Pay instructions page, which allows customers to view the QR
       * code, and supports QR code refreshing on expiration.
       */
      @SerializedName("hosted_instructions_url")
      String hostedInstructionsUrl;

      /** The url for mobile redirect based auth. */
      @SerializedName("mobile_auth_url")
      String mobileAuthUrl;

      @SerializedName("qr_code")
      QrCode qrCode;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class QrCode extends StripeObject {
        /** The date (unix timestamp) when the QR code expires. */
        @SerializedName("expires_at")
        Long expiresAt;

        /** The image_url_png string used to render QR code. */
        @SerializedName("image_url_png")
        String imageUrlPng;

        /** The image_url_svg string used to render QR code. */
        @SerializedName("image_url_svg")
        String imageUrlSvg;
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class DisplayBankTransferInstructions extends StripeObject {
      /** The remaining amount that needs to be transferred to complete the payment. */
      @SerializedName("amount_remaining")
      Long amountRemaining;

      /**
       * Three-letter <a href="https://www.iso.org/iso-4217-currency-codes.html">ISO currency
       * code</a>, in lowercase. Must be a <a href="https://stripe.com/docs/currencies">supported
       * currency</a>.
       */
      @SerializedName("currency")
      String currency;

      /** A list of financial addresses that can be used to fund the customer balance. */
      @SerializedName("financial_addresses")
      List<PaymentIntent.NextAction.DisplayBankTransferInstructions.FinancialAddress>
          financialAddresses;

      /** A link to a hosted page that guides your customer through completing the transfer. */
      @SerializedName("hosted_instructions_url")
      String hostedInstructionsUrl;

      /**
       * A string identifying this payment. Instruct your customer to include this code in the
       * reference or memo field of their bank transfer.
       */
      @SerializedName("reference")
      String reference;

      /**
       * Type of bank transfer
       *
       * <p>One of {@code eu_bank_transfer}, {@code gb_bank_transfer}, {@code jp_bank_transfer},
       * {@code mx_bank_transfer}, or {@code us_bank_transfer}.
       */
      @SerializedName("type")
      String type;

      /** FinancialAddresses contain identifying information that resolves to a FinancialAccount. */
      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class FinancialAddress extends StripeObject {
        /** Iban Records contain E.U. bank account details per the SEPA format. */
        @SerializedName("iban")
        Iban iban;

        /** Sort Code Records contain U.K. bank account details per the sort code format. */
        @SerializedName("sort_code")
        SortCode sortCode;

        /** SPEI Records contain Mexico bank account details per the SPEI format. */
        @SerializedName("spei")
        Spei spei;

        /** The payment networks supported by this FinancialAddress. */
        @SerializedName("supported_networks")
        List<String> supportedNetworks;

        /**
         * The type of financial address
         *
         * <p>One of {@code iban}, {@code sort_code}, {@code spei}, or {@code zengin}.
         */
        @SerializedName("type")
        String type;

        /** Zengin Records contain Japan bank account details per the Zengin format. */
        @SerializedName("zengin")
        Zengin zengin;

        /** Iban Records contain E.U. bank account details per the SEPA format. */
        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Iban extends StripeObject {
          /** The name of the person or business that owns the bank account. */
          @SerializedName("account_holder_name")
          String accountHolderName;

          /** The BIC/SWIFT code of the account. */
          @SerializedName("bic")
          String bic;

          /**
           * Two-letter country code (<a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO
           * 3166-1 alpha-2</a>).
           */
          @SerializedName("country")
          String country;

          /** The IBAN of the account. */
          @SerializedName("iban")
          String iban;
        }

        /** Sort Code Records contain U.K. bank account details per the sort code format. */
        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class SortCode extends StripeObject {
          /** The name of the person or business that owns the bank account. */
          @SerializedName("account_holder_name")
          String accountHolderName;

          /** The account number. */
          @SerializedName("account_number")
          String accountNumber;

          /** The six-digit sort code. */
          @SerializedName("sort_code")
          String sortCode;
        }

        /** SPEI Records contain Mexico bank account details per the SPEI format. */
        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Spei extends StripeObject {
          /** The three-digit bank code. */
          @SerializedName("bank_code")
          String bankCode;

          /** The short banking institution name. */
          @SerializedName("bank_name")
          String bankName;

          /** The CLABE number. */
          @SerializedName("clabe")
          String clabe;
        }

        /** Zengin Records contain Japan bank account details per the Zengin format. */
        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Zengin extends StripeObject {
          /** The account holder name. */
          @SerializedName("account_holder_name")
          String accountHolderName;

          /** The account number. */
          @SerializedName("account_number")
          String accountNumber;

          /** The bank account type. In Japan, this can only be {@code futsu} or {@code toza}. */
          @SerializedName("account_type")
          String accountType;

          /** The bank code of the account. */
          @SerializedName("bank_code")
          String bankCode;

          /** The bank name of the account. */
          @SerializedName("bank_name")
          String bankName;

          /** The branch code of the account. */
          @SerializedName("branch_code")
          String branchCode;

          /** The branch name of the account. */
          @SerializedName("branch_name")
          String branchName;
        }
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class KonbiniDisplayDetails extends StripeObject {
      /** The timestamp at which the pending Konbini payment expires. */
      @SerializedName("expires_at")
      Long expiresAt;

      /**
       * The URL for the Konbini payment instructions page, which allows customers to view and print
       * a Konbini voucher.
       */
      @SerializedName("hosted_voucher_url")
      String hostedVoucherUrl;

      @SerializedName("stores")
      Stores stores;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class Stores extends StripeObject {
        /** FamilyMart instruction details. */
        @SerializedName("familymart")
        Familymart familymart;

        /** Lawson instruction details. */
        @SerializedName("lawson")
        Lawson lawson;

        /** Ministop instruction details. */
        @SerializedName("ministop")
        Ministop ministop;

        /** Seicomart instruction details. */
        @SerializedName("seicomart")
        Seicomart seicomart;

        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Familymart extends StripeObject {
          /** The confirmation number. */
          @SerializedName("confirmation_number")
          String confirmationNumber;

          /** The payment code. */
          @SerializedName("payment_code")
          String paymentCode;
        }

        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Lawson extends StripeObject {
          /** The confirmation number. */
          @SerializedName("confirmation_number")
          String confirmationNumber;

          /** The payment code. */
          @SerializedName("payment_code")
          String paymentCode;
        }

        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Ministop extends StripeObject {
          /** The confirmation number. */
          @SerializedName("confirmation_number")
          String confirmationNumber;

          /** The payment code. */
          @SerializedName("payment_code")
          String paymentCode;
        }

        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Seicomart extends StripeObject {
          /** The confirmation number. */
          @SerializedName("confirmation_number")
          String confirmationNumber;

          /** The payment code. */
          @SerializedName("payment_code")
          String paymentCode;
        }
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class OxxoDisplayDetails extends StripeObject {
      /** The timestamp after which the OXXO voucher expires. */
      @SerializedName("expires_after")
      Long expiresAfter;

      /**
       * The URL for the hosted OXXO voucher page, which allows customers to view and print an OXXO
       * voucher.
       */
      @SerializedName("hosted_voucher_url")
      String hostedVoucherUrl;

      /** OXXO reference number. */
      @SerializedName("number")
      String number;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class PaynowDisplayQrCode extends StripeObject {
      /**
       * The raw data string used to generate QR code, it should be used together with QR code
       * library.
       */
      @SerializedName("data")
      String data;

      /**
       * The URL to the hosted PayNow instructions page, which allows customers to view the PayNow
       * QR code.
       */
      @SerializedName("hosted_instructions_url")
      String hostedInstructionsUrl;

      /** The image_url_png string used to render QR code. */
      @SerializedName("image_url_png")
      String imageUrlPng;

      /** The image_url_svg string used to render QR code. */
      @SerializedName("image_url_svg")
      String imageUrlSvg;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class PixDisplayQrCode extends StripeObject {
      /**
       * The raw data string used to generate QR code, it should be used together with QR code
       * library.
       */
      @SerializedName("data")
      String data;

      /** The date (unix timestamp) when the PIX expires. */
      @SerializedName("expires_at")
      Long expiresAt;

      /**
       * The URL to the hosted pix instructions page, which allows customers to view the pix QR
       * code.
       */
      @SerializedName("hosted_instructions_url")
      String hostedInstructionsUrl;

      /** The image_url_png string used to render png QR code. */
      @SerializedName("image_url_png")
      String imageUrlPng;

      /** The image_url_svg string used to render svg QR code. */
      @SerializedName("image_url_svg")
      String imageUrlSvg;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class PromptpayDisplayQrCode extends StripeObject {
      /**
       * The raw data string used to generate QR code, it should be used together with QR code
       * library.
       */
      @SerializedName("data")
      String data;

      /**
       * The URL to the hosted PromptPay instructions page, which allows customers to view the
       * PromptPay QR code.
       */
      @SerializedName("hosted_instructions_url")
      String hostedInstructionsUrl;

      /** The PNG path used to render the QR code, can be used as the source in an HTML img tag. */
      @SerializedName("image_url_png")
      String imageUrlPng;

      /** The SVG path used to render the QR code, can be used as the source in an HTML img tag. */
      @SerializedName("image_url_svg")
      String imageUrlSvg;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class RedirectToUrl extends StripeObject {
      /**
       * If the customer does not exit their browser while authenticating, they will be redirected
       * to this specified URL after completion.
       */
      @SerializedName("return_url")
      String returnUrl;

      /** The URL you must redirect your customer to in order to authenticate the payment. */
      @SerializedName("url")
      String url;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class VerifyWithMicrodeposits extends StripeObject {
      /** The timestamp when the microdeposits are expected to land. */
      @SerializedName("arrival_date")
      Long arrivalDate;

      /**
       * The URL for the hosted verification page, which allows customers to verify their bank
       * account.
       */
      @SerializedName("hosted_verification_url")
      String hostedVerificationUrl;

      /**
       * The type of the microdeposit sent to the customer. Used to distinguish between different
       * verification methods.
       *
       * <p>One of {@code amounts}, or {@code descriptor_code}.
       */
      @SerializedName("microdeposit_type")
      String microdepositType;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class WechatPayDisplayQrCode extends StripeObject {
      /** The data being used to generate QR code. */
      @SerializedName("data")
      String data;

      /**
       * The URL to the hosted WeChat Pay instructions page, which allows customers to view the
       * WeChat Pay QR code.
       */
      @SerializedName("hosted_instructions_url")
      String hostedInstructionsUrl;

      /** The base64 image data for a pre-generated QR code. */
      @SerializedName("image_data_url")
      String imageDataUrl;

      /** The image_url_png string used to render QR code. */
      @SerializedName("image_url_png")
      String imageUrlPng;

      /** The image_url_svg string used to render QR code. */
      @SerializedName("image_url_svg")
      String imageUrlSvg;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class WechatPayRedirectToAndroidApp extends StripeObject {
      /** app_id is the APP ID registered on WeChat open platform. */
      @SerializedName("app_id")
      String appId;

      /** nonce_str is a random string. */
      @SerializedName("nonce_str")
      String nonceStr;

      /** an unique merchant ID assigned by WeChat Pay. */
      @SerializedName("partner_id")
      String partnerId;

      /** an unique trading ID assigned by WeChat Pay. */
      @SerializedName("prepay_id")
      String prepayId;

      /** A signature. */
      @SerializedName("sign")
      String sign;

      /** Specifies the current time in epoch format. */
      @SerializedName("timestamp")
      String timestamp;

      // package is a reserved word so we append an
      // underscore to the private field and expose
      // a custom getter and setter
      @SerializedName("package")
      String package_;

      public String getPackage() {
        return this.package_;
      }

      public void setPackage(String package_) {
        this.package_ = package_;
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class WechatPayRedirectToIosApp extends StripeObject {
      /** An universal link that redirect to WeChat Pay app. */
      @SerializedName("native_url")
      String nativeUrl;
    }
  }

  @Getter
  @Setter
  @EqualsAndHashCode(callSuper = false)
  public static class PaymentMethodOptions extends StripeObject {
    @SerializedName("acss_debit")
    AcssDebit acssDebit;

    @SerializedName("affirm")
    Affirm affirm;

    @SerializedName("afterpay_clearpay")
    AfterpayClearpay afterpayClearpay;

    @SerializedName("alipay")
    Alipay alipay;

    @SerializedName("au_becs_debit")
    AuBecsDebit auBecsDebit;

    @SerializedName("bacs_debit")
    BacsDebit bacsDebit;

    @SerializedName("bancontact")
    Bancontact bancontact;

    @SerializedName("blik")
    Blik blik;

    @SerializedName("boleto")
    Boleto boleto;

    @SerializedName("card")
    Card card;

    @SerializedName("card_present")
    CardPresent cardPresent;

    @SerializedName("cashapp")
    Cashapp cashapp;

    @SerializedName("customer_balance")
    CustomerBalance customerBalance;

    @SerializedName("eps")
    Eps eps;

    @SerializedName("fpx")
    Fpx fpx;

    @SerializedName("giropay")
    Giropay giropay;

    @SerializedName("grabpay")
    Grabpay grabpay;

    @SerializedName("ideal")
    Ideal ideal;

    @SerializedName("interac_present")
    InteracPresent interacPresent;

    @SerializedName("klarna")
    Klarna klarna;

    @SerializedName("konbini")
    Konbini konbini;

    @SerializedName("link")
    Link link;

    @SerializedName("oxxo")
    Oxxo oxxo;

    @SerializedName("p24")
    P24 p24;

    @SerializedName("paynow")
    Paynow paynow;

    @SerializedName("paypal")
    Paypal paypal;

    @SerializedName("pix")
    Pix pix;

    @SerializedName("promptpay")
    Promptpay promptpay;

    @SerializedName("sepa_debit")
    SepaDebit sepaDebit;

    @SerializedName("sofort")
    Sofort sofort;

    @SerializedName("us_bank_account")
    UsBankAccount usBankAccount;

    @SerializedName("wechat_pay")
    WechatPay wechatPay;

    @SerializedName("zip")
    Zip zip;

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class AcssDebit extends StripeObject {
      @SerializedName("mandate_options")
      MandateOptions mandateOptions;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;

      /**
       * Bank account verification method.
       *
       * <p>One of {@code automatic}, {@code instant}, or {@code microdeposits}.
       */
      @SerializedName("verification_method")
      String verificationMethod;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class MandateOptions extends StripeObject {
        /** A URL for custom mandate text. */
        @SerializedName("custom_mandate_url")
        String customMandateUrl;

        /**
         * Description of the interval. Only required if the 'payment_schedule' parameter is
         * 'interval' or 'combined'.
         */
        @SerializedName("interval_description")
        String intervalDescription;

        /**
         * Payment schedule for the mandate.
         *
         * <p>One of {@code combined}, {@code interval}, or {@code sporadic}.
         */
        @SerializedName("payment_schedule")
        String paymentSchedule;

        /**
         * Transaction type of the mandate.
         *
         * <p>One of {@code business}, or {@code personal}.
         */
        @SerializedName("transaction_type")
        String transactionType;
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Affirm extends StripeObject {
      /**
       * Controls when the funds will be captured from the customer's account.
       *
       * <p>Equal to {@code manual}.
       */
      @SerializedName("capture_method")
      String captureMethod;

      /** Preferred language of the Affirm authorization page that the customer is redirected to. */
      @SerializedName("preferred_locale")
      String preferredLocale;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class AfterpayClearpay extends StripeObject {
      /**
       * Controls when the funds will be captured from the customer's account.
       *
       * <p>Equal to {@code manual}.
       */
      @SerializedName("capture_method")
      String captureMethod;

      /**
       * Order identifier shown to the customer in Afterpay’s online portal. We recommend using a
       * value that helps you answer any questions a customer might have about the payment. The
       * identifier is limited to 128 characters and may contain only letters, digits, underscores,
       * backslashes and dashes.
       */
      @SerializedName("reference")
      String reference;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Alipay extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, or {@code off_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class AuBecsDebit extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class BacsDebit extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Bancontact extends StripeObject {
      /**
       * Preferred language of the Bancontact authorization page that the customer is redirected to.
       *
       * <p>One of {@code de}, {@code en}, {@code fr}, or {@code nl}.
       */
      @SerializedName("preferred_language")
      String preferredLanguage;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, or {@code off_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Blik extends StripeObject {}

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Boleto extends StripeObject {
      /**
       * The number of calendar days before a Boleto voucher expires. For example, if you create a
       * Boleto voucher on Monday and you set expires_after_days to 2, the Boleto voucher will
       * expire on Wednesday at 23:59 America/Sao_Paulo time.
       */
      @SerializedName("expires_after_days")
      Long expiresAfterDays;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Card extends StripeObject {
      /**
       * Controls when the funds will be captured from the customer's account.
       *
       * <p>Equal to {@code manual}.
       */
      @SerializedName("capture_method")
      String captureMethod;

      /**
       * Installment details for this payment (Mexico only).
       *
       * <p>For more information, see the <a
       * href="https://stripe.com/docs/payments/installments">installments integration guide</a>.
       */
      @SerializedName("installments")
      Installments installments;

      /** Configuration options for setting up an eMandate for cards issued in India. */
      @SerializedName("mandate_options")
      MandateOptions mandateOptions;

      /**
       * Selected network to process this payment intent on. Depends on the available networks of
       * the card attached to the payment intent. Can be only set confirm-time.
       */
      @SerializedName("network")
      String network;

      /**
       * We strongly recommend that you rely on our SCA Engine to automatically prompt your
       * customers for authentication based on risk level and <a
       * href="https://stripe.com/docs/strong-customer-authentication">other requirements</a>.
       * However, if you wish to request 3D Secure based on logic from your own fraud engine,
       * provide this option. Permitted values include: {@code automatic} or {@code any}. If not
       * provided, defaults to {@code automatic}. Read our guide on <a
       * href="https://stripe.com/docs/payments/3d-secure#manual-three-ds">manually requesting 3D
       * Secure</a> for more information on how this configuration interacts with Radar and our SCA
       * Engine.
       *
       * <p>One of {@code any}, {@code automatic}, or {@code challenge_only}.
       */
      @SerializedName("request_three_d_secure")
      String requestThreeDSecure;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;

      /**
       * Provides information about a card payment that customers see on their statements.
       * Concatenated with the Kana prefix (shortened Kana descriptor) or Kana statement descriptor
       * that’s set on the account to form the complete statement descriptor. Maximum 22 characters.
       * On card statements, the <em>concatenation</em> of both prefix and suffix (including
       * separators) will appear truncated to 22 characters.
       */
      @SerializedName("statement_descriptor_suffix_kana")
      String statementDescriptorSuffixKana;

      /**
       * Provides information about a card payment that customers see on their statements.
       * Concatenated with the Kanji prefix (shortened Kanji descriptor) or Kanji statement
       * descriptor that’s set on the account to form the complete statement descriptor. Maximum 17
       * characters. On card statements, the <em>concatenation</em> of both prefix and suffix
       * (including separators) will appear truncated to 17 characters.
       */
      @SerializedName("statement_descriptor_suffix_kanji")
      String statementDescriptorSuffixKanji;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class Installments extends StripeObject {
        /** Installment plans that may be selected for this PaymentIntent. */
        @SerializedName("available_plans")
        List<PaymentIntent.PaymentMethodOptions.Card.Installments.AvailablePlan> availablePlans;

        /** Whether Installments are enabled for this PaymentIntent. */
        @SerializedName("enabled")
        Boolean enabled;

        /** Installment plan selected for this PaymentIntent. */
        @SerializedName("plan")
        Plan plan;

        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class AvailablePlan extends StripeObject {
          /**
           * For {@code fixed_count} installment plans, this is the number of installment payments
           * your customer will make to their credit card.
           */
          @SerializedName("count")
          Long count;

          /**
           * For {@code fixed_count} installment plans, this is the interval between installment
           * payments your customer will make to their credit card. One of {@code month}.
           */
          @SerializedName("interval")
          String interval;

          /** Type of installment plan, one of {@code fixed_count}. */
          @SerializedName("type")
          String type;
        }

        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class Plan extends StripeObject {
          /**
           * For {@code fixed_count} installment plans, this is the number of installment payments
           * your customer will make to their credit card.
           */
          @SerializedName("count")
          Long count;

          /**
           * For {@code fixed_count} installment plans, this is the interval between installment
           * payments your customer will make to their credit card. One of {@code month}.
           */
          @SerializedName("interval")
          String interval;

          /** Type of installment plan, one of {@code fixed_count}. */
          @SerializedName("type")
          String type;
        }
      }

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class MandateOptions extends StripeObject {
        /** Amount to be charged for future payments. */
        @SerializedName("amount")
        Long amount;

        /**
         * One of {@code fixed} or {@code maximum}. If {@code fixed}, the {@code amount} param
         * refers to the exact amount to be charged in future payments. If {@code maximum}, the
         * amount charged can be up to the value passed for the {@code amount} param.
         */
        @SerializedName("amount_type")
        String amountType;

        /**
         * A description of the mandate or subscription that is meant to be displayed to the
         * customer.
         */
        @SerializedName("description")
        String description;

        /**
         * End date of the mandate or subscription. If not provided, the mandate will be active
         * until canceled. If provided, end date should be after start date.
         */
        @SerializedName("end_date")
        Long endDate;

        /**
         * Specifies payment frequency. One of {@code day}, {@code week}, {@code month}, {@code
         * year}, or {@code sporadic}.
         */
        @SerializedName("interval")
        String interval;

        /**
         * The number of intervals between payments. For example, {@code interval=month} and {@code
         * interval_count=3} indicates one payment every three months. Maximum of one year interval
         * allowed (1 year, 12 months, or 52 weeks). This parameter is optional when {@code
         * interval=sporadic}.
         */
        @SerializedName("interval_count")
        Long intervalCount;

        /** Unique identifier for the mandate or subscription. */
        @SerializedName("reference")
        String reference;

        /**
         * Start date of the mandate or subscription. Start date should not be lesser than
         * yesterday.
         */
        @SerializedName("start_date")
        Long startDate;

        /** Specifies the type of mandates supported. Possible values are {@code india}. */
        @SerializedName("supported_types")
        List<String> supportedTypes;
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class CardPresent extends StripeObject {
      /**
       * Request ability to capture this payment beyond the standard <a
       * href="https://stripe.com/docs/terminal/features/extended-authorizations#authorization-validity">authorization
       * validity window.</a>
       */
      @SerializedName("request_extended_authorization")
      Boolean requestExtendedAuthorization;

      /**
       * Request ability to <a
       * href="https://stripe.com/docs/terminal/features/incremental-authorizations">increment</a>
       * this PaymentIntent if the combination of MCC and card brand is eligible. Check <a
       * href="https://stripe.com/docs/api/charges/object#charge_object-payment_method_details-card_present-incremental_authorization_supported">incremental_authorization_supported</a>
       * in the <a href="https://stripe.com/docs/api/payment_intents/confirm">Confirm</a> response
       * to verify support.
       */
      @SerializedName("request_incremental_authorization_support")
      Boolean requestIncrementalAuthorizationSupport;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Cashapp extends StripeObject {
      /**
       * Controls when the funds will be captured from the customer's account.
       *
       * <p>Equal to {@code manual}.
       */
      @SerializedName("capture_method")
      String captureMethod;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class CustomerBalance extends StripeObject {
      @SerializedName("bank_transfer")
      BankTransfer bankTransfer;

      /**
       * The funding method type to be used when there are not enough funds in the customer balance.
       * Permitted values include: {@code bank_transfer}.
       *
       * <p>Equal to {@code bank_transfer}.
       */
      @SerializedName("funding_type")
      String fundingType;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class BankTransfer extends StripeObject {
        @SerializedName("eu_bank_transfer")
        EuBankTransfer euBankTransfer;

        /**
         * List of address types that should be returned in the financial_addresses response. If not
         * specified, all valid types will be returned.
         *
         * <p>Permitted values include: {@code sort_code}, {@code zengin}, {@code iban}, or {@code
         * spei}.
         */
        @SerializedName("requested_address_types")
        List<String> requestedAddressTypes;

        /**
         * The bank transfer type that this PaymentIntent is allowed to use for funding Permitted
         * values include: {@code eu_bank_transfer}, {@code gb_bank_transfer}, {@code
         * jp_bank_transfer}, {@code mx_bank_transfer}, or {@code us_bank_transfer}.
         *
         * <p>One of {@code eu_bank_transfer}, {@code gb_bank_transfer}, {@code jp_bank_transfer},
         * {@code mx_bank_transfer}, or {@code us_bank_transfer}.
         */
        @SerializedName("type")
        String type;

        @Getter
        @Setter
        @EqualsAndHashCode(callSuper = false)
        public static class EuBankTransfer extends StripeObject {
          /**
           * The desired country code of the bank account information. Permitted values include:
           * {@code BE}, {@code DE}, {@code ES}, {@code FR}, {@code IE}, or {@code NL}.
           *
           * <p>One of {@code BE}, {@code DE}, {@code ES}, {@code FR}, {@code IE}, or {@code NL}.
           */
          @SerializedName("country")
          String country;
        }
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Eps extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Fpx extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Giropay extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Grabpay extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Ideal extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, or {@code off_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class InteracPresent extends StripeObject {}

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Klarna extends StripeObject {
      /**
       * Controls when the funds will be captured from the customer's account.
       *
       * <p>Equal to {@code manual}.
       */
      @SerializedName("capture_method")
      String captureMethod;

      /** Preferred locale of the Klarna checkout page that the customer is redirected to. */
      @SerializedName("preferred_locale")
      String preferredLocale;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Konbini extends StripeObject {
      /**
       * An optional 10 to 11 digit numeric-only string determining the confirmation code at
       * applicable convenience stores.
       */
      @SerializedName("confirmation_number")
      String confirmationNumber;

      /**
       * The number of calendar days (between 1 and 60) after which Konbini payment instructions
       * will expire. For example, if a PaymentIntent is confirmed with Konbini and {@code
       * expires_after_days} set to 2 on Monday JST, the instructions will expire on Wednesday
       * 23:59:59 JST.
       */
      @SerializedName("expires_after_days")
      Long expiresAfterDays;

      /**
       * The timestamp at which the Konbini payment instructions will expire. Only one of {@code
       * expires_after_days} or {@code expires_at} may be set.
       */
      @SerializedName("expires_at")
      Long expiresAt;

      /**
       * A product descriptor of up to 22 characters, which will appear to customers at the
       * convenience store.
       */
      @SerializedName("product_description")
      String productDescription;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Link extends StripeObject {
      /**
       * Controls when the funds will be captured from the customer's account.
       *
       * <p>Equal to {@code manual}.
       */
      @SerializedName("capture_method")
      String captureMethod;

      /** [Deprecated] This is a legacy parameter that no longer has any function. */
      @SerializedName("persistent_token")
      String persistentToken;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, or {@code off_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Oxxo extends StripeObject {
      /**
       * The number of calendar days before an OXXO invoice expires. For example, if you create an
       * OXXO invoice on Monday and you set expires_after_days to 2, the OXXO invoice will expire on
       * Wednesday at 23:59 America/Mexico_City time.
       */
      @SerializedName("expires_after_days")
      Long expiresAfterDays;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class P24 extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Paynow extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Paypal extends StripeObject {
      /**
       * Controls when the funds will be captured from the customer's account.
       *
       * <p>Equal to {@code manual}.
       */
      @SerializedName("capture_method")
      String captureMethod;

      /** Preferred locale of the PayPal checkout page that the customer is redirected to. */
      @SerializedName("preferred_locale")
      String preferredLocale;

      /**
       * A reference of the PayPal transaction visible to customer which is mapped to PayPal's
       * invoice ID. This must be a globally unique ID if you have configured in your PayPal
       * settings to block multiple payments per invoice ID.
       */
      @SerializedName("reference")
      String reference;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, or {@code off_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Pix extends StripeObject {
      /** The number of seconds (between 10 and 1209600) after which Pix payment will expire. */
      @SerializedName("expires_after_seconds")
      Long expiresAfterSeconds;

      /** The timestamp at which the Pix expires. */
      @SerializedName("expires_at")
      Long expiresAt;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Promptpay extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class SepaDebit extends StripeObject {
      @SerializedName("mandate_options")
      MandateOptions mandateOptions;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class MandateOptions extends StripeObject {}
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Sofort extends StripeObject {
      /**
       * Preferred language of the SOFORT authorization page that the customer is redirected to.
       *
       * <p>One of {@code de}, {@code en}, {@code es}, {@code fr}, {@code it}, {@code nl}, or {@code
       * pl}.
       */
      @SerializedName("preferred_language")
      String preferredLanguage;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, or {@code off_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class UsBankAccount extends StripeObject {
      @SerializedName("financial_connections")
      FinancialConnections financialConnections;

      /**
       * Preferred transaction settlement speed
       *
       * <p>One of {@code fastest}, or {@code standard}.
       */
      @SerializedName("preferred_settlement_speed")
      String preferredSettlementSpeed;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>One of {@code none}, {@code off_session}, or {@code on_session}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;

      /**
       * Bank account verification method.
       *
       * <p>One of {@code automatic}, {@code instant}, or {@code microdeposits}.
       */
      @SerializedName("verification_method")
      String verificationMethod;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class FinancialConnections extends StripeObject {
        /**
         * The list of permissions to request. The {@code payment_method} permission must be
         * included.
         */
        @SerializedName("permissions")
        List<String> permissions;

        /**
         * For webview integrations only. Upon completing OAuth login in the native browser, the
         * user will be redirected to this URL to return to your app.
         */
        @SerializedName("return_url")
        String returnUrl;
      }
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class WechatPay extends StripeObject {
      /** The app ID registered with WeChat Pay. Only required when client is ios or android. */
      @SerializedName("app_id")
      String appId;

      /**
       * The client type that the end customer will pay from
       *
       * <p>One of {@code android}, {@code ios}, or {@code web}.
       */
      @SerializedName("client")
      String client;

      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Zip extends StripeObject {
      /**
       * Indicates that you intend to make future payments with this PaymentIntent's payment method.
       *
       * <p>Providing this parameter will <a
       * href="https://stripe.com/docs/payments/save-during-payment">attach the payment method</a>
       * to the PaymentIntent's Customer, if present, after the PaymentIntent is confirmed and any
       * required actions from the user are complete. If no Customer was provided, the payment
       * method can still be <a
       * href="https://stripe.com/docs/api/payment_methods/attach">attached</a> to a Customer after
       * the transaction completes.
       *
       * <p>When processing card payments, Stripe also uses {@code setup_future_usage} to
       * dynamically optimize your payment flow and comply with regional legislation and network
       * rules, such as <a href="https://stripe.com/docs/strong-customer-authentication">SCA</a>.
       *
       * <p>Equal to {@code none}.
       */
      @SerializedName("setup_future_usage")
      String setupFutureUsage;
    }
  }

  @Getter
  @Setter
  @EqualsAndHashCode(callSuper = false)
  public static class Processing extends StripeObject {
    @SerializedName("card")
    Card card;

    /**
     * Type of the payment method for which payment is in {@code processing} state, one of {@code
     * card}.
     */
    @SerializedName("type")
    String type;

    @Getter
    @Setter
    @EqualsAndHashCode(callSuper = false)
    public static class Card extends StripeObject {
      @SerializedName("customer_notification")
      CustomerNotification customerNotification;

      @Getter
      @Setter
      @EqualsAndHashCode(callSuper = false)
      public static class CustomerNotification extends StripeObject {
        /**
         * Whether customer approval has been requested for this payment. For payments greater than
         * INR 15000 or mandate amount, the customer must provide explicit approval of the payment
         * with their bank.
         */
        @SerializedName("approval_requested")
        Boolean approvalRequested;

        /** If customer approval is required, they need to provide approval before this time. */
        @SerializedName("completes_at")
        Long completesAt;
      }
    }
  }

  @Getter
  @Setter
  @EqualsAndHashCode(callSuper = false)
  public static class TransferData extends StripeObject {
    /**
     * Amount intended to be collected by this PaymentIntent. A positive integer representing how
     * much to charge in the <a href="https://stripe.com/docs/currencies#zero-decimal">smallest
     * currency unit</a> (e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal
     * currency). The minimum amount is $0.50 US or <a
     * href="https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts">equivalent in
     * charge currency</a>. The amount value supports up to eight digits (e.g., a value of 99999999
     * for a USD charge of $999,999.99).
     */
    @SerializedName("amount")
    Long amount;

    /**
     * The account (if any) the payment will be attributed to for tax reporting, and where funds
     * from the payment will be transferred to upon payment success.
     */
    @SerializedName("destination")
    @Getter(lombok.AccessLevel.NONE)
    @Setter(lombok.AccessLevel.NONE)
    ExpandableField<Account> destination;

    /** Get ID of expandable {@code destination} object. */
    public String getDestination() {
      return (this.destination != null) ? this.destination.getId() : null;
    }

    public void setDestination(String id) {
      this.destination = ApiResource.setExpandableFieldId(id, this.destination);
    }

    /** Get expanded {@code destination}. */
    public Account getDestinationObject() {
      return (this.destination != null) ? this.destination.getExpanded() : null;
    }

    public void setDestinationObject(Account expandableObject) {
      this.destination = new ExpandableField<Account>(expandableObject.getId(), expandableObject);
    }
  }

  @Override
  public void setResponseGetter(StripeResponseGetter responseGetter) {
    super.setResponseGetter(responseGetter);
    trySetResponseGetter(amountDetails, responseGetter);
    trySetResponseGetter(application, responseGetter);
    trySetResponseGetter(automaticPaymentMethods, responseGetter);
    trySetResponseGetter(customer, responseGetter);
    trySetResponseGetter(invoice, responseGetter);
    trySetResponseGetter(lastPaymentError, responseGetter);
    trySetResponseGetter(latestCharge, responseGetter);
    trySetResponseGetter(nextAction, responseGetter);
    trySetResponseGetter(onBehalfOf, responseGetter);
    trySetResponseGetter(paymentMethod, responseGetter);
    trySetResponseGetter(paymentMethodOptions, responseGetter);
    trySetResponseGetter(processing, responseGetter);
    trySetResponseGetter(review, responseGetter);
    trySetResponseGetter(shipping, responseGetter);
    trySetResponseGetter(source, responseGetter);
    trySetResponseGetter(transferData, responseGetter);
  }
}
