-
Notifications
You must be signed in to change notification settings - Fork 389
Migration guide for v9
Note: starting from stripe-java version 8, API requests are made with a version header not according to your account API version, but that specified by this library. If you are upgrading from stripe-java version 7 or below, please see version 8 migration guide here.
stripe-java version 9 drops supports for jdk 7. Majority of users on jdk 8 and above will not be affected. Additionally, this new major version introduces typed parameters and improves event deserialization. Both are breaking backward-compatibility, but only minor migration effort is expected.
Currently, API calls rely on untyped parameters and unsafe parameters can be passed. Now, each API call has specific typed parameters with builder-style constructors.
The new methods with typed parameters simply overloads the current method replacing the untyped map object with the typed one. The library now supports both usage.
Current:
Map<String, Object> untypedParams = new HashMap<>();
params.put("amount", 100);
params.put("currency", "usd");
params.put("source", "card_123");
Charge charge = Charge.create(untypedParams);New:
ChargeCreateParams typedParams = ChargeCreateParams.builder()
.setAmount(100L)
.setCurrency("usd")
.setSource("card_123")
.build();
Charge charge = Charge.create(typedParams);One breaking change arises from overloading method names. Existing integrations passing null to
the parameters argument will see complier error due to ambiguous types; the compiler does not
know whether null is a null untyped map, or null typed parameters. You should instead create an
empty parameters with either an empty map, or a built typed parameters without any values set.
To ensure safe migration, consider testing equality between your current untyped Map<String, Object> parameters and the new typed parameters with toMap() to get the untyped representation.
Map<String, Object> untypedParams = getUntypedParams();
ApiRequestParams typedParams = getTypedParams();
Map<String, Object> typedParamsAsMap = typedParams.toMap();
assertEquals(untypedParams, typedParamsAsMap);- When parameters have nested objects, there are builders for each one via
builder()method. Here,SkuCreateParams.Inventoryis separately built, and used in settingSkuCreateParamsroot-level parameters. Note that nested objects are not shared among parameters of different methods. For instance, parameter class to update SKUSkuUpdateParamsseparately has its nested object ofSkuUpdateParams.Inventorywhich can differ from that in parameters to create SKU.
SkuCreateParams.Inventory inventoryParams = SkuCreateParams.Inventory.builder()
.setQuantity(4L)
.build();
SkuCreateParams createParams = SkuCreateParams.builder()
.setPrice(99L)
.setCurrency("usd")
.setInventory(inventoryParams)
.setProduct("prod_123")
.build();
Sku sku = Sku.create(createParams);- When parameters require a list or a map, there are similar interfaces to
addandaddAllinList<T>, andputandputAllinMap<String, T>.
PaymentIntentRetrieveParams typedParams = PaymentIntentRetrieveParams.builder()
// support both adding individual element or the whole list
.addExpand("application")
.addExpand("on_behalf_of")
.addAllExpand(Arrays.asList("review", "source", "transfer_data.destination"))
.build();
CustomerUpdateParams customerUpdateParams = CustomerUpdateParams.builder()
// support both putting individual entry or the whole map
.putMetadata("key1", "value1")
.putAllMetadata(ImmutableMap.of("key2", "value2"))
.build();- When parameters require enums, there are specific enums for each parameter.
WebhookEndpointCreateParams createParams = WebhookEndpointCreateParams
.builder()
.addEnabledEvent(WebhookEndpointCreateParams.EnabledEvent.CHARGE__SUCCEEDED)
.setApiVersion(WebhookEndpointCreateParams.ApiVersion.VERSION_2019_03_14)
.setUrl("https://myEndPoint.com")
.build();This has been a long-standing ask from the community, so we thank you for your patience!
- Currently, untyped map
Event#previousAttributesmay contain valueObject[]to represent a list. NowList<Object>is the deserialized object for list content. This addresses the issue. - Currently,
EventDataObjectDeserializer#getObjectreturnsStripeObjectwhich can benullwhen there is API version mismatch betweenstripe-javapinned versionStripe#API_VERSIONand the event versionEvent#apiVersion. Now, with jdk8 and above,Optional<StripeObject>is returned, and the check methoddeserializewhether deserialization is successful is removed from the public call.
Current:
Event event = getEventFromWebhookOrEndpoint();
EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
if (dataObjectDeserializer.deserialize()) {
StripeObject stripeObject = dataObjectDeserializer.getObject();
doSomething(stripeObject);
}New:
Event event = getEventFromWebhookOrEndpoint();
EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
if (dataObjectDeserializer.getObject().isPresent()) {
StripeObject stripeObject = dataObjectDeserializer.getObject().get();
doSomething(stripeObject);
} else {
// Handle absent data object with `deserializeUnsafe` or `deserializeUnsafeWith`.
// Please see the usage details in java doc on the class `EventDataObjectDeserializer`.
}-
ScheduledQueryRun#Erroris renamed toScheduledQueryRun#RunErrorto prevent potential ambiguous reference to basicjava.lang.Error