Skip to content

Commit 93b0e74

Browse files
author
Riyaz Panjwani
committed
Add support for Set App Account Token endpoint
1 parent 1443155 commit 93b0e74

File tree

6 files changed

+148
-0
lines changed

6 files changed

+148
-0
lines changed

index.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import fetch from 'node-fetch';
44
import { CheckTestNotificationResponse, CheckTestNotificationResponseValidator } from './models/CheckTestNotificationResponse';
55
import { ConsumptionRequest } from './models/ConsumptionRequest';
6+
import { UpdateAppAccountTokenRequest } from './models/UpdateAppAccountTokenRequest'
67
import { Environment } from './models/Environment';
78
import { ExtendRenewalDateRequest } from './models/ExtendRenewalDateRequest';
89
import { ExtendRenewalDateResponse, ExtendRenewalDateResponseValidator } from './models/ExtendRenewalDateResponse';
@@ -24,6 +25,7 @@ export { AccountTenure } from "./models/AccountTenure"
2425
export { AutoRenewStatus } from './models/AutoRenewStatus'
2526
export { CheckTestNotificationResponse } from './models/CheckTestNotificationResponse'
2627
export { ConsumptionRequest } from './models/ConsumptionRequest'
28+
export { UpdateAppAccountTokenRequest } from './models/UpdateAppAccountTokenRequest'
2729
export { ConsumptionStatus } from './models/ConsumptionStatus'
2830
export { Data } from './models/Data'
2931
export { DeliveryStatus } from './models/DeliveryStatus'
@@ -375,6 +377,18 @@ export class AppStoreServerAPIClient {
375377
await this.makeRequest("/inApps/v1/transactions/consumption/" + transactionId, "PUT", {}, consumptionRequest, null);
376378
}
377379

380+
/**
381+
* Sets the app account token value for a purchase the customer makes outside your app, or updates its value in an existing transaction.
382+
*
383+
* @param originalTransactionId The original transaction identifier of the transaction to receive the app account token update.
384+
* @param updateAppAccountTokenRequest The request body that contains a valid app account token value.
385+
* @throws APIException If a response was returned indicating the request could not be processed.
386+
* {@link https://developer.apple.com/documentation/appstoreserverapi/set-app-account-token Set App Account Token}
387+
*/
388+
public async setAppAccountToken(originalTransactionId: string, updateAppAccountTokenRequest: UpdateAppAccountTokenRequest): Promise<void> {
389+
await this.makeRequest("/inApps/v1/transactions/" + originalTransactionId + "/appAccountToken", "PUT", {}, updateAppAccountTokenRequest, null);
390+
}
391+
378392
private createBearerToken(): string {
379393
const payload = {
380394
bid: this.bundleId
@@ -694,6 +708,27 @@ export enum APIError {
694708
*/
695709
APP_TRANSACTION_ID_NOT_SUPPORTED_ERROR = 4000048,
696710

711+
/**
712+
* An error that indicates the app account token value is not a valid UUID.
713+
*
714+
* {@link https://developer.apple.com/documentation/appstoreserverapi/invalidappaccounttokenuuiderror InvalidAppAccountTokenUUIDError}
715+
*/
716+
INVALID_APP_ACCOUNT_TOKEN_UUID_ERROR = 4000183,
717+
718+
/**
719+
* An error that indicates the transaction is for a product the customer obtains through Family Sharing, which the endpoint doesn’t support.
720+
*
721+
* {@link https://developer.apple.com/documentation/appstoreserverapi/familytransactionnotsupportederror FamilyTransactionNotSupportedError}
722+
*/
723+
FAMILY_TRANSACTION_NOT_SUPPORTED_ERROR = 4000185,
724+
725+
/**
726+
* An error that indicates the endpoint expects an original transaction identifier.
727+
*
728+
* {@link https://developer.apple.com/documentation/appstoreserverapi/transactionidisnotoriginaltransactioniderror TransactionIdIsNotOriginalTransactionIdError}
729+
*/
730+
TRANSACTION_ID_IS_NOT_ORIGINAL_TRANSACTION_ID_ERROR = 4000187,
731+
697732
/**
698733
* An error that indicates the subscription doesn't qualify for a renewal-date extension due to its subscription state.
699734
*
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) 2025 Apple Inc. Licensed under MIT License.
2+
3+
/**
4+
* The request body that contains an app account token value.
5+
*
6+
* {@link https://developer.apple.com/documentation/appstoreserverapi/updateappaccounttokenrequest UpdateAppAccountTokenRequest}
7+
*/
8+
export interface UpdateAppAccountTokenRequest {
9+
10+
/**
11+
* The UUID that an app optionally generates to map a customer's in-app purchase with its resulting App Store transaction.
12+
*
13+
* {@link https://developer.apple.com/documentation/appstoreserverapi/appaccounttoken appAccountToken}
14+
**/
15+
appAccountToken: string
16+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4000185,
3+
"errorMessage": "Invalid request. Family Sharing transactions aren't supported by this endpoint."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4000183,
3+
"errorMessage": "Invalid request. The app account token field must be a valid UUID."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"errorCode": 4000187,
3+
"errorMessage": "Invalid request. The transaction ID provided is not an original transaction ID."
4+
}

tests/unit-tests/api_client.test.ts

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

33
import { AccountTenure } from "../../models/AccountTenure";
44
import { ConsumptionRequest } from "../../models/ConsumptionRequest";
5+
import { UpdateAppAccountTokenRequest } from "../../models/UpdateAppAccountTokenRequest";
56
import { ConsumptionStatus } from "../../models/ConsumptionStatus";
67
import { DeliveryStatus } from "../../models/DeliveryStatus";
78
import { Environment } from "../../models/Environment";
@@ -556,4 +557,88 @@ describe('The api client ', () => {
556557
expect(error.message).toBe("Xcode is not a supported environment for an AppStoreServerAPIClient")
557558
}
558559
})
560+
561+
it('calls setAppAccountToken', async () => {
562+
const client = getAppStoreServerAPIClient("", 200, (path: string, parsedQueryParameters: URLSearchParams, method: string, stringBody: string | undefined, headers: { [key: string]: string; }) => {
563+
expect("PUT").toBe(method)
564+
expect("/inApps/v1/transactions/49571273/appAccountToken").toBe(path)
565+
expect(parsedQueryParameters.entries.length).toBe(0)
566+
567+
expect(stringBody).toBeTruthy()
568+
const body = JSON.parse(stringBody!)
569+
expect("7389a31a-fb6d-4569-a2a6-db7d85d84813").toBe(body.appAccountToken)
570+
});
571+
572+
const updateAppAccountTokenRequest: UpdateAppAccountTokenRequest = {
573+
appAccountToken: "7389a31a-fb6d-4569-a2a6-db7d85d84813"
574+
}
575+
576+
client.setAppAccountToken("49571273", updateAppAccountTokenRequest);
577+
})
578+
579+
it('calls setAppAccountToken but receives an invalid UUID error', async () => {
580+
const client = getClientWithBody("tests/resources/models/invalidAppAccountTokenUUIDError.json", (path: string, parsedQueryParameters: URLSearchParams, method: string, stringBody: string | undefined, headers: { [key: string]: string; }) => {
581+
expect("PUT").toBe(method)
582+
expect("/inApps/v1/transactions/49571273/appAccountToken").toBe(path)
583+
expect(parsedQueryParameters.entries.length).toBe(0)
584+
expect(stringBody).toBeTruthy()
585+
}, 400);
586+
587+
try {
588+
const updateAppAccountTokenRequest: UpdateAppAccountTokenRequest = {
589+
appAccountToken: "abc"
590+
}
591+
await client.setAppAccountToken("49571273", updateAppAccountTokenRequest);
592+
fail('this test call is expected to throw')
593+
} catch (e) {
594+
let error = e as APIException
595+
expect(error.httpStatusCode).toBe(400)
596+
expect(error.apiError).toBe(4000183)
597+
expect(error.errorMessage).toBe("Invalid request. The app account token field must be a valid UUID.")
598+
}
599+
})
600+
601+
it('calls setAppAccountToken but receives family transaction not supported error', async () => {
602+
const client = getClientWithBody("tests/resources/models/familyTransactionNotSupportedError.json", (path: string, parsedQueryParameters: URLSearchParams, method: string, stringBody: string | undefined, headers: { [key: string]: string; }) => {
603+
expect("PUT").toBe(method)
604+
expect("/inApps/v1/transactions/1234/appAccountToken").toBe(path)
605+
expect(parsedQueryParameters.entries.length).toBe(0)
606+
expect(stringBody).toBeTruthy()
607+
}, 400);
608+
609+
try {
610+
const updateAppAccountTokenRequest: UpdateAppAccountTokenRequest = {
611+
appAccountToken: "7389a31a-fb6d-4569-a2a6-db7d85d84813"
612+
}
613+
await client.setAppAccountToken("1234", updateAppAccountTokenRequest);
614+
fail('this test call is expected to throw')
615+
} catch (e) {
616+
let error = e as APIException
617+
expect(error.httpStatusCode).toBe(400)
618+
expect(error.apiError).toBe(4000185)
619+
expect(error.errorMessage).toBe("Invalid request. Family Sharing transactions aren't supported by this endpoint.")
620+
}
621+
})
622+
623+
it('calls setAppAccountToken but transactionId not originalTransactionId error', async () => {
624+
const client = getClientWithBody("tests/resources/models/transactionIdNotOriginalTransactionId.json", (path: string, parsedQueryParameters: URLSearchParams, method: string, stringBody: string | undefined, headers: { [key: string]: string; }) => {
625+
expect("PUT").toBe(method)
626+
expect("/inApps/v1/transactions/1234/appAccountToken").toBe(path)
627+
expect(parsedQueryParameters.entries.length).toBe(0)
628+
expect(stringBody).toBeTruthy()
629+
}, 400);
630+
631+
try {
632+
const updateAppAccountTokenRequest: UpdateAppAccountTokenRequest = {
633+
appAccountToken: "7389a31a-fb6d-4569-a2a6-db7d85d84813"
634+
}
635+
await client.setAppAccountToken("1234", updateAppAccountTokenRequest);
636+
fail('this test call is expected to throw')
637+
} catch (e) {
638+
let error = e as APIException
639+
expect(error.httpStatusCode).toBe(400)
640+
expect(error.apiError).toBe(4000187)
641+
expect(error.errorMessage).toBe("Invalid request. The transaction ID provided is not an original transaction ID.")
642+
}
643+
})
559644
})

0 commit comments

Comments
 (0)