iap-apple
v3.0.4
Published
Integration with Apples InAppPurchases in Typescript, available for NodeJS environments.
Maintainers
Readme
| Statements | Branches | Functions | Lines |
| --------------------------- | ----------------------- | ------------------------- | ----------------- |
| |
|
|
|
iap-apple
Lightweight Apple App Store receipt validation for Node.js - Zero dependencies, TypeScript-first, blazing fast.
Why iap-apple? 🤔
| Feature | iap-apple | Others | |---------|-----------|--------| | Runtime Dependencies | 0 | 5-10+ | | TypeScript | Native | Partial/None | | Bundle Size | ~15KB | 100KB+ | | Node.js Fetch | Native | axios/request | | Maintained | 2024+ | Often stale |
- Zero Dependencies - Uses Node.js native
fetch, no bloat - TypeScript-First - Full type definitions, great IDE support
- Production Ready - 93%+ test coverage, battle-tested
- Simple API - One function to validate, intuitive helpers
Installation 📦
# pnpm (recommended)
pnpm add iap-apple
# npm
npm install iap-apple
# yarn
yarn add iap-appleRequirements: Node.js 22+
Quick Start 🚀
import { verify, getPurchasedItems, isPurchasedItemExpired } from 'iap-apple';
// Validate a receipt
const response = await verify(receiptData, {
appSharedSecret: 'your-shared-secret',
});
// Get purchased items (sorted by date, deduplicated)
const items = getPurchasedItems(response);
// Check subscription status
const latestPurchase = items[0];
if (!isPurchasedItemExpired(latestPurchase)) {
console.log('Subscription is active!');
}API Reference 📚
verify(receipt, config)
Validates a receipt against Apple's verifyReceipt endpoint. Automatically handles production/sandbox fallback.
import { verify, IAPAppleError } from 'iap-apple';
try {
const response = await verify(receiptData, {
// Required: Your app's shared secret from App Store Connect
appSharedSecret: 'your-shared-secret',
// Optional: Exclude old transactions (default: false)
appleExcludeOldTransactions: true,
// Optional: Force sandbox environment (default: false)
test: false,
// Optional: Debug logging
logger: console,
});
console.log('Receipt validated:', response.status === 0);
} catch (error) {
const { rejectionMessage, data } = error as IAPAppleError;
console.error('Validation failed:', rejectionMessage);
}isVerifiedReceipt(response)
Check if a receipt validation was successful.
import { verify, isVerifiedReceipt } from 'iap-apple';
const response = await verify(receipt, config);
if (isVerifiedReceipt(response)) {
// Receipt is valid
}getPurchasedItems(response)
Extract purchased items from the response. Returns items sorted by purchase date (newest first), deduplicated by original_transaction_id.
import { verify, getPurchasedItems } from 'iap-apple';
const response = await verify(receipt, config);
const items = getPurchasedItems(response);
for (const item of items) {
console.log(`Product: ${item.productId}`);
console.log(`Purchased: ${new Date(item.purchaseDateMS)}`);
console.log(`Expires: ${item.expirationDateMS ? new Date(item.expirationDateMS) : 'Never'}`);
}isPurchasedItemExpired(item)
Check if a subscription has expired or been cancelled.
import { getPurchasedItems, isPurchasedItemExpired } from 'iap-apple';
const items = getPurchasedItems(response);
const subscription = items[0];
if (isPurchasedItemExpired(subscription)) {
console.log('Subscription expired or cancelled');
} else {
console.log('Subscription is active');
}isPurchasedItemCanceled(item)
Check if a purchase was cancelled (refunded).
import { getPurchasedItems, isPurchasedItemCanceled } from 'iap-apple';
const items = getPurchasedItems(response);
if (isPurchasedItemCanceled(items[0])) {
console.log('User received a refund');
}Types 📝
PurchasedItem
interface PurchasedItem {
bundleId: string;
appItemId: string;
transactionId: string;
originalTransactionId?: string;
productId: string;
purchaseDateMS: number;
originalPurchaseDateMS?: number;
expirationDateMS?: number;
cancellationDateMS?: number;
isTrialPeriod: boolean;
quantity: number;
}IIAPAppleConfig
interface IIAPAppleConfig {
appSharedSecret: string; // Required
appleExcludeOldTransactions?: boolean; // Default: false
test?: boolean; // Default: false
logger?: ILogger | null; // Default: null
}Error Handling
All errors are thrown as IAPAppleError:
interface IAPAppleError {
rejectionMessage: string;
data?: IVerifyReceiptResponseBody | null;
}Common status codes:
21002- Malformed receipt data21003- Receipt authentication failed21004- Shared secret mismatch21005- Apple server unavailable21006- Subscription expired21007- Sandbox receipt sent to production21008- Production receipt sent to sandbox
StoreKit 2 / App Store Server API 🆕
This library uses Apple's legacy verifyReceipt endpoint, which still works but is deprecated for new apps.
For new projects using StoreKit 2, consider Apple's official library:
npm install @apple/app-store-server-libraryWhen to use iap-apple:
- Existing apps using StoreKit 1
- Need zero dependencies
- Want a simpler API
- Validating receipts from older iOS versions
When to use Apple's library:
- New apps with StoreKit 2
- Need App Store Server Notifications V2
- Need subscription offer signing
Contributing 🤝
Contributions are welcome! Please open an issue or submit a PR.
License 📄
ISC
