---
title: "Building Apps With a Purpose: Charitable Payments in iOS"
description: "Integrating charitable micro-donations into iOS apps using StoreKit - the technical implementation and the philosophy behind purpose-driven software."
date: 2026-01-18T00:00:00.000Z
category: iOS
readingTime: "4 min read"
---


Software doesn't have to be transactional. It can be purposeful. With Snooze If You Can, I wanted to prove that a free, open-source app could also be a vehicle for doing good - one snooze at a time.

## The Concept

Every time you snooze your alarm in Snooze If You Can, you have the option to make a small donation to Darüşşafaka, a Turkish educational foundation that provides free education to children who have lost one or both parents. The idea is simple: if you're going to lose five more minutes of your morning, at least make those five minutes count for someone.

It's opt-in, configurable, and completely transparent. Users choose their donation amount per snooze (from ₺1 to ₺10), and every transaction is visible in-app.

## Why Darüşşafaka

Darüşşafaka has been providing free education since 1863 - over 160 years. It's one of Turkey's oldest and most respected educational institutions. Children who can't afford education get a full scholarship including boarding, meals, and educational materials.

As someone who's benefited enormously from access to education and technology, directing micro-donations to educational access felt right. The foundation is reputable, transparent with its finances, and the impact is direct - your donation supports a specific child's education.

## StoreKit 2 Integration

Apple's StoreKit 2 framework handles in-app purchases and subscriptions. For charitable donations through the App Store, the technical implementation uses consumable in-app purchases.

```swift
import StoreKit

class DonationManager: ObservableObject {
    @Published var products: [Product] = []
    
    func loadProducts() async {
        do {
            products = try await Product.products(for: [
                "donation_tier_1",  // ₺1
                "donation_tier_2",  // ₺3
                "donation_tier_5",  // ₺5
                "donation_tier_10"  // ₺10
            ])
        } catch {
            print("Failed to load products: \(error)")
        }
    }
    
    func purchase(_ product: Product) async throws -> Transaction? {
        let result = try await product.purchase()
        
        switch result {
        case .success(let verification):
            let transaction = try checkVerified(verification)
            await transaction.finish()
            return transaction
        case .userCancelled, .pending:
            return nil
        @unknown default:
            return nil
        }
    }
}
```

StoreKit 2's async/await API is a significant improvement over the original StoreKit. Purchase flows are straightforward: load products, present them, process the result.

## The Apple Tax Question

Apple takes a 30% cut (15% for small businesses) of every in-app purchase, including charitable donations. This is the most common criticism of the approach.

I considered alternatives:
- **Direct payment processing** - bypasses Apple's cut but violates App Store guidelines for digital goods
- **Web-based donations** - allowed, but adds friction (users leave the app to donate)
- **External link** - Apple now permits links to external payment methods in some regions, but the UX is clunky

The pragmatic choice: use StoreKit and accept the platform fee. The alternative - not having donations at all because the fee isn't ideal - helps nobody. 70-85% of the donation reaching the foundation is better than 0%.

I'm transparent about this in the app. The donation screen shows exactly what percentage reaches Darüşşafaka after Apple's fee.

## Tracking and Transparency

Every donation is tracked locally and users can view their donation history:

```swift
struct DonationRecord: Codable, Identifiable {
    let id: UUID
    let date: Date
    let amount: Decimal
    let productId: String
    let transactionId: UInt64
    let netAmount: Decimal // after Apple's cut
}
```

The app shows:
- Total donated this month
- Total donated all-time
- Breakdown by donation tier
- Estimated net amount reaching the foundation

No data is sent to external servers. All donation records are stored locally in the user's device using SwiftData. Privacy is non-negotiable.

## The UI: Making Giving Feel Good

The donation flow is integrated into the alarm experience without being pushy:

1. **Alarm goes off** → Complete challenge → Alarm dismissed
2. **Post-dismissal screen** shows a gentle prompt: "Make your morning count?"
3. **One tap** to donate at the user's pre-configured tier
4. **Confirmation** with a simple animation and the running total

The key UX principle: charitable giving should feel rewarding, not guilting. The prompt appears after the alarm is dismissed (not during, when the user is frustrated). The language is positive. The default is to skip - donations are never the default action.

## Server-Side Verification

For donation integrity, every transaction is verified server-side using Apple's App Store Server API:

```swift
func verifyTransaction(_ transaction: Transaction) async -> Bool {
    // Verify the JWS (JSON Web Signature) signed by Apple
    guard let appTransaction = try? await AppTransaction.shared else {
        return false
    }
    
    // Verify the transaction belongs to this app
    // and hasn't been previously consumed
    return transaction.productType == .consumable
        && transaction.environment == .production
}
```

This prevents receipt fraud - someone couldn't forge a donation record to inflate their dashboard numbers. Every donation displayed in the app corresponds to a verified Apple transaction.

## Impact So Far

Since launching the donation feature:

- Hundreds of micro-donations processed
- Users who enable donations snooze less frequently (an unexpected behavioral side effect - perhaps knowing a snooze costs something, even voluntarily, makes you think twice)
- Multiple users requested additional foundation options - planning to add more in a future update

## Lessons for Purpose-Driven Apps

1. **Make it opt-in.** Forced charitable features breed resentment. Optional ones build loyalty.
2. **Be transparent about fees.** Users respect honesty about platform costs.
3. **Privacy first.** Donation data is personal. Keep it on-device.
4. **Don't over-complicate.** One tap to donate. One screen to review. That's it.

Building software with purpose doesn't require a nonprofit structure or a complex social impact framework. It requires a simple question: "Can this app do something good while doing what it already does?"

For Snooze If You Can, the answer was yes.

---

*Building an app? Consider how it could make a small positive impact. Micro-donations, awareness features, or educational components - purpose doesn't have to be the product. It can be a feature.*
