diff --git a/src/main/java/com/apple/itunes/storekit/client/BaseAppStoreServerAPIClient.java b/src/main/java/com/apple/itunes/storekit/client/BaseAppStoreServerAPIClient.java
index 8e9a8151..d6ebc09d 100644
--- a/src/main/java/com/apple/itunes/storekit/client/BaseAppStoreServerAPIClient.java
+++ b/src/main/java/com/apple/itunes/storekit/client/BaseAppStoreServerAPIClient.java
@@ -2,6 +2,18 @@
package com.apple.itunes.storekit.client;
+import com.apple.itunes.storekit.model.AdvancedCommerceRequestRefundRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceRequestRefundResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionCancelRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionCancelResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionChangeMetadataRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionChangeMetadataResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionMigrateRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionMigrateResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionPriceChangeRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionPriceChangeResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionRevokeRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionRevokeResponse;
import com.apple.itunes.storekit.model.AppTransactionInfoResponse;
import com.apple.itunes.storekit.model.CheckTestNotificationResponse;
import com.apple.itunes.storekit.model.ConsumptionRequest;
@@ -623,6 +635,90 @@ public void finishTransaction(String transactionId) throws APIException, IOExcep
makeHttpCall("/inApps/v1/transactions/" + transactionId + "/finish", "POST", Map.of(), null, Void.class, null);
}
+ /**
+ * Increase or decrease the price of an auto-renewable subscription, a bundle, or individual items within a subscription at the next renewal.
+ *
+ * @param transactionId A transaction identifier of the auto-renewable subscription that is subject to the price change.
+ * @param subscriptionPriceChangeRequest The request body that contains the details of the price change.
+ * @return A response that contains signed JWS renewal and JWS transaction information after a subscription price change request.
+ * @throws APIException If a response was returned indicating the request could not be processed
+ * @throws IOException If an exception was thrown while making the request
+ * @see Change Subscription Price
+ */
+ public AdvancedCommerceSubscriptionPriceChangeResponse changeSubscriptionPrice(String transactionId, AdvancedCommerceSubscriptionPriceChangeRequest subscriptionPriceChangeRequest) throws APIException, IOException {
+ return makeHttpCall("/advancedCommerce/v1/subscription/changePrice/" + transactionId, "POST", Map.of(), subscriptionPriceChangeRequest, AdvancedCommerceSubscriptionPriceChangeResponse.class, JSON);
+ }
+
+ /**
+ * Turn off automatic renewal to cancel a customer’s auto-renewable subscription.
+ *
+ * @param transactionId The transaction identifier of the auto-renewable subscription to cancel.
+ * @param subscriptionCancelRequest The request body that includes information about the subscription to cancel.
+ * @return The response body for a successful subscription cancellation.
+ * @throws APIException If a response was returned indicating the request could not be processed
+ * @throws IOException If an exception was thrown while making the request
+ * @see Cancel a Subscription
+ */
+ public AdvancedCommerceSubscriptionCancelResponse cancelSubscription(String transactionId, AdvancedCommerceSubscriptionCancelRequest subscriptionCancelRequest) throws APIException, IOException {
+ return makeHttpCall("/advancedCommerce/v1/subscription/cancel/" + transactionId, "POST", Map.of(), subscriptionCancelRequest, AdvancedCommerceSubscriptionCancelResponse.class, JSON);
+ }
+
+ /**
+ * Immediately cancel a customer’s subscription and all the items that are included in the subscription, and request a full or prorated refund.
+ *
+ * @param transactionId The transaction identifier of the auto-renewable subscription to revoke.
+ * @param subscriptionRevokeRequest The request body you provide to terminate a subscription and all its items immediately.
+ * @return The response body for a successful revoke-subscription request.
+ * @throws APIException If a response was returned indicating the request could not be processed
+ * @throws IOException If an exception was thrown while making the request
+ * @see Revoke Subscription
+ */
+ public AdvancedCommerceSubscriptionRevokeResponse revokeSubscription(String transactionId, AdvancedCommerceSubscriptionRevokeRequest subscriptionRevokeRequest) throws APIException, IOException {
+ return makeHttpCall("/advancedCommerce/v1/subscription/revoke/" + transactionId, "POST", Map.of(), subscriptionRevokeRequest, AdvancedCommerceSubscriptionRevokeResponse.class, JSON);
+ }
+
+ /**
+ * Request a refund for a one-time charge or subscription transaction.
+ *
+ * @param transactionId The transaction identifier for which you request a refund.
+ * @param requestRefundRequest The request body for requesting a refund for a transaction.
+ * @return The response body for a transaction refund request.
+ * @throws APIException If a response was returned indicating the request could not be processed
+ * @throws IOException If an exception was thrown while making the request
+ * @see Request Transaction Refund
+ */
+ public AdvancedCommerceRequestRefundResponse requestTransactionRefund(String transactionId, AdvancedCommerceRequestRefundRequest requestRefundRequest) throws APIException, IOException {
+ return makeHttpCall("/advancedCommerce/v1/transaction/requestRefund/" + transactionId, "POST", Map.of(), requestRefundRequest, AdvancedCommerceRequestRefundResponse.class, JSON);
+ }
+
+ /**
+ * Update the SKU, display name, and description associated with a subscription, without affecting the subscription’s billing or its service.
+ *
+ * @param transactionId The transaction identifier of the auto-renewable subscription to get changes to its metadata.
+ * @param subscriptionChangeMetadataRequest The request body that contains the metadata changes.
+ * @return The response body for a successful subscription metadata change.
+ * @throws APIException If a response was returned indicating the request could not be processed
+ * @throws IOException If an exception was thrown while making the request
+ * @see Change Subscription Metadata
+ */
+ public AdvancedCommerceSubscriptionChangeMetadataResponse changeSubscriptionMetadata(String transactionId, AdvancedCommerceSubscriptionChangeMetadataRequest subscriptionChangeMetadataRequest) throws APIException, IOException {
+ return makeHttpCall("/advancedCommerce/v1/subscription/changeMetadata/" + transactionId, "POST", Map.of(), subscriptionChangeMetadataRequest, AdvancedCommerceSubscriptionChangeMetadataResponse.class, JSON);
+ }
+
+ /**
+ * Migrate a subscription that a customer purchased through Apple In-App Purchase to a subscription you manage using the Advanced Commerce API.
+ *
+ * @param transactionId The transaction identifier of the auto-renewable subscription to migrate.
+ * @param subscriptionMigrateRequest The request body that contains the details for the migration.
+ * @return A response that contains signed renewal and transaction information after a subscription successfully migrates to the Advanced Commerce API.
+ * @throws APIException If a response was returned indicating the request could not be processed
+ * @throws IOException If an exception was thrown while making the request
+ * @see Migrate a Subscription to Advanced Commerce API
+ */
+ public AdvancedCommerceSubscriptionMigrateResponse migrateSubscriptionToAdvancedCommerceAPI(String transactionId, AdvancedCommerceSubscriptionMigrateRequest subscriptionMigrateRequest) throws APIException, IOException {
+ return makeHttpCall("/advancedCommerce/v1/subscription/migrate/" + transactionId, "POST", Map.of(), subscriptionMigrateRequest, AdvancedCommerceSubscriptionMigrateResponse.class, JSON);
+ }
+
protected interface HttpResponseInterface extends Closeable {
/**
* @return The HTTP status code of the response
diff --git a/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java b/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java
index f6b1a5d3..ceda9c57 100644
--- a/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java
+++ b/src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java
@@ -3,6 +3,28 @@
package com.apple.itunes.storekit.client;
import com.apple.itunes.storekit.model.AccountTenure;
+import com.apple.itunes.storekit.model.AdvancedCommerceEffective;
+import com.apple.itunes.storekit.model.AdvancedCommerceRefundReason;
+import com.apple.itunes.storekit.model.AdvancedCommerceRefundType;
+import com.apple.itunes.storekit.model.AdvancedCommerceRequestInfo;
+import com.apple.itunes.storekit.model.AdvancedCommerceRequestRefundItem;
+import com.apple.itunes.storekit.model.AdvancedCommerceRequestRefundRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceRequestRefundResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionCancelRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionCancelResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionChangeMetadataDescriptors;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionChangeMetadataItem;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionChangeMetadataRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionChangeMetadataResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionMigrateDescriptors;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionMigrateItem;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionMigrateRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionMigrateResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionPriceChangeItem;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionPriceChangeRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionPriceChangeResponse;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionRevokeRequest;
+import com.apple.itunes.storekit.model.AdvancedCommerceSubscriptionRevokeResponse;
import com.apple.itunes.storekit.model.AppTransactionInfoResponse;
import com.apple.itunes.storekit.model.BulletPoint;
import com.apple.itunes.storekit.model.CheckTestNotificationResponse;
@@ -1313,6 +1335,267 @@ public void testGetPerformanceTestResults() throws IOException, APIException {
Assertions.assertEquals(Map.of("TIMED_OUT", 1, "NO_RESPONSE", 1), response.getRawFailures());
}
+ @Test
+ public void testChangeSubscriptionPrice() throws IOException, APIException {
+ AppStoreServerAPIClient client = getClientWithBody("models/advancedCommerceSubscriptionPriceChangeResponse.json", request -> {
+ Assertions.assertEquals("POST", request.method());
+ Assertions.assertEquals("/advancedCommerce/v1/subscription/changePrice/4124214", request.url().encodedPath());
+ RequestBody body = request.body();
+ Assertions.assertNotNull(body);
+ Assertions.assertEquals(expectedMediaType, body.contentType());
+ Buffer buffer = new Buffer();
+ try {
+ body.writeTo(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Map root;
+ try {
+ root = new ObjectMapper().readValue(buffer.readUtf8(), Map.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ Assertions.assertEquals("7c80bb86-f892-4b21-a919-1357811d6c4f", ((Map, ?>) root.get("requestInfo")).get("requestReferenceId"));
+ Assertions.assertEquals("USD", root.get("currency"));
+ Assertions.assertEquals("USA", root.get("storefront"));
+ Map, ?> item = (Map, ?>) ((List>) root.get("items")).get(0);
+ Assertions.assertEquals("AD_FREE_1M", item.get("SKU"));
+ Assertions.assertEquals(12990, ((Number) item.get("price")).intValue());
+ Assertions.assertEquals(List.of("ADVANCED_FEATURES_1M"), item.get("dependentSKUs"));
+ });
+
+ AdvancedCommerceSubscriptionPriceChangeRequest priceChangeRequest = new AdvancedCommerceSubscriptionPriceChangeRequest(
+ new AdvancedCommerceRequestInfo(UUID.fromString("7c80bb86-f892-4b21-a919-1357811d6c4f")),
+ List.of(new AdvancedCommerceSubscriptionPriceChangeItem("AD_FREE_1M", 12990L)
+ .dependentSKUs(List.of("ADVANCED_FEATURES_1M"))))
+ .currency("USD")
+ .storefront("USA");
+
+ AdvancedCommerceSubscriptionPriceChangeResponse response = client.changeSubscriptionPrice("4124214", priceChangeRequest);
+
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("signed_renewal_info", response.getSignedRenewalInfo());
+ Assertions.assertEquals("signed_transaction_info", response.getSignedTransactionInfo());
+ }
+
+ @Test
+ public void testCancelSubscription() throws IOException, APIException {
+ AppStoreServerAPIClient client = getClientWithBody("models/advancedCommerceSubscriptionCancelResponse.json", request -> {
+ Assertions.assertEquals("POST", request.method());
+ Assertions.assertEquals("/advancedCommerce/v1/subscription/cancel/4124214", request.url().encodedPath());
+ RequestBody body = request.body();
+ Assertions.assertNotNull(body);
+ Assertions.assertEquals(expectedMediaType, body.contentType());
+ Buffer buffer = new Buffer();
+ try {
+ body.writeTo(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Map root;
+ try {
+ root = new ObjectMapper().readValue(buffer.readUtf8(), Map.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ Assertions.assertEquals("932c6903-0ab8-4469-9f21-015f6fab013c", ((Map, ?>) root.get("requestInfo")).get("requestReferenceId"));
+ Assertions.assertEquals("USA", root.get("storefront"));
+ });
+
+ AdvancedCommerceSubscriptionCancelRequest cancelRequest = new AdvancedCommerceSubscriptionCancelRequest(
+ new AdvancedCommerceRequestInfo(UUID.fromString("932c6903-0ab8-4469-9f21-015f6fab013c")))
+ .storefront("USA");
+
+ AdvancedCommerceSubscriptionCancelResponse response = client.cancelSubscription("4124214", cancelRequest);
+
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("signed_renewal_info", response.getSignedRenewalInfo());
+ Assertions.assertEquals("signed_transaction_info", response.getSignedTransactionInfo());
+ }
+
+ @Test
+ public void testRevokeSubscription() throws IOException, APIException {
+ AppStoreServerAPIClient client = getClientWithBody("models/advancedCommerceSubscriptionRevokeResponse.json", request -> {
+ Assertions.assertEquals("POST", request.method());
+ Assertions.assertEquals("/advancedCommerce/v1/subscription/revoke/4124214", request.url().encodedPath());
+ RequestBody body = request.body();
+ Assertions.assertNotNull(body);
+ Assertions.assertEquals(expectedMediaType, body.contentType());
+ Buffer buffer = new Buffer();
+ try {
+ body.writeTo(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Map root;
+ try {
+ root = new ObjectMapper().readValue(buffer.readUtf8(), Map.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ Assertions.assertEquals("932c6903-0ab8-4469-9f21-015f6fab013c", ((Map, ?>) root.get("requestInfo")).get("requestReferenceId"));
+ Assertions.assertEquals("UNINTENDED_PURCHASE", root.get("refundReason"));
+ Assertions.assertEquals("PRORATED", root.get("refundType"));
+ Assertions.assertTrue((Boolean) root.get("refundRiskingPreference"));
+ Assertions.assertEquals("USA", root.get("storefront"));
+ });
+
+ AdvancedCommerceSubscriptionRevokeRequest revokeRequest = new AdvancedCommerceSubscriptionRevokeRequest(
+ new AdvancedCommerceRequestInfo(UUID.fromString("932c6903-0ab8-4469-9f21-015f6fab013c")),
+ true,
+ AdvancedCommerceRefundReason.UNINTENDED_PURCHASE,
+ AdvancedCommerceRefundType.PRORATED.getValue())
+ .storefront("USA");
+
+ AdvancedCommerceSubscriptionRevokeResponse response = client.revokeSubscription("4124214", revokeRequest);
+
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("signed_renewal_info", response.getSignedRenewalInfo());
+ Assertions.assertEquals("signed_transaction_info", response.getSignedTransactionInfo());
+ }
+
+ @Test
+ public void testRequestTransactionRefund() throws IOException, APIException {
+ AppStoreServerAPIClient client = getClientWithBody("models/advancedCommerceRequestRefundResponse.json", request -> {
+ Assertions.assertEquals("POST", request.method());
+ Assertions.assertEquals("/advancedCommerce/v1/transaction/requestRefund/4124214", request.url().encodedPath());
+ RequestBody body = request.body();
+ Assertions.assertNotNull(body);
+ Assertions.assertEquals(expectedMediaType, body.contentType());
+ Buffer buffer = new Buffer();
+ try {
+ body.writeTo(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Map root;
+ try {
+ root = new ObjectMapper().readValue(buffer.readUtf8(), Map.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ Assertions.assertEquals("932c6903-0ab8-4469-9f21-015f6fab013c", ((Map, ?>) root.get("requestInfo")).get("requestReferenceId"));
+ Assertions.assertEquals("USD", root.get("currency"));
+ Assertions.assertEquals("USA", root.get("storefront"));
+ Assertions.assertTrue((Boolean) root.get("refundRiskingPreference"));
+ Map, ?> item = (Map, ?>) ((List>) root.get("items")).get(0);
+ Assertions.assertEquals("AD_FREE_1M", item.get("SKU"));
+ Assertions.assertEquals("UNSATISFIED_WITH_PURCHASE", item.get("refundReason"));
+ Assertions.assertEquals("FULL", item.get("refundType"));
+ Assertions.assertTrue((Boolean) item.get("revoke"));
+ });
+
+ AdvancedCommerceRequestRefundRequest requestRefundRequest = new AdvancedCommerceRequestRefundRequest(
+ List.of(new AdvancedCommerceRequestRefundItem("AD_FREE_1M", AdvancedCommerceRefundReason.UNSATISFIED_WITH_PURCHASE, AdvancedCommerceRefundType.FULL, true)),
+ true,
+ new AdvancedCommerceRequestInfo(UUID.fromString("932c6903-0ab8-4469-9f21-015f6fab013c")))
+ .currency("USD")
+ .storefront("USA");
+
+ AdvancedCommerceRequestRefundResponse response = client.requestTransactionRefund("4124214", requestRefundRequest);
+
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("signed_transaction_info_value", response.getSignedTransactionInfo());
+ }
+
+ @Test
+ public void testChangeSubscriptionMetadata() throws IOException, APIException {
+ AppStoreServerAPIClient client = getClientWithBody("models/advancedCommerceSubscriptionChangeMetadataResponse.json", request -> {
+ Assertions.assertEquals("POST", request.method());
+ Assertions.assertEquals("/advancedCommerce/v1/subscription/changeMetadata/4124214", request.url().encodedPath());
+ RequestBody body = request.body();
+ Assertions.assertNotNull(body);
+ Assertions.assertEquals(expectedMediaType, body.contentType());
+ Buffer buffer = new Buffer();
+ try {
+ body.writeTo(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Map root;
+ try {
+ root = new ObjectMapper().readValue(buffer.readUtf8(), Map.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ Assertions.assertEquals("932c6903-0ab8-4469-9f21-015f6fab013c", ((Map, ?>) root.get("requestInfo")).get("requestReferenceId"));
+ Assertions.assertEquals("USA", root.get("storefront"));
+ Assertions.assertEquals("C003-00-1", root.get("taxCode"));
+ Map, ?> descriptors = (Map, ?>) root.get("descriptors");
+ Assertions.assertEquals("NEXT_BILL_CYCLE", descriptors.get("effective"));
+ Assertions.assertEquals("Remove ads and unlock advanced features.", descriptors.get("description"));
+ Assertions.assertEquals("Ad-free package", descriptors.get("displayName"));
+ Map, ?> item = (Map, ?>) ((List>) root.get("items")).get(0);
+ Assertions.assertEquals("AD_FREE_1M", item.get("currentSKU"));
+ Assertions.assertEquals("NEXT_BILL_CYCLE", item.get("effective"));
+ Assertions.assertEquals("AD_FREE_1M_V2", item.get("SKU"));
+ });
+
+ AdvancedCommerceSubscriptionChangeMetadataRequest changeMetadataRequest = new AdvancedCommerceSubscriptionChangeMetadataRequest(
+ new AdvancedCommerceRequestInfo(UUID.fromString("932c6903-0ab8-4469-9f21-015f6fab013c")))
+ .descriptors(new AdvancedCommerceSubscriptionChangeMetadataDescriptors(AdvancedCommerceEffective.NEXT_BILL_CYCLE)
+ .description("Remove ads and unlock advanced features.")
+ .displayName("Ad-free package"))
+ .items(List.of(new AdvancedCommerceSubscriptionChangeMetadataItem("AD_FREE_1M", AdvancedCommerceEffective.NEXT_BILL_CYCLE)
+ .sku("AD_FREE_1M_V2")))
+ .storefront("USA")
+ .taxCode("C003-00-1");
+
+ AdvancedCommerceSubscriptionChangeMetadataResponse response = client.changeSubscriptionMetadata("4124214", changeMetadataRequest);
+
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("signed_renewal_info", response.getSignedRenewalInfo());
+ Assertions.assertEquals("signed_transaction_info", response.getSignedTransactionInfo());
+ }
+
+ @Test
+ public void testMigrateSubscriptionToAdvancedCommerceAPI() throws IOException, APIException {
+ AppStoreServerAPIClient client = getClientWithBody("models/advancedCommerceSubscriptionMigrateResponse.json", request -> {
+ Assertions.assertEquals("POST", request.method());
+ Assertions.assertEquals("/advancedCommerce/v1/subscription/migrate/4124214", request.url().encodedPath());
+ RequestBody body = request.body();
+ Assertions.assertNotNull(body);
+ Assertions.assertEquals(expectedMediaType, body.contentType());
+ Buffer buffer = new Buffer();
+ try {
+ body.writeTo(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Map root;
+ try {
+ root = new ObjectMapper().readValue(buffer.readUtf8(), Map.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ Assertions.assertEquals("932c6903-0ab8-4469-9f21-015f6fab013c", ((Map, ?>) root.get("requestInfo")).get("requestReferenceId"));
+ Assertions.assertEquals("com.example.base", root.get("targetProductId"));
+ Assertions.assertEquals("C003-00-1", root.get("taxCode"));
+ Assertions.assertEquals("USA", root.get("storefront"));
+ Map, ?> descriptors = (Map, ?>) root.get("descriptors");
+ Assertions.assertEquals("Remove ads and unlock advanced features.", descriptors.get("description"));
+ Assertions.assertEquals("Ad-free package", descriptors.get("displayName"));
+ Map, ?> item = (Map, ?>) ((List>) root.get("items")).get(0);
+ Assertions.assertEquals("AD_FREE_1M", item.get("SKU"));
+ Assertions.assertEquals("Remove ads for the service.", item.get("description"));
+ Assertions.assertEquals("Ad-free monthly plan", item.get("displayName"));
+ });
+
+ AdvancedCommerceSubscriptionMigrateRequest migrateRequest = new AdvancedCommerceSubscriptionMigrateRequest(
+ new AdvancedCommerceRequestInfo(UUID.fromString("932c6903-0ab8-4469-9f21-015f6fab013c")),
+ new AdvancedCommerceSubscriptionMigrateDescriptors("Remove ads and unlock advanced features.", "Ad-free package"),
+ List.of(new AdvancedCommerceSubscriptionMigrateItem("AD_FREE_1M", "Remove ads for the service.", "Ad-free monthly plan")),
+ "com.example.base",
+ "C003-00-1")
+ .storefront("USA");
+
+ AdvancedCommerceSubscriptionMigrateResponse response = client.migrateSubscriptionToAdvancedCommerceAPI("4124214", migrateRequest);
+
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("signed_renewal_info_value", response.getSignedRenewalInfo());
+ Assertions.assertEquals("signed_transaction_info_value", response.getSignedTransactionInfo());
+ }
+
public AppStoreServerAPIClient getClientWithBody(String path, Consumer requestVerifier) throws IOException {
String body = TestingUtility.readFile(path);
return getAppStoreServerAPIClient(body, requestVerifier);