Skip to content

Commit eccbdda

Browse files
Merge pull request #201 from riyazpanjwani/main
Adding support for Get App Transaction Info endpoint
2 parents a330d61 + 806a80b commit eccbdda

File tree

8 files changed

+188
-0
lines changed

8 files changed

+188
-0
lines changed

src/main/java/com/apple/itunes/storekit/client/APIError.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,13 @@ public enum APIError {
496496
*/
497497
MESSAGE_NOT_FOUND(4040015L),
498498

499+
/**
500+
* An error response that indicates an app transaction doesn’t exist for the specified customer.
501+
*
502+
* @see <a href="https://developer.apple.com/documentation/appstoreserverapi/apptransactiondoesnotexisterror">AppTransactionDoesNotExistError</a>
503+
*/
504+
APP_TRANSACTION_DOES_NOT_EXIST_ERROR(4040019L),
505+
499506
/**
500507
* An error that indicates the image identifier already exists.
501508
*

src/main/java/com/apple/itunes/storekit/client/BaseAppStoreServerAPIClient.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
package com.apple.itunes.storekit.client;
44

5+
import com.apple.itunes.storekit.model.AppTransactionInfoResponse;
56
import com.apple.itunes.storekit.model.CheckTestNotificationResponse;
67
import com.apple.itunes.storekit.model.ConsumptionRequest;
78
import com.apple.itunes.storekit.model.DefaultConfigurationRequest;
@@ -485,6 +486,19 @@ public void deleteDefaultMessage(String productId, String locale) throws APIExce
485486
makeHttpCall("/inApps/v1/messaging/default/" + productId + "/" + locale, "DELETE", Map.of(), null, Void.class, null);
486487
}
487488

489+
/**
490+
* Get a customer’s app transaction information for your app.
491+
*
492+
* @param transactionId Any originalTransactionId, transactionId or appTransactionId that belongs to the customer for your app.
493+
* @return A response that contains signed app transaction information for a customer.
494+
* @throws APIException If a response was returned indicating the request could not be processed.
495+
* @throws IOException If an exception was thrown while making the request.
496+
* @see <a href="https://developer.apple.com/documentation/appstoreserverapi/get-app-transaction-info">Get App Transaction Info</a>
497+
*/
498+
public AppTransactionInfoResponse getAppTransactionInfo(String transactionId) throws APIException, IOException {
499+
return makeHttpCall("/inApps/v1/transactions/appTransactions/" + transactionId, "GET", Map.of(), null, AppTransactionInfoResponse.class, null);
500+
}
501+
488502
protected interface HttpResponseInterface extends Closeable {
489503
/**
490504
* @return The HTTP status code of the response
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (c) 2025 Apple Inc. Licensed under MIT License.
2+
3+
package com.apple.itunes.storekit.model;
4+
5+
import com.fasterxml.jackson.annotation.JsonAnySetter;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
8+
import java.util.Map;
9+
import java.util.Objects;
10+
11+
/**
12+
* A response that contains signed app transaction information for a customer.
13+
*
14+
* @see <a href="https://developer.apple.com/documentation/appstoreserverapi/apptransactioninforesponse">AppTransactionInfoResponse</a>
15+
*/
16+
public class AppTransactionInfoResponse {
17+
private static final String SERIALIZED_NAME_SIGNED_APP_TRANSACTION_INFO = "signedAppTransactionInfo";
18+
19+
@JsonProperty(SERIALIZED_NAME_SIGNED_APP_TRANSACTION_INFO)
20+
private String signedAppTransactionInfo;
21+
@JsonAnySetter
22+
private Map<String, Object> unknownFields;
23+
24+
public AppTransactionInfoResponse() {
25+
}
26+
27+
public AppTransactionInfoResponse signedAppTransactionInfo(String signedAppTransactionInfo) {
28+
this.signedAppTransactionInfo = signedAppTransactionInfo;
29+
return this;
30+
}
31+
32+
/**
33+
* A customer’s app transaction information, signed by Apple, in JSON Web Signature (JWS) format.
34+
*
35+
* @return signedAppTransactionInfo
36+
* @see <a href="https://developer.apple.com/documentation/appstoreserverapi/jwsapptransaction">JWSAppTransaction</a>
37+
**/
38+
public String getSignedAppTransactionInfo() {
39+
return signedAppTransactionInfo;
40+
}
41+
42+
public void setSignedAppTransactionInfo(String signedAppTransactionInfo) {
43+
this.signedAppTransactionInfo = signedAppTransactionInfo;
44+
}
45+
46+
public AppTransactionInfoResponse unknownFields(Map<String, Object> unknownFields) {
47+
this.unknownFields = unknownFields;
48+
return this;
49+
}
50+
51+
/**
52+
* Fields that are not recognized for this object.
53+
*
54+
* @return A map of JSON keys to objects.
55+
*/
56+
public Map<String, Object> getUnknownFields() {
57+
return unknownFields;
58+
}
59+
60+
public void setUnknownFields(Map<String, Object> unknownFields) {
61+
this.unknownFields = unknownFields;
62+
}
63+
64+
@Override
65+
public boolean equals(Object o) {
66+
if (this == o) {
67+
return true;
68+
}
69+
if (o == null || getClass() != o.getClass()) {
70+
return false;
71+
}
72+
AppTransactionInfoResponse that = (AppTransactionInfoResponse) o;
73+
return Objects.equals(this.signedAppTransactionInfo, that.signedAppTransactionInfo) &&
74+
Objects.equals(this.unknownFields, that.unknownFields);
75+
}
76+
77+
@Override
78+
public int hashCode() {
79+
return Objects.hash(signedAppTransactionInfo, unknownFields);
80+
}
81+
82+
@Override
83+
public String toString() {
84+
return "AppTransactionInfoResponse{" +
85+
"signedAppTransactionInfo='" + signedAppTransactionInfo + '\'' +
86+
", unknownFields=" + unknownFields +
87+
'}';
88+
}
89+
}

src/test/java/com/apple/itunes/storekit/client/AppStoreServerAPIClientTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package com.apple.itunes.storekit.client;
44

55
import com.apple.itunes.storekit.model.AccountTenure;
6+
import com.apple.itunes.storekit.model.AppTransactionInfoResponse;
67
import com.apple.itunes.storekit.model.CheckTestNotificationResponse;
78
import com.apple.itunes.storekit.model.ConsumptionRequest;
89
import com.apple.itunes.storekit.model.ConsumptionStatus;
@@ -913,6 +914,68 @@ public void testTransactionIdNotOriginalTransactionId() throws IOException {
913914
Assertions.fail();
914915
}
915916

917+
@Test
918+
public void testGetAppTransactionInfo() throws APIException, IOException {
919+
AppStoreServerAPIClient client = getClientWithBody("models/appTransactionInfoResponse.json", request -> {
920+
Assertions.assertEquals("GET", request.method());
921+
Assertions.assertEquals("/inApps/v1/transactions/appTransactions/1234", request.url().encodedPath());
922+
Assertions.assertNull(request.body());
923+
});
924+
925+
AppTransactionInfoResponse appTransactionInfoResponse = client.getAppTransactionInfo("1234");
926+
927+
Assertions.assertNotNull(appTransactionInfoResponse);
928+
Assertions.assertEquals("signed_app_transaction_info_value", appTransactionInfoResponse.getSignedAppTransactionInfo());
929+
}
930+
931+
@Test
932+
public void testGetAppTransactionInfoInvalidTransactionIdError() throws IOException {
933+
String body = TestingUtility.readFile("models/invalidTransactionIdError.json");
934+
AppStoreServerAPIClient client = getAppStoreServerAPIClient(body, request -> {}, 400);
935+
try {
936+
client.getAppTransactionInfo("invalid_transaction_id");
937+
} catch (APIException e) {
938+
Assertions.assertEquals(400, e.getHttpStatusCode());
939+
Assertions.assertEquals(APIError.INVALID_TRANSACTION_ID, e.getApiError());
940+
Assertions.assertEquals(4000006L, e.getRawApiError());
941+
Assertions.assertEquals("Invalid transaction id.", e.getApiErrorMessage());
942+
return;
943+
}
944+
Assertions.fail();
945+
}
946+
947+
@Test
948+
public void testGetAppTransactionInfoAppTransactionDoesNotExistError() throws IOException {
949+
String body = TestingUtility.readFile("models/appTransactionDoesNotExistError.json");
950+
AppStoreServerAPIClient client = getAppStoreServerAPIClient(body, request -> {}, 404);
951+
try {
952+
client.getAppTransactionInfo("nonexistent_transaction_id");
953+
} catch (APIException e) {
954+
Assertions.assertEquals(404, e.getHttpStatusCode());
955+
Assertions.assertEquals(APIError.APP_TRANSACTION_DOES_NOT_EXIST_ERROR, e.getApiError());
956+
Assertions.assertEquals(4040019L, e.getRawApiError());
957+
Assertions.assertEquals("No AppTransaction exists for the customer.", e.getApiErrorMessage());
958+
return;
959+
}
960+
Assertions.fail();
961+
}
962+
963+
@Test
964+
public void testGetAppTransactionInfoTransactionIdNotFoundError() throws IOException {
965+
String body = TestingUtility.readFile("models/transactionIdNotFoundError.json");
966+
AppStoreServerAPIClient client = getAppStoreServerAPIClient(body, request -> {}, 404);
967+
try {
968+
client.getAppTransactionInfo("not_found_transaction_id");
969+
} catch (APIException e) {
970+
Assertions.assertEquals(404, e.getHttpStatusCode());
971+
Assertions.assertEquals(APIError.TRANSACTION_ID_NOT_FOUND, e.getApiError());
972+
Assertions.assertEquals(4040010L, e.getRawApiError());
973+
Assertions.assertEquals("Transaction id not found.", e.getApiErrorMessage());
974+
return;
975+
}
976+
Assertions.fail();
977+
}
978+
916979
public AppStoreServerAPIClient getClientWithBody(String path, Consumer<Request> requestVerifier) throws IOException {
917980
String body = TestingUtility.readFile(path);
918981
return getAppStoreServerAPIClient(body, requestVerifier);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4040019,
3+
"errorMessage": "No AppTransaction exists for the customer."
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"signedAppTransactionInfo": "signed_app_transaction_info_value"
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4000006,
3+
"errorMessage": "Invalid transaction id."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4040010,
3+
"errorMessage": "Transaction id not found."
4+
}

0 commit comments

Comments
 (0)