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

Prev Next

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

/**
 * @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:

/**
 * @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.

/**
 * @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: 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