概要
KlugBilling は、AIR アプリから買い切り商品とサブスクリプションを販売します。iPhone と iPad ではApp Storeと、Android ではGoogle Playと通信し、ActionScript のコードはどちらでも同じです。
ローカライズされたタイトルと価格で商品を読み込み、ストアの購入シートを開き、取引のすべてのステップを報告し、商品を提供した後に取引を完了します。以前の購入の復元、iOS のアプリレシート、Google Play の署名付き購入データも含まれているため、サーバーですべての販売を検証できます。
Android では KlugBilling は最新のGoogle Play Billing Library 8を使用します。アプリのパッケージ化時に自動的に追加され、新規アプリとアップデートに対する Google Play の要件を満たしています。
KlugBilling は、実証の場である当社のアプリの iOS 版と Android 版でサブスクリプションを販売しています。
機能
- 自己完結型:ANE 1つで完結し、コアライブラリや依存 ANE の追加は不要
- App Store と Google Play に共通のひとつの API
- 買い切り商品と自動更新サブスクリプション
- ストアから直接取得する、ローカライズされたタイトル、説明、価格
- サブスクリプション期間、オファー、価格フェーズ
- すべての取引状態をイベントとして通知:購入中、購入済み、失敗、キャンセル、復元、保留
- 購入の復元(iOS)と所有している購入の一覧取得(Android)
- サーバー側での検証用データ:iOS のアプリレシート、Google の署名付き購入データと署名
- Android:購入は Play の公開鍵で検証
対応プラットフォーム
他のプラットフォームでは InAppBilling.isSupported が false を返すため、クロスプラットフォームアプリに同じコードをそのまま残せます。
はじめに
アプリケーション記述子に拡張機能を追加します:
<extensions>
<extensionID>com.klug.billing</extensionID>
</extensions>
マニフェストのエントリもアクティビティも不要です。App Store Connect と Google Play Console で同じ商品 ID を使って商品を作成し、Play Console(収益化のセットアップ)からアプリの base64 公開鍵をコピーします。
コード例
当社のアプリで稼働している API から取り出した、4つの完全なフローです。すべての呼び出しは即座に返り、結果は InAppBilling.service のイベントとして届きます。完全なドキュメント →
import com.klug.billing.*; import com.klug.billing.events.*; var store:InAppBillingService = InAppBilling.service; if ( InAppBilling.isSupported ) // iOS, Android { store.addEventListener( InAppBillingEvent.SETUP_SUCCESS, onSetup ); store.addEventListener( InAppBillingEvent.SETUP_FAILURE, onSetupFailed ); store.addEventListener( PurchaseEvent.PURCHASES_UPDATED, onPurchasesUpdated ); // see 3 var service:BillingService = new BillingService(); if ( store.platform == "android" ) service.setServiceType( InAppBillingServiceTypes.GOOGLE_PLAY_INAPP_BILLING ) .setGooglePlayPublicKey( "MIIBIjANBgkqh..." ); // from the Play Console, Android only else service.setServiceType( InAppBillingServiceTypes.APPLE_INAPP_PURCHASE ); store.setup( service ); } function onSetup( e:InAppBillingEvent ):void { store.checkAvailability( function( result:String ):void { if ( result == InAppBillingAvailability.AVAILABLE ) loadProducts(); // see 2 else hideShop(); // e.g. purchases disabled by Screen Time }); }
function loadProducts():void { store.addEventListener( ProductEvent.PRODUCTS_LOADED, onProducts ); store.addEventListener( ProductEvent.PRODUCTS_FAILED, function( e:ProductEvent ):void { trace( "store not reachable: " + e.message ); }); // one-time products first, subscriptions second store.getProducts( [ "com.example.removeads" ], [ "com.example.pro.monthly", "com.example.pro.yearly" ] ); } function onProducts( e:ProductEvent ):void { for each ( var p:Product in e.products ) { // e.g. "Pro Yearly · 19,99 €" in the user's currency and language addShopButton( p.id, p.title + " · " + p.priceString ); // your app function } }
function buy( productId:String ):void { var request:PurchaseRequest = new PurchaseRequest().setProductId( productId ); if ( store.checkPurchaseRequestValid( request ) ) store.makePurchase( request ); } // every step of every transaction, also open ones from earlier sessions function onPurchasesUpdated( e:PurchaseEvent ):void { for each ( var p:Purchase in e.data ) { switch ( p.transactionState ) { case Purchase.STATE_PURCHASED: case Purchase.STATE_RESTORED: // iOS: p.transactionReceipt (app receipt) // Android: p.originalMessage + p.signature (Google's signed purchase data) verifyOnServer( p, function():void { // your server call unlock( p.productId ); // your app function store.finishPurchase( p ); // close it, or the store sends it again }); break; case Purchase.STATE_FAILED: case Purchase.STATE_CANCELLED: store.finishPurchase( p ); break; case Purchase.STATE_DEFERRED: showHint( "Waiting for approval" ); // e.g. Ask to Buy break; } } }
function restore():void { if ( store.isGetPurchasesSupported ) // Android: list what the Google account owns { store.addEventListener( PurchaseEvent.GET_PURCHASES_COMPLETE, function( e:PurchaseEvent ):void { for each ( var p:Purchase in e.data ) unlock( p.productId ); }); store.getPurchases(); } else // iOS: restored transactions arrive in onPurchasesUpdated with STATE_RESTORED { store.addEventListener( PurchaseEvent.RESTORE_PURCHASES_SUCCESS, function( e:PurchaseEvent ):void { showHint( "Purchases restored" ); }); store.restorePurchases(); } }
API 概要
| InAppBilling.isSupported | iOS と Android では true、それ以外では false です。 |
| InAppBilling.service | 唯一のストアサービスです。以下のすべての呼び出しとイベントはこれを通じて行います。 |
| setup(service) | BillingService で指定されたストアに接続します。結果:SETUP_SUCCESS または SETUP_FAILURE。 |
| checkAvailability(callback) | AVAILABLE、NOT_AVAILABLE、または STORE_UPGRADE_REQUIRED。 |
| canMakePayments | デバイスで購入が無効になっている場合は false です。 |
| getProducts(productIds, subscriptionIds) | ストアのデータを読み込みます。結果:PRODUCTS_LOADED、INVALID_PRODUCT、または PRODUCTS_FAILED。 |
| getProduct(id) | 読み込まれた Product:title, description, price, priceString, currencyCode, subscriptionPeriod, subscriptionOffers。 |
| makePurchase(request) | PurchaseRequest に対してストアの購入シートを開きます。サブスクリプションのオファーは任意です。 |
| finishPurchase(purchase) | 提供後に取引を完了します。結果:FINISH_SUCCESS または FINISH_FAILED。 |
| getPendingPurchases() | ストアでまだ未完了のままの取引。 |
| restorePurchases() | iOS:Apple ID の以前の購入を復元します。 |
| getPurchases() | Android:Google アカウントの購入を一覧表示します。 |
| applicationReceipt | iOS:サーバー用の base64 形式のアプリレシート。refresh() で更新できます。 |
| dispose() | ストアから切断します。 |
イベント
| InAppBillingEvent | SETUP_SUCCESS, SETUP_FAILURE, RESTORE_PURCHASES_SUCCESS, RESTORE_PURCHASES_FAILED |
| ProductEvent | PRODUCTS_LOADED (products), INVALID_PRODUCT, PRODUCTS_FAILED |
| PurchaseEvent | PURCHASES_UPDATED(data = Purchase オブジェクト), PURCHASE_FAILED, FINISH_SUCCESS, FINISH_FAILED, RESTORE_PURCHASES_SUCCESS, RESTORE_PURCHASES_FAILED, GET_PURCHASES_COMPLETE, GET_PURCHASES_FAILED |
| AvailabilityEvent | COMPLETE(利用可否の結果付き) |
| ApplicationReceiptEvent | REFRESH_SUCCESS, REFRESH_FAILED |
KlugBilling を購入
AIR アプリケーション1つ分の年間ライセンスで、12か月間のすべてのアップデートが含まれます。お支払い後、拡張機能、ActionScript ライブラリ、ドキュメントをメールでお送りします(通常は1営業日以内)。ライセンスと条件
動作要件
| AIR SDK | 51.x(HARMAN) |
| iOS | iOS 13 以降、App Store Connect に登録した商品 |
| Android | Android 6.0(API 23)以降、Google Play Console に登録した商品 |
| Google Play | Play Billing Library 8.3(パッケージ化時に追加) |
| サーバー(推奨) | iOS のアプリレシートまたは Google の署名付き購入データを検証 |