Giter Club home page Giter Club logo

gdx-pay's Introduction

Maven Central

This project aims to provide a cross-platform API for InApp purchasing. The gdx-pay project is a libGDX extension. Current release version is 1.3.7. Please use at least libGDX v1.9.8 or Robovm 2.3.5.

SNAPSHOT builds are published regularly on https://oss.sonatype.org/content/repositories/snapshots/.

Supported payment services

Click on the links to view the subproject's readme files for service-dependant information and artifacts.

Installation

The recommended way to use gdx-pay is via dependency management with Gradle or Maven. Artifacts are available in Maven Central.

project-root/build.gradle:

ext {
    gdxPayVersion = '1.3.7'
}

Add the following dependencies:

core:

    implementation "com.badlogicgames.gdxpay:gdx-pay-client:$gdxPayVersion"

html:

    implementation "com.badlogicgames.gdxpay:gdx-pay:$gdxPayVersion:sources"
    implementation "com.badlogicgames.gdxpay:gdx-pay-client:$gdxPayVersion:sources"

You also need to add the following file to your GdxDefinition.gwt.xml in your html project:

    <inherits name="com.badlogic.gdx.pay_client"/>

That's all you need to use gdx-pay in the core project. Of course, you want to use a certain IAP service in your game. Look in the service subproject's readme files linked above.

Usage

The main interface you use to communicate with payment services is the PurchaseManager. Add a field holding it to your main game class:

public PurchaseManager purchaseManager;

In the launcher class you instantiate the PurchaseManager for the payment service you want to use:

game.purchaseManager = new DesiredPlatformPurchaseManager(...);

See the documentation of your desired payment service linked above on how to instantiate its PurchaseManager implementation.

Configuration

Before using the PurchaseManager for payments, it needs to get installed: You need to provide a callback listener implementing the PurchaseObserver interface and a configuration. Typically, the configuration just passes the items you want to offer:

PurchaseManagerConfig pmc = new PurchaseManagerConfig();
pmc.addOffer(new Offer().setType(OfferType.ENTITLEMENT).setIdentifier(YOUR_ITEM_SKU));
pmc.addOffer(new Offer().setType(OfferType.CONSUMABLE).setIdentifier(YOUR_ITEM_SKU));
pmc.addOffer(new Offer().setType(OfferType.SUBSCRIPTION).setIdentifier(YOUR_ITEM_SKU));
// some payment services might need special parameters, see documentation
pmc.addStoreParam(storename, param)

purchaseManager.install(new MyPurchaseObserver(), pmc, true);

When the PurchaseManager is sucessfully installed, your PurchaseObserver will receive a callback and purchaseManager.installed() will return true. That might take some seconds depending on the payment service. You can now request information or purchase items.

If you are completely done with the PurchaseManager, call its dispose() method.

Request item information

It is important to know which of the items you added to the configuration are available at which price. Use getInformation() to retrieve an item Information object to do so:

Information skuInfo = purchaseManager.getInformation(sku);
if (skuInfo == null || skuInfo.equals(Information.UNAVAILABLE)) {
   // the item is not available...
   purchaseButton.setDisabled(true);
} else {
   // enable a purchase button and set its price label
   purchaseButton.setText(skuInfo.getLocalPricing());
}

Purchase items

This is for what you are reading this! It is pretty easy to start a purchasement:

purchaseManager.purchase(sku);

If the purchasement was successfully done, you will receive a call to PurchaseObserver.handlePurchase(). If there was an error, you might receive a call to your observer's handlePurchaseError() or handlePurchaseCanceled() method.

Restore purchases

If the user reinstalls your game or erased its data, it is important to let him restore his past purchases. You can do so by calling

purchaseManager.purchaseRestore()

You will get a callback to your observer's handleRestore() method with a list of past transactions.

Please note: Don't use this to query the user's bought entitlements on every game start, but persist them yourself. Call this method only when the user hits a "reclaim" button. The most important reasons for this:

  • (iOS only) Apple will reject your game if it calls purchaseRestore() without user interaction
  • You get only reliable results if the device is connected to the internet. If you don't persist entitlements yourself, your paying users are not able to use their purchases offline.
  • purchaseRestore() might take some time to fetch its results

Example project

If you have questions or problems, take a look at the example project demonstrating how to configure and use gdx-pay.

News & Community

Check the libGDX blog for news and updates. You can get help on the libGDX forum and talk to other users on the IRC channel #libgdx at irc.freenode.net or the libgdx discord.

Reporting Issues

Something not working quite as expected? Do you need a feature that has not been implemented yet? Check the issue tracker and add a new one if your problem is not already listed. Please try to provide a detailed description of your problem, including the steps to reproduce it.

Building from source

To build from source, clone or download this repository, then open it in Android Studio. Perform the following command to compile and upload the library in your local repository:

./gradlew publishToMavenLocal

See build.gradle file for current version to use in your dependencies.

Contributing

Awesome! If you would like to contribute with a new feature or a bugfix, fork this repo and submit a pull request. Also, before we can accept substantial code contributions, we need you to sign the libGDX Contributor License Agreement.

License

The gdx-pay project is licensed under the Apache 2 License, meaning you can use it free of charge, without strings attached in commercial and non-commercial projects. We love to get (non-mandatory) credit in case you release a game or app using gdx-pay!

gdx-pay's People

Contributors

aberkowski avatar adventuretc avatar alex-dorokhov avatar arthurtemple avatar b4dt0bi avatar bachtrong43 avatar balepc avatar bitdream avatar blueriverinteractive avatar calfur avatar fmatera-duckma avatar fstranieri avatar jstuyts avatar junkdog avatar just4phil avatar keesvandieren avatar liliomk avatar lucas-kakele avatar mobidevelop avatar moritzmusel avatar mrstahlfelge avatar noblemaster avatar peterwilli avatar piotr-j avatar prineside avatar simonit avatar tom-ski avatar xoppa avatar zfreeds avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gdx-pay's Issues

Purchasing a subscription on openiab results in an error

I'm not very familiar with gdx-pay, but it looks like there's an issue with purchasing a subscription on android/openiab. When purchasing an Offer with type OfferType.SUBSCRIPTION it results in the following error:

IabResult: -1008, IAB returned null purchaseData or dataSignature (response: -1008:Unknown error)

this link suggests that this line should call helper.launchSubscriptionPurchaseFlow instead when its type is subscription.

Onactivityresult

I integrated Google play IAP yesterday (by the way: our little framework is awesome!! ;)
But now my app crashes after purchasing.... I think it is caused because I didn't set on activity result.....
What exactly must I do to make the request code thing work correctly on android and where?

ERROR ITMS-90035: "Invalid Signature. A sealed resource is missing or invalid

When i use gdx-pay-0.6.0 and gdx-pay-iosrobovm-apple, and upload .ipa use Application Loader i have problem :

"ERROR ITMS-90035: "Invalid Signature. A sealed resource is missing or invalid. Make sure you have signed your application with a distribution certificate, not an ad hoc certificate or a development certificate. Verify that the code signing settings in Xcode are correct at the target level (which override any values at the project level). Additionally, make sure the bundle you are uploading was built using a Release target in Xcode, not a Simulator target. If you are certain your code signing settings are correct, choose "Clean All" in Xcode, delete the "build" directory in the Finder, and rebuild your release target. For more information, please consult https://developer.apple.com/library/ios/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html",

but when i use gdx-pay-0.5.0 it upload good. i can't use 0.5.0 because it has problem NoSuchMethodError: org.robovm.apple.storekit.SKPayment.createFromProduc

java.lang.NoClassDefFoundError

@noblemaster
i added the gdx-pay projects to my game and added them to the build-paths
but i always get java.lang.NoClassDefFoundError: com.badlogic.gdx.pay.android.ouya.PurchaseManagerAndroidOUYA
(and for the androidIAB too)
what can be the reason? (does all that reflection code work properly?)

Failed to invoke onActivityResult , 1.6.2 + gdx pay 4.0 & 5.0-SNAPSHOT Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.sec.android.iap.service.iapService }

this happens on Android 5.0 , Samsung S5, Google Play 5.6.8

openiab-0.9.8.6

but on different test devices it works as expected

what the hell ? ;)

06-10 12:34:58.293: D/GdxPay/IAP(23868): Failed to invoke onActivityResult(...) on purchase manager.
06-10 12:34:58.293: D/GdxPay/IAP(23868): java.lang.reflect.InvocationTargetException
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at java.lang.reflect.Method.invoke(Native Method)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at java.lang.reflect.Method.invoke(Method.java:372)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at com.badlogic.gdx.pay.android.IAP.onActivityResult(IAP.java:99)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at com.badlogic.gdx.backends.android.AndroidApplication.onActivityResult(AndroidApplication.java:473)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.Activity.dispatchActivityResult(Activity.java:6475)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3970)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4017)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ActivityThread.access$1400(ActivityThread.java:172)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1471)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.os.Handler.dispatchMessage(Handler.java:102)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.os.Looper.loop(Looper.java:145)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ActivityThread.main(ActivityThread.java:5832)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at java.lang.reflect.Method.invoke(Native Method)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at java.lang.reflect.Method.invoke(Method.java:372)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
06-10 12:34:58.293: D/GdxPay/IAP(23868): Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.sec.android.iap.service.iapService }
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1982)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:2090)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.app.ContextImpl.bindService(ContextImpl.java:2068)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at android.content.ContextWrapper.bindService(ContextWrapper.java:559)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at org.onepf.oms.appstore.SamsungAppsBillingService.bindIapService(SamsungAppsBillingService.java:383)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at org.onepf.oms.appstore.SamsungAppsBillingService.handleActivityResult(SamsungAppsBillingService.java:268)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at org.onepf.oms.OpenIabHelper.handleActivityResult(OpenIabHelper.java:1341)
06-10 12:34:58.293: D/GdxPay/IAP(23868):    at com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB.onActivityResult(PurchaseManagerAndroidOpenIAB.java:437)

Missing PurchaseObserver & PurchaseSystem in JAR's

Hi

I just updated my JAR's from 0.5 > 0.6 and com.badlogic.gdx.pay.PurchaseObserver and com.badlogic.gdx.pay.PurchaseSystem are gone.

Unless I am missing something, doesn't this break all the things?

Amazon Fire TV not recognized during reflection?

Hi @noblemaster
if i use gdx-pay regularly on my amazon fire tv i always get a purchasemanager == null.
after investigation i found out:

gdxClazz = com.badlogic.gdx.Gdx
gdxLifecycleListenerClazz = com.badlogic.gdx.LifecycleListener
gdxAppObject = null !!! => Object gdxAppObject = gdxClazz.getField("app").get(null);
gdxAppLogMethod => fails because gdxAppObject == null => catch error

with deactivated purchasesystem all is running fine!

what can be the problem?
bye
phil

Is gdx-pay compatible to ouya-sdk-2.0.1?

I prefer using dependencies instead of manually copying ouya-sdk.jar to the libs folder.

repositories {
    maven {
        url "http://maven.ouya.tv/"
    }
}
dependencies {
    compile 'ouya:ouya-sdk:2.0.1'
}

Since the latest ouya-sdk is 2.0.1 which means they did a major release lately, I wonder if using this version of ouya-sdk is breaking gdx-pay. The ouya-sdk in this repository is from 2014 and i cannot figure out which version this is. If 2.0.1 breaks gdx-pay, what is the version in this repository?

Android: PurchaseSystem.install(...) throws exception

If you call PurchaseSystem.install(...) in ApplicationListener.create()/ApplicationAdapter.create() like in the test (https://github.com/libgdx/gdx-pay/blob/master/gdx-pay-tests/src/com/badlogic/gdx/pay/tests/PayTest.java) you get the following exception on Android:

02-07 01:30:50.183  21823-21855/com.example.game E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 877
    Process: com.example.game, PID: 21823
    java.lang.IllegalStateException: Must be called from UI thread.
            at org.onepf.oms.OpenIabHelper.finishSetup(OpenIabHelper.java:896)
            at org.onepf.oms.OpenIabHelper.finishSetup(OpenIabHelper.java:889)
            at org.onepf.oms.OpenIabHelper.finishSetup(OpenIabHelper.java:881)
            at org.onepf.oms.OpenIabHelper.setupWithStrategy(OpenIabHelper.java:539)
            at org.onepf.oms.OpenIabHelper.startSetup(OpenIabHelper.java:519)
            at com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB.install(PurchaseManagerAndroidOpenIAB.java:222)
            at com.badlogic.gdx.pay.PurchaseSystem.install(PurchaseSystem.java:168)
            at com.example.game.Main.create(Main.java:124)
            at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:241)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1511)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)

With version 0.2.0 that doesn't happen.

Query inventory without internet connection

It's not possible to offline query inventory (without sku details). querySkuDetails variable (line 249 in file gdx-pay/gdx-pay-android-openiab/src/com/badlogic/gdx/pay/android/openiab/PurchaseManagerAndroidOpenIAB.java ) is always set up to true. According to this comment http://stackoverflow.com/questions/14231859/how-to-best-save-inapp-purchase-status-locally#comment41999027_15569448 it could be fixed by changing querySkuDetails to false. I know that this variable cannot always be false, but maybe it could be parametrized earlier.

IAP: gdx-pay successfully instantiated.

Dear all,

I do not know if I am doing anything wrong, gdx-pay seems to work very well the only thing is when I hit the back button on android, the following log keeps appearing "IAP: gdx-pay successfully instantiated." infinitly... and if I get back to my game the phone completly freeze. It seems that gdx-pay instantiation is called in a loop.... (via reflection??) .

[iOS] NoSuchMethodError: org.robovm.apple.storekit.SKPayment.createFromProduct

Hi,

Recently I tried testing my in app purchases on iOS and it doesnt work as expected.
I updated to the latest LibGDX (1.5.5) and RoboVM (1.0.0)

I can recall it used to work (or atleast purchasing) and I am stuck on this error when I try to purchase a product:

java.lang.NoSuchMethodError: org.robovm.apple.storekit.SKPayment.createFromProduct(Lorg/robovm/apple/storekit/SKProduct;)Lorg/robovm/apple/storekit/SKPayment;
    at com.badlogic.gdx.pay.ios.apple.PurchaseManageriOSApple.purchase(PurchaseManageriOSApple.java)
    at com.badlogic.gdx.pay.PurchaseSystem.purchase(PurchaseSystem.java)
    at co.codebuffet.mazle.shop.ItemButton.didClick(ItemButton.java)
    at co.codebuffet.libraries.DarkeningImageScrollButton$1.touchUp(DarkeningImageScrollButton.java)
    at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java)
    at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java)
    at com.badlogic.gdx.InputMultiplexer.touchUp(InputMultiplexer.java)
    at com.badlogic.gdx.backends.iosrobovm.IOSInput.processEvents(IOSInput.java)
    at com.badlogic.gdx.backends.iosrobovm.IOSGraphics.draw(IOSGraphics.java)
    at com.badlogic.gdx.backends.iosrobovm.IOSGraphics$1.draw(IOSGraphics.java)
    at org.robovm.apple.uikit.UIView.$cb$drawRect$(UIView.java)
    at org.robovm.apple.uikit.UIApplication.main(Native Method)
    at org.robovm.apple.uikit.UIApplication.main(UIApplication.java)
    at co.codebuffet.mazle.IOSLauncher.main(IOSLauncher.java)

I also removed my robovm cache prior to running (using rm -rf ~/.robovm/cache) and strangely enough, loading products seems to work fine:

[GdxPay/AppleIOS] Products successfully received!
[GdxPay/AppleIOS] Purchase observer successfully installed!

I'm struggling with this all day and still am :( It would be really nice if someone knows what's going on! Thanks in advance!

Update

It seems that RoboVM updated their function naming!
See: http://docs.robovm.com/api/1.0.0/org/robovm/apple/storekit/SKPayment.html#createFromProduct-org.robovm.apple.storekit.SKProduct-
It's called public static SKPayment create(SKProduct product) in 1.0.0

But let's take a beta of 1.0 (LibGDX 1.5.4 uses the snapshot build of robovm): http://docs.robovm.com/api/1.0.0-beta-03/org/robovm/apple/storekit/SKPayment.html#createFromProduct-org.robovm.apple.storekit.SKProduct-
There it's called: public static SKPayment createFromProduct(SKProduct product)

Update 2
Testing fix now

OUYA Backend: Order ID/Purchase Date

What would it take to supply order ID and Purchase date for each transaction for the OUYA backend? It's difficult to differentiate orders on a server if those are missing. At least Order ID would be very nice to have.

Also, I updated OpenIAB & the iOS backend to allow purchases for product identifiers that were added after both backends are installed. What would it take to add that to OUYA as well?

No rush :-D

getInformation(...) for Google play

Is getInformation implemented for Google play yet? I looked at the code but wasn't sure and couldn't get it work on my device. I really need this to provide In-App-Purchase only in selected countries.

Could not find property 'sourceSets' on project ':gdx-pay-tests-iosrobovm'.

hi @noblemaster
after pulling the latest changes i cant gradle-refresh my projects anymore:


FAILURE: Build failed with an exception.

  • Where:
    Build file 'L:\Bitbucket\gdx-pay\gdx-pay-tests-iosrobovm\build.gradle' line: 1

  • What went wrong:
    A problem occurred evaluating project ':gdx-pay-tests-iosrobovm'.

    Could not find property 'sourceSets' on project ':gdx-pay-tests-iosrobovm'.

IAB helper setup is in progress. Can't perform operation: queryInventory

09-15 20:16:57.952: E/OpenIAB(6040): Illegal state for operation (queryInventory): IAB helper setup is in progress.
09-15 20:16:57.952: W/dalvikvm(6040): threadid=14: thread exiting with uncaught exception (group=0x40c431f8)
09-15 20:16:57.962: E/AndroidRuntime(6040): FATAL EXCEPTION: GLThread 569
09-15 20:16:57.962: E/AndroidRuntime(6040): java.lang.IllegalStateException: IAB helper setup is in progress. Can't perform operation: queryInventory
09-15 20:16:57.962: E/AndroidRuntime(6040): at org.onepf.oms.OpenIabHelper.checkSetupDone(OpenIabHelper.java:1545)
09-15 20:16:57.962: E/AndroidRuntime(6040): at org.onepf.oms.OpenIabHelper.queryInventoryAsync(OpenIabHelper.java:1441)
09-15 20:16:57.962: E/AndroidRuntime(6040): at com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB.purchaseRestore(PurchaseManagerAndroidOpenIAB.java:364)
09-15 20:16:57.962: E/AndroidRuntime(6040): at com.twosquidgames.ninesquids.handlers.PlatformResolver.requestPurchaseRestore(PlatformResolver.java:56)
09-15 20:16:57.962: E/AndroidRuntime(6040): at com.twosquidgames.ninesquids.NineSquids.create(NineSquids.java:1347)

Crashed in IOS

When I made a purchase, the last output was "Purchasing product my product ...", then the game crashed.This situation was random, but once it appear, it appear every time after that moment. The crash log was:

Incident Identifier: F38A4409-CA2E-4615-9FE6-6EB1F8400A4E
CrashReporter Key: c31979bcee3754c5758b99fee7e241707111909f
Hardware Model: iPhone5,2
Process: xmjwz [10752]
Path: /private/var/mobile/Containers/Bundle/Application/1F97A1A6-441D-46C4-A9E2-6F556487E73F/xmjwz.app/xmjwz
Identifier: me.gall.zumafighter
Version: 1506021500 (1.0.2)
Code Type: ARM (Native)
Parent Process: launchd [1]

Date/Time: 2015-06-03 10:19:13.944 +0800
Launch Time: 2015-06-03 10:18:40.694 +0800
OS Version: iOS 8.0.2 (12A405)
Report Version: 105

Exception Type: EXC_BAD_ACCESS (SIGABRT)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000
Triggered by Thread: 0

Last Exception Backtrace:
0 CoreFoundation 0x27851e3a exceptionPreprocess + 122
1 libobjc.A.dylib 0x34effc86 objc_exception_throw + 34
2 CoreFoundation 0x27851d80 +[NSException raise:format:] + 108
3 xmjwz 0x00292a1c 0x9a000 + 2066972
4 libsystem_platform.dylib 0x355bf86e _sigtramp + 30
5 xmjwz 0x00600f84 0x9a000 + 5664644
6 xmjwz 0x0046ebfc 0x9a000 + 4017148
7 xmjwz 0x0046e174 0x9a000 + 4014452
8 StoreKit 0x2ac70094 __NotifyObserverAboutChanges + 80
9 CoreFoundation 0x27764088 CFArrayApplyFunction + 32
10 StoreKit 0x2ac70030 -[SKPaymentQueue _notifyObserversAboutChanges:sendUpdatedDownloads:] + 124
11 StoreKit 0x2ac70942 -[SKPaymentQueue _processUpdates:trimUnmatched:sendUpdatedDownloads:] + 1070
12 StoreKit 0x2ac71028 -[SKPaymentQueue _setTransactionsWithReply:] + 124
13 StoreKit 0x2ac6fbc8 __38-[SKPaymentQueue _establishConnection]_block_invoke_2 + 56
14 libdispatch.dylib 0x3545f8c6 _dispatch_call_block_and_release + 6
15 libdispatch.dylib 0x3545f8b2 _dispatch_client_callout + 18
16 libdispatch.dylib 0x354630ba _dispatch_main_queue_callback_4CF + 718
17 CoreFoundation 0x27817be4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE
+ 4
18 CoreFoundation 0x278162e4 __CFRunLoopRun + 1508
19 CoreFoundation 0x2776461c CFRunLoopRunSpecific + 472
20 CoreFoundation 0x2776442e CFRunLoopRunInMode + 102
21 GraphicsServices 0x2eb130a4 GSEventRunModal + 132
22 UIKit 0x2ad4f354 UIApplicationMain + 1436
23 xmjwz 0x00a93d14 0x9a000 + 10460436
24 xmjwz 0x00a93376 0x9a000 + 10457974
25 xmjwz 0x00a92a72 0x9a000 + 10455666
26 xmjwz 0x00799d52 0x9a000 + 7339346
27 xmjwz 0x00be433e 0x9a000 + 11838270
28 xmjwz 0x00bdce5e 0x9a000 + 11808350
29 xmjwz 0x00bde912 0x9a000 + 11815186
30 xmjwz 0x00bde968 0x9a000 + 11815272
31 xmjwz 0x00bd8c76 0x9a000 + 11791478
32 xmjwz 0x00bd1184 0x9a000 + 11760004
33 xmjwz 0x002c3714 0x9a000 + 2266900

And my code:

        PurchaseManagerConfig config = new PurchaseManagerConfig();
        config.addOffer(new Offer().setType(OfferType.CONSUMABLE).setIdentifier("my product"));
        PurchaseSystem.install(new PurchaseObserver()
        {

            @Override
            public void handleRestoreError(Throwable e)
            {
                // TODO Auto-generated method stub
            }

            @Override
            public void handleRestore(Transaction[] transactions)
            {
                // TODO Auto-generated method stub

            }

            @Override
            public void handlePurchaseError(Throwable e)
            {
                e.printStackTrace();
                PurchaseSystem.dispose();
            }

            @Override
            public void handlePurchaseCanceled()
            {
                PurchaseSystem.dispose();
            }

            @Override
            public void handlePurchase(Transaction transaction)
            {
                System.out.println(transaction.getIdentifier());
                PurchaseSystem.dispose();
            }

            @Override
            public void handleInstallError(Throwable e)
            {
                e.printStackTrace();
                PurchaseSystem.dispose();
            }

            @Override
            public void handleInstall()
            {
                PurchaseSystem.purchase("my product");
            }
        }, config);

libgdx:1.5.6
gdx-pay:0.5.0-SNAPSHOT
robovm:1.3.0

iOS: SKPayment create() is protected -> Constructor made public

Hey,

it seems like starting with RoboVM 1.8, the SKPayment class has changed. SKPayment.create() is made protected, which I think is why PurchaseManageriOSApple produces a NoSuchMethodError exception when running the purchase() method:
java.lang.NoSuchMethodError: org.robovm.apple.storekit.SKPayment.create(Lorg/robovm/apple/storekit/SKProduct;)Lorg/robovm/apple/storekit/SKPayment; at com.badlogic.gdx.pay.ios.apple.PurchaseManageriOSApple.purchase(PurchaseManageriOSApple.java) at com.badlogic.gdx.pay.PurchaseSystem.purchase(PurchaseSystem.java)

I'd say we are required to call the constructor for SKPayment instead.

EDIT: OK, I see now that this is already fixed in 0.6.0-SNAPSHOT. Sorry, and thanks for making this project! :)

Gdx-pay issue

Hi,

I've managed to implement gdx-pay in my game. However, I am always getting

"Authentication error, you need to sign in with your google account."

I suspect I've set the wrong google play key. I haven't yet finished my game so I haven't uploaded my game to the google store so I don't have a google key. Is it a google developer key meant or another key? If I don't have a key how can I test gdx-pay in my app? Any info appreciated.

Thank you

gdx-pay-tests-android

gdx-pay-tests-android cant run with last pull.

PS: In my project:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
SkyIslandGUI skyIslandGUI = new SkyIslandGUI();
initialize(skyIslandGUI);

if (PurchaseSystem.hasManager()) {
     PurchaseManagerConfig config2 = new PurchaseManagerConfig();
    config.addOffer(new Offer().setType(OfferType.CONSUMABLE).setIdentifier("fish.coin"));
    config.addStoreParam(PurchaseManagerConfig.STORE_NAME_ANDROID_GOOGLE, GOOGLEKEY);
        PurchaseSystem.install(new PurchaseObserver() {
        ...
        }, config);
}

}

02-04 20:29:35.844: E/AndroidRuntime(28093): Caused by: java.lang.RuntimeException: Problem setting up in-app billing: IabResult: 3, No suitable appstore was found (response: 3:Billing Unavailable)

consume purchased item

In google play we can't buy item that already owned. How to consume purchased item?

Thanks for creating this wonderful framework :)

NoClassDefFoundError: org.onepf.oms.OpenIabHelper$Options$Builder

Hello, I am just learning to work with libGdx and gdx-pay.And i have the following problem:

java.lang.NoClassDefFoundError: org.onepf.oms.OpenIabHelper$Options$Builder
at com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB.install(PurchaseManagerAndroidOpenIAB.java:219)
at com.badlogic.gdx.pay.PurchaseSystem.install(PurchaseSystem.java:168)
at com.altinntech.slots.services.PlatformResolver.initializeIAP(PlatformResolver.java:29)
at com.altinntech.slots.AndroidResolver.(AndroidResolver.java:28)
at com.altinntech.slots.MainActivity.onCreate(MainActivity.java:185)

In the build.gradle i addded:

     project(":android") {
apply plugin: "android"

configurations { natives }

repositories {
    mavenCentral()
    maven { url "https://oss.sonatype.org/content/repositories/releases/" }
}


dependencies {
    compile project(":core")
    compile 'com.facebook.android:facebook-android-sdk:4.4.0'
    compile "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
    natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
    compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi-v7a"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86"
    compile "com.badlogicgames.gdxpay:gdx-pay-android:$gdxpayVersion"
    compile "com.badlogicgames.gdxpay:gdx-pay-android-openiab:$gdxpayVersion"

// compile "com.badlogicgames.gdxpay:gdx-pay-android-openiab:$gdxpayVersion:library"
// compile "com.badlogicgames.gdxpay:gdx-pay-android-ouya:$gdxpayVersion"
// compile "org.onepf:openiab:0.9.8.7"
compile fileTree(dir: 'libs', include: ['*.jar'])
}
}

if I add ... compile "org.onepf:openiab:0.9.8.7" then see the error

Error:Gradle: Execution failed for task ':android:dexDebug'.

com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.8.0_25\bin\java.exe'' finished with non-zero exit value 2

Please tell me, what am I doing wrong?

iOS NullPointerException

I'm currently running RoboVM version 1.1.0 and gdx-pay version 0.4.0.

Please let me know if you'd like more information.

2015-05-18 18:48:29.771 IOSLauncher[431:40159] [debug] IOSApplication: iOS version: 8.3
2015-05-18 18:48:29.773 IOSLauncher[431:40159] [debug] IOSApplication: Running in 32-bit mode
2015-05-18 18:48:29.786 IOSLauncher[431:40159] [debug] IOSApplication: scale: 2.0
2015-05-18 18:48:29.872 IOSLauncher[431:40159] [debug] IOSApplication: Unscaled View: LandscapeRight 568x320
2015-05-18 18:48:29.873 IOSLauncher[431:40159] [debug] IOSApplication: View: LandscapeRight 1136x640
2015-05-18 18:48:29.873 IOSLauncher[431:40159] [debug] IOSGraphics: 1136.0x640.0, 2.0
2015-05-18 18:48:30.197 IOSLauncher[431:40159] [debug] IOSGraphics: Display: ppi=326, density=2.0375
2015-05-18 18:48:30.607 IOSLauncher[431:40159] [debug] IOSApplication: created
2015-05-18 18:48:30.919 IOSLauncher[431:40159] [debug] didBecomeActive: Returning from: fb
2015-05-18 18:48:30.920 IOSLauncher[431:40159] [debug] IOSApplication: resumed
Loading class 'java.util.logging.ConsoleHandler' failed
java.lang.ClassNotFoundException: java.util.logging.ConsoleHandler
2015-05-18 18:48:32.988 IOSLauncher[431:40159] [info] IAP: IAP: gdx-pay successfully instantiated.
[GdxPay/AppleIOS] Installing purchase observer...
[GdxPay/AppleIOS] Requesting products...
[GdxPay/AppleIOS] Products successfully received!
[GdxPay/AppleIOS] Purchase observer successfully installed!
java.lang.NullPointerException
    at com.badlogic.gdx.pay.ios.apple.PurchaseManageriOSApple$AppleTransactionObserver.updatedTransactions(PurchaseManageriOSApple.java)
    at org.robovm.apple.storekit.SKPaymentTransactionObserver$ObjCProxy.$cb$paymentQueue$updatedTransactions$(Unknown Source)
    at org.robovm.apple.uikit.UIApplication.main(Native Method)
    at org.robovm.apple.uikit.UIApplication.main(UIApplication.java)
    at com.company.game.IOSLauncher.main(IOSLauncher.java)

Building with gradle results in dependencies not found

I might be missing something as I am new to gradle but it looks like the sub projects have their dependency versions set to unspecified:

https://repo1.maven.org/maven2/com/badlogicgames/gdxpay/gdx-pay-android-openiab/0.1.0/gdx-pay-android-openiab-0.1.0.pom

which causes you to get this error when building:

A problem occurred configuring project ':common-android'.

Could not resolve all dependencies for configuration ':common-android:_debugCompile'.
Could not find libgdx-pay:gdx-pay:unspecified.
Required by:
games:common-android:1.0 > com.badlogicgames.gdxpay:gdx-pay-android:0.1.0
Could not find libgdx-pay:gdx-pay-android:unspecified.
Required by:
games:common-android:1.0 > com.badlogicgames.gdxpay:gdx-pay-android-openiab:0.1.0
games:common-android:1.0 > com.badlogicgames.gdxpay:gdx-pay-android-ouya:0.1.0

java.lang.NoSuchMethodError: org.onepf.oms.OpenIabHelper$Options$Builder.setStoreSearchStrategy

I am trying to use gdx-pay in my game but I get error when I try to install PurchaseObserver:
PurchaseSystem.install(new PurchaseObserver() {

The error I get is this:
03-13 23:05:11.953: E/AndroidRuntime(12352): java.lang.NoSuchMethodError: org.onepf.oms.OpenIabHelper$Options$Builder.setStoreSearchStrategy
03-13 23:05:11.953: E/AndroidRuntime(12352): at com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB.install(PurchaseManagerAndroidOpenIAB.java:221)
03-13 23:05:11.953: E/AndroidRuntime(12352): at com.badlogic.gdx.pay.PurchaseSystem.install(PurchaseSystem.java:168)

I have added jar of gdx-pay-0.4.0 to core project,
gdx-pay-android-0.4.0 and gdx-pay-android-openiab-0.4.0 to android project.

Can anyone help me out. What am I doing wrong?

Unfinished transactions are not restored on iOS

If anything bad is occurred during handling transaction in observer (like NPE, out of memory, shutdown of the device, or any other unexpected exit from the app), then transaction is not marked as finished. The consequences are:

  1. You spent your money and gets nothing back
  2. If you try to buy the same item (in hope it will be bought this time), you gets the message: "This item is already bought, you will get it for free.", then you press OK and nothing happens. If you press again to buy the item, it shows the same message. Even if you reinstall the app, it will not help.

It is written in the Apple docs, SQPaymentQueue should be called right at the app start, before any other action is performed with the queue. In the current version the transaction observer is set up after product information is fetched. I have tried to change gdx-pay to setup observer right inside PurchaseManager.install method and this helped to finish the transaction and get my gems, which I have paid for.

But the problem is SKPaymentQueue restores unfinished transactions before we have any information about products (like price and currency), which is required to fill gdxpay.Transaction object (see PurchaseManageriOSApple.transaction(SKPaymentTransaction)). So, seems it is kind of a dead loop.

Seems to fix this bug, we need an architectural change. Or do you have any other ideas?

Nullpointerexception for PurchaseSystem.getInformation on android 4.x

PurchaseSystem.getInformation(..) throws NullPointerException when a device is in airplanemode.

Error occurred with both 0.5.0 and 0.6.0-SNAPSHOT. Only with android 4.x (tested on Galaxy S3, Note 1), not on 2.x (Galaxy S1) or 5.x (Note 3).

It happens always in the emulator regardless of the android version.

How to use developerPayload in Google In-app?

Hi,
Follow Google development doc here: https://developer.android.com/google/play/billing/billing_integrate.html

Security Recommendation: When you send a purchase request, create a String token that uniquely identifies this purchase request and include this token in the developerPayload.You can use a randomly generated string as the token. When you receive the purchase response from Google Play, make sure to check the returned data signature, the orderId, and the developerPayload String. For added security, you should perform the checking on your own secure server. Make sure to verify that the orderId is a unique value that you have not previously processed, and the developerPayload String matches the token that you sent previously with the purchase request.

How can I send a developerPayload with identifier?

Thanks,

Module reaarange for GWT support

I found, that gdx-pay is not ready to be used with GWT.
A project using gdx-pay just can't be compiled with GWT, because of using java reflections in PurchaseSystem.
Libgdx provides ClassReflection utility to use reflections in cross-platform way. But in this case gdx-pay module will be dependent from libgdx, and then gdx-pay-server will also depend from libgdx.
So I suggest to add additional module: gdx-pay-common, which will contain common classes for gdx-pay and gdx-pay-server, but will not depend from libgdx. So, gdx-pay-server will not depend from gdx-pay, but only from gdx-common. And gdx-pay will depend from libgdx. That will also simplify PurchaseSystem code. However it will make it impossible to use gdx-pay without libgdx.
What do you think? Once you agree on the changes, I will implement them.

Android 2.3.3: Error refreshing inventory (querying prices of items).

gdx-pay works fine on my Nexus 5 (5.0.2) and Nexus 7 2012 (5.0.1) but on my Galaxy S1 (2.3.3) I get the following exception when the app starts.

01-01 01:10:28.023    1232-1280/com.example.game E/OpenIAB﹕ queryInventoryAsync() Error :
    org.onepf.oms.appstore.googleUtils.IabException: Error refreshing inventory (querying prices of items). (response: 6:Error)
            at org.onepf.oms.appstore.googleUtils.IabHelper.queryInventory(IabHelper.java:588)
            at org.onepf.oms.OpenIabHelper.queryInventory(OpenIabHelper.java:1371)
            at org.onepf.oms.OpenIabHelper$17.run(OpenIabHelper.java:1423)
            at java.lang.Thread.run(Thread.java:1019)
01-01 01:10:28.093    1232-1283/com.example.game E/OpenIAB﹕ queryInventoryAsync() Error :
    org.onepf.oms.appstore.googleUtils.IabException: Error refreshing inventory (querying prices of items). (response: 6:Error)
            at org.onepf.oms.appstore.googleUtils.IabHelper.queryInventory(IabHelper.java:588)
            at org.onepf.oms.OpenIabHelper.queryInventory(OpenIabHelper.java:1371)
            at org.onepf.oms.OpenIabHelper$17.run(OpenIabHelper.java:1423)
            at java.lang.Thread.run(Thread.java:1019)
01-01 01:10:28.097    1232-1232/com.example.game D/AndroidRuntime﹕ Shutting down VM
01-01 01:10:28.097    1232-1232/com.example.game W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x40015578)
01-01 01:10:28.117    1232-1232/com.example.game E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB$3.onQueryInventoryFinished(PurchaseManagerAndroidOpenIAB.java:356)
            at org.onepf.oms.OpenIabHelper$17$1.run(OpenIabHelper.java:1435)
            at android.os.Handler.handleCallback(Handler.java:587)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:123)
            at android.app.ActivityThread.main(ActivityThread.java:3687)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:507)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
            at dalvik.system.NativeStart.main(Native Method)

Testing for amazon - billing unavailable

(0.5.0-snapshot)

build gradle, android part:
...
compile "com.badlogicgames.gdxpay:gdx-pay-android:$gdxPayVersion"
compile "com.badlogicgames.gdxpay:gdx-pay-android-openiab:$gdxPayVersion:library"
compile "com.badlogicgames.gdxpay:gdx-pay-android-ouya:$gdxPayVersion:library
...

I've tried all possible combinations but I always get this on start when testing for amazon :

error installing purchase manager: java.lang.RuntimeException: Problem setting up in-app billing: IabResult: 3, No suitable appstore was found (response: 3:Billing Unavailable)

What am I doing wrong? App tester is there, json on sdcard and store app is installed and also installing apk using this:

adb install -i com.amazon.venezia com.package.name

But with gdx-pay I get only billing unavailable. What's interesting using the same environment with clean OpenIAB works fine!

Amazon AppStore is even supported at this time? Please let me know if you know how to fix it.

OUYA Mgr: do we need Looper / Looper.prepare() ?

hi friends!
in PurchaseManagerAndroidOUYA.java -> row 194 i use the Handler to send messages to the ui-thread.
i dont call Looper.prepare and Looper.loop() but evrything works fine!
so i am a bit confused if that is needed and why it works without!?
if we need it there then how? (i tried to implement it but got some errors .... maybe because the manager is not a thread)
bye
phil

dependency to gdx-pay-client:0.6.0-SNAPSHOT

The released version of android pay has a dependency to the above mentioned jar, which doesn't exist in the maven repo. I think you need to update to to the released version

Purchase restoration on iOS

As of now, I am not locally storing items that have been purchased. On Android, that isn't a problem because I'm able to call PurchaseSystem.purchaseRestore and build the array of unlocked id's at runtime every time the app is launched.

On iOS, restoring the purchases displays an ugly password prompt and will also get the app rejected if it's not done explicitly by the user. As such, should the app persist purchases locally? If so, I think a note should be added to the readme to reflect this.

Presumably, using libgdx's Preferences class for this shouldn't be much of a problem, right?

proguard problem with 0.4.0/0.5.0-SNAPSHOT (0.3.0 did work)

I get this error with 0.4.0/0.5.0-SNAPSHOT: (0.3.0 does work work) when proguard is enabled. Tried both proguard configurations mentioned in the README and the one in the WIKI.

Warning: com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB: can't find referenced method 'org.onepf.oms.OpenIabHelper$Options$Builder setStoreSearchStrategy(int)' in program class org.onepf.oms.OpenIabHelper$Options$Builder
Warning: there were 1 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile the code.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
:android:proguardDebug FAILED

cant work with libraries

@noblemaster
hi chris!
i just wanted to try to work with the gradle dependencies. i added to gradle.build:

gdxpayVersion = '0.2.0-SNAPSHOT'
compile "com.badlogicgames.gdxpay:gdx-pay:$gdxpayVersion:library"

after gradle-refresh all the compiling worked without errors, but i cant import the classes in eclipse.
PurchaseSystem.hasManager() => PurchaseSystem cannot be resolved

what can be the reason?

gdx-pay (iOS) transaction.getTransactionData() == null

Hello! I test in-app purchase service in my application (for ios) . Tell me please what's wrong: I made a purchase, it was successfully. But validation at the server not passed because "transaction.getTransactionData() == null".

NPE in PurchaseManagerAndroidOpenIAB setup callback

Using latest gdx-pay and google play store I got the following exception:

java.lang.NullPointerException
       at com.badlogic.gdx.pay.android.openiab.PurchaseManagerAndroidOpenIAB$1$1.onIabSetupFinished(PurchaseManagerAndroidOpenIAB.java:248)
       at org.onepf.oms.appstore.googleUtils.IabHelper$1.onServiceConnected(IabHelper.java:267)
       at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1110)
       at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1127)
       at android.os.Handler.handleCallback(Handler.java:733)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:136)
       at android.app.ActivityThread.main(ActivityThread.java:5050)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
       at dalvik.system.NativeStart.main(NativeStart.java)

Seems, helper was set to null before OpenIAB had replied...

purchaseManager is null but PurchaseSystem.resolve() gives no information

I'm trying to use gdx-pay 0.5.0 for Android and iOS using the platform resolvers from the wiki. I have no problems with Android. But in iOS, I always get this error when trying to buy something:
[info] ERROR: gdx-pay: requestPurchase(): purchaseManager == null
That's not surprising because the purchaseManager is already null when I call the "initializeIAP" method. There I get "gdx-pay: initializeIAP(): purchaseManager == null => call PurchaseSystem.hasManager()". hasManager() (=false) calls getManager() and getManager() calls resolve(). So resolve() should give me some information on why there is no purchaseManager. But I don't get any errors until I click the button that calls the purchase() method.

TrivialDrive

I need a method for this:
// Do we have the premium upgrade?
Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
mIsPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));

can u add more interface in PurchaseManager to check products purchased.
I think you should make an example as TrivialDrive.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.