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.