Git Product home page Git Product logo

cordova-plugin-wizpurchase's Introduction

cordova-plugin-wizpurchase

A cross-platform mobile application payment API for iOS IAP and Android Billing.

  • PhoneGap Version : 3.3

Major API changes warning

API changed since v1.x.x. Please be sure you target the right version. There are no API changes except on new major versions. If your plugin dependency points directly to Github, make sure to have the right version by adding it at the end of the URL, e.g.: https://github.com/Wizcorp/cordova-plugin-wizpurchase#v1.2.0


NOTE:

  • Not currently supporting subscriptions.
  • Receipts on iOS use API appStoreReceiptURL available from iOS 7

A lot of work from the Android side of this plugin must be credited to @poiuytrez's AndroidInAppBilling plugin. We re-used some plugin class code and all the utility classes, but replaced a lot of the API to be usable in a cross-platform manner with iOS. Many thanks goes to him for his hard work.

Install

via CLI

cordova plugin add https://github.com/Wizcorp/cordova-plugin-wizpurchase --variable BILLING_KEY="YOUR_BILLING_KEY"

via config.xml

<plugin name="cordova-plugin-wizpurchase" spec="2.2.0">
    <variable name="BILLING_KEY" value="YOUR_BILLING_KEY" />
</plugin>

via Phonegap Build (PGB)

<plugin name="cordova-plugin-wizpurchase" spec="2.2.0">
		<param name="BILLING_KEY" value="YOUR_BILLING_KEY" />
</plugin>

You need to specify your billing key only if you need Android support.

Setup

iOS

  • In iTunes Connect create: your application, any items and an IAP test user (on the main screen see "Manage Users").

  • Test on a real device (not simulator).

  • Log out of any existing Apple iTunes accounts on the device before testing.

  • Make sure your application has a version number (do not leave it blank).

Android

  • Set debuggable to false and upload a signed version of you application to the Google Play Developer Console.

  • Add items to the Google Play Developer Console.

  • Upload your apk to Alpha or Beta environment.

  • Add your list of test users (Google Group), in the same screen you should see a link ** *1 **

  • ** *1 download the application from the link above [important!] **

  • Be sure you are logged in to a Google Developer Account on your device.

  • Be sure to use a real device (not emulator).

Purchase Flow

image

Purchase object

Purchase objects contain product information that can be used for verification.

{
	platform: "ios" or "android",
	orderId: transaction identifier for iOS or order ID for Android,
	receipt: purchaseToken or ios receipt as String,
	productId: "sword001",
	packageName: "jp.wizcorp.game",
	purchaseTime: Android-specific, time the product was purchased in ms since the epoch (Jan 1, 1970),
	purchaseState: Android-specific, "0" (purchased), "1" (canceled) or "2" (refunded),
	json: Android-specific, original JSON purchase data,
	developerPayload: Android-specific, string specified by the developer in the purchase request,
	signature: Android-specific, signature of the purchase data signed with the private key of the developer
}

JavaScript APIs

getPendingPurchases(Function success, Function failure)

Get a list of purchases which have not been ended yet using finishPurchase.

  • Return success with an Array of zero or more Purchase objects.
  • Return failure with error

Developers should check any returned items with server APIs and complete their purchase using finishPurchase.

restoreAllPurchases(Function success, Function failure)

Get a list of previous purchases of non-consumable and not yet finished purchases.

  • Return success with an Array of zero or more Purchase objects.
  • Return failure with error

Developers should check any returned items with server APIs. If any items that exist are consumables but have not been consumed, the developer should consume them using finishPurchase because it is likely that a previous purchase was not completed.

makePurchase(String productId, Function success, Function failure)

Make a purchase given a product ID (Quantity is not settable with the API, it is always 1 to be cross-platform complete).

(ANDROID: A NON-CONSUMABLE CANNOT BE PURCHASED IF IT IS ALREADY OWNED [not-consumed], this applies to any product ID that has not been consumed with finishPurchase).

** See security notes below **

  • Return success with a Purchase Object
  • Return failure with error

On success do a receipt verification (if server API exists) gift the user.

| Android Verification API | | --------- |:--------:| ------:| | URIs relative to https://www.googleapis.com/androidpublisher/v1.1/applications, unless otherwise note | | GET | | / [packageName]/inapp/[productId]/purchases/[token] | | Checks the purchase and consumption status of an inapp item. |

| iOS Verification API | | --------- |:--------:| ------:| | Base64 encode the receipt and create a JSON object as follows: { "receipt-data" : "receipt bytes here" }
| POST | | https://buy.itunes.apple.com/verifyReceipt | | JSON is returned. If the value of the status key is 0, this is a valid receipt. |

NOTE: Always verify your receipt for auto-renewable subscriptions first with the production URL; proceed to verify with the sandbox URL if you receive a 21007 status code. Following this approach ensures that you do not have to switch between URLs while your application is being tested or reviewed in the sandbox or is live in the App Store.

finishPurchase(String productId, Boolean isConsumable, Function success, Function failure)

Finish transaction of a purchase for given productId. Its associated product will be consumed if isConsumable is set to true.

  • Return success
  • Return failure with error

getProductDetails(String productId or Array of productIds, Function success, Function failure)

Get the details for a single productId or for an Array of productIds.

  • Return success with Object containing country, currency code and key/value map of products
  • Return failure with error

NB: Currently on Android the country code can not be guessed and as such, it is not returned.

{
	"country": "GB",
	"currency": "GBP",
	"products": {
		"sword001": {
			"productId": "sword001",
			"name": "Sword of Truths",
			"description": "Very pointy sword. Sword knows if you are lying, so don't lie.",
			"price": "Formatted price of the item, including its currency sign.",
			"priceMicros": "Price in micro-units as an unformatted string, where 1,000,000 micro-units equal one unit of the currency."
		},
		"shield001": {
			"productId": "shield001",
			"name": "Shield of Peanuts",
			"description": "A shield made entirely of peanuts.",
			"price": "Formatted price of the item, including its currency sign.",
			"priceMicros": "Price in micro-units as an unformatted string, where 1,000,000 micro-units equal one unit of the currency."
		}
	}
}

or empty { } if productIds was an empty array.

  • Return failure with error as the only argument

refreshReceipt(Function success, Function failure)

Refresh the receipt on iOS, do nothing on Android.

  • Return success
  • Return failure with error

setApplicationUsername(String applicationUsername, Function success, Function failure)

On iOS, set the application username for all purchases following this call. More information here.

Do nothing on Android.

  • Return success
  • Return failure with error

Security notes (Android)

*** You (the developer) should 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. As a further security precaution, you should perform the verification on your own secure server. ***

Error Handling

Failure callbacks return an error as an integer. See the following error table:

Code Constant Description
1 UNKNOWN_ERROR
2 ARGS_TYPE_MISMATCH
3 ARGS_ARITY_MISMATCH
4 IOS_VERSION_ERR
5 INVALID_RECEIPT
6 INVALID_TRANSACTION_STATE
7 PURCHASE_NOT_FOUND
8 PURCHASE_NOT_PENDING
9 REMOTE_EXCEPTION
10 BAD_RESPONSE
11 BAD_SIGNATURE
12 SEND_INTENT_FAILED
13 USER_CANCELLED Indicates that the user cancelled a payment request
14 INVALID_PURCHASE
15 MISSING_TOKEN
16 NO_SUBSCRIPTIONS
17 INVALID_CONSUMPTION
18 CANNOT_PURCHASE Purchasing is not possible for the following reasons:
- purchase is being made on a simulator or emulator,
- the device has been identified as rooted
19 UNKNOWN_PRODUCT_ID Indicates that the requested product is not available or could not be found in the store
20 ALREADY_OWNED [Android only] This item has already been bought. It cannot be bought again without consuming it first
21 NOT_OWNED
22 INVALID_CLIENT Indicates that the client is not allowed to perform the attempted action
23 INVALID_PAYMENT Indicates that one of the payment parameters was not recognized
24 UNAUTHORIZED Indicates that the user is not allowed to authorise payments (e.g. parental lock)
25 RECEIPT_REFRESH_FAILED

====== Ref Links

iOS

http://docs.xamarin.com/guides/ios/application_fundamentals/in-app_purchasing/part_4_-_purchasing_non-consumable_products/

https://github.com/Wizcorp/phonegap-plugin-inAppPurchaseManager/blob/v3.0/platforms/ios/HelloCordova/Plugins/InAppPurchaseManager/InAppPurchaseManager.m

http://stackoverflow.com/a/17734756/2206385

Android

http://developer.android.com/google/play/billing/api.html

http://developer.android.com/training/in-app-billing/purchase-iab-products.html

https://github.com/poiuytrez/AndroidInAppBilling/blob/master/v3/src/android/com/smartmobilesoftware/util/IabHelper.java

https://github.com/poiuytrez/AndroidInAppBilling/blob/master/v3/src/android/com/smartmobilesoftware/inappbilling/InAppBillingPlugin.java

https://developers.google.com/android-publisher/v1_1/

cordova-plugin-wizpurchase's People

Contributors

aogilvie avatar cyrilleguimezanes avatar jrouault 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

Watchers

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

cordova-plugin-wizpurchase's Issues

Apple TestFlight - Feedback

Hello,

Have you ever succefully test the plugin on Apple TestFlight. In my tests, my app crash but I'm not sure if it's because my IAP are not validated yet by Apple.

Any Feedback?

Regards,

Samples in repo

After adding the plugin to my project, I am trying to commit the changes to my project repo. However, your repo contains sample apps for both ios and android and referencing plugin files from within these project. I can understand that it's practical for you during development, however, as a lib user, I don't want to import 2.5 meg of data to my own repo. I am right now trying to find files in plugin.xml, check them in my repo, and ignore all else. This is cumbersome and not trivial at all.

I would suggest to keep the example project somewhere else in the repo, for instance, I created a separate repo for my examples, in each branch of that repo, I am implementing an example for another plugin. (see cordova-facebook and cordova-sample repos of mine)

Android cannot consume unmanaged products

The error callback of consumePurchase is invoked with message:

Sku: ["XXXX"] was not consumable

Looks like mInventory.getPurchase(sku) is returning null even for owned products, though I do see them when I call getPending

This also leads to the item cannot be purchased again (alreadyOwned error)

Is it required to call getProductDetail before makePurchase?

I am building an app with 'premium' features that I wish users to unlock by purchasing a known sku.

However, when I call makePurchase, it can never seem to find the sku. I've followed all steps to setup my test sandbox correctly (APK uploaded to Google Play, digital goods created, test user account setup, etc.) However despite all efforts, it always says that the product cannot be found.

So does that mean I always need to call getProductDetail() before, in order to fill a local cache with necessary data that is used by makePurchase?

getProductDetail with an array of product ids failing in Java

I am calling getProductDetail with an array of id's. When I debug, I see that you are catching some "missingSku" (loop at line 400 in java). Your loop is wrong somehow.

I wanted to fix that issue myself, but, in my opinion, you should not do that check at all, it's my responsibility as an app developer to do that check if I want to. Just return me the data you got from google play as a library.

Android application not building after install. Error: " class WizPurchasePlugin is public, should be declared in a file named WizPurchasePlugin.java"

I installed the file using the following method:

cordova plugin add https://github.com/aogilvie/phonegap-plugin-wizPurchase
cordova build

But when I run cordova build I get the following error and the build fails:

-compile:
    [javac] Compiling 38 source files to D:\wamp\www\AppName\platforms\android\ant-build\classes
    [javac] D:\wamp\www\AppName\platforms\android\src\jp\wizcorp\phonegap\plugin\wizPurchase\wizPurchasePlugin.java:32: error: class WizPurchasePlugin is public, should be declared in a file named WizPurchasePlugin.java
    [javac] public class WizPurchasePlugin extends CordovaPlugin {
    [javac]        ^
    [javac] Note: D:\wamp\www\AppName\platforms\android\src\org\apache\cordova\file\DirectoryManager.java uses or overrides a deprecated API.
    [javac] Note: Recompile with -Xlint:deprecation for details.
    [javac] 1 error

Not exactly sure what to do here to fix it. :/

Edit: I'm also using Cordova 3.5.0. The README of this plugin says Cordova 3.3, so maybe the newer version is breaking things?

Question about Auto-Renewing Subscriptions

Hello!

I am currently using the cordova-purchase-plugin but I am looking to implement auto-renewing subscriptions in my app which seems extremely complicated for some reason.

Does this plugin handle the receipt validation without the need of our own server? If it does not, is there something that is plug and play to handle validation? Ideally, I would love to just fire up a Heroku instance or something to handle it if I can.

How does this plugin handle expired subscriptions and how can I check for that? Didn't see this mentioned in the readme.

Thank you.

wizPurchase.restoreAll always return OK on android

when I try to use wizPurchase.restoreAll(function (result) { alert("OK") }, function (error) { alert("NOT OK!") }); it always return OK.. (Non-consumeable)

makePurchase works as it should (returning error when no login, insufficient funds, etc).

restoreAll works as it should on iOS.

NPE on auto-test done by Google

Hello,

When I publish my app, Google starts auto-test on various devices. Since two releases Google give a NPE with this stack trace:

java.lang.NullPointerException: Attempt to invoke interface method 'android.os.Bundle com.android.vending.billing.IInAppBillingService.getBuyIntent(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String)' on a null object reference
 	at com.smartmobilesoftware.util.IabHelper.launchPurchaseFlow(IabHelper.java:386)
 	at com.smartmobilesoftware.util.IabHelper.launchPurchaseFlow(IabHelper.java:338)
 	at jp.wizcorp.wizpurchase.WizPurchase.buy(WizPurchase.java:416)
 	at jp.wizcorp.wizpurchase.WizPurchase.access$200(WizPurchase.java:40)
 	at jp.wizcorp.wizpurchase.WizPurchase$4.run(WizPurchase.java:296)
 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
 	at java.lang.Thread.run(Thread.java:818)

In a physical use, no exception...

Google told me that the tested device is Galaxy S6 under Android 5.1. Others 5.1 devices pass all the tests.

android crash on

wizPurchase.makePurchase("adfree", function (result) { alert("ok") }, function (error) { alert("nope"); });

iOS purchase restore not work

hello
I do not know if I am writing in the right place.
I'm using this plugin and I have had some problems
The restore purchases "non-consumable" on ios does not work.
They are not returning data to the JS
I think I've solved the problem, I modified the paymentQueueRestoreCompletedTransactionsFinished in WizPurchasePlugin.m function in the following way:

  • (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
    // WizLog(@"[paymentQueueRestoreCompletedTransactionsFinished]");
    if (restorePurchaseCb != NULL) {
    NSMutableArray *receipts;
    receipts = [[NSMutableArray alloc] init];
    if ([[[SKPaymentQueue defaultQueue] transactions] count] > 0) {
    for (SKPaymentTransaction *transaction in [[SKPaymentQueue defaultQueue] transactions]) {
    // Build array of restored receipt items
    // [receipts arrayByAddingObject:[transaction transactionReceipt]];
    NSString *receipt = [[NSString alloc] initWithData:[transaction transactionReceipt] encoding:NSUTF8StringEncoding];
    NSDictionary *result = @{
    @"platform": @"ios",
    @"receipt": receipt,
    @"productId": transaction.payment.productIdentifier,
    @"packageName": [[NSBundle mainBundle] bundleIdentifier]
    };
    WizLog(@"-- %@",result);
    [receipts addObject:result];
    }
    // } else {
    // receipts = [[NSArray alloc] init];
    }

    // Return result to JavaScript
    CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
                                                       messageAsArray:receipts];
    
    [self.commandDelegate sendPluginResult:pluginResult callbackId:restorePurchaseCb];
    restorePurchaseCb = NULL;
    

    }
    }

Android - NPE on cancel purchase

Hello!

I have found an NPE here are the logs:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.smartmobilesoftware.util.Purchase.getSku()' on a null object reference
at jp.wizcorp.wizpurchase.WizPurchase$10.onIabPurchaseFinished(WizPurchase.java:727)

It happen when I start a purchase, and cancel it buy clicking outside de Google Play window.

File:
https://github.com/Wizcorp/cordova-plugin-wizpurchase/blob/master/src/android/WizPurchase.java#L727

I thought about make a PR with a
if(purchase != null)

But not sure if it's normal that purchase is null here...

Regards,

Sample code in README inconsistent with /www sample

First of all - thank you for producing and sharing this plugin.

I'm having some trouble getting it to work however so am trying to explore what's wrong.

I noticed the code snippets shown in the README are different than what this plugin appears to support, as revealed in the sample app found in the /www folder.

For example, in the readme, the getProductDetail() method accepts a single parameter (skus) but in the /www folder I see it also has success / fail callback parameters.

What is the correct JavaScript API for this plugin?

getProductDetail works in test / adhoc builds, not on live (iOS)

Hi, I've used this plugin for the first time and to date everything has worked great. Have been able to test the entire flow and had no issues (in dev & adhoc builds, including via TestFlight). The app has just been approved today and is in the app store. When I install the live app and launch it I receive an error when it calls getProductDetail. I'm not outputting the actual error to the user, just a general message but I know from the message that it's triggered from the fail callback for that method. Have tried with a clean install (removing any test installs) and same issue.

Any idea why this could be?

Method Buy - IllegalStateException

Hello,

On Google Play Console I have crash report with this stack trace:

image

I'm not able to reproduce: When I buy an object everything works well but it's a test purchase.

Do you know if I miss something? This seem to concern every device (3 exemples since I use 2.2.0 )

Frozen UI on Android when I call getProductDetail

I'm not sure why, but when I call the getProductDetail(), the UI in my app freezes and eventually the app crashes. It suggests there might be an out of control loop / memory leak. Is that something you've seen before?

I imported my project into Eclipse so I could debug the app and step through this plugin. I see that the call to init(requestDetailSkus); in the new thread is successfully made (https://github.com/Wizcorp/phonegap-plugin-wizPurchase/blob/master/platforms/android/src/jp/wizcorp/phonegap/plugin/wizPurchase/WizPurchasePlugin.java#L161).

However, after that, the UI freezes.

Any ideas what the problem might be? Or how I can troubleshoot this further?

Note: I get this behavior when running the sample app published in this repo's /www folder

Please help

Hi, this should be asked on StackOverflow, I know, but I am not sure if I get answers there because Google did not find too many wizPurchase hits.

My problem is that nothing seems to happen. I tried to make purchase using debug version of the app and logged the results, hoping I get an error, but nothing. I created signed release version, uploaded to alpha channel, tested using test account, again nothing. Not dialog from Google Play asking for money, no error. I have a div in the page where I log json stringified logs, I use it when I don't have console, in release mode. I tried to write there the success and error responses from wizPurchase.getProductDetails, makePurchase, but nothing appears.

I will paste here some of my code, maybe you find the problem:

import store from '../store'
var dispatch = store.dispatch

var StoreHolder = {}
;(function() {
  window.addEventListener('load', ev => {
    document.addEventListener(
      'deviceready',
      deviceready => {
        console.log('window in deviceready', window)
        init()
      },
      false
    )
  })
})()

function init() {
  dispatch('insertLog', { timeStamp: new Date(), info: 'init window.wizPurchase', details: window.wizPurchase })
  StoreHolder.wizPurchase = window.wizPurchase
}

export default StoreHolder

Then in my Vue.js app I check vor wizPurchase being present and only then I call its methods:

    import StoreHolder from './modules/store'
    //...
    test(id) {
      this.insertLog({ timeStamp: new Date(), info: 'test call', details: StoreHolder })

      if (StoreHolder.wizPurchase) {
        this.insertLog({ timeStamp: new Date(), info: 'test wizPurchase', details: StoreHolder.wizPurchase })
        // I get to this place, StoreHolder.wizPurchase exists and it is logged

        //below code seems to be doing nothing at all, also no error
        StoreHolder.wizPurchase.getProductDetails(
          id,
          success => {
            this.insertLog({ timeStamp: new Date(), info: 'test call', details: success })
            console.log('success', success)
          },
          error => {
            this.insertLog({ timeStamp: new Date(), info: 'test call', details: error })
            console.log('error', error)
          }
        )
      }
    }

Thank you for your help!

java.util.NoSuchElementException - QueryInventoryFinishedListener

QueryInventoryFinishedListener fails for entries which are not the first element in SkuDetails sku : skuList

The following code fails because it calls next on the iterator inside the sku iterator

//This should be caching each entry in requestSkuIter and looping through skuList
if (!sku.getSku().equalsIgnoreCase(requestSkuIter.next()) ) { 

Below is the stack trace

08-29 10:11:47.222: E/AndroidRuntime(9018): java.util.NoSuchElementException
08-29 10:11:47.222: E/AndroidRuntime(9018):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
08-29 10:11:47.222: E/AndroidRuntime(9018):     at jp.wizcorp.phonegap.plugin.wizPurchase.WizPurchasePlugin$2.onQueryInventoryFinished(WizPurchasePlugin.java:523)
08-29 10:11:47.222: E/AndroidRuntime(9018):     at com.smartmobilesoftware.util.IabHelper$2$1.run(IabHelper.java:630)

Android purchase restore - from 0.2.1 to 0.3 - stop working

hello
I do not know if I am writing in the right place.
I'm using this plugin and I have had some problems
after being passed from version 0.2.1 to 0.3, the restore on Android has stopped working.
Always return empty array "[]".

in the function QueryInventoryFinishedListener when create return Object the "developerPayload" not exist in skuObject and cause exception.
I fix with this code:

if(skuObject.has("developerPayload")){
pendingObject.putOpt("developerPayload", skuObject.getString("developerPayload"));
}else{
pendingObject.putOpt("developerPayload", "");
}

Consuming in Android

When I check the consumePurchase call, in readme it says it accepts array. Java side seem to accept object with an array, well the code actually does not implement. There is no loop there (in consumePurchase function) at all!

In any case, I am trying with a single product id. The call fails with Json error. There is also another problem, before null check you are calling purchase.toString to log. Anyway, the clean and working version for consumePurchase body is as follows (for a single product id consuming)

Purchase purchase = myInventory.getPurchase(data.getString(0));
        if (purchase != null) {
            // Consume it
            Log.d(TAG, "purchase is: " + purchase.toString());
            mHelper.consumeAsync(purchase, mConsumeFinishedListener);                   
        } else {
            if (consumeCbContext != null) {
                consumeCbContext.error("notConsumable");
                consumeCbContext = null;
            }
        }

Hope that helps.

Return whole product detail data in getProductDetails (Java)

You are returning only a subset of sku data although SkuDetails type has toJson method. I suppose you are doing this to unify data with iOS side.

However, I would need raw price (price_amount_micros) to sort, report, etc on js side. I also would need currency string, to report to analytics as well.

Please at least add these to data you are returning, iOS has the same properties as well (probably with a different name only)..

orderId in makePurchase (in Java)

You seem to return a very limited set of data on makePurchase response. At least orderId and developerPayload seem to be required. (They are mentioned in your readme at android security notes).

As far as I remember, iOS also has transactionId (similar to orderId). I understand you are trying to unify both markets but in my humble opinion you shouldn't be limiting the users of your library during simplification. I would prefer the whole data coming from google play, you have platform returned anyway.

Typo in config.xml syntaxe

Hello,

There is a small error into your config.xml definition:

<variable name="BILLING_KEY" value="YOUR_BILLING_KEY" />

Become:
<param name="BILLING_KEY" value="YOUR_BILLING_KEY" />

Regards,

Callbacks Not Fired on Android

I've seen at least two errors... "not logged in" and "item not available" while testing my Android integration so far. These were admittedly on a debug build, but the plugin isn't firing the error callbacks at all. I'll try it as an alpha build now.

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.