# Optional purchases — exact V1 configuration

Bundle identifier: `com.gallaxgames.quietplaces`. Five StoreKit 2 products. No advertising, ad-removal product, subscription or family sharing.

| Product ID suffix | Type | Proposed UK price | Store display name | Store description |
| --- | --- | --- | --- | --- |
| marks100 | Consumable | £0.99 | 100 Postmarks | 100 Postmarks for supplies or sail colours. |
| marks550 | Consumable | £3.99 | 550 Postmarks | 550 Postmarks for supplies or sail colours. |
| charts | Non-consumable | £4.99 | Luminous charts | Permanently earn 50% more Discoveries. |
| hold | Non-consumable | £2.99 | Deep hold | Keep up to 32 hours of offline earnings. |
| signal | Non-consumable | £2.99 | Companion signal | One permanent scout; 20% more scout income. |

Full IDs are `com.gallaxgames.quietplaces.` followed by the suffix. Proposed prices are local test configuration, not evidence of live price schedules. The app always displays Apple's localised `displayPrice` for available products. Never replace an unavailable product with a hardcoded price or simulated purchase.

## Exact benefits

Postmarks never expire. A first visit grants 4, New Bearings grants 2, and Passing the Atlas grants 10. They are preserved through both prestige layers and the deliberate fresh-voyage action. Available optional spending:

- 25 Postmarks: `ordinaryRate × 3,600` Discoveries, using current equipment, current route and permanent bonuses. This includes scouts, excludes temporary currents, first-visit bonuses and exceptional surveys, and does not advance a route. The preview displays the current amount and asks before spending.
- 40 Postmarks each: permanent Apricot or Turquoise sail colour. Ivory is free. Selecting an owned colour costs nothing.

Luminous charts multiplies all Discovery grants from arrivals and scouts by 1.5, including offline and supplies. It does not change travel distance, Postmarks or direct Knowledge awards. Prestige thresholds account for permanent production multipliers.

Deep hold gives 32 hours of offline travel and scout earnings per absence. The free hold starts at eight hours and reaches 24 through cargo and generations. It does not multiply production speed.

Companion signal adds one scout that survives resets and multiplies total scout income by 1.2. It does not multiply arrival rewards. The permanent scout participates in the fleet's every-fifth-scout bonus.

All three permanent purchases survive both prestige layers and remain eligible for restoration. Consumable balances are saved locally; already delivered packs cannot be restored after app deletion or loss of the save. Apple handles payments and refunds.

## Transaction handling

Only verified, recognised StoreKit transactions are delivered. A transaction ID ledger prevents duplicate delivery. The updated balance or entitlement is saved successfully before `finish()`. Storage failures leave the transaction unfinished for launch-time recovery. `Transaction.updates` is observed throughout the app's lifetime. Pending approval and cancellation do not grant items. Revoked non-consumables are removed and saved. Current entitlements and restoration reconcile permanent ownership; concurrent updates are handled without discarding fresh entitlements.

## Local testing versus live configuration

`Configuration/QuietPlaces.storekit` supplies local GB/US test metadata to the Debug run/test scheme. The app-host StoreKitTest suite passed all nine cases: two currency packs with exact-once persistence, all permanent products through both resets and restoration, Ask to Buy, interrupted delivery, failed-save retry, refund/revocation, offline catalogue ownership preservation, cancellation and an unavailable purchase. See VERIFICATION.md for the final build record.

Run the app-host PurchaseTests before UI-only shop captures to initialise the local simulator catalogue. Xcode 26.6 / iOS 26.5 returned SKInternalErrorDomain Code 3 when a UI runner tried to create its own SKTestSession; the supported app-host harness and subsequent UI shop checks passed. The test plan runs these suites serially.

The Release scheme has no StoreKit test configuration. Local tests do **not** create App Store Connect records or verify Apple's sandbox, real billing, agreements or production availability.

## Owner / App Store Connect work

Create the separate app record and bundle ID in the correct developer account. Create all five products with the exact IDs/types above, choose territory availability and final prices, complete tax/banking/paid-app agreements, supply purchase review screenshots and submit the products with the first app version. Complete a real sandbox/TestFlight purchase and restore pass before release. Do not mark any of these complete from local StoreKitTest results alone.
