Implementing In-App Purchases in React Native

App Overview

In-app purchases are a way for mobile apps to receive payments from users, either through subscription or one-time payment to unlock specific features or content. In this tutorial, we’ll explore how to implement in-app purchases in React Native, covering both the frontend and backend aspects.

The app we’ll be building is a subscription-based app that requires users to subscribe using in-app purchases to unlock premium features.

Setting Up the Project

Create a new bare Expo project and install the required dependencies:

  • expo-in-app-purchases
  • react-native-start
  • react-native-simple-toast
  • react-native-paper
  • axios
  • expo-secure-store
npm install expo-in-app-purchases react-native-start react-native-simple-toast react-native-paper axios expo-secure-store

Setting Up the Server

Create a new Laravel project and install the required dependencies:

  • Laravel Sanctum
  • Google Cloud PubSub library
composer require laravel/sanctum google/cloud-pubsub

Update the .env file with your database credentials and migrate the database:

php artisan migrate

Setting Up In-App Purchases for Android

Create a subscription on the Google Play Console and set up notifications for subscriptions. Add license testers to test out in-app purchases.

Setting Up In-App Purchases for iOS

Create an auto-renewable subscription on App Store Connect and add it to your app. Update the ios/RNIAPSample.xcworkspace file to add the In-App Purchases capability.

Building the App

Create the login screen, account screen, and locked screen components. Implement the login functionality using Axios and Expo Secure Store:

import axios from 'axios';
import { SecureStore } from 'expo-secure-store';

const login = async () => {
  try {
    const response = await axios.post('/login', {
      username: 'username',
      password: 'password',
    });
    await SecureStore.setItemAsync('token', response.data.token);
  } catch (error) {
    console.error(error);
  }
};

Use the expo-in-app-purchases module to handle in-app purchases:

import { InAppPurchases } from 'expo-in-app-purchases';

const purchase = async () => {
  try {
    const purchase = await InAppPurchases.purchase('com.example.product');
    // Handle purchase result
  } catch (error) {
    console.error(error);
  }
};

Handling Subscriptions in Android

Save the purchase token and order ID in the database when the app makes a request to the /subscribe route:

$request->validate([
    'purchase_token' => 'equired',
    'order_id' => 'equired',
]);

// Save purchase token and order ID to database

Listen for notifications sent by Google Cloud PubSub and update the user’s subscription data:

$pubSub->subscribe('subscription-updated', function ($message) {
    // Update user's subscription data
});

Handling Subscriptions in iOS

Verify the transaction receipt with Apple’s servers using the verifySubscription method:

import { verifySubscription } from './verifySubscription';

const verifyReceipt = async () => {
  try {
    const receipt = await verifySubscription(receiptData);
    // Update user's subscription data if receipt is valid
  } catch (error) {
    console.error(error);
  }
};

Returning Data for Locked Content

Create a controller to return data for locked content:

class LockedContentController extends Controller
{
    public function index()
    {
        // Return data for locked content
    }
}

Running the App

Make the server accessible to the internet using Valet or ngrok. Update the src/config.js file with your HTTPS URL:

export default {
  apiUrl: 'https://example.com/api',
};

Run the app:

npm start

View the project source code on GitHub.

Leave a Reply