Översikt
KlugBilling säljer engångsprodukter och prenumerationer från din AIR-app. På iPhone och iPad kommunicerar det med App Store, på Android med Google Play, och din ActionScript-kod förblir densamma för båda.
Det laddar dina produkter med lokaliserade titlar och priser, öppnar butikens köpruta, rapporterar varje steg i en transaktion och avslutar den när du har levererat produkten. Återställning av tidigare köp, iOS-appkvittot och Google Plays signerade köpdata ingår, så att din server kan verifiera varje försäljning.
På Android använder KlugBilling det aktuella Google Play Billing Library 8. Det läggs till automatiskt när appen paketeras och uppfyller Google Plays krav för nya appar och uppdateringar.
KlugBilling säljer prenumerationerna i våra appar på iOS och Android, vårt proof of concept.
Funktioner
- Fristående: ett ANE, inget kärnbibliotek eller beroende-ANE:er att lägga till
- Ett API för App Store och Google Play
- Engångsprodukter och automatiskt förnyade prenumerationer
- Lokaliserade titlar, beskrivningar och priser direkt från butiken
- Prenumerationsperioder, erbjudanden och prisfaser
- Varje transaktionsstatus som en händelse: köper, köpt, misslyckad, avbruten, återställd, uppskjuten
- Återställ köp (iOS) och lista ägda köp (Android)
- Data för kontroller på serversidan: iOS-appkvittot, Googles signerade köpdata och signatur
- Android: köp kontrolleras mot din offentliga Play-nyckel
Plattformar som stöds
På andra plattformar returnerar InAppBilling.isSupported false, så att samma kod kan ligga kvar i en plattformsoberoende app.
Kom igång
Lägg till tillägget i din applikationsbeskrivning (application descriptor):
<extensions>
<extensionID>com.klug.billing</extensionID>
</extensions>
Inga manifestposter och inga aktiviteter behövs. Skapa dina produkter i App Store Connect och i Google Play Console med samma produkt-ID:n, och kopiera appens offentliga base64-nyckel från Play Console (Monetization setup).
Kodexempel
Fyra kompletta flöden, hämtade från det API som körs i våra appar. Varje anrop returnerar direkt; resultat kommer som händelser på InAppBilling.service. Fullständig dokumentation →
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-översikt
| InAppBilling.isSupported | True på iOS och Android, false på övriga. |
| InAppBilling.service | Den enda butikstjänsten; alla anrop och händelser nedan. |
| setup(service) | Ansluter till butiken som beskrivs av en BillingService. Resultat: SETUP_SUCCESS eller SETUP_FAILURE. |
| checkAvailability(callback) | AVAILABLE, NOT_AVAILABLE eller STORE_UPGRADE_REQUIRED. |
| canMakePayments | False när köp är inaktiverade på enheten. |
| getProducts(productIds, subscriptionIds) | Laddar butiksdata. Resultat: PRODUCTS_LOADED, INVALID_PRODUCT eller PRODUCTS_FAILED. |
| getProduct(id) | En laddad Product: title, description, price, priceString, currencyCode, subscriptionPeriod, subscriptionOffers. |
| makePurchase(request) | Öppnar butikens köpruta för en PurchaseRequest; valfritt prenumerationserbjudande. |
| finishPurchase(purchase) | Avslutar en transaktion efter leverans. Resultat: FINISH_SUCCESS eller FINISH_FAILED. |
| getPendingPurchases() | Transaktioner som butiken fortfarande håller öppna. |
| restorePurchases() | iOS: återställer tidigare köp för Apple-ID:t. |
| getPurchases() | Android: listar Google-kontots köp. |
| applicationReceipt | iOS: appkvittot som base64 för din server, med refresh(). |
| dispose() | Kopplar från butiken. |
Händelser
| InAppBillingEvent | SETUP_SUCCESS, SETUP_FAILURE, RESTORE_PURCHASES_SUCCESS, RESTORE_PURCHASES_FAILED |
| ProductEvent | PRODUCTS_LOADED (products), INVALID_PRODUCT, PRODUCTS_FAILED |
| PurchaseEvent | PURCHASES_UPDATED (data = Purchase-objekt), PURCHASE_FAILED, FINISH_SUCCESS, FINISH_FAILED, RESTORE_PURCHASES_SUCCESS, RESTORE_PURCHASES_FAILED, GET_PURCHASES_COMPLETE, GET_PURCHASES_FAILED |
| AvailabilityEvent | COMPLETE med tillgänglighetsresultatet |
| ApplicationReceiptEvent | REFRESH_SUCCESS, REFRESH_FAILED |
Köp KlugBilling
En årslicens för en AIR-applikation, med alla uppdateringar i 12 månader. Efter betalning får du tillägget, ActionScript-biblioteket och dokumentationen via e-post, vanligtvis inom en arbetsdag. Licens och villkor
- Licens för en AIR-applikation
- Alla uppdateringar i 12 månader
- Ingen support
- Licens för en AIR-applikation
- Alla uppdateringar i 12 månader
- Svar via e-post inom 7 dagar
- Licens för en AIR-applikation
- Alla uppdateringar i 12 månader
- Svar via e-post inom 48 timmar
Krav
| AIR SDK | 51.x (HARMAN) |
| iOS | iOS 13 eller senare, produkter i App Store Connect |
| Android | Android 6.0 (API 23) eller senare, produkter i Google Play Console |
| Google Play | Play Billing Library 8.3, läggs till vid paketeringen |
| Server (rekommenderas) | Verifierar iOS-appkvittot eller Googles signerade köpdata |