In-App Purchase (IAP) Flow
Flow Overview
These diagrams outline the different parts of the process for handling Apple In-App Purchases.
1. Initial Purchase Flow (Client-Side - DEPRECATED)
2. Apple Server Notifications & Subscription Update
3. Transaction History Fetching
Process Description
-
Initial Purchase (Client-Side Triggered): Note: This flow relying on the client sending the final transaction is considered deprecated. The preferred method relies on Apple Server-to-Server notifications (see Point 2).
- User initiates a purchase in the mobile app for a
VipPackage. - The app calls the backend's
createFirstOrderendpoint (handled byInAppPurchaseService). - An
Orderrecord is created withstatus = PENDING,payment_method = IAP, and a uniqueiap_order_id(UUID). Thisiap_order_idis returned to the app. - The app uses the product ID (
iap_product_id) to proceed with the Apple purchase flow, providing theiap_order_idas theappAccountToken. - Upon successful Apple payment, the app receives transaction details.
- The app sends these transaction details back to the backend's
/callbackendpoint (from mobile). InAppPurchaseService::callbackcallsprocessClientCallbackNotification.processClientCallbackNotificationcallsupdateOrderto find the pendingOrder(usingiap_order_idfrom the transaction'sappAccountToken) and updates itsstatustoCOMPLETED, storing payment details (payment_reference_id,paid_amount,paid_currency, etc.). It also calculates potential free trial days.- The
OrderObserver(triggered by theOrderupdate) callsVipSubscriptionServiceto create/activate theVipSubscription. (See VIP Subscriptions Flow for details on subscription creation/activation logic).
- User initiates a purchase in the mobile app for a
-
Server-to-Server Notifications (Apple Triggered):
- Apple sends notifications (callbacks) to the backend endpoint for various subscription events (e.g.,
SUBSCRIBED,DID_RENEW,EXPIRED,DID_FAIL_TO_RENEW,REFUND,DID_CHANGE_RENEWAL_PREF,PRICE_INCREASE). - The callback endpoint receives the signed payload and dispatches
ProcessIapCallbackJob. - The job calls
InAppPurchaseService::callback(with$from_mobile = false). InAppPurchaseServicefirst logs the raw callback data usingcreateCallbackLog.- It then calls
processServerCallbackNotification, parsing the signed transaction and notification data. - Based on the
notificationTypeandsubtype, it routes to specific handling methods:subscriptibe: Handles initial buys or resubscriptions. It might update an existing pending order or create a new completed order if the subscription originated outside the app flow (e.g., managed directly in the App Store). CallsVipSubscriptionService::renewVipSubscription.renewSubscription: Handles successful renewals. Creates a newOrderrecord for the renewal transaction usingcreateRenewOrderand callsVipSubscriptionService::renewVipSubscription.expireSubscription: Handles expirations or renewal failures. CallsVipSubscriptionService::processExpireVipSubscription.refundSubscription: Handles refunds. CallsVipSubscriptionService::refundVipSubscription.- Other methods (
upgradeSubscription,downgradeSubscription,handlePriceIncreaseNotification): Handle specific lifecycle events, often interacting withVipSubscriptionService.
- Note: The core logic for creating, updating, and managing the state of the
VipSubscriptionrecord itself (e.g., setting dates, status, history) resides within theVipSubscriptionService, as detailed in the VIP Subscriptions Flow.
- Apple sends notifications (callbacks) to the backend endpoint for various subscription events (e.g.,
-
Fetching Transaction History:
- The
getHistoriesmethod allows fetching notification/transaction history from Apple's API for a given date range. - It uses a JWT token for authentication with Apple's API.
- It handles pagination (
paginationToken,hasMore) using theloopmethod if necessary to retrieve all records. - It parses the signed payloads (
signedPayload,signedTransactionInfo) from the history response. - It can return raw transaction data, associated order IDs, user IDs, etc.
- The
Key Models & Services
- InAppPurchaseService: Core service handling all interactions with Apple's IAP system (callbacks, history, transaction parsing).
- Order: Represents the purchase transaction, linking the User and VipPackage, storing payment status and IAP details (
iap_order_id,payment_reference_id). - VipPackage: Defines the product being purchased, including its
iap_product_id. - VipSubscription: Represents the user's access grant, managed based on order completion and IAP notifications.
- VipSubscriptionService: Handles the business logic for creating, renewing, expiring, and refunding
VipSubscriptionrecords based on triggers fromInAppPurchaseServiceorOrderObserver. - CallbackLog: Stores raw data received from Apple's server-to-server notifications for auditing and debugging.
- User: The customer account making the purchase.
- ProcessIapCallbackJob: A queued job to process incoming Apple server notifications asynchronously.
- OrderObserver: Listens for
Ordermodel events (specifically updates) to triggerVipSubscriptionServiceactions upon order completion.