Giter Club home page Giter Club logo

stripe-java's Introduction

Stripe Java client library

Maven Central JavaDoc Build Status Coverage Status

The official Stripe Java client library.

Installation

Requirements

  • Java 1.8 or later

Gradle users

Add this dependency to your project's build file:

implementation "com.stripe:stripe-java:25.11.0"

Maven users

Add this dependency to your project's POM:

<dependency>
  <groupId>com.stripe</groupId>
  <artifactId>stripe-java</artifactId>
  <version>25.11.0</version>
</dependency>

Others

You'll need to manually install the following JARs:

If you're planning on using ProGuard, make sure that you exclude the Stripe client library. You can do this by adding the following to your proguard.cfg file:

-keep class com.stripe.** { *; }

Documentation

Please see the Java API docs for the most up-to-date documentation.

See video demonstrations covering how to use the library.

You can also refer to the online Javadoc.

Usage

StripeExample.java

import java.util.HashMap;
import java.util.Map;

import com.stripe.StripeClient;
import com.stripe.exception.StripeException;
import com.stripe.model.Customer;
import com.stripe.net.RequestOptions;
import com.stripe.param.CustomerCreateParams;

public class StripeExample {

    public static void main(String[] args) {
        StripeClient client = new StripeClient("sk_test_...");
        CustomerCreateParams params =
            CustomerCreateParams
                .builder()
                .setDescription("Example description")
                .setEmail("[email protected]")
                .setPaymentMethod("pm_card_visa")  // obtained via Stripe.js
                .build();

        try {
            Customer customer = client.customers().create(params);
            System.out.println(customer);
        } catch (StripeException e) {
            e.printStackTrace();
        }
    }
}

See the project's functional tests for more examples.

Per-request Configuration

All of the request methods accept an optional RequestOptions object. This is used if you want to set an idempotency key, if you are using Stripe Connect, or if you want to pass the secret API key on each method.

RequestOptions requestOptions = RequestOptions.builder()
    .setApiKey("sk_test_...")
    .setIdempotencyKey("a1b2c3...")
    .setStripeAccount("acct_...")
    .build();

client.customers().list(requestOptions);

client.customers().retrieve("cus_123456789", requestOptions);

Configuring automatic retries

The library can be configured to automatically retry requests that fail due to an intermittent network problem or other knowingly non-deterministic errors. This can be enabled globally:

StripeClient client = StripeClient.builder()
        .setMaxNetworkRetries(2)
        .build();

Or on a finer grain level using RequestOptions:

RequestOptions options = RequestOptions.builder()
    .setMaxNetworkRetries(2)
    .build();
client.customers().create(params, options);

Idempotency keys are added to requests to guarantee that retries are safe.

Configuring Timeouts

Connect and read timeouts can be configured globally:

StripeClient client = StripeClient.builder()
        .setConnectTimeout(30 * 1000); // in milliseconds
        .setReadTimeout(80 * 1000);
        .build();

Or on a finer grain level using RequestOptions:

RequestOptions options = RequestOptions.builder()
    .setConnectTimeout(30 * 1000) // in milliseconds
    .setReadTimeout(80 * 1000)
    .build();
client.customers().create(params, options);

Please take care to set conservative read timeouts. Some API requests can take some time, and a short timeout increases the likelihood of a problem within our servers.

Configuring DNS Cache TTL

We cannot guarantee that the IP address of the Stripe API will be static. Commonly, default JVM configurations can have their DNS cache TTL set to forever. If Stripe's IP address changes, your application's requests to Stripe will all fail until the JVM restarts. Therefore we recommend that you modify the JVM's networkaddress.cache.ttl property to 60 seconds.

How to use undocumented parameters and properties

stripe-java is a typed library and it supports all public properties or parameters.

Stripe sometimes has beta which introduces new properties or parameters that are not immediately public. The library does not support these properties or parameters until they are public but there is still an approach that allows you to use them.

Parameters

To pass undocumented parameters to Stripe using stripe-java you need to use the putExtraParam() method, as shown below:

CustomerCreateParams params =
  CustomerCreateParams.builder()
    .setEmail("[email protected]")
    .putExtraParam("secret_feature_enabled", "true")
    .putExtraParam("secret_parameter[primary]", "primary value")
    .putExtraParam("secret_parameter[secondary]", "secondary value")
    .build();

client.customers().create(params);

Properties

To retrieve undocumented properties from Stripe using Java you can use an option in the library to return the raw JSON object and return the property as a native type. An example of this is shown below:

final Customer customer = client.customers().retrieve("cus_1234");
Boolean featureEnabled =
  customer.getRawJsonObject()
    .getAsJsonPrimitive("secret_feature_enabled")
    .getAsBoolean();
String primaryValue =
  customer.getRawJsonObject()
    .getAsJsonObject("secret_parameter")
    .getAsJsonPrimitive("primary")
    .getAsString();
String secondaryValue =
  customer.getRawJsonObject()
    .getAsJsonObject("secret_parameter")
    .getAsJsonPrimitive("secondary")
    .getAsString();

Writing a plugin

If you're writing a plugin that uses the library, we'd appreciate it if you identified using Stripe.setAppInfo():

Stripe.setAppInfo("MyAwesomePlugin", "1.2.34", "https://myawesomeplugin.info");

This information is passed along when the library makes calls to the Stripe API.

Request latency telemetry

By default, the library sends request latency telemetry to Stripe. These numbers help Stripe improve the overall latency of its API for all users.

You can disable this behavior if you prefer:

Stripe.enableTelemetry = false;

Beta SDKs

Stripe has features in the beta phase that can be accessed via the beta version of this package. We would love for you to try these and share feedback with us before these features reach the stable phase. To install a beta version of stripe-java follow steps installation steps above using the beta library version.

Note There can be breaking changes between beta versions. Therefore we recommend pinning the package version to a specific version. This way you can install the same version each time without breaking changes unless you are intentionally looking for the latest beta version.

We highly recommend keeping an eye on when the beta feature you are interested in goes from beta to stable so that you can move from using a beta version of the SDK to the stable version.

If your beta feature requires a Stripe-Version header to be sent, set the Stripe.stripeVersion field by calling Stripe.addBetaVersion:

Note Beta version headers can only be set in beta versions of the library.

Stripe.addBetaVersion("feature_beta", "v3");

Support

New features and bug fixes are released on the latest major version of the Stripe Java client library. If you are on an older major version, we recommend that you upgrade to the latest in order to use the new features and bug fixes including those for security vulnerabilities. Older major versions of the package will continue to be available for use, but will not be receiving any updates.

Development

JDK 17 is required to build the Stripe Java library. By default, tests use the same Java runtime as the build. To use a custom version of Java runtime for tests set the JAVA_TEST_HOME environment variable to runtime's home directory.

The test suite depends on stripe-mock, so make sure to fetch and run it from a background terminal (stripe-mock's README also contains instructions for installing via Homebrew and other methods):

go get -u github.com/stripe/stripe-mock
stripe-mock

To run all checks (tests and code formatting):

./gradlew check

To run the tests:

./gradlew test

You can run particular tests by passing --tests Class#method. Make sure you use the fully qualified class name. For example:

./gradlew test --tests com.stripe.model.AccountTest
./gradlew test --tests com.stripe.functional.CustomerTest
./gradlew test --tests com.stripe.functional.CustomerTest.testCustomerCreate

The library uses Spotless along with google-java-format for code formatting. Code must be formatted before PRs are submitted, otherwise CI will fail. Run the formatter with:

./gradlew spotlessApply

The library uses Project Lombok. While it is not a requirement, you might want to install a plugin for your favorite IDE to facilitate development.

stripe-java's People

Contributors

amber-stripe avatar andrewpthorp avatar anniel-stripe avatar anurag avatar brandur avatar brandur-stripe avatar ctrudeau-stripe avatar dcr-stripe avatar dpetrovics-stripe avatar evan-stripe avatar jameshageman-stripe avatar jim-stripe avatar jimdanz avatar kamil-stripe avatar kjc-stripe avatar kyleconroy avatar mickjermsurawong-stripe avatar ob-stripe avatar pakrym-stripe avatar pc avatar ramya-stripe avatar remi-stripe avatar richardm-stripe avatar shale-stripe avatar shalecraig avatar spakanati avatar stephen avatar sterfried avatar stripe-openapi[bot] avatar yejia-stripe 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stripe-java's Issues

Webhooks

Can you guys implement webhooks in the API/Java client? I would like to be able to manage my webhooks using my client code instead of having to go to my dashboard and create them.

Url in InvoiceLineItemCollection is not set

The all method(s) in InvoiceLineItemCollection does not work, because the request url is not set correctly.

I wanted to use it to retrieve the line items of an invoice as described here: https://stripe.com/docs/api/java#invoice_lines

But this results in the following exception:
java.net.UnknownHostException: api.stripe.comnull

For anyone who needs a dirty quick fix, I've hardcoded the url on a branch in my fork:
https://github.com/ExNexu/stripe-java/tree/InvoiceLineItemCollection-url-hack

Card.{cvc,addressZip,addressLine1}Check have incorrect values

We're currently using a boolean to store the various checks, but the values returned aren't boolean (they're a tri-state string: "pass", "fail", or "unchecked"). This results in them always getting casted to a false value when gson decodes them.

We should probably use either a string or an enum for those fields (and if it's an enum, make sure that gson can cast them correctly)

Adding card by token

while adding card using card token by stripe.js

Map<String, Object> params = new HashMap<String, Object>();
    params.put("card", "tok_2T0m1NEnYtsrIh");
    cu.createCard(params);

this gives exception

com.stripe.exception.CardException: The card object must have a value for 'number'.

1.2.4 on Maven

Hey all,

Can you push 1.2.4 to Maven please? It's still at 1.2.2 there.

EventDeserializer throwing nullpointer on account.application.deauthorized webhook

Hi,

I am trying to convert json returned via webhook back to event class. This is what is returned in the webhook...

{
"id": "evt_29R...",
"created": 1373168226,
"livemode": false,
"type": "account.application.deauthorized",
"data": {
"object": {
"id": "ca_29OdJ8Q3Hy...",
"name": "Name"
}
},
"object": "event",
"pending_webhooks": 2,
"request": null,
"user_id": "acct_1iLgTA..."
}

When i parse it via Event.gson.fromJson() i get following exception.

java.lang.NullPointerException
at com.stripe.model.EventDataDeserializer.deserialize(EventDataDeserializer.java:102)
at com.stripe.model.EventDataDeserializer.deserialize(EventDataDeserializer.java:17)
at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.google.gson.Gson.fromJson(Gson.java:689)

Ive looked through the code and it appears that it is looking for "object" in
{
"id": "ca_29OdJ8Q3Hy...",
"name": "Name"
}
and throws NullPointer when it cannot find it.

Any help would be appreciated.

Thanks
Ashish

Add ability to get raw request / response for audit log

For auditing purposes we need to log every single call made to Stripe, and precisely what was sent and what was received back (yes, I'm aware of your corresponding log, that is unfortunately not sufficient here).

Currently it is not possible to get that information - as soon as _request returns it is dropped on the floor: https://github.com/stripe/stripe-java/blob/master/src/main/java/com/stripe/net/APIResource.java#L418

It would be great if that capability could be added - would be unfortunate to have to roll our own SDK "just" to get that.

Thanks!

Change Example Card Expiration Date

com.stripe.exception.CardException: Your card's expiration year is invalid
at com.stripe.net.APIResource.handleAPIError(APIResource.java:396)
at com.stripe.net.APIResource._request(APIResource.java:378)
at com.stripe.net.APIResource.request(APIResource.java:317)
at com.stripe.model.Charge.create(Charge.java:222)
at com.stripe.model.Charge.create(Charge.java:180)
at com.example.service.StripeService.main(StripeService.java:23)

Solution:
cardMap.put("exp_year", 2013);

Customer#getPlan returns null

I am getting a null response for the following:

Customer me = Customer.retrieve( "cus_SOME_VALID_CUSTOMER" );
String planName = me.getPlan();

At this point, planName is null even though the Stripe portal shows that that customer has subscribed to a plan.

Move towards NIO

Please can you move towards NIO HTTP connections.

You could use Netty, or I think Java 8 will have better HTTP connection support.

Without this, I think you will be blocking threads, and so reducing throughput considerably.

64-bit Timestamp

Documentation should mention that timestamps are 32-bit long not 64-bit.

For instance, in order to set trial end I had to do it this way with a 64-bit JVM

subscriptionParams.put("trial_end", utcDate.getTime() / 1000L);

Global Variable apiKey

Please remove the dependency on the global variable apiKey. This implementation makes it very difficult to write concurrent code that leverages multiple api keys. If you're writing anything that's going to be used by multiple clients, this is a really unfortunate restriction of the library. Thanks for your consideration.

Russell

Separate exceptions for specific failures

Currently whenever there's an issue with a request, the library throws com.stripe.exception.InvalidRequestException. This exception is very generic. In certain situations
(e.g. an attempt to create a customer with an ID that's already taken) it would be useful to have
more specific exceptions instead of matching response text (which feels really fragile).

Charge creation is broken on AppEngine after updating to 1.19.0

Hi, for some reason charge processing stopped working after updating to 1.19.0

Here's the way I'm trying to use it in my GAE app
This works on version 1.18.0:

Map<String, Object> chargeMap = Maps.newHashMap();
chargeMap.put("amount", amount);
chargeMap.put("currency", "gbp");
chargeMap.put("card", token);
Charge.create(chargeMap);

but after updating I am getting this:

com.stripe.exception.APIException: Sorry, an unknown error occurred while trying to use 
the Google App Engine runtime. Please contact [email protected] for assistance.
    at com.stripe.net.APIResource.makeAppEngineRequest(APIResource.java:602)
    at com.stripe.net.APIResource._request(APIResource.java:475)
    at com.stripe.net.APIResource.request(APIResource.java:423)
    at com.stripe.model.Charge.create(Charge.java:278)
    at com.stripe.model.Charge.create(Charge.java:218)

Can you please check this?

Thanks

Can't set at_period_end when deleting a subscription

Reported in Campfire.

APIResource.createDeleteConnection doesn't accept query parameters, so the at_period_end option to deleting a subscription gets dropped.

That's currently the only place where we pass a query parameter to a DELETE request, so nothing else should be affected.

please add support for serializing Stripe objects back to JSON

It would be great to have official support for serializing the Stripe object back to JSON format.
The use case is saving the objects to the disk for later processing / caching.

Serializing and then deserializing almost works, however at least when deserializing an Event object EventDataDeserializer.java will throw a NullPointerException on line 105, because the data.object.object attribute does not get created.

Example code:

String json=APIResource.GSON.toJson(Event.retrieve("..."));
// the json string is now missing the data.object.object attribute, which
// will result in an NPE
Event restored=APIResource.GSON.fromJson(json, Event.class);

StripeCollection should implement java.util.Iterable

Currently StripeCollection subclasses are somewhat inconvenient to iterate over, even though semantically they represent a lazy collection (or result set cursor).

Have you considered making StripeCollection implement java.util.Iterable? Would a pull request
that makes the change have a chance at getting merged?

Add Metadata to InvoiceItem.

When we added Metadata to the Java Bindings, the InvoiceItem was missed.

edit: InvoiceItem, not InvoiceLineItem.

charge.getDisputed()

not sure its an issue or not...

Charge charge = Charge.retrieve("XXX", apiKey);

The result from the API for "disputed" attribude inside the charge comes as a object instead of a boolean, so when I call charge.getDisputed (not getDispute), I am getting null, instead of true/false.

Issue using library on android (4.0.3)

hey guys, I am having this exception when using any version of the library that checks for the SSL certificate... I am using the latest one now...

06-13 13:03:58.215: W/System.err(14566): java.lang.IllegalStateException
06-13 13:03:58.220: W/System.err(14566): at libcore.net.http.HttpEngine.getCacheResponse(HttpEngine.java:412)
06-13 13:03:58.220: W/System.err(14566): at libcore.net.http.HttpsURLConnectionImpl$HttpUrlConnectionDelegate.getCacheResponse(HttpsURLConnectionImpl.java:390)
06-13 13:03:58.220: W/System.err(14566): at libcore.net.http.HttpsURLConnectionImpl.getServerCertificates(HttpsURLConnectionImpl.java:87)
06-13 13:03:58.220: W/System.err(14566): at com.stripe.net.APIResource.checkSSLCert(APIResource.java:189)
06-13 13:03:58.220: W/System.err(14566): at com.stripe.net.APIResource.createGetConnection(APIResource.java:218)
06-13 13:03:58.220: W/System.err(14566): at com.stripe.net.APIResource.makeURLConnectionRequest(APIResource.java:340)
06-13 13:03:58.220: W/System.err(14566): at com.stripe.net.APIResource._request(APIResource.java:449)
06-13 13:03:58.220: W/System.err(14566): at com.stripe.net.APIResource.request(APIResource.java:402)
06-13 13:03:58.220: W/System.err(14566): at com.stripe.model.Account.retrieve(Account.java:78)

Refund non-static

Hi,

Just wondering, as a new consumer of your API, which the refund is not a static method like the charge method? I.e., when creating charges, I simply do:

Charge.create(map, key);

whereas with refund I have to do:

new Charge().refund(map, key);

This feels a bit inconsistent - but perhaps there is a decision on why that is the way it is :-)

-=david=-

Java library doesnt support lasted api update

2014-03-28
Remove count property from list responses, replacing it with the optional property total_count. You can request that total_count be included in your responses by specifying include[]=total_count.

ChargeCollection still supports getCount and doesnt have the getTotalCount. Good practive to keep both in case of backward compatibility.

Documentation

I'm trying to implement the Stripe API into a java system. However I can't seem to find any solid documentation on how to do it. I have been to this URL:

https://stripe.com/docs/api?lang=java

But it is very general. Is there a javadoc set available for this? Are there any examples? I'm trying to integrate tightly to the Stripe service and seem to be spending most of my time on trial and error testing to figure out the API.

Coupons with special characters cannot be retrieved without URL-encoding

If you add coupon with the id "735*%24" via the Dashboard, the following returns null:

Coupon.retrieve("735*%24", "your api key");

However, this returns the expected coupon:

Coupon.retrieve(URLEncoder.encode("735*%24", "UTF-8"), "your api key");

This isn't specifically an issue with stripe-java, but I noticed that the path to this coupon in the Dashboard is something like: https://manage.stripe.com/coupons/735*%2524

The URL is what prompted me to try fixing my issue by URL encoding the coupon ID, and it worked.

Charge object doesn't have a customer id field

There is a customer token returned in the Charge JSON that is not available in the java model object. When receiving events I need this token to find the appropriate customer with that token in my system.

Verification Status

In my application I am adding recipient through code. After that when ever they call transfer function fund will be transfer to their account. But before I want to know that If I create recipient based on information provided by customer how to know that customer has provide me valid bank account no.? Because in live mode I added one recipient with code . I insert valid routing number but account no. was test bank account number. Though It is added successfully but it is showing me verify status : false . Does it mean bank number is not valid?

Add new dispute attributes

The dispute objects should have three new fields

  • preliminary_inquiry_needs_response
  • preliminary_inquiry_under_review
  • charge_refunded

Connection to stripe fails after some days running

Grails app with stripe, running on tomcat. Works fine for some days and then all connections fail. Must restart tomcat in order to work.

Stacktrace:
com.stripe.exception.APIConnectionException: Could not connect to Stripe (https://api.stripe.com). Please check your internet connection and try again. If this problem persists,you should check Stripe's service status at https://twitter.com/stripestatus, or let us know at [email protected].
at com.stripe.net.APIResource.makeURLConnectionRequest(APIResource.java:296)
at com.stripe.net.APIResource._request(APIResource.java:374)
at com.stripe.net.APIResource.request(APIResource.java:328)
at com.stripe.model.Customer.retrieve(Customer.java:218)
at com.stripe.model.Customer.retrieve(Customer.java:151)
Caused by: javax.net.ssl.SSLException: java.lang.NullPointerException
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1747)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1708)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1691)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1222)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
at com.stripe.net.APIResource.makeURLConnectionRequest(APIResource.java:287)
... 16 more
Caused by: java.lang.NullPointerException
at com.sun.net.ssl.internal.ssl.ECDHCrypt.(ECDHCrypt.java:59)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:568)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:198)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:943)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215)
... 19 more

version. 1.4.2

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.