@encorekit/iap-setup
v1.0.8
Published
IAP Setup CLI for Encore
Downloads
572
Readme
@encore/app-store-connect
App Store Connect API client for automated IAP (In-App Purchase) provisioning.
Overview
This package automates the creation of auto-renewable subscriptions in App Store Connect, reducing the 11-step manual process to a single command.
Installation
npm install @encorekit/iap-setupCLI Usage
Interactive Mode
npx setup-iapThis will prompt you for:
- App Store Connect API credentials
- App bundle ID
- Subscription configuration (product ID, name, period, price tier)
Config File Mode
npx @encorekit/iap-setup setup-iap --config ./iap-config.jsonExample config file:
{
"appBundleId": "com.example.myapp",
"groupName": "Encore Premium",
"subscription": {
"productId": "com.example.myapp.premium.monthly",
"name": "Premium Monthly",
"period": "ONE_MONTH",
"familySharable": false
},
"localization": {
"locale": "en-US",
"name": "Premium Monthly",
"description": "Unlock all premium features"
},
"pricing": {
"baseTerritoryId": "USA",
"tierIndex": 10
}
}Environment Variables
Set these to skip interactive prompts:
export ASC_ISSUER_ID="12345678-1234-1234-1234-123456789012"
export ASC_KEY_ID="ABC123DEF4"
export ASC_PRIVATE_KEY_PATH="./AuthKey_ABC123DEF4.p8"Or provide the key contents directly:
export ASC_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"CLI Flags
--config <path>- Path to JSON config file--dry-run- Check what would be created without making changes--validate- Only validate credentials, don't provision
Programmatic Usage
import { createProvisioner } from '@encore/app-store-connect';
const provisioner = createProvisioner({
issuerId: '12345678-1234-1234-1234-123456789012',
keyId: 'ABC123DEF4',
privateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----',
});
// Validate connection
const { valid, message } = await provisioner.validateConnection();
console.log(message); // "Connected successfully. Found 3 app(s)..."
// Provision subscription
const result = await provisioner.provision({
appBundleId: 'com.example.myapp',
groupName: 'Premium',
subscription: {
productId: 'com.example.myapp.premium.monthly',
name: 'Premium Monthly',
period: 'ONE_MONTH',
},
localization: {
locale: 'en-US',
name: 'Premium Monthly',
},
pricing: {
baseTerritoryId: 'USA',
tierIndex: 10, // $9.99
},
}, (step) => {
// Progress callback
console.log(`${step.name}: ${step.status} - ${step.message}`);
});
if (result.success) {
console.log('Product ID:', result.subscriptionId);
}Low-Level API Access
For advanced use cases, access individual resources directly:
import { AppStoreConnectClient, AppsResource, SubscriptionsResource } from '@encore/app-store-connect';
const client = new AppStoreConnectClient(credentials);
// Apps
const apps = new AppsResource(client);
const app = await apps.findByBundleId('com.example.myapp');
// Subscription Groups
const groups = new SubscriptionGroupsResource(client);
const group = await groups.getOrCreate(app.id, 'Premium');
// Subscriptions
const subscriptions = new SubscriptionsResource(client);
const sub = await subscriptions.create(group.id, {
name: 'Premium Monthly',
productId: 'com.example.premium.monthly',
subscriptionPeriod: 'ONE_MONTH',
});Price Tiers
Common price tier mappings (USD, subject to Apple's pricing):
| Tier | Price | | ---- | ------ | | 0 | Free | | 1 | $0.99 | | 5 | $4.99 | | 10 | $9.99 | | 20 | $19.99 | | 50 | $49.99 | | 100 | $99.99 |
Getting API Credentials
- Go to App Store Connect
- Click "Integrations" > "App Store Connect API"
- Click "+" to create a new key
- Select "App Manager" role (minimum required)
- Download the .p8 private key file (only available once!)
- Note the Key ID and Issuer ID
Idempotency
All provisioning operations are idempotent. Running the provisioner multiple times with the same configuration will:
- Find existing resources instead of creating duplicates
- Skip steps that are already complete
- Return the same result IDs
This makes it safe to re-run provisioning if a step fails partway through.
Error Handling
import { AppStoreConnectError } from '@encore/app-store-connect';
try {
await provisioner.provision(config);
} catch (error) {
if (error instanceof AppStoreConnectError) {
console.log('Status:', error.status);
console.log('Detail:', error.detail);
console.log('Retryable:', error.isRetryable);
}
}Security
Dependencies
This package uses minimal, well-vetted dependencies:
| Package | Purpose | Notes |
| ------- | ------------------------------ | ------------------------------------------------------------ |
| jose | JWT signing for Apple API auth | Zero-dependency, maintained by @panva. v6.x is latest stable |
| zod | Schema validation | Zero-dependency, v3.24+ is latest 3.x stable |
Credential Handling
- CLI Mode: Credentials stay local on your machine. Private key is read from file, not stored.
- Ephemeral Mode: If integrated with a hosted service, credentials should be used once and immediately discarded (not stored in database).
- Environment Variables: Prefer
ASC_PRIVATE_KEY_PATHoverASC_PRIVATE_KEYto avoid key contents in shell history.
API Key Permissions
Request the minimum required role when creating your App Store Connect API key:
- App Manager - Required for subscription management
- Avoid Admin unless necessary for other tasks
Audit
Run npm audit to check for vulnerabilities:
npm auditLicense
MIT
