--- title: "Apple App Store Integration" slug: "apple-app-store-integration" updated: 2026-07-09T05:09:07Z published: 2026-07-09T05:09:07Z canonical: "help.frisbii.com/apple-app-store-integration" --- > ## Documentation Index > Fetch the complete documentation index at: https://help.frisbii.com/llms.txt > Use this file to discover all available pages before exploring further. # Apple App Store Integration Your backend receives the purchase receipt or transaction ID from the app and forwards it to Frisbii Media for validation. Frisbii Media validates it server-to-server with Apple and returns an `inAppToken`. Two StoreKit versions are supported: - **StoreKit v1** — uses a base64-encoded receipt from `SKPaymentTransaction.transactionReceipt` - **StoreKit v2** — uses a transaction ID string from `Transaction.id` --- ## StoreKit v1 — Add a purchase ```php /** * @Route("/apple/receipts/add", name="AppleReceipt", methods={"POST"}) */ public function addAppleReceipt(Request $request): Response {    $content     = json_decode($request->getContent(), true);    // The app bundle identifier sent by the app as a request header    $appIdentifier = $request->headers->get('x-app-bundle');    // @see https://api.frisbii-media.com/#tag/App-Stores/operation/addAppleAppStorePurchase    $response = json_decode($client->request('POST', '/appstores/apple/purchases', [        'headers' => ['X-plenigo-token' => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9],        'json'    => [            'appIdentifier' => $appIdentifier,            'receiptData'   => $content['receiptData'], // base64-encoded receipt from StoreKit v1        ],    ])->getBody()->getContents(), true);    // inAppToken identifies this purchase until it is associated with a customer    $inAppToken = $response['inAppToken'];    return new JsonResponse(['inAppToken' => $inAppToken]); } ``` --- ## StoreKit v2 — Add a purchase StoreKit v2 uses a transaction ID instead of a receipt blob: ```php /** * @Route("/apple/transactions/add", name="AppleTransaction", methods={"POST"}) */ public function addAppleTransaction(Request $request): Response {    $content       = json_decode($request->getContent(), true);    $appIdentifier = $request->headers->get('x-app-bundle');    // @see https://api.frisbii-media.com/#tag/App-Stores/operation/addAppleAppStorePurchase    $response = json_decode($client->request('POST', '/appstores/apple/purchases', [        'headers' => ['X-plenigo-token' => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9],        'json'    => [            'appIdentifier' => $appIdentifier,            'transactionId' => $content['transactionId'], // transaction ID string from StoreKit v2        ],    ])->getBody()->getContents(), true);    $inAppToken = $response['inAppToken'];    return new JsonResponse(['inAppToken' => $inAppToken]); } ``` --- ## Verify an existing Apple purchase Apple sends server-to-server notifications (App Store Server Notifications) to your backend for subscription events — renewals, cancellations, refunds, billing failures, and so on. Forward each notification to Frisbii Media using the same endpoint to keep the subscription state in sync. ```php /** * @Route("/apple/receipts/verify", name="AppleReceiptVerify", methods={"POST"}) */ public function verifyAppleReceipt(Request $request): Response {    $content       = json_decode($request->getContent(), true);    $appIdentifier = $request->headers->get('x-app-bundle');    // @see https://api.frisbii-media.com/#tag/App-Stores/operation/verifyAppleAppStorePurchase    $response = json_decode($client->request('PUT', '/appstores/apple/purchases/verify', [        'headers' => ['X-plenigo-token' => eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9],        'json'    => [            'appIdentifier' => $appIdentifier,            'receiptData'   => $content['receiptData'], // StoreKit v1            // 'transactionId' => $content['transactionId'], // StoreKit v2        ],    ])->getBody()->getContents(), true);    return new JsonResponse($response); } ``` > [!TIP] > **Tip:** Use the same verify endpoint for both the initial validation callbacks and ongoing renewal callbacks from Apple. The endpoint is idempotent — passing the same receipt twice does not create a duplicate order. --- ## Request payload reference | Field | StoreKit version | Description | | --- | --- | --- | | `appIdentifier` | v1 + v2 | Your Apple App Bundle ID (e.g. `com.example.myapp`) | | `receiptData` | v1 only | Base64-encoded receipt data from `SKPaymentTransaction.transactionReceipt` | | `transactionId` | v2 only | Transaction ID string from `Transaction.id` | --- ## API reference - [addAppleAppStorePurchase](https://api.plenigo.com/#tag/App-Stores/operation/addAppleAppStorePurchase) - [verifyAppleAppStorePurchase](https://api.plenigo.com/#tag/App-Stores/operation/verifyAppleAppStorePurchase) ---