見出し画像

React Native で iOSのアプリ内課金 を試す

「React Native」で「iOSのアプリ内課金」を試したのでまとめました。


前回

1. アプリ内課金

「アプリ内課金」の種類は、次の3つです。

1-1. 消耗型

料金を​支払って​獲得した​ものを​一度の​使用で​終了する​課金方式です。​使い​切りの​ため、​必要になるたびに​何度も​支払う​ことに​なります。

【例】
・ゲーム内で使える通貨やアイテム
・ガチャ

1-2. 非消耗型

一度の​支払いで​購入した​コンテンツや​機能を​永続的に​利用できるようになる​課金方式です。

【例】
・​アプリの機能​制限の​解除 (永続)
・​書籍の​閲覧制限の​解除
(永続)
・​広告の​非表示
(永続)

1-3. サブスクリプション

月ごとなど​一定の​期間に​一定額の​料金を​支払う​契約に​より、​期間内で​あれば​所定の​サービスを​自由に​利用する​ことのできる​課金方式です。ユーザーが​解約するまで​持続的に課金できます。

【例】
・​アプリの機能​制限の​解除
・​書籍の​閲覧制限の​解除
・​広告の​非表示

2. アプリ内課金のアイテムの準備

(1) 「App Store Connect」のアプリページで「収益化→商品→アプリ内アイテム」を選択し、「アプリ内課金+」をクリック。

(3) アイテムの情報を入力して、「作成」をクリック。

・種類 : 消費型
・参照名 
: 100コイン
・製品ID : net.npaka.hello.coin100

(4) 「配信可否」「価格表」「税金カテゴリ」「App Storeのローカリゼーション」を設定して「保存」をクリック。

3. アプリ内課金の実装

アプリ内課金の実装手順は、次のとおりです。

(1) パッケージのインストール。

npm install react-native-iap

(2) 「App.tsx」を次のように編集。
実運用では、自前のサーバーにレシートを送り、検証してはじめて購入完了となります。finishTransaction() は、「App Store」に購入が完了したことを通知するために必要です。

import React, { useEffect, useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import * as RNIap from 'react-native-iap';

// アイテムの型定義
interface IAPProduct {
  productId: string;
  title: string;
  description: string;
  localizedPrice: string;
}

// アイテムID
const productIds = ['net.npaka.hello.coin100'];

// アプリ
export default function App() {
  const [products, setProducts] = useState<IAPProduct[]>([]);

  // 初期化
  useEffect(() => {       
    const initIAP = async () => {
      try {
        // 課金機能の初期化
        await RNIap.initConnection();

        // プロダクト情報を取得
        const availableProducts = await RNIap.getProducts({skus: productIds}); 
        setProducts(availableProducts);
      } catch (err: any) {
        console.warn(err.code, err.message);
      }      
    };

    initIAP();

    return () => {
      RNIap.endConnection(); // 後処理
    };
  }, []);

  const purchaseProduct = async (productId: string) => {
    try {
      // アイテムを購入
      const purchase = await RNIap.requestPurchase({
        sku: productId,
        andDangerouslyFinishTransactionAutomaticallyIOS: false,
      });
      if (purchase && !Array.isArray(purchase)) {
        // レシートの取得
        const receipt = purchase.transactionReceipt;
        Alert.alert('購入成功', `レシート: ${receipt}`);

        // トランザクション終了
        await RNIap.finishTransaction({
          purchase: purchase,
          isConsumable: true,
        });          
      }
    } catch (err: any) {
      console.warn(err.code, err.message);
      Alert.alert('購入失敗', err.message);
    }
  };

  return (
    <View>
      <Text></Text>
      <Text></Text>
      <Text></Text>
      <Text>アプリ内課金のアイテム</Text>
      {products.map((product) => (
        <View key={product.productId}>
          <Text>{product.title}</Text>
          <Text>{product.localizedPrice}</Text>
          <Button
            title="購入"
            onPress={() => purchaseProduct(product.productId)}
          />
        </View>
      ))}
    </View>
  );
};

(2) アプリの実行。
アプリの動作確認を行います。

npm start



この記事が気に入ったらサポートをしてみませんか?