Skip to content

Latest commit

 

History

History
978 lines (867 loc) · 38.9 KB

MIGRATING.md

File metadata and controls

978 lines (867 loc) · 38.9 KB

Migration Guide

Migrating from versions < 16.0.0

  • Changes to CardInputWidget and CardMultilineWidget
    • To enable 19-digit card support, [PaymentConfiguration.init] must be called before the card widgets are instantiated.
    • card and cardBuilder are deprecated. Use cardParams instead.
  • Changes to CardNumberEditText
    • lengthMax and cardNumber are deprecated
  • Changes to CvcEditText
    • cvcValue is deprecated
  • Changes to Card
    • number and cvc are deprecated and will be removed in a future release.
    • Card.Builder and toBuilder() are deprecated; use CardParams instead.
    • Card.fromString(), Card.fromJson(), and Card.create() are deprecated and will be removed in a future release.
    • metadata is deprecated and no longer populated on the client. It must be fetched on your server using your secret key. If this is causing issues with your deployed app versions please reach out to Stripe Support. This field will be removed in a future SDK version.
    • toPaymentMethodsParams() and toPaymentMethodParamsCard() are deprecated; use PaymentMethodCreateParams.createCard() instead.
    • validateCard(), validateNumber(), validateExpiryDate(), validateCVC(), validateExpMonth() are deprecated
  • Changes to CardBrand
    • Methods fromCardNumber(), formatNumber(), groupNumber(), getSpacePositionsForCardNumber(), getMaxLengthWithSpacesForCardNumber(), getMaxLengthForCardNumber() are deprecated
    • Properties defaultMaxLength, pattern, and defaultSpacePositions are deprecated
  • Changes to CardUtils
    • getPossibleCardBrand() and isValidCardNumber are deprecated
  • Changes to StripeTextUtils
    • removeSpacesAndHyphens() is deprecated
  • Changes to SourceParams
    • createCardToken() that accepts a Card parameter is deprecated. Use createCardToken() that accepts a CardParams parameter instead.
    • createCardTokenSynchronous() that accepts a Card parameter is deprecated. Use createCardTokenSynchronous() that accepts a CardParams parameter instead.
  • Changes to Source
    • metadata is deprecated and no longer populated on the client. It must be fetched on your server using your secret key. If this is causing issues with your deployed app versions please reach out to Stripe Support. This field will be removed in a future SDK version.
  • Changes to PaymentMethod
    • metadata is deprecated and no longer populated on the client. It must be fetched on your server using your secret key. If this is causing issues with your deployed app versions please reach out to Stripe Support. This field will be removed in a future SDK version.
  • Changes to Stripe
    • createCardParams() that accepts a Card parameter is deprecated. Use createCardParams() that accepts a CardParams parameter instead.
    • createToken() has been removed; use createCardToken() instead.

Migrating from versions < 15.0.0

  • The SDK now targets JVM 1.8
  • The SDK now requires Android 5.0+ (API level 21+)
  • Changes to PaymentIntent
    • PaymentIntent#captureMethod is now an enum, PaymentIntent.CaptureMethod
      // before
      if (paymentIntent.captureMethod == "automatic") {
      
      } else if (paymentIntent.captureMethod == "manual") {
      
      }
      
      // after
      when (paymentIntent.captureMethod) {
          PaymentIntent.CaptureMethod.Automatic -> {}
          PaymentIntent.CaptureMethod.Manual -> {}
      }
    • PaymentIntent#confirmationMethod is now an enum, PaymentIntent.ConfirmationMethod
      // before
      if (paymentIntent.confirmationMethod == "automatic") {
      
      } else if (paymentIntent.confirmationMethod == "manual") {
      
      }
      
      // after
      when (paymentIntent.confirmationMethod) {
          PaymentIntent.ConfirmationMethod.Automatic -> {}
          PaymentIntent.ConfirmationMethod.Manual -> {}
      }
  • Changes to PaymentMethod
    • PaymentMethod.Card#brand is now a CardBrand
      // before
      when (paymentMethod.card?.brand) {
          "visa" -> {}
          "mastercard" -> {}
          else -> {}
      }
      
      // after
      when (paymentMethod.card?.brand) {
          CardBrand.Visa -> {}
          CardBrand.MasterCard -> {}
          else -> {}
      }
  • Changes to Token
    • Token.TokenType is renamed to Token.Type and is now an enum
      // before
      when (token.type) {
          Token.TokenType.CARD -> {}
          Token.TokenType.BANK_ACCOUNT -> {}
          else -> {}
      }
      
      // after
      when (token.type) {
          Token.Type.Card -> {}
          Token.Type.BankAccount -> {}
          else -> {}
      }
  • Changes to PaymentSession
    • Remove PaymentSession#ActivityPaymentSessionListener
  • Changes to CustomerSession
    • CustomerSession's constructor no longer takes a stripeAccountId; instead, instantiate PaymentConfiguration with a stripeAccountId
      // before
      PaymentConfiguration.init(
          context,
          "pk_test"
      )
      CustomerSession.initCustomerSession(
          context
          ephemeralKeyProvider,
          "acct_1234"
      )
      
      // after
      PaymentConfiguration.init(
          context,
          "pk_test",
          "acct_1234"
      )
      CustomerSession.initCustomerSession(
          context
          ephemeralKeyProvider
      )
    • Remove CustomerSession#ActivityCustomerRetrievalListener, CustomerSession#ActivityPaymentMethodRetrievalListener, CustomerSession#ActivityPaymentMethodsRetrievalListener, and CustomerSession#ActivitySourceRetrievalListener
  • Changes to AddPaymentMethodActivity
    • When PaymentConfiguration is instantiated with a stripeAccountId, it will be used in AddPaymentMethodActivity when creating a payment method
      PaymentConfiguration.init(context, "pk_test", "acct_1234")
    • AddPaymentMethodActivity.Result is now a sealed class with Success, Failure, and Canceled subclasses
      // before
      val result = AddPaymentMethodActivityStarter.Result.fromIntent(
          intent
      )
      when {
          result != null -> result.paymentMethod
          else -> {
              // error happened or customer canceled
          }
      }
      
      // after
      val result = AddPaymentMethodActivityStarter.Result.fromIntent(
          intent
      )
      when (result) {
          is AddPaymentMethodActivityStarter.Result.Success -> {
              result.paymentMethod
          }
          is AddPaymentMethodActivityStarter.Result.Failure -> {
              result.exception
          }
          is AddPaymentMethodActivityStarter.Result.Canceled -> {
              // customer canceled
          }
      }
  • Changes to ShippingInfoWidget
    • setOptionalFields() is now optionalFields
    • setHiddenFields() is now hiddenFields
    • CustomizableShippingField is now an enum
  • Changes to Source
    • Source.SourceFlow has been renamed to Source.Flow and is now an enum
    • Source.SourceStatus has been renamed to Source.Status and is now an enum
    • Source.Usage is now an enum
    • SourceCodeVerification has been moved to Source.CodeVerification
    • SourceOwner has been moved to Source.Owner
    • SourceReceiver has been moved to Source.Receiver
    • SourceRedirect has been moved to Source.Redirect
  • Changes to CustomerSource
    • CustomerSource#tokenizationMethod is now a TokenizationMethod?
  • Changes to SourceTypeModel.Card
    • SourceTypeModel.Card.ThreeDSecureStatus is now an enum
  • Changes to BankAccount
    • public constructors have been removed
    • BankAccount#accountNumber has been removed
    • Stripe#createBankAccountToken() no longer accepts a BankAccount instance; instead, use BankAccountTokenParams
    • Stripe#createBankAccountTokenSynchronous() no longer accepts a BankAccount instance; instead, use BankAccountTokenParams
  • Changes to AccountParams
    • Remove AccountParams.create() that takes a raw map; instead, use create() method that takes a AccountParams.BusinessTypeParams.Individual or AccountParams.BusinessTypeParams.Company
  • Changes to CardInputListener
    • FocusField is now an enum

Migrating from versions < 14.5.0

  • Changes to StripeIntent
    • redirectData is now deprecated.

      If a PaymentIntent or SetupIntent requires a redirect to authenticate, this information will be in nextActionData. However, as before, this action will be handled by the SDK in Stripe.confirmPayment/Stripe.confirmSetupIntent.

      // before
      if (intent.redirectData != null) {
          // requires redirect
      }
      
      // after
      when (intent.nextActionData) {
          is StripeIntent.RedirectData.RedirectToUrl -> // requires redirect
      }
    • stripeSdkData is now deprecated.

      If a PaymentIntent or SetupIntent requires 3DS1 or 3DS2 authentication, this information will be in nextActionData. However, as before, this action will be handled by the SDK in Stripe.confirmPayment/Stripe.confirmSetupIntent.

      // before
      if (intent.stripeSdkData != null) {
          // requires 3D Secure auth
      }
      
      // after
      when (intent.nextActionData) {
          is StripeIntent.RedirectData.SdkData -> // requires 3D Secure auth
      }

Migrating from versions < 14.0.0

  • Changes to Stripe Error localization
    • All Stripe Error messages are now localized based on the device locale.

      For example, when retrieving a SetupIntent with a nonexistent id when the device locale is set to Locale.JAPAN, the error message will now be localized.

      // before - English
      "No such setupintent: seti_invalid123"
      
      // after - Japanese
      "そのような setupintent はありません : seti_invalid123"
      
  • Changes to Material Components
    • com.google.android.material:material has been updated to v1.1.0
  • Changes to PaymentSession
    • When instantiating a PaymentSession() with an Activity, it must now be a ComponentActivity (e.g. AppCompatActivity or FragmentActivity)
    • PaymentSession#init() no longer takes a savedInstanceState argument
      // before
      paymentSession.init(listener, savedInstancedState)
      
      // after
      paymentSession.init(listener)
    • PaymentSession#savePaymentSessionInstanceState() has been removed; state management is handled by PaymentSession
    • PaymentSession#onDestroy() has been removed; the listener instance is now released automatically when the host Activity or Fragment is destroyed
    • Remove PaymentSessionData.paymentSessionData; this data will be returned via `PaymentSessionListener#onPaymentSessionDataChanged()
  • Changes to StripeSourceTypeModel
    • Rename to SourceTypeModel and make a sealed class
    • Move SourceCardData subclass to SourceTypeModel.Card
    • Move SourceSepaDebitData subclass to SourceTypeModel.SepaDebit
    • Change type of Source#sourceTypeModel to SourceTypeModel?
  • Changes to Card.FundingType
    • Rename to CardFunding and convert to an enum
  • Changes to StripeException subclasses
    • InvalidRequestException is now final
    • Remove InvalidRequestException's param, errorCode, and errorDeclineCode properties; these can be accessed via the stripeError property
      // before
      invalidRequestException.param
      invalidRequestException.errorCode
      invalidRequestException.errorDeclineCode
      
      // after
      invalidRequestException.stripeError?.param
      invalidRequestException.stripeError?.code
      invalidRequestException.stripeError?.declineCode
    • RateLimitException now extends StripeException
  • Update 3DS2 styles
    • Create BaseStripe3DS2TextInputLayout that extends Widget.MaterialComponents.TextInputLayout.OutlinedBox
    • Create Stripe3DS2TextInputLayout that extends BaseStripe3DS2TextInputLayout
    • Apply Stripe3DS2TextInputLayout to TextInputLayout
    • Create BaseStripe3DS2EditText with parent Widget.MaterialComponents.TextInputEditText.OutlinedBox
    • Rename Stripe3DS2EditTextTheme to Stripe3DS2EditText and change its parent to BaseStripe3DS2EditText
    • Apply Stripe3DS2EditText to TextInputEditText

Migrating from versions < 13.0.0

  • Changes to Card and SourceCardData
    • Change the type of brand property from String? to CardBrand
    • Remove Card.CardBrand
    • Change the type of tokenizationMethod property from String? to TokenizationMethod?
      // before
      card.tokenizationMethod == "google_pay"
      
      // after
      card.tokenizationMethod == TokenizationMethod.GooglePay
  • Changes to PaymentMethod
    • Change the type of type property from String? to PaymentMethod.Type?
      // before
      paymentMethod.type == "card"
      
      // after
      paymentMethod.type == PaymentMethod.Type.Card
  • Changes to SourceParams
    • setOwner() now takes OwnerParams instead of Map
      // before
      sourceParams
          .setOwner(mapOf(
              "name" to "Jenny Rosen"
          ))
      
      // after
      sourceParams
          .setOwner(OwnerParams(
              name = "Jenny Rosen"
          ))
    • setRedirect() has been removed; use setReturnUrl() instead
      // before
      sourceParams
          .setRedirect(mapOf("return_url" to "myapp://return"))
      
      // after
      sourceParams
          .setReturnUrl("myapp://return")
  • Changes to AccountParams
    • AccountParams.createAccountParams() is now deprecated; use the appropriate AccountParams.create() method.
      // before
      AccountParams.createAccountParams(
          true,
          AccountParams.BusinessType.Individual,
          mapOf(
              "address" to mapOf(
                  "line1" to "123 Market St",
                  "line2" to "#345",
                  "city" to "San Francisco",
                  "state" to "CA",
                  "postal_code" to "94107",
                  "country" to "US"
              ),
              "ssn_last_4" to "1234",
              "first_name" to "Jenny",
              "last_name" to "Rosen"
          )
      )
      
      // after
      AccountParams.create(
          true,
          AccountParams.BusinessTypeParams.Individual(
              address = Address(
                  line1 = "123 Market St",
                  line2 = "#345",
                  city = "San Francisco",
                  state = "CA",
                  postal_code = "94107",
                  country = "US"
              ),
              ssnLast4 = "1234",
              firstName = "Jenny",
              lastName = "Rosen"
          )
      )
  • Changes to StripeEditText
    • StripeEditText now extends TextInputEditText instead of AppCompatEditText
  • Changes to CardInputWidget
    • The postal code field is now displayed by default
    • The postal code input is not validated
    • StripeEditText subclasses (e.g. CardNumberEditText) used in this widget are now wrapped in TextInputLayout
  • Changes to CardMultilineWidget
    • The postal code field is now displayed by default
    • The postal code field is now optional when displayed
    • The postal code input is not validated
    • CardInputListener.onPostalCodeComplete() has been removed
  • Changes to Stripe
    • Bindings for API POST methods now take an optional idempotencyKey. Read about Idempotent Requests for more details.
      // before
      stripe.createPaymentMethod(
            paymentMethodCreateParams,
            callback
      )
      
      // after - without idempotency key
      stripe.createPaymentMethod(
            paymentMethodCreateParams,
            callback = callback
      )
      
      // after - with idempotency key
      stripe.createPaymentMethod(
            paymentMethodCreateParams,
            idempotencyKey = idempotencyKey,
            callback = callback
      )
  • Changes to PaymentMethodsActivityStarter.Result
    • The type of paymentMethod has been changed from PaymentMethod to PaymentMethod? (i.e. it is nullable)
  • Changes to PaymentSession
    • PaymentSession now takes the PaymentSessionConfig instance through its constructor, instead of init()

      // before
      val paymentSession = PaymentSession(activity)
      paymentSession.init(listener, paymentSessionConfig)
      
      // after
      val paymentSession = PaymentSession(activity, paymentSessionConfig)
      paymentSession.init(listener)
    • By default, users will be asked for their postal code (i.e. BillingAddressFields.PostalCode) when adding a new card payment method.

    • PaymentSession#init() no longer takes a shouldPrefetchCustomer argument. If you need to specify shouldPrefetchCustomer, use PaymentSessionConfig.Builder.setShouldPrefetchCustomer().

    • PaymentSession#presentPaymentMethodSelection(shouldRequirePostalCode, userSelectedPaymentMethodId) is deleted. If you need to specify billing details, use PaymentSessionConfig.Builder#setBillingAddressFields().

    • setShouldRequirePostalCode() has been removed from AddPaymentMethodActivityStarter.Args and PaymentMethodsActivityStarter.Args. Use setBillingAddressFields() instead.

    • Shipping information validation and shipping methods creation logic when using PaymentSession has been improved. Previously, this was accomplished by creating a BroadcastReceiver and registering it for a particular Intent. This has been greatly simplified by providing ShippingInformationValidator and ShippingMethodsFactory interfaces that can be defined when creating the PaymentSessionConfig. See below for an example.

      • Before, using BroadcastReceiver

        class PaymentSessionActivity : AppCompatActivity() {
            private lateinit var broadcastReceiver: BroadcastReceiver
        
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
        
                val localBroadcastManager = LocalBroadcastManager.getInstance(this)
                broadcastReceiver = object : BroadcastReceiver() {
                    override fun onReceive(context: Context, intent: Intent) {
                        val shippingInformation = intent
                            .getParcelableExtra<ShippingInformation>(EXTRA_SHIPPING_INFO_DATA)
                        val shippingInfoProcessedIntent = Intent(EVENT_SHIPPING_INFO_PROCESSED)
                        if (!isValidShippingInfo(shippingInformation)) {
                            shippingInfoProcessedIntent.putExtra(EXTRA_IS_SHIPPING_INFO_VALID, false)
                        } else {
                            shippingInfoProcessedIntent
                                .putExtra(EXTRA_IS_SHIPPING_INFO_VALID, true)
                                .putParcelableArrayListExtra(
                                    EXTRA_VALID_SHIPPING_METHODS, SHIPPING_METHODS
                                )
                                .putExtra(
                                    EXTRA_DEFAULT_SHIPPING_METHOD, SHIPPING_METHODS.last()
                                )
                        }
                        localBroadcastManager.sendBroadcast(shippingInfoProcessedIntent)
                    }
        
                    private fun isValidShippingInfo(shippingInfo: ShippingInformation?): Boolean {
                        return shippingInfo?.address?.country == Locale.US.country
                    }
                }
                localBroadcastManager.registerReceiver(broadcastReceiver,
                    IntentFilter(EVENT_SHIPPING_INFO_SUBMITTED))
            }
        
            override fun onDestroy() {
                LocalBroadcastManager.getInstance(this)
                    .unregisterReceiver(broadcastReceiver)
                super.onDestroy()
            }
        
            private companion object {
                private val SHIPPING_METHODS = arrayListOf(
                    ShippingMethod("UPS Ground", "ups-ground",
                        0, "USD", "Arrives in 3-5 days"),
                    ShippingMethod("FedEx", "fedex",
                        599, "USD", "Arrives tomorrow")
                )
            }
        }
      • After, using ShippingInformationValidator and ShippingMethodsFactory

        class PaymentSessionActivity : AppCompatActivity() {
            private fun createPaymentSession(): PaymentSession {
                val customerSession = createCustomerSession()
                val paymentSession = PaymentSession(this)
                paymentSession.init(
                    listener = createPaymentSessionListener(),
                    paymentSessionConfig = createPaymentSessionConfig(),
                    savedInstanceState = savedInstanceState
                )
                return paymentSession
            }
        
            private fun createPaymentSessionConfig(): PaymentSessionConfig {
                PaymentSessionConfig.Builder()
                    .setShippingInformationValidator(ShippingInformationValidator())
                    .setShippingMethodsFactory(ShippingMethodsFactory())
                    .build()
            }
        
            private class ShippingInformationValidator :
                    PaymentSessionConfig.ShippingInformationValidator {
                override fun isValid(
                    shippingInformation: ShippingInformation
                ): Boolean {
                    return shippingInformation.address?.country == Locale.US.country
                }
        
                override fun getErrorMessage(
                    shippingInformation: ShippingInformation
                ): String {
                    return "The country must be US."
                }
            }
        
            private class ShippingMethodsFactory :
                    PaymentSessionConfig.ShippingMethodsFactory {
                override fun create(
                    shippingInformation: ShippingInformation
                ): List<ShippingMethod> {
                    return listOf(
                        ShippingMethod("UPS Ground", "ups-ground",
                            0, "USD", "Arrives in 3-5 days"),
                        ShippingMethod("FedEx", "fedex",
                            599, "USD", "Arrives tomorrow")
                    )
                }
            }
        }
    • Related to the above, PaymentFlowExtras is deleted

Migrating from versions < 12.0.0

  • Replace Stripe#createTokenSynchronous(Card) with Stripe#createCardTokenSynchronous(Card)

    // Java
    
    // before
    stripe.createTokenSynchronous(card);
    
    // after
    stripe.createCardTokenSynchronous(card);
    // Kotlin
    
    // before
    stripe.createTokenSynchronous(card)
    
    // after
    stripe.createCardTokenSynchronous(card)
  • Replace Card#getCVC() with Card#getCvc()

    // Java
    
    // before
    card.getCVC();
    
    // after
    card.getCvc();
    // Kotlin
    
    // before
    card.getCVC()
    
    // after
    card.cvc
  • Remove AddPaymentMethodActivity#EXTRA_NEW_PAYMENT_METHOD, use AddPaymentMethodActivityStarter.Result.fromIntent() instead

    // Java
    
    // before
    private PaymentMethod getPaymentMethodFromIntent(@NonNull Intent intent) {
        return intent.getParcelableExtra<PaymentMethod>(AddPaymentMethodActivity.EXTRA_NEW_PAYMENT_METHOD);
    }
    
    // after
    private PaymentMethod getPaymentMethodFromIntent(@NonNull Intent intent) {
        final AddPaymentMethodActivityStarter.Result result =
            AddPaymentMethodActivityStarter.Result.fromIntent(intent)
        return result != null ? result.paymentMethod : null;
    }
    // Kotlin
    
    // before
    private fun getPaymentMethodFromIntent(intent: Intent): PaymentMethod? {
        return intent.getParcelableExtra(AddPaymentMethodActivity.EXTRA_NEW_PAYMENT_METHOD)
    }
    
    // after
    private fun getPaymentMethodFromIntent(intent: Intent): PaymentMethod? {
        val result: AddPaymentMethodActivityStarter.Result? =
            AddPaymentMethodActivityStarter.Result.fromIntent(intent)
        return result?.paymentMethod
    }
  • Create overloaded ShippingMethod constructor with optional detail argument

    // Java
    
    // before
    ShippingMethod("FedEx", "fedex", null, 599, "USD");
    ShippingMethod("FedEx", "fedex", "Arrives tomorrow", 599, "USD");
    
    // after
    ShippingMethod("FedEx", "fedex", 599, "USD");
    ShippingMethod("FedEx", "fedex", 599, "USD", "Arrives tomorrow");
    // Kotlin
    
    // before
    ShippingMethod("FedEx", "fedex", null, 599, "USD")
    ShippingMethod("FedEx", "fedex", "Arrives tomorrow", 599, "USD")
    
    // after
    ShippingMethod("FedEx", "fedex", 599, "USD")
    ShippingMethod("FedEx", "fedex", 599, "USD", "Arrives tomorrow")
  • Payment Intent requests (i.e. requests to /v1/payment_intents) now return localized error messages

    // Java
    
    // before
    @Test
    public void testErrorMessage() {
        Locale.setDefault(Locale.GERMANY);
    
        final Stripe stripe = createStripe();
        final InvalidRequestException exception = assertThrows(
                InvalidRequestException.class,
                new ThrowingRunnable() {
                    @Override
                    public void run() throws Throwable {
                        stripe.retrievePaymentIntentSynchronous("invalid");
                    }
                });
        
        // Locale is Germany, error message is in English
        assertEquals(
                "No such payment_intent: invalid",
                exception.getStripeError().getMessage()
        );
    }
    
    // after
    @Test
    public void testErrorMessage() {
        Locale.setDefault(Locale.GERMANY);
    
        final Stripe stripe = createStripe();
        final InvalidRequestException exception = assertThrows(
                InvalidRequestException.class,
                new ThrowingRunnable() {
                    @Override
                    public void run() throws Throwable {
                        stripe.retrievePaymentIntentSynchronous("invalid");
                    }
                });
    
        // Locale is Germany, error message is in Germany
        assertEquals(
                "Keine solche payment_intent: invalid",
                exception.getStripeError().getMessage()
        );
    }

Migrating from versions < 11.0.0

  • AndroidX is required. Please read the Migrating to AndroidX guide for more information. See #1478.
  • The signatures of PaymentConfiguration.init() and PaymentConfiguration.getInstance() have been changed. They now both take a Context instance as the first argument. See #1479.
    // before
    PaymentConfiguration.init("publishable_key")
    PaymentConfiguration.getInstance()
    
    // after
    PaymentConfiguration.init(context, "publishable_key")
    PaymentConfiguration.getInstance(context)
  • Remove Stripe methods that accept a publishable key. Pass publishable key in the Stripe constructor.
    // Example
    
    // before
    val stripe = Stripe(context)
    stripe.createPaymentMethodSynchronous(params, "pk_test_demo123")
    
    // after
    val stripe = Stripe(context, "pk_test_demo123")
    stripe.createPaymentMethodSynchronous(params)
    
  • Source is immutable. All setter methods have been removed. See #1480.
  • TokenCallback and SourceCallback have been removed. Use ApiResultCallback<Token> and ApiResultCallback<Source> instead. See #1481.
  • StripeIntent#getStatus() has been removed. Use StripeIntent#getOutcome() instead.
  • PaymentIntent#getSource() has been removed. Use PaymentIntent#getPaymentMethodId() instead.
  • SetupIntent#getCustomerId() has been removed. This method was unintentionally added and always returned null.
  • The samplestore app has moved to stripe-samples/sample-store-android.
  • Remove PaymentMethodsActivity.newIntent(). Use PaymentMethodsActivityStarter#startForResult() to start PaymentMethodsActivity.
  • Remove PaymentMethodsActivity.EXTRA_SELECTED_PAYMENT. Use PaymentMethodsActivityStarter.Result#fromIntent(intent) to obtain the result of PaymentMethodsActivity.
  • Remove Stripe#createToken() with Executor argument. Use Stripe#createCardToken() instead.

Migration from versions < 10.1.0

  • You must call PaymentConfiguration.init() before calling CustomerSession.initCustomerSession().
    PaymentConfiguration.init(PUBLISHABLE_KEY);
    CustomerSession.initCustomerSession(context, ephemeralKeyProvider);

Migration from versions < 10.0.0

  • The signature of Stripe#retrievePaymentIntentSynchronous() has changed. It now takes a client_secret String instead of a PaymentIntentParams instance. See #1172.

    // before
    stripe.retrievePaymentIntentSynchronous(
          PaymentIntentParams.createRetrievePaymentIntentParams(clientSecret));
    
    // after
    stripe.retrievePaymentIntentSynchronous(clientSecret);
  • PaymentIntentParams is now ConfirmPaymentIntentParams and its method names have been simplified. See #1172.

    // before
    PaymentIntentParams.createConfirmPaymentIntentWithPaymentMethodId(
          paymentMethodId, clientSecret, returnUrl);
    
    // after
    ConfirmPaymentIntentParams.createWithPaymentMethodId(paymentMethodId, clientSecret, returnUrl);
  • All @StringDef constants have been inlined in their respective @interface. Below is an example from Card.FundingType. See #1173.

    // before
    @Retention(RetentionPolicy.SOURCE)
    @StringDef({
            FUNDING_CREDIT,
            FUNDING_DEBIT,
            FUNDING_PREPAID,
            FUNDING_UNKNOWN
    })
    public @interface FundingType { }
    public static final String FUNDING_CREDIT = "credit";
    public static final String FUNDING_DEBIT = "debit";
    public static final String FUNDING_PREPAID = "prepaid";
    public static final String FUNDING_UNKNOWN = "unknown";
    
    // after
    @Retention(RetentionPolicy.SOURCE)
    @StringDef({
            FundingType.CREDIT,
            FundingType.DEBIT,
            FundingType.PREPAID,
            FundingType.UNKNOWN
    })
    public @interface FundingType {
        String CREDIT = "credit";
        String DEBIT = "debit";
        String PREPAID = "prepaid";
        String UNKNOWN = "unknown";
    }

Migration from versions < 9.3.3

  • The enum PaymentIntent.Status is now StripeIntent.Status
  • The enum PaymentIntent.NextActionType is now StripeIntent.NextActionType

These changes should not impact Java integrations. For Kotlin integrations, please change your reference as shown in the example below.

// before
PaymentIntent.Status.Succeeded

// after
StripeIntent.Status.Succeeded

Migration from versions < 9.3.0

  • CustomerSession's Listener interfaces's onError() method now have a @NonNull errorMessage argument

    // before
    new CustomerSession.CustomerRetrievalListener() {
        @Override
        public void onError(int errorCode, @Nullable String errorMessage,
                            @Nullable StripeError stripeError) {
    
        }
    }
    
    // after
    new CustomerSession.CustomerRetrievalListener() {
        @Override
        public void onError(int errorCode, @NonNull String errorMessage,
                            @Nullable StripeError stripeError) {
    
        }
    }
  • PaymentResultListener has been removed

  • PaymentSession#completePayment() has been replaced with PaymentSession#onCompleted()

    // before
    private void chargePaymentMethod() {
        mPaymentSession.completePayment(new PaymentCompletionProvider() {
            @Override
            public void completePayment(@NonNull PaymentSessionData data,
                                        @NonNull PaymentResultListener listener) {
                // Make async request to your backend to charge the payment method.
                // Upon success, call:
                listener.onPaymentResult(PaymentResultListener.SUCCESS);
            }
        });
    }
    
    // after
    private void chargePaymentMethod() {
        // Make async request to your backend to charge the payment method.
        // Upon success, call:
        mPaymentSession.onCompleted();
    }

Migration from versions < 9.2.0

  • Card model is now immutable
    • Card#getType() is now Card#getBrand()

Migration from versions < 9.1.0

  • Standard UI components now use PaymentMethod instead of Source
    • Setting a customer's default payment method is not available for PaymentMethod objects
    • CustomerSession#getPaymentMethods() and CustomerSession#attachPaymentMethod() have been added
    • PaymentSessionData#getSelectedPaymentMethodId() is now PaymentSessionData#getPaymentMethod() and returns a PaymentMethod. See usage in the samplestore app's PaymentActivity.java.
  • Remove the following unused methods from PaymentConfiguration
    • getRequiredBillingAddressFields()
    • setRequiredBillingAddressFields()
    • getShouldUseSourcesForCards()
    • setShouldUseSourcesForCards()

Migration from versions < 9.0.0

  • minSdkVersion is now 19

  • AccountParams.createAccountParams() requires a AccountParams#BusinessType parameter

    // before
    AccountParams.createAccountParams(
      true,
      createBusinessData()
    );
    
    // after, AccountParams.BusinessType is required
    
    // for Individual entities
    AccountParams.createAccountParams(
      true,
      BusinessType.Individual,
      createBusinessData()
    );
    
    // for Company entities
    AccountParams.createAccountParams(
      true,
      BusinessType.Company,
      createBusinessData()
    );
  • CustomerSession.initCustomerSession() now has a Context parameter. Related, CustomerSession public instance methods no longer have a Context parameter.

    // before
    CustomerSession.initCustomerSession(ephemeralKeyProvider);
    CustomerSession.getInstance().setCustomerShippingInformation(this, listener);
    
    // after
    CustomerSession.initCustomerSession(this, ephemeralKeyProvider);
    CustomerSession.getInstance().setCustomerShippingInformation(listener);
  • PaymentIntent has been updated to reflect API version 2019-02-11

    • PaymentIntent.Status.RequiresSource is now PaymentIntent.Status.RequiresPaymentMethod
    • PaymentIntent.Status.RequiresSourceAction is now PaymentIntent.Status.RequiresAction
    • PaymentIntent.NextActionType.AuthorizeWithUrl has been removed
    • PaymentIntent#getNextSourceAction() is now PaymentIntent#getNextAction()
    • PaymentIntent#getAuthorizationUrl() is now PaymentIntent#getRedirectUrl()
    • PaymentIntent#requiresAction() has been added as a convenience
    • PaymentIntent#getStatus() now returns a PaymentIntent.Status enum value instead of a String
  • Address is now immutable and its setters have been removed. Use Address.Builder to create a new Address object.

Migrating from versions < 7.0.0

  • Remove Bitcoin source support because Stripe no longer processes Bitcoin payments
    • Sources can no longer have a "BITCOIN" source type. These sources will now be interpreted as "UNKNOWN".
    • You can no longer createBitcoinParams. Please use a different payment method.

Migrating from versions < 5.0.0

  • StripeApiHandler methods can no longer be called directly.
  • PaymentConfiguration now stores your public key and is depended upon for CustomerSession.
  • Many Utils classes have been migrated to package-private access.

Migrating from versions < 4.0.0

  • Instantiation of a Stripe object can no longer throw an AuthenticationException.
    • Any time you were instantiating a Stripe object in a try/catch block will be simplified.
    Stripe stripe;
    try {
       stripe = new Stripe(mContext, MY_PUBLISHABLE_KEY);
    } catch (AuthenticationException authEx) {
       // This never happens because you check your key.
    }
    now becomes
    Stripe stripe = new Stripe(mContext, MY_PUBLISHABLE_KEY);
  • Stripe#setDefaultPublishableKey(String key) has similarly been changed, and no longer needs to be wrapped.
  • Both methods can still throw an IllegalArgumentException if an invalid key is used, but as a runtime exception, that does not need to be wrapped.
  • AuthenticationException will now only be thrown if you attempt to create a Token or Source with an invalid key.