<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Fadi Fannoun]]></title><description><![CDATA[Engineering notes by Fadi Fannoun — a senior full-stack engineer with 15+ years building enterprise platforms, SaaS systems, and developer tooling. Writing about software, systems, and the craft of engineering.]]></description><link>https://dev.fadifannoun.com</link><image><url>https://cdn.hashnode.com/uploads/logos/66e89728efba165029b58ab3/214bc2f7-6070-4f78-af0e-2abb6c8fad59.png</url><title>Fadi Fannoun</title><link>https://dev.fadifannoun.com</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 18 May 2026 03:12:40 GMT</lastBuildDate><atom:link href="https://dev.fadifannoun.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA["IAP" The In-App Purchase Journey – Part 2: Apple Setup - The Bureaucratic Maze]]></title><description><![CDATA[Welcome back to IAP hell. If you missed Part 1, go read it first - you'll need the context for what's coming.
Remember that naive confidence from Part 1? Well, this is where it officially dies. Today ]]></description><link>https://dev.fadifannoun.com/iap-the-in-app-purchase-journey-part-2-apple-setup-the-bureaucratic-maze</link><guid isPermaLink="true">https://dev.fadifannoun.com/iap-the-in-app-purchase-journey-part-2-apple-setup-the-bureaucratic-maze</guid><dc:creator><![CDATA[Fadi Fannoun]]></dc:creator><pubDate>Mon, 18 May 2026 02:37:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1751927082207/17b395b0-be10-4b52-b8c1-12f039971656.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Welcome back to IAP hell. If you missed</em> <a href="https://dev.fadifannoun.com/iap-the-in-app-purchase-journey-part-1-intro"><em>Part 1</em></a><em>, go read it first - you'll need the context for what's coming.</em></p>
<p>Remember that naive confidence from Part 1? Well, this is where it officially dies. Today we're diving into Apple's App Store Connect - a system that feels like it was designed by someone who <em>really</em> loves paperwork.</p>
<p>If you thought creating a simple product would be straightforward, prepare to discover that Apple has turned it into an art form involving endless forms, mysterious approval processes, and screenshots that nobody will actually look at.</p>
<h2>⚡ Quick Setup Guide (Skip the Journey, Get It Done)</h2>
<p><em>Need to set up IAP products fast? Here's the step-by-step without the commentary. For context and gotchas, read the detailed sections below.</em></p>
<h3>Step-by-Step Apple IAP Setup</h3>
<p><strong>1. Navigate to IAP Section</strong></p>
<ul>
<li>App Store Connect → My Apps → [Your App] → Montization → In-App Purchases → Click "+"</li>
</ul>
<p><strong>2. Choose Product Type</strong> ⚠️ <em>Cannot be changed later</em></p>
<ul>
<li><p><strong>Non-Consumable</strong>: Premium features, ad removal, permanent unlocks</p>
</li>
<li><p><strong>Consumable</strong>: Coins, lives, temporary items</p>
</li>
<li><p><strong>Subscriptions</strong>: Recurring access (complex setup)</p>
</li>
</ul>
<p><strong>3. Configure Basic Info</strong></p>
<pre><code class="language-markdown">Product ID: com.yourapp.feature_v1 (permanent identifier)
Reference Name: "Premium Features" (internal only)
Price Tier: Pick from Apple's predetermined list
</code></pre>
<p><strong>4. Localization</strong> ⚠️ <em>Required for all supported countries</em></p>
<pre><code class="language-markdown">Display Name: "Premium Monthly"
Description: "Unlock advanced editing tools, exclusive templates, and priority support"
</code></pre>
<p><strong>5. Screenshots</strong> <em>(Subscriptions only)</em></p>
<ul>
<li><p>Show subscription benefits clearly</p>
</li>
<li><p>Include text overlays explaining value</p>
</li>
<li><p>Professional quality required</p>
</li>
</ul>
<p><strong>6. Submit for Review</strong></p>
<ul>
<li><p>Status: "Waiting for Review"</p>
</li>
<li><p>Timeline: 24 hours to 2 weeks</p>
</li>
<li><p>Prepare for possible rejection and resubmission</p>
</li>
</ul>
<p><strong>7. Test in Sandbox</strong></p>
<pre><code class="language-markdown">Create sandbox tester: App Store Connect → Users &amp; Access → Sandbox Testers
Device: Sign out of App Store, don't sign back in until purchase prompt
Test: Look for [Environment: Sandbox] in purchase dialog
</code></pre>
<h3>Common Mistakes to Avoid</h3>
<ul>
<li><p>❌ Generic product names ("Pro", "Premium")</p>
</li>
<li><p>❌ Missing localizations for supported countries</p>
</li>
<li><p>❌ Screenshots that don't match description</p>
</li>
<li><p>❌ Mixing sandbox and production Apple IDs</p>
</li>
<li><p>❌ Insufficient description detail</p>
</li>
</ul>
<h3>Quick Reference Links</h3>
<ul>
<li><p><strong>Detailed Apple Process</strong>: [See below sections]</p>
</li>
<li><p><strong>Product Type Selection</strong>: [Choosing Your Product Type section]</p>
</li>
<li><p><strong>Sandbox Testing</strong>: [Testing in the Sandbox section]</p>
</li>
<li><p><strong>Troubleshooting</strong>: [Common Issues section]</p>
</li>
</ul>
<hr />
<p><em>Need more context? Read on for the full journey, edge cases, and advanced scenarios.</em></p>
<h2>🍎 Welcome to Apple's World of Forms</h2>
<p>Apple's approach to IAP feels like they hired a bureaucrat from the DMV and said, "Make this more complex." Everything requires forms, approvals, and documentation that seems designed to test your commitment to mobile development.</p>
<h3>Prerequisites (The Entry Fee)</h3>
<p>Before you can even begin this journey, you'll need:</p>
<ul>
<li><p><strong>Active Apple Developer Program membership</strong> ($99/year - your first IAP cost)</p>
</li>
<li><p><strong>App created in App Store Connect</strong> (even if it's not published yet)</p>
</li>
<li><p><strong>Valid iOS Distribution Certificate</strong> (because Apple loves certificates)</p>
</li>
<li><p><strong>Admin or App Manager role access</strong> (no peasants allowed)</p>
</li>
</ul>
<h3>Finding the IAP Section</h3>
<p>Navigate to <strong>My Apps</strong> → Select Your App → <strong>Features</strong> → <strong>In-App Purchases</strong>. Click that innocent-looking "+" button and welcome to the maze where your optimism goes to die.</p>
<h2>🎭 Choosing Your Product Type (Choose Wisely, Young Hobbit)</h2>
<p>Here's where Apple shows its true nature - you get <strong>one shot</strong> at picking the right product type. No take-backs, no changes, no "oops I meant the other one." It's like choosing your house at Bag End - commit now, face consequences later.</p>
<h3>Consumable Products</h3>
<p>Perfect for things users buy repeatedly - coins, gems, lives, or your will to continue this project. These disappear after use like your sanity during this process.</p>
<p><strong>Use cases:</strong></p>
<ul>
<li><p>Virtual currency (coins, gems, credits)</p>
</li>
<li><p>Temporary boosts or power-ups</p>
</li>
<li><p>Extra lives or attempts</p>
</li>
<li><p>Consumable items that get "used up"</p>
</li>
</ul>
<p><strong>The fine print:</strong> No restore functionality needed because they're meant to be consumed. Apple won't test restore for these.</p>
<p><strong>Technical note:</strong> While Apple technically allows restore functionality for consumables (useful for refund scenarios), best practice is to not implement it since consumables should be "consumed" after use.</p>
<h3>Non-Consumable Products</h3>
<p>The "buy once, own forever" items - premium features, ad removal, or that sense of accomplishment when this finally works.</p>
<p><strong>Use cases:</strong></p>
<ul>
<li><p>Premium app features</p>
</li>
<li><p>Ad removal</p>
</li>
<li><p>Permanent character unlocks</p>
</li>
<li><p>One-time feature purchases</p>
</li>
</ul>
<p>⚠️ <strong>Critical requirement:</strong> These <em>must</em> have restore functionality because Apple will test it. Your app needs to remember these purchases across devices and reinstalls.</p>
<h3>Auto-Renewable Subscriptions</h3>
<p>The money printer - automatic billing and renewal with the most complex approval process known to mankind.</p>
<p><strong>Use cases:</strong></p>
<ul>
<li><p>Monthly/yearly premium memberships</p>
</li>
<li><p>Content subscriptions</p>
</li>
<li><p>Service access</p>
</li>
<li><p>Feature subscriptions</p>
</li>
</ul>
<p><strong>The complexity warning:</strong> Requires additional setup including subscription groups, promotional offers, and enough documentation to fill a small library. We'll dive deep into this complexity below.</p>
<h3>Non-Renewing Subscriptions</h3>
<p>The manual labor version - fixed-term access that users must manually renew.</p>
<p><strong>Use cases:</strong></p>
<ul>
<li><p>Seasonal passes</p>
</li>
<li><p>Course access</p>
</li>
<li><p>Time-limited premium features</p>
</li>
<li><p>Event-based subscriptions</p>
</li>
</ul>
<p><strong>Reality check:</strong> Most developers want auto-renewable subscriptions but end up here because the approval process is simpler.</p>
<p>⚠️ <strong>Critical Warning:</strong> Product type cannot be changed after creation. Choose carefully, or you'll be deleting products and starting over.</p>
<h2>📱 Case Study: The Rejection Loop from Hell</h2>
<p>Before we dive into configuration, let me share a real scenario that happened to a popular photo editing app (anonymized for obvious reasons).</p>
<p><strong>The Setup:</strong> They launched with a simple "Premium Monthly" subscription offering advanced filters and cloud storage. Seemed straightforward enough.</p>
<p><strong>The Reality:</strong></p>
<ul>
<li><p><strong>Attempt 1:</strong> Rejected for "insufficient description detail"</p>
</li>
<li><p><strong>Attempt 2:</strong> Rejected for "screenshot doesn't clearly show subscription benefits"</p>
</li>
<li><p><strong>Attempt 3:</strong> Rejected for "missing localization for French Canada" (they supported French, but not Canadian French specifically)</p>
</li>
<li><p><strong>Attempt 4:</strong> Rejected for "product name too generic"</p>
</li>
<li><p><strong>Attempt 5:</strong> Finally approved after 3 weeks</p>
</li>
</ul>
<p><strong>The Cost:</strong> 3 weeks of delays, missed marketing launch, frustrated team, and about 40 hours of developer time resubmitting the same product with minor tweaks.</p>
<p><strong>The Lesson:</strong> Apple's review process for IAP products is just as unpredictable as app review, but with less clear feedback. Every detail matters, and "good enough" isn't good enough.</p>
<p>Now let's make sure you don't repeat their mistakes.</p>
<h2>📝 The Product Configuration Gauntlet</h2>
<p>Time for the real fun - filling out forms that feel designed to test your patience and attention to detail.</p>
<h3>Product ID (Your Permanent Identity Crisis)</h3>
<p>This is your unique identifier, and you're stuck with it forever. Apple prefers reverse domain notation, and they're very particular about format.</p>
<p><strong>Apple's preferred format:</strong></p>
<pre><code class="language-markdown">✅ Good: com.yourapp.premium
✅ Good: com.yourapp.coins_100
✅ Good: com.yourapp.monthly_subscription

❌ Bad: premium!
❌ Bad: my-product
❌ Bad: 123product
❌ Bad: Premium Features
</code></pre>
<p><strong>The rules:</strong></p>
<ul>
<li><p>Alphanumeric characters, dots, and underscores only</p>
</li>
<li><p>Case-sensitive (they care about capitalization)</p>
</li>
<li><p>Can start with letter or underscore</p>
</li>
<li><p>Maximum 255 characters (generous compared to what's coming in Part 3)</p>
</li>
</ul>
<p><strong>Pro tip:</strong> Choose something descriptive but concise. You'll be typing this ID approximately 847 times during testing.</p>
<h3>Reference Name (Your Internal Sanity Keeper)</h3>
<p>This is what you'll see internally in App Store Connect. Make it descriptive because you'll be staring at it during 3 AM debugging sessions when nothing works and you're questioning your career choices.</p>
<p><strong>Examples:</strong></p>
<pre><code class="language-markdown">✅ Good: "Premium Monthly Subscription"
✅ Good: "100 Coins Pack"
✅ Good: "Remove Ads Forever"

❌ Bad: "Product 1"
❌ Bad: "Thing"
❌ Bad: "IAP"
</code></pre>
<h3>Price Tiers (Apple's Price Prison)</h3>
<p>Here's where Apple shows its control-freak nature. Want to charge $4.37? Too bad. You must pick from their predetermined price tiers.</p>
<p><strong>Popular Price Tiers:</strong></p>
<table>
<thead>
<tr>
<th>Tier</th>
<th>USD</th>
<th>Common Usage</th>
<th>User Psychology</th>
</tr>
</thead>
<tbody><tr>
<td>Tier 1</td>
<td>$0.99</td>
<td>Impulse purchases, small coin packs</td>
<td>"Under a dollar" threshold</td>
</tr>
<tr>
<td>Tier 3</td>
<td>$2.99</td>
<td>Remove ads, small features</td>
<td>Sweet spot for casual purchases</td>
</tr>
<tr>
<td>Tier 5</td>
<td>$4.99</td>
<td>Premium features</td>
<td>"Fiver" psychological barrier</td>
</tr>
<tr>
<td>Tier 10</td>
<td>$9.99</td>
<td>Monthly subscriptions</td>
<td>Standard subscription pricing</td>
</tr>
<tr>
<td>Tier 20</td>
<td>$19.99</td>
<td>Annual subscriptions</td>
<td>Discount vs monthly</td>
</tr>
<tr>
<td>Tier 50</td>
<td>$49.99</td>
<td>Professional features</td>
<td>High-value offerings</td>
</tr>
</tbody></table>
<p><strong>Pricing psychology tips:</strong></p>
<ul>
<li><p>Tier 1 ($0.99) triggers impulse buying behavior</p>
</li>
<li><p>Tier 3 ($2.99) is the most popular choice for small features</p>
</li>
<li><p>Avoid "awkward" tiers like $7.99 - users prefer round numbers</p>
</li>
<li><p>Higher tiers work for subscriptions but rarely for one-time purchases</p>
</li>
</ul>
<h2>💰 Complex Scenario: Multi-Region Pricing Strategy</h2>
<p>Here's where Apple's price tiers become both a blessing and a curse. Let me walk you through a real-world pricing challenge.</p>
<p><strong>The Challenge:</strong> You want to launch globally but need competitive pricing in different markets. A $9.99 subscription in the US might be too expensive in emerging markets but too cheap in premium markets like Switzerland.</p>
<p><strong>Apple's Approach:</strong> You pick a tier, and Apple converts it globally using their predetermined rates:</p>
<table>
<thead>
<tr>
<th>Region</th>
<th>Tier 10 Equivalent</th>
<th>Local Competition</th>
<th>Market Reality</th>
</tr>
</thead>
<tbody><tr>
<td>United States</td>
<td>$9.99</td>
<td>\(8.99-\)12.99</td>
<td>Perfect fit</td>
</tr>
<tr>
<td>United Kingdom</td>
<td>£9.99</td>
<td>£6.99-£9.99</td>
<td>Slightly high</td>
</tr>
<tr>
<td>Germany</td>
<td>€10.99</td>
<td>€7.99-€9.99</td>
<td>Too expensive</td>
</tr>
<tr>
<td>India</td>
<td>₹799</td>
<td>₹199-₹499</td>
<td>Way too expensive</td>
</tr>
<tr>
<td>Brazil</td>
<td>R$54.90</td>
<td>R\(19.90-R\)29.90</td>
<td>Completely uncompetitive</td>
</tr>
</tbody></table>
<p><strong>The Problem:</strong> Apple's conversion doesn't consider:</p>
<ul>
<li><p>Local purchasing power</p>
</li>
<li><p>Competitive landscape</p>
</li>
<li><p>Cultural pricing preferences</p>
</li>
<li><p>Economic conditions</p>
</li>
</ul>
<p><strong>Your Options:</strong></p>
<p><strong>Option 1: Accept Apple's Global Pricing</strong></p>
<ul>
<li><p>Pros: Simple setup, consistent margins</p>
</li>
<li><p>Cons: Uncompetitive in many markets, lost revenue</p>
</li>
</ul>
<p><strong>Option 2: Create Region-Specific Products</strong></p>
<pre><code class="language-markdown">premium_monthly_us_v1    ($9.99 - Tier 10)
premium_monthly_eu_v1    (€7.99 - Tier 8) 
premium_monthly_in_v1    (₹449 - Tier 4)
premium_monthly_br_v1    (R$27.90 - Tier 6)
</code></pre>
<ul>
<li><p>Pros: Competitive pricing, better conversion</p>
</li>
<li><p>Cons: Complex management, different feature parity</p>
</li>
</ul>
<p><strong>Option 3: Tiered Feature Model</strong></p>
<pre><code class="language-markdown">basic_monthly_v1     ($2.99 global - Tier 3)
premium_monthly_v1   ($9.99 in rich markets - Tier 10)
premium_monthly_v1   ($4.99 in emerging markets - Tier 5)
</code></pre>
<ul>
<li><p>Pros: Market-appropriate pricing with feature differentiation</p>
</li>
<li><p>Cons: Most complex to implement and maintain</p>
</li>
</ul>
<p><strong>Real-World Recommendation:</strong> Most successful apps start with Option 1 for simplicity, then gradually implement Option 2 for their top 5-10 revenue markets. The complexity isn't worth it until you have significant international revenue.</p>
<h2>🌍 The Localization Nightmare</h2>
<p>Here's where Apple's attention to detail becomes your personal nightmare. They want localized names and descriptions for <em>every single country</em> your app supports. Not just languages - countries.</p>
<h3>The Scope of Madness</h3>
<p>It starts innocently - "Display Name" and "Description" for English. Then you realize Apple wants separate entries for:</p>
<ul>
<li><p>English (United States)</p>
</li>
<li><p>English (United Kingdom)</p>
</li>
<li><p>English (Australia)</p>
</li>
<li><p>English (Canada)</p>
</li>
<li><p>English (India)</p>
</li>
<li><p>...and 40+ other English "variations"</p>
</li>
</ul>
<p>Plus every other language your app supports.</p>
<h3>What Apple Wants For Each Locale</h3>
<p><strong>Display Name:</strong> What users see in the purchase dialog</p>
<pre><code class="language-markdown">English (US): "Premium Monthly"
Spanish: "Premium Mensual"
French: "Premium Mensuel"
German: "Premium Monatlich"
</code></pre>
<p><strong>Description:</strong> Detailed explanation of what they're buying</p>
<pre><code class="language-markdown">English (US): "Unlock all premium features including advanced editing tools, exclusive templates, and priority support."

Spanish: "Desbloquea todas las funciones premium incluyendo herramientas de edición avanzadas, plantillas exclusivas y soporte prioritario."
</code></pre>
<h3>Translation Strategy (Don't Get Burned)</h3>
<p><strong>Option 1: Professional Translation</strong></p>
<ul>
<li><p>Costs money but looks professional</p>
</li>
<li><p>Culturally appropriate messaging</p>
</li>
<li><p>Better conversion rates in international markets</p>
</li>
</ul>
<p><strong>Option 2: Google Translate</strong></p>
<ul>
<li><p>Free but risky</p>
</li>
<li><p>Can create embarrassing mistranslations</p>
</li>
<li><p>"Premium Features" might become "High-Quality Characteristics"</p>
</li>
</ul>
<p><strong>Option 3: English Only</strong></p>
<ul>
<li><p>Simple but limiting</p>
</li>
<li><p>Reduced international appeal</p>
</li>
<li><p>Apple may reject if your app supports multiple languages</p>
</li>
</ul>
<p>⚠️ <strong>Rejection Warning:</strong> Missing localizations for countries your app supports = automatic rejection. Trust me on this one.</p>
<h3>Smart Localization Tips</h3>
<p><strong>Start minimal:</strong> Only localize for countries that represent &gt;5% of your user base <strong>Use consistent terminology:</strong> Keep product names similar across languages <strong>Cultural considerations:</strong> Some cultures prefer different value propositions <strong>Legal requirements:</strong> Some countries require specific subscription language</p>
<p><strong>Reality check:</strong> Apple strongly recommends localization for all supported countries but won't automatically reject for missing translations if you provide comprehensive English (US) content. However, better localization = better user experience = higher conversion rates.</p>
<h3>Advanced Localization Scenarios</h3>
<p><strong>The Family Sharing Complication:</strong> If your app supports family sharing, your product descriptions need to clearly explain what's shared vs. what's individual. Apple requires specific language:</p>
<pre><code class="language-markdown">✅ Good: "Premium subscription includes advanced features for the subscriber. Family members get basic access to shared templates."

❌ Bad: "Premium features for everyone in the family."
</code></pre>
<p><strong>Subscription-Specific Requirements:</strong> Auto-renewable subscriptions need legal disclaimer text in many regions:</p>
<pre><code class="language-markdown">// Required for EU markets
"Subscription automatically renews unless auto-renew is turned off at least 24 hours before the end of the current period. Account will be charged for renewal within 24 hours prior to the end of the current period."

// Must be translated accurately - no Google Translate shortcuts
</code></pre>
<h2>📸 The Screenshot Mystery (Subscriptions Only)</h2>
<p>If you're dealing with subscriptions, Apple wants screenshots. Not of your app interface - screenshots that show what the subscription <em>gives</em> users. This is where things get weird.</p>
<h3>What Apple Actually Wants</h3>
<p><strong>For subscription products:</strong></p>
<ul>
<li><p>Screenshots showing subscription benefits</p>
</li>
<li><p>Text overlays explaining the value proposition</p>
</li>
<li><p>Professional-looking marketing materials</p>
</li>
<li><p>Clear before/after comparisons</p>
</li>
</ul>
<p><strong>The reality gap:</strong></p>
<ul>
<li><p><strong>What you have:</strong> A half-finished app and growing existential dread</p>
</li>
<li><p><strong>What Apple wants:</strong> Professional marketing screenshots with perfect UI and compelling copy</p>
</li>
</ul>
<h3>Screenshot Requirements</h3>
<p><strong>Technical specs:</strong></p>
<ul>
<li><p>JPG or PNG format</p>
</li>
<li><p>Maximum 8MB file size</p>
</li>
<li><p>High resolution (recommended: iPhone Pro Max dimensions)</p>
</li>
<li><p>Clear, professional appearance</p>
</li>
</ul>
<p><strong>Content requirements:</strong></p>
<ul>
<li><p>Show actual app features (not generic stock photos)</p>
</li>
<li><p>Include text explaining subscription benefits</p>
</li>
<li><p>Demonstrate clear value proposition</p>
</li>
<li><p>Professional design quality</p>
</li>
</ul>
<p><strong>Examples of good screenshot content:</strong></p>
<pre><code class="language-markdown">✅ Before/after showing premium features unlocked
✅ Feature comparison charts
✅ Screenshots with benefit callouts
✅ Value proposition overlays

❌ Generic app store screenshots
❌ Unrelated stock photos
❌ Poor quality or blurry images
❌ Screenshots that don't match the description
</code></pre>
<h2>🧪 Testing in the Sandbox (Where Hope Goes to Die)</h2>
<p>Apple's sandbox environment is where you'll test purchases without spending real money. In theory, it's simple. In practice, it's a special kind of purgatory designed to test your debugging skills and patience.</p>
<h3>Creating Sandbox Testers (Your Fake Friends)</h3>
<p><strong>Step 1:</strong> Navigate to <strong>Users and Access</strong> → <strong>Sandbox Testers</strong> <strong>Step 2:</strong> Click the "+" button to add a new tester <strong>Step 3:</strong> Fill out the form with fake but realistic information</p>
<p><strong>Required information:</strong></p>
<pre><code class="language-markdown">Email: test1@yourdomain.com (must be unique, never used for real Apple ID)
Password: TestPassword123! (meet Apple's complexity requirements)
First Name: Test
Last Name: User
Date of Birth: Valid date (affects content ratings)
App Store Territory: Your primary market (US, UK, etc.)
</code></pre>
<p>⚠️ <strong>The Golden Rule:</strong> Never, ever use a sandbox Apple ID for real App Store purchases. Write this on a sticky note and put it somewhere visible. Mixing sandbox and production accounts creates permanent, unfixable problems.</p>
<h3>The Sandbox Testing Process</h3>
<p><strong>Device preparation:</strong></p>
<ol>
<li><p>Go to <strong>Settings</strong> → <strong>App Store</strong></p>
</li>
<li><p>Sign out of any existing Apple ID</p>
</li>
<li><p>DO NOT sign back in until your app prompts for purchase</p>
</li>
</ol>
<p><strong>Testing flow:</strong></p>
<ol>
<li><p>Launch your app</p>
</li>
<li><p>Trigger a purchase</p>
</li>
<li><p>iOS shows purchase dialog with <strong>[Environment: Sandbox]</strong> label</p>
</li>
<li><p>Sign in with sandbox Apple ID when prompted</p>
</li>
<li><p>Complete purchase (no real money charged)</p>
</li>
<li><p>Verify purchase processing in your app</p>
</li>
</ol>
<h3>Common Sandbox Issues That Will Ruin Your Day</h3>
<h4>"Cannot Connect to iTunes Store"</h4>
<p><strong>Possible causes:</strong></p>
<ul>
<li><p>Mixed sandbox and production Apple IDs on the device</p>
</li>
<li><p>Network connectivity issues</p>
</li>
<li><p>Apple's sandbox servers having "a moment"</p>
</li>
<li><p>Device region doesn't match sandbox account region</p>
</li>
</ul>
<p><strong>Solutions:</strong></p>
<ul>
<li><p>Sign out of ALL Apple IDs, restart device, try again</p>
</li>
<li><p>Use a different sandbox account</p>
</li>
<li><p>Check Apple's system status page</p>
</li>
<li><p>Wait (sometimes it's literally just Apple having server issues)</p>
</li>
</ul>
<h4>"Invalid Product Identifier"</h4>
<p><strong>Possible causes:</strong></p>
<ul>
<li><p>Product not approved/released yet</p>
</li>
<li><p>Typo in product ID in your app code</p>
</li>
<li><p>App not using correct provisioning profile</p>
</li>
<li><p>Product not available in sandbox account's region</p>
</li>
</ul>
<p><strong>Solutions:</strong></p>
<ul>
<li><p>Verify product status in App Store Connect</p>
</li>
<li><p>Double-check product IDs match exactly (case-sensitive!)</p>
</li>
<li><p>Ensure app uses development or distribution provisioning profile</p>
</li>
<li><p>Check product availability in tester's region</p>
</li>
</ul>
<h4>Purchase Dialog Shows Wrong Information</h4>
<p><strong>Possible causes:</strong></p>
<ul>
<li><p>Cached product information</p>
</li>
<li><p>Product information updated but not propagated</p>
</li>
<li><p>Localization issues</p>
</li>
</ul>
<p><strong>Solutions:</strong></p>
<ul>
<li><p>Delete and reinstall app</p>
</li>
<li><p>Wait for Apple's cache to refresh (up to 24 hours)</p>
</li>
<li><p>Test with different sandbox account</p>
</li>
</ul>
<h4>Purchases Succeed But Don't Register in App</h4>
<p><strong>Possible causes:</strong></p>
<ul>
<li><p>Not properly listening for purchase updates</p>
</li>
<li><p>Receipt validation logic errors</p>
</li>
<li><p>Transaction finishing prematurely</p>
</li>
</ul>
<p><strong>Solutions:</strong></p>
<ul>
<li><p>Check purchase observer implementation</p>
</li>
<li><p>Verify receipt validation code</p>
</li>
<li><p>Add extensive logging to debug transaction flow</p>
</li>
</ul>
<h2>🔄 Sandbox Testing: Advanced Scenarios</h2>
<p>Beyond basic purchase testing, here are complex scenarios you need to verify in sandbox:</p>
<h3>Testing Subscription Renewals</h3>
<p><strong>The Challenge:</strong> How do you test monthly/yearly renewals without waiting months?</p>
<p><strong>Apple's Solution:</strong> Accelerated renewal rates in sandbox:</p>
<ul>
<li><p>1 week subscription renews every 3 minutes</p>
</li>
<li><p>1 month subscription renews every 5 minutes</p>
</li>
<li><p>2 months subscription renews every 10 minutes</p>
</li>
<li><p>3 months subscription renews every 15 minutes</p>
</li>
<li><p>6 months subscription renews every 30 minutes</p>
</li>
<li><p>1 year subscription renews every hour</p>
</li>
</ul>
<p><strong>What to Test:</strong></p>
<pre><code class="language-javascript">// Your app should handle:
1. Successful renewals (subscription continues)
2. Failed renewals (payment method expired) 
3. Canceled renewals (user turned off auto-renew)
4. Billing retry periods (Apple tries failed payments for 60 days)
5. Billing grace periods (temporary access during payment issues)
</code></pre>
<h3>Testing Family Sharing</h3>
<p><strong>Setup Requirements:</strong></p>
<ul>
<li><p>Multiple sandbox Apple IDs in same family</p>
</li>
<li><p>Different devices or simulator instances</p>
</li>
<li><p>Family organizer with valid payment method</p>
</li>
</ul>
<p><strong>Scenarios to Test:</strong></p>
<ul>
<li><p>Purchase on organizer account, verify access on family member device</p>
</li>
<li><p>Family member leaves family, verify access revocation</p>
</li>
<li><p>Multiple family members try to access same shared purchase</p>
</li>
</ul>
<h3>Testing Promotional Offers</h3>
<p><strong>Prerequisites:</strong></p>
<ul>
<li><p>Server-side signature generation setup</p>
</li>
<li><p>Promotional offer configured in App Store Connect</p>
</li>
<li><p>User eligible for promotional offer</p>
</li>
</ul>
<p><strong>Complex Flow:</strong></p>
<pre><code class="language-javascript">// 1. Check user eligibility server-side
// 2. Generate promotional offer signature
// 3. Present offer in app
// 4. User accepts promotional pricing
// 5. Verify promotional receipt
// 6. Track promotional usage for business analytics
</code></pre>
<h2>⏰ The Review Process (AKA "Pending Purgatory")</h2>
<p>Apple's documentation cheerfully states that products are "usually reviewed within 24-48 hours." This is technically true in the same way that saying "it usually doesn't rain" is true - sometimes accurate, often wildly optimistic.</p>
<h3>The Reality Timeline</h3>
<p><strong>Apple says:</strong> 24-48 hours <strong>Reality:</strong> Anywhere from 6 hours to 2 weeks, depending on:</p>
<ul>
<li><p>Phase of the moon</p>
</li>
<li><p>Apple reviewer workload</p>
</li>
<li><p>Cosmic alignment</p>
</li>
<li><p>Whether Mercury is in retrograde</p>
</li>
<li><p>Your karma from previous app submissions</p>
</li>
</ul>
<h3>Common Rejection Reasons (And How to Fix Them)</h3>
<h4>"Description doesn't clearly explain the product"</h4>
<p><strong>What Apple sees:</strong> Generic or vague description <strong>What you probably wrote:</strong> "Premium features" <strong>What Apple wants:</strong> "Unlock advanced photo editing tools, 50+ exclusive filters, and cloud storage for unlimited photos"</p>
<h4>"Screenshot doesn't show the feature"</h4>
<p><strong>What Apple sees:</strong> Screenshot that doesn't match description <strong>What you probably did:</strong> Used generic app screenshots <strong>What Apple wants:</strong> Screenshots specifically showing subscription benefits with clear callouts</p>
<h4>"Product name is confusing"</h4>
<p><strong>What Apple sees:</strong> Unclear or misleading product name <strong>What you probably wrote:</strong> "Pro" <strong>What Apple wants:</strong> "Pro Monthly Subscription" or "Premium Photo Editor"</p>
<h4>"Insufficient localization"</h4>
<p><strong>What Apple sees:</strong> Missing translations for supported countries <strong>What you probably did:</strong> Only provided English text <strong>What Apple wants:</strong> Proper localization for every country your app supports</p>
<h3>Appealing Rejections</h3>
<p>If your product gets rejected:</p>
<ol>
<li><p><strong>Don't panic</strong> - it happens to everyone</p>
</li>
<li><p><strong>Read the rejection reason carefully</strong> - Apple usually tells you exactly what's wrong</p>
</li>
<li><p><strong>Fix the specific issues mentioned</strong> - don't change unrelated things</p>
</li>
<li><p><strong>Resubmit promptly</strong> - delays don't help your review time</p>
</li>
</ol>
<h2>🎯 Apple Setup Survival Tips</h2>
<h3>Before You Start</h3>
<ul>
<li><p>Plan your product hierarchy and naming scheme</p>
</li>
<li><p>Prepare localized content for all target markets</p>
</li>
<li><p>Create professional screenshots if doing subscriptions</p>
</li>
<li><p>Set up sandbox testers before you need them</p>
</li>
</ul>
<h3>During Setup</h3>
<ul>
<li><p>Double-check product IDs before submitting (you can't change them)</p>
</li>
<li><p>Be specific and detailed in descriptions</p>
</li>
<li><p>Include clear value propositions in product names</p>
</li>
<li><p>Test everything in sandbox before submitting for review</p>
</li>
</ul>
<h3>After Approval</h3>
<ul>
<li><p>Don't celebrate yet - implementation is where the real pain begins</p>
</li>
<li><p>Keep sandbox accounts organized and documented</p>
</li>
<li><p>Monitor for any status changes in App Store Connect</p>
</li>
<li><p>Prepare for Part 3: Google's completely different approach</p>
</li>
</ul>
<h2>🚧 Coming Next</h2>
<p>Congratulations! You've survived Apple's bureaucratic maze and successfully configured your first IAP products. Your products are now sitting in "Ready to Submit" or "Waiting for Review" status, and you're probably questioning why you didn't just become an accountant.</p>
<p>But don't rest yet - in <strong>Part 3: Google Play Setup</strong>, we'll discover that Google took a completely different approach to the same problems. Where Apple loves forms, Google loves flexibility. Where Apple has rigid rules, Google has mysterious algorithms.</p>
<p>It's like learning a second language where nothing translates directly from the first.</p>
<h2>📋 TL;DR - Apple Setup Quick Reference</h2>
<p><strong>Bottom Line:</strong> Apple's IAP setup is bureaucratic but predictable. Follow their rules exactly, prepare for rejection cycles, and plan for complexity from day one.</p>
<p><strong>Series Focus:</strong> While this guide covers all product types, we'll primarily focus on <strong>non-consumable products</strong> (premium features, ad removal, permanent unlocks) throughout the series. They represent the most common use case and have the most complex backend implementation challenges. Consumables and subscriptions follow similar setup patterns with variations we'll note where relevant.</p>
<h3>Essential Steps Checklist</h3>
<pre><code class="language-markdown">□ Choose product type carefully (can't change later)
□ Use reverse domain notation for Product IDs
□ Write detailed, benefit-focused descriptions
□ Localize for ALL supported countries
□ Create professional screenshots (subscriptions only)
□ Set up sandbox testers with unique Apple IDs
□ Test everything in sandbox before submitting
□ Prepare for 24 hours to 2 weeks review time
□ Plan for rejection and resubmission cycles
</code></pre>
<h3>Critical Success Factors</h3>
<p><strong>🎯 Product Configuration:</strong></p>
<ul>
<li><p>Product ID: <code>com.yourapp.feature_v1</code> format</p>
</li>
<li><p>Reference Name: Descriptive for internal use</p>
</li>
<li><p>Price: Choose popular tiers (1, 3, 5, 10, 20)</p>
</li>
<li><p>Descriptions: Specific benefits, not generic features</p>
</li>
</ul>
<p><strong>🌍 Localization Strategy:</strong></p>
<ul>
<li><p>Start with top 5 revenue markets only</p>
</li>
<li><p>Use professional translation, not Google Translate</p>
</li>
<li><p>Include required legal language for subscriptions</p>
</li>
<li><p>Plan for region-specific compliance requirements</p>
</li>
</ul>
<p><strong>🧪 Testing Approach:</strong></p>
<ul>
<li><p>Never mix sandbox and production Apple IDs</p>
</li>
<li><p>Test all subscription states (renewal, failure, cancellation)</p>
</li>
<li><p>Verify family sharing behavior if enabled</p>
</li>
<li><p>Test promotional offers with signature generation</p>
</li>
</ul>
<p><strong>⚠️ Common Pitfalls to Avoid:</strong></p>
<ul>
<li><p>Generic product names ("Premium", "Pro")</p>
</li>
<li><p>Missing localizations for any supported country</p>
</li>
<li><p>Screenshots that don't match subscription benefits</p>
</li>
<li><p>Insufficient description detail</p>
</li>
<li><p>Wrong product type selection</p>
</li>
</ul>
<h3>Key Takeaways</h3>
<ol>
<li><p><strong>Apple favors detail over simplicity</strong> - More information is always better</p>
</li>
<li><p><strong>Rejection is normal</strong> - Plan for multiple submission cycles</p>
</li>
<li><p><strong>Subscriptions are complex</strong> - Intro offers, promotions, and family sharing add significant complexity</p>
</li>
<li><p><strong>Global pricing is rigid</strong> - Accept Apple's tiers or create region-specific products</p>
</li>
<li><p><strong>Testing is critical</strong> - Sandbox environment catches issues before production</p>
</li>
</ol>
<h3>When to Consider Advanced Features</h3>
<ul>
<li><p><strong>Introductory Offers:</strong> If acquisition cost is high and you need conversion boost</p>
</li>
<li><p><strong>Promotional Offers:</strong> If you have significant churn and want win-back campaigns</p>
</li>
<li><p><strong>Subscription Groups:</strong> If you plan multiple subscription tiers</p>
</li>
<li><p><strong>Family Sharing:</strong> If your app has family-oriented features</p>
</li>
</ul>
<h3>Red Flags That Indicate Problems</h3>
<ul>
<li><p>Product stuck in "Waiting for Review" &gt; 1 week</p>
</li>
<li><p>Repeated rejections for same issue</p>
</li>
<li><p>Sandbox purchases not working after product approval</p>
</li>
<li><p>Missing product options in sandbox testing</p>
</li>
<li><p>Family sharing not working as expected</p>
</li>
</ul>
<hr />
<p><em>Survived Apple's bureaucratic gauntlet? Share your rejection stories in the comments. We're building a support group, and Apple App Store Connect trauma is our specialty.</em></p>
<p><em>Next is Part 3 - Google Play Setup, where we'll learn that "more flexible" doesn't necessarily mean "easier."</em></p>
]]></content:encoded></item><item><title><![CDATA[Raw Notes On Management and Beyond: A Dev's Perspective]]></title><description><![CDATA[Warning: Long read. May contain 7 Tyrion Lannister Pro Tips

Management—this boogeyman word every developer hates or avoids. But hey, it doesn't have to relate to executive management specifically, or to be confined to the bureaucracy of institutions...]]></description><link>https://dev.fadifannoun.com/raw-notes-on-management-and-beyond-a-devs-perspective</link><guid isPermaLink="true">https://dev.fadifannoun.com/raw-notes-on-management-and-beyond-a-devs-perspective</guid><category><![CDATA[Task Execution Management]]></category><category><![CDATA[management]]></category><category><![CDATA[self management]]></category><category><![CDATA[development]]></category><category><![CDATA[notes]]></category><category><![CDATA[Productivity]]></category><category><![CDATA[software development]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[workflow]]></category><category><![CDATA[agile]]></category><category><![CDATA[antware ]]></category><category><![CDATA[palestine]]></category><category><![CDATA[Philosophy]]></category><category><![CDATA[raw]]></category><category><![CDATA[Beyond ]]></category><dc:creator><![CDATA[Fadi Fannoun]]></dc:creator><pubDate>Fri, 27 Jun 2025 15:32:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750911661504/97e5ddf5-7a59-42cc-b466-eb99222f83af.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong>Warning</strong>: <strong>Long read. May contain 7 Tyrion Lannister Pro Tips</strong></p>
</blockquote>
<p>Management—this boogeyman word every developer hates or avoids. But hey, it doesn't have to relate to executive management specifically, or to be confined to the bureaucracy of institutions and companies.</p>
<p>There are possibly countless types of management—not in the sense that they are endless, but rather in their categorization and contextualization. From where I stand, I can speak about a few types: <strong>Self-Management</strong>, <strong>Task Management</strong>, <strong>Task Execution Management</strong>, and <strong>People Management</strong>.</p>
<p>My concern is about Self-Management and Task Execution Management. They are the most crucial types for devs and non-managerial positions, because they directly impact your—as a developer—daily progress and achievement. While other management types are important, e.g Task Management, which might be familiar to many teams and widely adopted in different forms like Agile methodology, I'm passing on them due to their organizational focus - they're externally structured frameworks that teams adopt rather than personal skills you develop.</p>
<h2 id="heading-self-management"><mark>Self-Management</mark></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752152612774/ad435b8b-7c12-47e8-941c-c4aa6046836a.jpeg" alt class="image--center mx-auto" /></p>
<p>Throughout my journey, I've met people with different self-management styles and personalities. Such observations extend to non-work related self-pillars like emotions, thoughts, and behavior. There are people who look like machines in terms of being fully self-managed; they manage their time, tasks, execution, emotions, thoughts, and so on. On the other side, there are people who need others to fully manage them, and of course there is a very wide range in between.</p>
<p>I'm not saying one of those styles is better than the other. Just as each person has their own genes, they have a different personality and type of self-management. If you accept this reality, this is what you get! But the important thing here is for someone with a need for "<mark>nano-management</mark>" to be aware of that. Being ignorant of such characteristics will put them out of their <strong><mark>circle of competence</mark></strong> and lead to focusing on distracting matters that would prevent their progress and reduce their productivity.</p>
<p>I encountered two kinds of people who need nano-management, not micromanagement. Some succeeded in carrying their duties because they were aware of the idea "this is what I can do," while the other type was not conscious about this "circle of competence"—as a concept, of course—which led them to chaos: missing deadlines, digging in the wrong place even with guidance and coaching, because they were refusing to admit the reality.</p>
<p>This is applicable to other areas - emotions for instance, which are generic, not limited to the workspace, and can reveal much about someone. Have you ever gotten into the office and seen your colleague's face about to explode? I bet this colleague of yours always lets outside variables affect their work performance and would need another person, maybe another colleague, to talk with—not in the sense of regular human interaction and discussion flow, but as a need for emotional direction.</p>
<p>An Islamic wisdom says <mark>"</mark><strong><mark>إنّ السماح رباح</mark></strong><mark>"</mark> which translates to <mark>"</mark><strong><mark>Allowance/Permitting is profitable</mark></strong><mark>"</mark>; that means giving people space to operate according to their nature, and permitting flexibility rather than imposing rigid control. It's about the profit that comes from allowing rather than restricting. And starting from oneself; you should allow your very nature, free from community and modernity stress. I knew a designer who was doing very impressive work; he could capture an idea and transform it into living graphics and animation, but he stressed himself trying to become an "entrepreneur". The word "<strong>سماح</strong>" also translates to "<strong>Forgiveness</strong>", and you might explore its relation to our context.</p>
<p>Speaking of myself: I struggle with vocally expressing ideas, as well as learning things at a good speed. I've come to the conclusion that I'm a slow learner and writer. That is fine; I've allowed myself to slowly learn and write, which in turn gave me a way to explore and understand complex and interconnected ideas on paper as iterations, rather than expressing them in linear sequencing—which speaking requires. So I embraced the mentioned saying above, kind of late.</p>
<p>I've succeeded in creating two new routines in my life; one is body activation to find the buried wisdom in flesh and bone. I'm not consistent in this routine—I don't show up at the gym every day—but I manage to find alternatives. The routine isn't about consistency; <mark>it's about recognition</mark>. Recognizing when my body needs movement to unlock or lock my mind. Sometimes that's the gym, sometimes it's pacing while debugging, sometimes it's just getting up from the damn chair. The second one is the mighty Sun Rituals. No further questions!</p>
<p><img src="https://videos.openai.com/vg-assets/assets%2Ftask_01jymj5r32fmpsk7tyzm1zge9a%2F1750889435_img_0.webp?st=2025-06-25T20%3A20%3A39Z&amp;se=2025-07-01T21%3A20%3A39Z&amp;sks=b&amp;skt=2025-06-25T20%3A20%3A39Z&amp;ske=2025-07-01T21%3A20%3A39Z&amp;sktid=a48cca56-e6da-484e-a814-9c849652bcb3&amp;skoid=8ebb0df1-a278-4e2e-9c20-f2d373479b3a&amp;skv=2019-02-02&amp;sv=2018-11-09&amp;sr=b&amp;sp=r&amp;spr=https%2Chttp&amp;sig=ndfbdWqPzQf1rW4XiQeFhu8kO64HP%2F%2Bt4G7A8lleAzU%3D&amp;az=oaivgprodscus" alt class="image--center mx-auto" /></p>
<p>Self-management is sometimes sold as if you need to treat yourself as a project or a well-defined algorithm. In contrast, we are complex entities.</p>
<p>Self-management books and LinkedIn carousels love to pretend you're a simple system that just needs the right inputs and processes. "Follow these 7 steps!" "Use this productivity framework!" "Optimize your morning routine!" As if humans were machines that respond predictably to the same commands every day.</p>
<p>But we're not algorithms. We have moods, energy cycles, creative blocks, emotional baggage from yesterday's failed deploy, or excitement about a new technology we want to try. Some days you're laser-focused, other days your brain feels like spaghetti code.</p>
<p>The productivity gurus want you to believe consistency is king—same routine, same methods, same outputs. But real self-management means working with your inconsistencies, not against them. It's more like debugging a complex system where the variables keep changing.</p>
<p>Maybe today you need nano-management (strict structure), tomorrow you need complete freedom to explore. Maybe this week you're energized by hard problems, next week you need easy wins to rebuild confidence. The complexity is the point. Managing a complex entity requires flexibility, not rigid frameworks.</p>
<p>Am I anti-consistency? I don't think so. I'm against how it has been framed to us.</p>
<h3 id="heading-the-strongly-typed-vs-loosely-typed-analogy"><mark>The "Strongly Typed vs Loosely Typed" analogy</mark></h3>
<p>Speaking coding language: keep your bigger picture/goals/milestones <strong>strongly typed</strong>—so core principles stay consistent. But adapt to <strong>loosely typed</strong> implementation based on context. You aren't going to create chaos, but flexibility instead. You'll have patterns, but not necessarily repeat yourself every day. This liquid world, as Bauman has described, will require you to allow this liquidity to pass, but not be affected by it. In this liquid modernity combined with your sophisticated personal circumstances: allowance and flexibility are survival necessities.</p>
<p>Personal creative processes aren't meant to be "managed" in the sense of standardization, systemization, or formalization. Imagine someone telling Leonardo da Vinci: "Hey, follow this framework, and you'll produce the most famous drawing ever." The absurdity is obvious—creativity resists systematization. But they can and should be self-micro-managed. So, <strong>Task Execution Management</strong> is an informal, non-universal, unofficial type you could call Micro-Decision Management, Self-OS, or keep it under Self-Management. You don't need to label it in the first place.</p>
<h2 id="heading-task-execution-management"><mark>Task Execution Management</mark></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752152367200/576a13dd-483e-4032-9f6a-b7c056044145.jpeg" alt class="image--center mx-auto" /></p>
<p><strong>Now to the <mark>Ghoul</mark>!</strong></p>
<p>I love Agile and its easing process. Once the sprint has started and you pick your first ticket, all echoes from the past start hunting you!</p>
<p>It doesn't matter what your code-level seniority is; what matters is your ability to manage this every time and every day, because each task is unique however similar it is to other tasks you've done before. You might already be confident about what you are going to do, but I bet you cannot explain the "How" each time in the same steps. If you fail to admit this, you've created another issue for yourself. Also, I haven't worked in big corporations, so I'm not aware of their processes, knowledge bases, or orientation programs that might help with task execution—this is coming from smaller team/startup experience.</p>
<p>No fancy promises such as you'll find here a "7 Ways To Flourish While Executing Your Daily Tasks"—which could be one of the top sellers in the future—guide. This would be exploring and insights sharing—you might find it useful and you may not. Also, none of my claims come from profound research; they are all raw observations and notes.</p>
<p>Whatever you are up to, don't start coding immediately—just don't!</p>
<p>Philosophers taught us about important life questions, which also happen to exist in most learning paths: <strong>What? When? Where? Who? Why?</strong></p>
<p>The good news: you don't have to answer the immediate "Why" like "why am I doing this task?" either from a business perspective or from your existential perspective. Also, you can safely eliminate the "Who" as no one else will do your job. I intentionally dropped the "How" as, if you remember, it is the main one you are trying to answer yourself silently.</p>
<h3 id="heading-what"><mark>"What"</mark></h3>
<p>Probably this is the easiest question, and most likely well defined in your board ticket, and you may even have a good picture of its implementation. Despite that, it is a tricky one, and highly interconnected with "When" and both need to be managed simultaneously.</p>
<h3 id="heading-where"><mark>"Where"</mark></h3>
<p>I take time to scan a project, even though I'm living with it every day and see those lines that blur my eyes more than my kids. I have to do this every time, regardless of whether I'm working solo or within a team. It's like a recap of what has been done; what to use; what to avoid duplicating; where the new service or new model shall live. It helps you strategically build the picture in your mind, and once it's there, you can blueprint on paper, draw a diagram, whatever suits you!</p>
<p>If I have to pick for you, I'd say start with 'Where' - it will be your friend. Unlike "What" which can spiral into endless requirements analysis, or “When” which opens the door to decision paralysis, "Where" grounds you in the actual codebase reality. It forces you to do that essential scanning ritual, rebuilding your mental map even when you think you know the code intimately. Starting with 'Where' prevents the common mistakes of duplicating functionality, breaking existing patterns, or creating isolated code islands, and it naturally connects to that "don't start coding immediately" wisdom - making you pause, think strategically, and build that blueprint in your mind before your fingers hit the keyboard.</p>
<p>Starting from the wrong place will create a time vortex like the ones Dr. Strange does, except you don't have the time stone or any Ancient One to guide you out. You need precision that will relieve you of the burden of answering other questions.</p>
<p><mark>Starting from "Where"</mark> might slow you down - short-term - but definitely will keep you on track - long-term benefit for better decisions, fewer rewrites, and cleaner execution.</p>
<h3 id="heading-when"><mark>"When"</mark></h3>
<p>This is a branched question that might hit technical and non-technical territories. I've been asked these kinds of questions while giving a training session, and honestly I did not have a clear answer that a fresh graduate would be satisfied with.</p>
<p>Have you ever asked yourself:</p>
<ul>
<li><p>When to start with UI and when with the data layer?</p>
</li>
<li><p>When to ask for help versus struggle alone?</p>
</li>
<li><p>When to refactor versus when to just make it work?</p>
</li>
<li><p>When to reset and when to proceed? (It is not obvious, by the way.)</p>
</li>
<li><p>When to over-engineer or under-engineer?</p>
</li>
<li><p>When to optimize for performance versus readability?</p>
</li>
<li><p>When to write tests first versus after?</p>
</li>
<li><p>When to tackle the hard part first versus start with easy wins?</p>
</li>
<li><p>When to make judgment calls versus have strict definitions?</p>
</li>
</ul>
<p>Pay attention during this stage of your execution, and if you followed the 'Where' advice, it might save you a lot of hassle. In this era, you're either under-productive or super productive; either way, pause. Such questions interfere with the organic "How", and if you want to be productive, never count lines. This is the big dilemma I'm wrestling with right now.</p>
<p>Sometimes you have to make judgement calls - stress on your instinct, conduct quick research, depend on your experience in similar cases, future proof thinking. But here's the thing: there's no universal formula for these decisions. What works in one context fails in another.</p>
<p>SE guidelines are great, when you are looking for "textbook answers", but they assume rational conditions, stable teams, and predictable environments. They don’t count your energy level, team dynamics, political pressure, real-word chaos, legacy codebase constraints, skill gaps, or business priorities.</p>
<p>For example, books say "Start with data layer" or "Start with UI" or "It depends", but rarely address what to do when you're solo switching contexts constantly, when business pressure forces a specific approach, when legacy constraints limit your choices, or when you're not sure what the final product should be.</p>
<p>The books assume you have time for proper analysis - they don't cover "I need to deliver something in 3 days and I'm not sure what the stakeholder actually wants."</p>
<p>Sometimes you'd start with UI to digest the complex requirements, other times you’d start with a simple function, more frequently you'll have to lay out the data foundation at the very beginning.</p>
<p>Your "when" instincts improve with experience, but they're always contextual. The same developer who knows exactly when to optimize for performance in a fintech app might be completely lost about when to write tests in a creative prototype.</p>
<p>The goal isn't perfect timing - it's conscious decision-making. Even when you get it "wrong," knowing <strong>why -</strong> tactical why - you made the choice helps you calibrate for next time. The developers who struggle most are the ones who make these decisions unconsciously, then wonder why their instincts never improve.</p>
<p>So yeah, even in ones and zeros world, developed instinct still valid.</p>
<h3 id="heading-how"><mark>"How"</mark></h3>
<p>As the above elaboration on questions may help you slightly in answering the main "How," keep in mind: the notes from the previous questions do not, in any way, mean to ignore guidelines. You still need to confirm the following practices while answering them: Clean Code, Best Practices, Authentic sources, team documentation and knowledge bases, SOLID and DRY, and all other hot stuff.</p>
<p>Our "How" isn't a tutorial; it's a survival kit that will activate as a primal instinct once you're trapped. To sum up, you'll keep bouncing between "What" and "Where" for a while until you have your mind-map fully developed, stepping into the next stage where all the magic happens. As simple as this, right?</p>
<h2 id="heading-the-existential-thread"><mark>The Existential Thread</mark></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752152384376/ad8e232c-95c5-4149-ba2e-5d43b8af5d70.jpeg" alt class="image--center mx-auto" /></p>
<p><strong>On Context and Complexity</strong>: I'll just remind you that there are no constants—rather the ones you define in your code—in all of that. So yes, context matters. Starting from your workspace, your development environment, to the exact case and scenario you are dealing with at the moment.</p>
<p>While Software Engineering focuses on disciplining development practices and processes, I'm tackling the individual psychology and real-time decision-making that happens within those processes—exploring how management concepts can help navigate the messy human side of coding.</p>
<p><strong>On the "Why" Trap</strong>: Starting with "Why" will lead you to an Existential Crisis; avoid it unless you are ready to fight these battles every day. You start with "when should I use this design pattern" and suddenly you're questioning the nature of universal truth, which is also typically not management's primary domain. But it also happens that practical whys (i.e., choosing one architectural pattern over another for maintainability over performance considerations) lead to the land of existential mines: Why this algorithm? For better performance. Why better performance? For user satisfaction. Why user satisfaction? For business success. Why business success? For... career advancement? Personal fulfillment? Societal contribution? Why do any of those matter? What's the point of any of this work? Why am I spending my finite existence writing code? If you happen to fall into this trap, run, lift weights, tire your body out. Nothing defeats the mind like exhausting the body.</p>
<p><strong>On Effectiveness vs. Balance</strong>: I'm not a fan of "work-life balance"; I'm a fan of "being effective in what you are doing," which might require you to balance things. This means developing mental structures, coping mechanisms, and agility and flexibility to get things done.</p>
<p><strong>On Perspective and Reality</strong>: Absolutely, my notes are irrelevant to other contexts, especially stable and systematic environments. But from where I'm talking, managing any task, let alone completing it, in <strong>Palestine</strong> is a victory over reality <strong><mark>(Militarized, Brutal, yet Liquid Modernity)</mark></strong>, not just an achievement.</p>
<p><strong>On Dramatic Transformation</strong>: Embrace the concept "The deceived is the one whose days are equal" to ensure forward movement without falling into the "why" trap. Switching between implementations while maintaining core principles will definitely add to your day.</p>
<p><strong>On Unconscious Competence</strong>: The best self-management often happens when you're not consciously managing - just following your natural rhythms and instincts.</p>
<hr />
<h2 id="heading-tyrion-lannister-pro-tips">Tyrion Lannister Pro Tips</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752152446511/15b6f090-8137-415c-97a5-4b70314d928a.jpeg" alt class="image--center mx-auto" /></p>
<p>I'm not trying to sell my word as other men's wisdom :) but you could use of them:</p>
<ul>
<li><p>Stick to your circle of competence, even if only momentarily.</p>
</li>
<li><p>Allowance is profitable, restricting is costly.</p>
</li>
<li><p>Answer the questions, even implicitly.</p>
</li>
<li><p>Start with "Where" not with coding, or "Why".</p>
</li>
<li><p>"Why" is a divisive question. Important in some contexts.</p>
</li>
<li><p>When you are under-productive, stop.</p>
</li>
<li><p>When you are super-productive, also stop.</p>
</li>
</ul>
<hr />
<blockquote>
<p>Yes, I accidentally created two sets of 7 points while making fun of '7 Ways' frameworks. The irony is not lost on me. 😄</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA["IAP" The In-App Purchase Journey – Part 1: Intro]]></title><description><![CDATA[Ouch. In-App Purchases (IAP) — also known as “Instant Agony Protocol” — are a true pain in the ass.
Once upon a time, we had a beautiful, well-designed, clearly documented mobile app. Everything was in harmony — code, design, logic — a dev’s little u...]]></description><link>https://dev.fadifannoun.com/iap-the-in-app-purchase-journey-part-1-intro</link><guid isPermaLink="true">https://dev.fadifannoun.com/iap-the-in-app-purchase-journey-part-1-intro</guid><category><![CDATA[antware ]]></category><category><![CDATA[IAP]]></category><category><![CDATA[in-app purchases]]></category><category><![CDATA[Ionic Framework]]></category><category><![CDATA[capacitor]]></category><category><![CDATA[nestjs]]></category><category><![CDATA[In app purchase]]></category><dc:creator><![CDATA[Fadi Fannoun]]></dc:creator><pubDate>Fri, 20 Jun 2025 02:15:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750386178151/495f7cae-a91a-4e44-aa03-eeabc28082ae.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Ouch. In-App Purchases (IAP) — also known as “Instant Agony Protocol” — are a true pain in the ass.</strong></p>
<p>Once upon a time, we had a beautiful, well-designed, clearly documented mobile app. Everything was in harmony — code, design, logic — a dev’s little utopia.</p>
<p>Then came the twist:</p>
<blockquote>
<p>“Users should be able to buy items.”</p>
</blockquote>
<p>Fair enough. I’ve built dozens of apps with third-party payment gateways — Stripe, PayPal, you name it. We scoped the vision, locked the timeline, and moved forward confidently.</p>
<p>But then the client dropped the bomb:</p>
<blockquote>
<p>They <em>had</em> to use the official App Store / Play Store IAP system.</p>
</blockquote>
<p>I paused, blinked, and thought,<br /><strong>“No big deal. How bad could it be? It’s just another payment gateway… right?”</strong></p>
<p>— <em>Naive me, 72 hours before descending into</em> IAP <em>hell.</em></p>
<hr />
<h2 id="heading-what-i-thought-vs-what-actually-happened">💭 <strong>What I Thought vs. What Actually Happened</strong></h2>
<p><strong>What I expected:</strong><br />A weekend project with clean documentation and straightforward integration.</p>
<p><strong>What I got:</strong><br />A month-long odyssey through bureaucratic nightmares, cryptic error messages, and the kind of debugging sessions that make you reconsider your career — and sanity.</p>
<hr />
<h2 id="heading-the-journey-ahead">🚀 <strong>The Journey Ahead</strong></h2>
<p>This series will walk you through the complete IAP implementation — the good, the bad, and the “why-is-this-even-a-thing” ugly. This series covers the complete IAP gauntlet:</p>
<hr />
<h3 id="heading-part-2-store-setup-the-bureaucratic-maze"><strong>Part 2: Store Setup – The Bureaucratic Maze</strong></h3>
<p>Setting up products in both App Store Connect and Google Play Console sounds simple — until you realize each platform speaks a different language.<br />We’ll dive into the endless forms, approval purgatory, and the mysterious art of getting test products to actually show up in sandbox mode.<br /><em>Spoiler alert:</em> “Pending review” will become your least favorite phrase.</p>
<hr />
<h3 id="heading-part-3-ionic-capacitor-implementation-when-plugins-attack"><strong>Part 3: Ionic Capacitor Implementation – When Plugins Attack</strong></h3>
<p>Integrating IAP into Ionic + Capacitor should be plug-and-play, right? <strong>Wrong.</strong><br />We’ll explore the fragmented plugin ecosystem, outdated docs, and the joy of discovering that what works on iOS breaks Android — and vice versa.<br />Plus: the not-so-universal "purchase flow."</p>
<hr />
<h3 id="heading-part-4-the-sync-nightmare-when-reality-hits"><strong>Part 4: The Sync Nightmare – When Reality Hits</strong></h3>
<p>Here’s where things get spicy.<br />Users buy products, but your backend doesn’t know.<br />Receipts validate but aren’t delivered.<br />Network failures create <strong>zombie transactions</strong>.<br />We’ll tackle:</p>
<ul>
<li><p>Receipt validation</p>
</li>
<li><p>Webhook reliability</p>
</li>
<li><p>The dark art of syncing chaotic platforms</p>
</li>
</ul>
<hr />
<h3 id="heading-part-5-admin-features-the-control-room"><strong>Part 5: Admin Features – The Control Room</strong></h3>
<p>Nothing says “pro” like giving your client full control without touching App Store dashboards.<br />We’ll build an admin interface to:</p>
<ul>
<li><p>Track purchases</p>
</li>
<li><p>Handle refunds</p>
</li>
<li><p>Manage IAP products</p>
</li>
</ul>
<p>A lifesaver for you, and your client’s support team.</p>
<hr />
<h2 id="heading-the-reality-check">🧯 <strong>The Reality Check</strong></h2>
<p>If you're about to embark on your own IAP journey, <strong>buckle up.</strong><br />This isn't your average API integration. It’s a multi-platform, multi-store, multi-headache saga that will test your patience, your debugging skills, and possibly your relationship with mobile development.</p>
<p>But once you survive it — and you <em>will</em> — you’ll have conquered one of mobile’s most notorious dragons.</p>
<p>And hey, you’ll have some killer war stories for your next dev meetup.</p>
<hr />
<h2 id="heading-coming-soon">Coming Soon</h2>
<p>🚧 Part 2: Store Setup – The Bureaucratic Maze</p>
<p>💡 As time allows:<br />I’m building <strong>MikaIAP</strong> — a full open-source In-App Purchase system using <strong>Ionic, NestJS, and MikaForm</strong>. Stay tuned for the GitHub release when it’s ready,</p>
]]></content:encoded></item></channel></rss>