In-App Purchase (IAP) API Documentation – Zaigo Infotech Software Solutions

Let’s craft brilliance together!

Request a free consultation and get a no-obligation quote for your project within one working day.

Company-Logo

Error: Contact form not found.

In-App Purchase (IAP) API Documentation

Laravel

PHP

In-App Purchase (IAP) API Documentation

Overview

This document outlines the setup process and API endpoints required for validating and handling In-App Purchases (IAP) from Google Play and the Apple App Store.

Google Play Setup

1. API Access

  • Ensure API access is enabled in the Google Cloud Console. 
  • Verify that the service account is linked to the Google Play Console. 

2. Install Google Client Library (PHP Example)

Run the following command in your project root:

composer require google/apiclient:^2.12

 

3. Sample API Request Body to Validate Subscription

{

  “package_name”: “com.example.app”,

  “product_id”: “monthly_subscription”,

  “purchase_token”: “purchase_token_from_client”

}

 

4. Sample Controller Code to Validate Subscription

namespace App\Http\Controllers\Api;

 

use App\Http\Controllers\Controller;

use App\Services\Api\GooglePlayService;

use Illuminate\Http\Request;

 

class GooglePlayController extends Controller

{

    protected $googlePlayService;

 

    public function __construct(GooglePlayService $googlePlayService)

    {

        $this->googlePlayService = $googlePlayService;

    }

 

    public function verifyPurchase(Request $request)

    {

        $request->validate([

            ‘package_name’ => ‘required’,

            ‘product_id’ => ‘required’,

            ‘purchase_token’ => ‘required’,

        ]);

 

        try {

            $data = $this->googlePlayService->verifySubscription(

                $request->package_name,

                $request->product_id,

                $request->purchase_token

            );

 

            if ($data[‘status’] === ‘valid’) {

                // Handle successful validation

            } else {

                // Handle invalid purchase

            }

        } catch (\Exception $e) {

            // Handle exception

        }

    }

}

 

5. GooglePlayService Class

namespace App\Services\Api;

 

use Google_Client;

use Google_Service_AndroidPublisher;

use Carbon\Carbon;

 

class GooglePlayService

{

    protected $client;

 

    public function __construct()

    {

        $this->client = new Google_Client();

        $this->client->setAuthConfig(base_path(‘service.json’)); // Path to your service account file

        $this->client->addScope(‘https://www.googleapis.com/auth/androidpublisher’);

    }

 

    public function verifySubscription($packageName, $productId, $purchaseToken)

    {

        $service = new Google_Service_AndroidPublisher($this->client);

 

        try {

            $subscription = $service->purchases_subscriptions->get(

                $packageName,

                $productId,

                $purchaseToken

            );

 

            $expiryTimeMillis = $subscription->getExpiryTimeMillis();

            $startTimeMillis = $subscription->getStartTimeMillis();

 

            return [

                ‘status’ => ‘valid’,

                ‘expiry_date’ => Carbon::createFromTimestampMs($expiryTimeMillis)->toDateTimeString(),

                ‘start_date’ => Carbon::createFromTimestampMs($startTimeMillis)->toDateTimeString(),

                ‘auto_renewing’ => $subscription->getAutoRenewing(),

                ‘purchase_state’ => $subscription->getPurchaseState() ?? null,

            ];

        } catch (\Exception $e) {

            // Handle exception

        }

    }

}

 

Google Webhook Setup

  • Ensure the webhook URL is added in the Google Cloud Console and is configured for Pub/Sub push. 
  • The webhook route must not require authentication. 

📌 This webhook is automatically triggered by Google for events such as purchase, cancellation, expiry, renewal, etc.

Webhook Endpoint Example

public function webhook(Request $request)

{

    // Send immediate response to avoid timeout

    response()->json([‘success’ => true])->send();

    flush();

 

    try {

        // Get raw body

        $rawInput = file_get_contents(‘php://input’);

 

        if (empty($rawInput)) {

            return;

        }

 

        // Decode the outer JSON

        $data = json_decode($rawInput, true);

 

        if (!isset($data[‘message’][‘data’])) {

            return;

        }

 

        // Decode the base64 message

        $message = base64_decode($data[‘message’][‘data’]);

        $notification = json_decode($message, true);

 

        // Validate the payload structure

        if (!isset($notification[‘subscriptionNotification’])) {

            throw new \Exception(‘Missing subscriptionNotification key in Google webhook payload.’);

        }

 

        $subscriptionNotification = $notification[‘subscriptionNotification’];

        $subscriptionId = $subscriptionNotification[‘subscriptionId’] ?? null;

        $purchaseToken = $subscriptionNotification[‘purchaseToken’] ?? null;

        $notificationType = $subscriptionNotification[‘notificationType’] ?? null;

        $packageName = $notification[‘packageName’] ?? null;

 

        switch ($notificationType) {

            case 1: // Subscription recovered

                // Handle recovery

                break;

 

            case 2: // Subscription renewed

                // Handle renewal

                break;

 

            case 3: // Subscription cancelled

                // Handle cancellation

                break;

 

            case 4: // Subscription purchased or resubscribed

                // Handle new purchase

                break;

 

            case 5: // SUBSCRIPTION_ON_HOLD

                // Handle expiration

                break;

 

            case 6: // SUBSCRIPTION_IN_GRACE_PERIOD

                // Handle revocation

                break;

 

            case 7: // Subscription restarted

                // Handle restart

                break;

 

            case 13: //SUBSCRIPTION_EXPIRED

                // Reserved for future use

                break;

        }

 

    } catch (\Exception $e) {

        // Log or handle error

    }

}

 

🔗 Reference: Real-time developer notifications (RTDN) – Google Documentation

Can't find what you are looking for?

Post your query now, and we will get in touch with you soon!

    Want to start a project?

    Our team is ready to implement your ideas. Contact us now to discuss your roadmap!

    GET IN TOUCH

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    INDIA

    9thfloor, (9A & 9B) Sapna Trade Centre, 135,
    Old 109, Poonamallee High Rd, Egmore,
    Chennai, Tamil Nadu 600084

    +91 9884783216

    marketing@zaigoinfotech.com

    USA

    170 Post Rd #211, Fairfield,
    CT 06824,
    USA

    +1 904-672-8617

    sales@zaigoinfotech.com