Fork of @apple/app-store-server-library-node (v3.0.0), rewritten to run natively on Cloudflare Workers and any WebCrypto-compatible runtime.
Covers the App Store Server API, App Store Server Notifications V2, and Retention Messaging API.
| Upstream (Node.js) | This fork (Workers) |
|---|---|
jsonwebtoken | jose |
jsrsasign (X509, ASN1HEX, OCSP) | @peculiar/x509 + manual DER parser |
crypto (X509Certificate, KeyObject, createHash, verify) | @peculiar/x509 + crypto.subtle |
node-fetch | native fetch |
Buffer | Uint8Array / atob / btoa |
base64url | manual base64url |
OCSP revocation checking is fully implemented using manual DER encoding/decoding and crypto.subtle for signature verification — no Node.js crypto dependencies.
jose ^5.9.0
@peculiar/x509 ^1.12.0
Zero Node.js-specific dependencies. Both packages work on Workers, Deno, Bun, and browsers.
# npm
npm install @studium-ignotum/app-store-server-library
# yarn
yarn add @studium-ignotum/app-store-server-library
# pnpm
pnpm add @studium-ignotum/app-store-server-libraryOr install directly from GitHub:
# npm
npm install github:studium-ignotum/app-store-server-library-node
# yarn
yarn add studium-ignotum/app-store-server-library-node
# pnpm
pnpm add github:studium-ignotum/app-store-server-library-nodeRequires a runtime with Web Crypto API (crypto.subtle) and native fetch.
import{AppStoreServerAPIClient,Environment}from"@studium-ignotum/app-store-server-library"constclient=newAppStoreServerAPIClient(encodedKey,keyId,issuerId,bundleId,Environment.SANDBOX)constresponse=awaitclient.requestTestNotification()import{SignedDataVerifier,Environment}from"@studium-ignotum/app-store-server-library"constrootCAs: Uint8Array[]=[appleRootG3DER]// DER-encoded Apple root certificatesconstverifier=newSignedDataVerifier(rootCAs,true,Environment.PRODUCTION,bundleId,appAppleId)constnotification=awaitverifier.verifyAndDecodeNotification(signedPayload)Constructor accepts
Uint8Array[](notBuffer[]).Bufferstill works at runtime since it extendsUint8Array.
import{ReceiptUtility}from"@studium-ignotum/app-store-server-library"constreceiptUtil=newReceiptUtility()consttransactionId=receiptUtil.extractTransactionIdFromAppReceipt(appReceipt)import{PromotionalOfferSignatureCreator}from"@studium-ignotum/app-store-server-library"constcreator=newPromotionalOfferSignatureCreator(encodedKey,keyId,bundleId)constsignature=awaitcreator.createSignature(productId,offerId,appAccountToken,nonce,timestamp)
createSignatureis now async (returnsPromise<string>).
import{AppStoreServerAPIClient,SignedDataVerifier,Environment}from"@studium-ignotum/app-store-server-library"exportdefault{asyncfetch(request: Request,env: Env): Promise<Response>{constverifier=newSignedDataVerifier([base64ToUint8Array(env.APPLE_ROOT_CA_G3)],true,Environment.PRODUCTION,env.BUNDLE_ID,Number(env.APP_APPLE_ID))const{ signedPayload }=awaitrequest.json<{signedPayload: string}>()constnotification=awaitverifier.verifyAndDecodeNotification(signedPayload)returnResponse.json({type: notification.notificationType})}}| Method / Constructor | Change |
|---|---|
new SignedDataVerifier(certs, ...) | certs type: Buffer[] → Uint8Array[] |
verifyCertificateChain(...) | Returns Promise<CryptoKey> instead of Promise<KeyObject> |
PromotionalOfferSignatureCreator.createSignature(...) | Now async — returns Promise<string> |
PromotionalOfferV2SignatureCreator.createSignature(...) | Now async — returns Promise<string> |
IntroductoryOfferEligibilitySignatureCreator.createSignature(...) | Now async — returns Promise<string> |
AdvancedCommerceInAppSignatureCreator.createSignature(...) | Now async — returns Promise<string> |
AppStoreServerAPIClient.uploadImage(id, image) | image type: Buffer → Uint8Array |
All other public APIs remain unchanged.
Download the root certificates from the Apple PKI site (Apple Root Certificates section). Store them as DER-encoded Uint8Array values and pass to SignedDataVerifier.
MIT — see LICENSE.txt. Original library by Apple Inc.