
Security News
NIST Officially Stops Enriching Most CVEs as Vulnerability Volume Skyrockets
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.
Integration with Apples InAppPurchases in Typescript, available for NodeJS environments.
| Statements | Branches | Functions | Lines |
|---|---|---|---|
Lightweight Apple App Store receipt validation for Node.js - Zero dependencies, TypeScript-first, blazing fast.
| 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 |
fetch, no bloat# pnpm (recommended)
pnpm add iap-apple
# npm
npm install iap-apple
# yarn
yarn add iap-apple
Requirements: Node.js 22+
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!');
}
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);
}
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
}
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'}`);
}
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');
}
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');
}
interface PurchasedItem {
bundleId: string;
appItemId: string;
transactionId: string;
originalTransactionId?: string;
productId: string;
purchaseDateMS: number;
originalPurchaseDateMS?: number;
expirationDateMS?: number;
cancellationDateMS?: number;
isTrialPeriod: boolean;
quantity: number;
}
interface IIAPAppleConfig {
appSharedSecret: string; // Required
appleExcludeOldTransactions?: boolean; // Default: false
test?: boolean; // Default: false
logger?: ILogger | null; // Default: null
}
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 sandboxThis 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-library
When to use iap-apple:
When to use Apple's library:
Contributions are welcome! Please open an issue or submit a PR.
ISC
FAQs
Integration with Apples InAppPurchases in Typescript, available for NodeJS environments.
The npm package iap-apple receives a total of 111 weekly downloads. As such, iap-apple popularity was classified as not popular.
We found that iap-apple demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.

Security News
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.