Giter VIP home page Giter VIP logo

braintree-android-binding's People

Contributors

dependabot[bot] avatar nghiahaminh25101995 avatar thuan93 avatar tuyen-vuduc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

braintree-android-binding's Issues

Integration whith a Xamarin Forms

Hi, I'm trying to implement Paypal payments in Xamarin Forms, I'm following this implementation guide: http://www.xamboy.com/2020/02/28/braintree-integration-in-xamarin-forms-part-3/
I have generated the token with the briantree PHP library, when I send the token to initialize it sends me the following error:
** Com.Braintreepayments.Api.Exceptions.InvalidArgumentException: ** 'Activity is null'
public async Task InitializeAsync (string clientToken)
{
try
{

             initializeTcs = new TaskCompletionSource <bool> ();
             mBraintreeFragment = BraintreeFragment.NewInstance (CrossCurrentActivity.Current.Activity, clientToken);
          
         
         }
         catch (InvalidArgumentException e)
         {
             initializeTcs.TrySetException (e);
         }
         return await initializeTcs.Task;
     }

Venmo not showing up in Drop In UI

I have been trying to get Venmo to show up with the drop-in on Android with no luck.

I noticed in the Braintree SDK docs this:

// to offer Venmo
implementation 'com.braintreepayments.api:venmo:4.+'

Is this API part of the binding?

Card Payment Saving the User in Vault even if the user does not select that option

I have the following issue in our Android implementation for Credit Card payments:

When the user selects that they don't want their card to be remembered, it still is. This happens even though we explicitly configure it to be set by the value chosen in the app.

We suspect the card is being linked to the vault during tokenization. We are going to share the relevant code with you, of both, client and server side, hoping it will be helpful.

Client Side:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Com.Braintreepayments.Api;
using Com.Braintreepayments.Api.Exceptions;
using Com.Braintreepayments.Api.Interfaces;
using Com.Braintreepayments.Api.Models;
using Plugin.CurrentActivity;
using UISend.Services;
using Xamarin.Forms;

 [assembly: Dependency(typeof(UISend.Droid.Services.AndroidPayService))]
namespace UISend.Droid.Services
{
  public class AndroidPayService : Java.Lang.Object, IPayService, IBraintreeResponseListener, IBraintreeErrorListener, 
  IPaymentMethodNonceCreatedListener, IBraintreeCancelListener, IConfigurationListener
   {
      TaskCompletionSource<bool> initializeTcs;
      TaskCompletionSource<string> payTcs;

    BraintreeFragment mBraintreeFragment;
    bool isReady = false;
    bool venmoReady = false;

    string nonce = null;
    public bool CanPay { get => isReady; }
    public bool VenmoReady { get => venmoReady; }

    public event EventHandler<MyEventArgs> OnTokenizationSuccessful;
    public event EventHandler<string> OnTokenizationError;



    public void OnCancel(int requestCode)
    {
        payTcs.SetCanceled();
        //mBraintreeFragment.RemoveListener(this);
    }




    public void OnResponse(Java.Lang.Object parameter)
    {
        if (parameter is Java.Lang.Boolean)
        {
            var res = parameter.JavaCast<Java.Lang.Boolean>();
            isReady = res.BooleanValue();
            initializeTcs?.TrySetResult(res.BooleanValue());
            //DataCollector.CollectDeviceData(mBraintreeFragment, this);
        }
        else if (parameter is Java.Lang.String)
        {
            var res = parameter.JavaCast<Java.Lang.String>();
            string deviceData = res.ToString();
            string nonce2 = payTcs.Task.Result;
            OnTokenizationSuccessful?.Invoke(this, new MyEventArgs(nonce2, deviceData));
            nonce = null;

        }
    }

    public void OnPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce)
    {
        // Send this nonce to your server
        string nonce = paymentMethodNonce.Nonce;
        //mBraintreeFragment.RemoveListener(this);
        payTcs?.TrySetResult(nonce);
        DataCollector.CollectDeviceData(mBraintreeFragment, this);
        //OnTokenizationSuccessful?.Invoke(this, nonce);
    }

    public void OnError(Java.Lang.Exception error)
    {
        if (error is ErrorWithResponse)
        {
            ErrorWithResponse errorWithResponse = (ErrorWithResponse)error;
            BraintreeError cardErrors = errorWithResponse.ErrorFor("creditCard");
            if (cardErrors != null)
            {
                BraintreeError expirationMonthError = cardErrors.ErrorFor("expirationMonth");
                if (expirationMonthError != null)
                {
                    OnTokenizationError?.Invoke(this, expirationMonthError.Message);
                    payTcs?.TrySetException(new System.Exception(expirationMonthError.Message));

                }
                else
                {
                    OnTokenizationError?.Invoke(this, cardErrors.Message);
                    payTcs?.TrySetException(new System.Exception(cardErrors.Message));

                }
            }
        }
        //mBraintreeFragment.RemoveListener(this);
    }



    public async Task<string> TokenizePayPal()
    {
        payTcs = new TaskCompletionSource<string>();
        if (isReady)
        {
            //mBraintreeFragment.AddListener(this);
            PayPal.AuthorizeAccount(mBraintreeFragment);
        }
        else
        {
            OnTokenizationError?.Invoke(this, "Platform is not ready to accept payments");
            payTcs.TrySetException(new System.Exception("Platform is not ready to accept payments"));

        }
        return await payTcs.Task;
    }

    public async Task<string> TokenizeVenmo()
    {
        //mBraintreeFragment.AddListener(this);
        payTcs = new TaskCompletionSource<string>();
        if (venmoReady)
        {
            Venmo.AuthorizeAccount(mBraintreeFragment, false);
        }
        else
        {
            OnTokenizationError?.Invoke(this, "Platform is not ready to accept payments");
            payTcs.TrySetException(new System.Exception("Platform is not ready to accept payments"));

        }
        return await payTcs.Task;
    }

    public async Task<string> TokenizeCard(string panNumber, string expirationMonth, string expirationYear , string cvv)
    {
        if (isReady)
        {
            payTcs = new TaskCompletionSource<string>();
            CardBuilder cardBuilder = new CardBuilder()
                .CardNumber(panNumber).JavaCast<CardBuilder>()
                .ExpirationMonth(expirationMonth).JavaCast<CardBuilder>()
                .ExpirationYear(expirationYear).JavaCast<CardBuilder>()
                .Cvv(cvv).JavaCast<CardBuilder>();

            mBraintreeFragment.AddListener(this);

            Card.Tokenize(mBraintreeFragment, cardBuilder);
        }
        else
        {
            OnTokenizationError?.Invoke(this, "Platform is not ready to accept payments");
            payTcs.TrySetException(new System.Exception("Platform is not ready to accept payments"));

        }
        return await payTcs.Task;
    }

    public async Task<bool> InitializeAsync(string clientToken)
    {
        try
        {
            initializeTcs = new TaskCompletionSource<bool>();
            mBraintreeFragment = BraintreeFragment.NewInstance(CrossCurrentActivity.Current.Activity, clientToken);
            GooglePayment.IsReadyToPay(mBraintreeFragment, this);
            mBraintreeFragment.AddListener(this);
            //isReady = true;
            //initializeTcs.TrySetResult(isReady);
        }
        catch (InvalidArgumentException e)
        {
            initializeTcs.TrySetException(e);
        }
        return await initializeTcs.Task;
    }

    public void OnConfigurationFetched(Configuration p0)
    {
        venmoReady = p0.PayWithVenmo.IsEnabled(CrossCurrentActivity.Current.Activity);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
            mBraintreeFragment.RemoveListener(this);
        base.Dispose(disposing);
    }
   }
  }

Server side:

                          Result<Transaction> result = null;
                         try
                        {
                           Trace.WriteLine("Attempting Braintree Payment...");
                           var braintreePayInfo = JsonConvert.DeserializeObject<Dictionary<string, string>>(paymentInfoJson);
                           bool rememberPayMethod = braintreePayInfo.ContainsKey("Remember") ? 
                           bool.Parse(braintreePayInfo["Remember"]) : false;

                        var gateway = new BraintreeGateway
                        {
                            Environment = Braintree.Environment.SANDBOX,
                            MerchantId = BraintreeConfig.MerchantId,
                            PublicKey = BraintreeConfig.PublicKey,
                            PrivateKey = BraintreeConfig.PrivateKey
                        };



                        var request = new TransactionRequest
                        {
                            Amount = decimal.Parse(braintreePayInfo["Amount"]),
                            Options = new TransactionOptionsRequest
                            {
                                SubmitForSettlement = true,
                            }
                        };
                        if(braintreePayInfo.ContainsKey("Token") && !string.IsNullOrEmpty(braintreePayInfo["Token"]))
                        {
                            // Pago con tarjeta existente
                            request.PaymentMethodToken = braintreePayInfo["Token"];
                        }
                        else if (braintreePayInfo.ContainsKey("Nonce") && !string.IsNullOrEmpty(braintreePayInfo["Nonce"]))
                        {
                            // Pago con cuenta paypal/venmo o nueva tarjeta
                            request.PaymentMethodNonce = braintreePayInfo["Nonce"];
                            // Guardar tarjeta en el vault?
                            if(order.PaymentMethod == "-BTCARD")
                            {
                                Trace.WriteLine($"Assigning value {rememberPayMethod} to StoreInVaultOnSuccess...");
                                request.Options.StoreInVaultOnSuccess = rememberPayMethod;
                                Trace.WriteLine($"Value {request.Options.StoreInVaultOnSuccess} assigned.");
                            }
                                
                        } else
                        {
                            throw new Exception("Payment method not found");
                        }



                        if (order.PaymentMethod == "--VENMO" || order.PaymentMethod == "-BTCARD" && 
                     braintreePayInfo.ContainsKey("DeviceData"))
                        {
                            request.DeviceData = braintreePayInfo["DeviceData"];
                        }



                        if(rememberPayMethod)
                        {
                            string braintreeId = order.UserId.ToString().ToUpper();
                            try
                            {
                                Customer customer = gateway.Customer.Find(braintreeId);
                                Trace.WriteLine("Adding existing Customer to transaction with ID " + customer.Id + "...");
                                request.CustomerId = customer.Id;
                            }
                            catch
                            {
                                Trace.WriteLine("Adding new Customer to transaction with ID " + braintreeId + "...");
                                request.Customer = new CustomerRequest { Id = braintreeId };
                            }
                        }
                        
                        result = gateway.Transaction.Sale(request);
                        var resultJson = JsonConvert.SerializeObject(result);
                        //Se le responde al user
                        Clients.Caller.ProcessPayment(name, orderJson, resultJson);
                    } catch(Exception ex)
                    {
                        var key8 = providerLocks.GetOrAdd(order.ProviderId.ToString(), new object());
                        lock (key8)
                        {
                            try
                            {
                                OrderHelper.RollbackOrder(order);
                            }
                            finally
                            {
                                providerLocks.TryRemove(order.ProviderId.ToString(), out _);
                            }
                        }



                        Trace.WriteLine("Error during Braintree Payment: " + ex.Message);
                        ExceptionHelper.DisplayExceptionInfo(ex);



                        throw ex;
                    }

We are using Xamarin.Forms (4.7.0.1080) version and Naxam.Braintree.Droid (2.10.0.1)

Google Pay option does not show up in drop in UI

I am using the Naxam.BraintreeDropIn.Droid library in my Xamarin.Android project and Google Pay option does not show up in the pop-up. I am using a client token that refers to an account with that option enabled. I would like to know if this is the way to add Google Pay to drop in, I have followed the Braintree's documentation but I'm not sure what is wrong. Thanks in advance

Here is the code:

DropInRequest dropInRequest = new DropInRequest()
       .ClientToken(clientToken);

TransactionInfo transactionInfo = TransactionInfo.NewBuilder()
                .SetTotalPrice("1.00")
                .SetTotalPriceStatus(WalletConstants.TotalPriceStatusFinal)
                .SetCurrencyCode("USD")
                .Build();

GooglePaymentRequest googlePaymentRequest = new GooglePaymentRequest().InvokeTransactionInfo(transactionInfo);

dropInRequest.InvokeGooglePaymentRequest(googlePaymentRequest);
          
StartActivityForResult(dropInRequest.GetIntent(this), LOAD_PAYMENT_DATA_REQUEST_CODE);

  • I have Xamarin.GooglePlayServices.Wallet installed(for Google Play Services-Wallet 11.4.2)

  • I included the wallet enabled meta-data tag in my AndroidManifest.xml

  • I enabled the Google Pay option in my sandbox account

ThreeDSecure classes have no setters on properties

Hello,

I'm trying to integrate the 3D Secure client into our Xamarin app.

However, after installing the 3D Secure nuget and trying to use the included classes, they don't seem to have the setters generated on their properties, making them unusable. See the attached screenshots below.

image
image

Would it be possible to fix this? And what about the newest version of the Braintree SDKs, is it possible to generate bindings for them?

com.braintreepayments.api.internal.AnalyticsIntentService cannot be instantiated

On Debug Mode I am able to complete the payment with my token from the Server where as on release mode this is the Log :
Platform Used : Xamarin Forms -> Android

[System.out] [okhttp]:check permission begin!
[System] ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
[System.out] [okhttp] e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaUtils
[System.out] [OkHttp] sendRequest>>
[System.out] [OkHttp] sendRequest<<
[com.pastryworld] type=1400 audit(0.0:604914): avc: denied { read } for name="cache" dev="dm-0" ino=17 scontext=u:r:untrusted_app:s0:c239,c256,c512,c768 tcontext=u:object_r:cache_file:s0 tclass=lnk_file permissive=0
[com.pastryworld] type=1400 audit(0.0:604916): avc: denied { read } for name="cache" dev="dm-0" ino=17 scontext=u:r:untrusted_app:s0:c239,c256,c512,c768 tcontext=u:object_r:cache_file:s0 tclass=lnk_file permissive=0
[System.out] [okhttp]:check permission begin!
[System] ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
[System.out] [okhttp] e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaUtils
[System.out] [okhttp]:check permission begin!
[System] ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
[System.out] [okhttp] e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaUtils
[System.out] [socket]:check permission begin!
[System] ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
[System.out] [socket] e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaUtils
[System.out] [socket]:check permission begin!
[System] ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
[System.out] [socket] e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaUtils
[System.out] [OkHttp] sendRequest<<
[System.out] [OkHttp] sendRequest>>
[System.out] [OkHttp] sendRequest<<
[MagnesPostRequest] MagnesPostRequest returned PayPal-Debug-Id: 28b3d69a7e0ac
[System.out] [okhttp]:check permission begin!
[System] ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
[System.out] [okhttp] e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaUtils
[System.out] [socket]:check permission begin!
[System] ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
[System.out] [socket] e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaUtils
[Surface] Surface::disconnect(this=0x71d20db000,api=1)
[Surface] Surface::disconnect(this=0x7206c80000,api=1)
[PhoneWindow] DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl@3d4f8f6, this = DecorView@91df91c[MainActivity]
[PhoneWindow] DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl@5ca6631, this = DecorView@6982a4a[DropInActivity]
[Surface] Surface::disconnect(this=0x71d2276000,api=1)
[GED] ged_boost_gpu_freq, level 100, eOrigin 2, final_idx 15, oppidx_max 15, oppidx_min 0
[AndroidRuntime] Shutting down VM
[AndroidRuntime] FATAL EXCEPTION: main
[AndroidRuntime] Process: com.pastryworld, PID: 5017
[AndroidRuntime] java.lang.RuntimeException: Unable to instantiate service com.braintreepayments.api.internal.AnalyticsIntentService: java.lang.InstantiationException: java.lang.Class<com.braintreepayments.api.internal.AnalyticsIntentService> cannot be instantiated
[AndroidRuntime] at android.app.ActivityThread.handleCreateService(ActivityThread.java:3968)
[AndroidRuntime] at android.app.ActivityThread.access$1600(ActivityThread.java:226)
[AndroidRuntime] at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1900)
[AndroidRuntime] at android.os.Handler.dispatchMessage(Handler.java:107)
[AndroidRuntime] at android.os.Looper.loop(Looper.java:214)
[AndroidRuntime] at android.app.ActivityThread.main(ActivityThread.java:7386)
[AndroidRuntime] at java.lang.reflect.Method.invoke(Native Method)
[AndroidRuntime] at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
[AndroidRuntime] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
[AndroidRuntime] Caused by: java.lang.InstantiationException: java.lang.Class<com.braintreepayments.api.internal.AnalyticsIntentService> cannot be instantiated
[AndroidRuntime] at java.lang.Class.newInstance(Native Method)
[AndroidRuntime] at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129)
[AndroidRuntime] at androidx.core.app.CoreComponentFactory.instantiateService(Unknown Source:0)
[AndroidRuntime] at android.app.ActivityThread.handleCreateService(ActivityThread.java:3963)
[AndroidRuntime] ... 8 more
[MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] Java.Lang.RuntimeException: Unable to instantiate service com.braintreepayments.api.internal.AnalyticsIntentService: java.lang.InstantiationException: java.lang.Class<com.braintreepayments.api.internal.AnalyticsIntentService> cannot be instantiated ---> Java.Lang.ReflectiveOperationException: java.lang.Class<com.braintreepayments.api.internal.AnalyticsIntentService> cannot be instantiated
[MonoDroid] --- End of inner exception stack trace ---
[MonoDroid] --- End of managed Java.Lang.RuntimeException stack trace ---
[MonoDroid] java.lang.RuntimeException: Unable to instantiate service com.braintreepayments.api.internal.AnalyticsIntentService: java.lang.InstantiationException: java.lang.Class<com.braintreepayments.api.internal.AnalyticsIntentService> cannot be instantiated
[MonoDroid] at android.app.ActivityThread.handleCreateService(ActivityThread.java:3968)
[MonoDroid] at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1900)
[MonoDroid] at android.os.Handler.dispatchMessage(Handler.java:107)
[MonoDroid] at android.os.Looper.loop(Looper.java:214)
[MonoDroid] at android.app.ActivityThread.main(ActivityThread.java:7386)
[MonoDroid] at java.lang.reflect.Method.invoke(Native Method)
[MonoDroid] at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
[MonoDroid] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
[MonoDroid] Caused by: java.lang.InstantiationException: java.lang.Class<com.braintreepayments.api.internal.AnalyticsIntentService> cannot be instantiated
[MonoDroid] at java.lang.Class.newInstance(Native Method)
[MonoDroid] at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129)
[MonoDroid] at androidx.core.app.CoreComponentFactory.instantiateService(Unknown Source:0)
[MonoDroid] at android.app.ActivityThread.handleCreateService(ActivityThread.java:3963)
[MonoDroid] ... 8 more
[MonoDroid]
[Process] Sending signal. PID: 5017 SIG: 9

MIssing dependency

It seems there is a missing dependency in the project which means we are unable to build any project using this package with the D8 compiler.

R8 : warning : Missing class: com.kount.api.DataCollector$CompletionHandler

Tried adding this to the -nowarn list in proguard.cfg, but that didn't help.

Android build error

Hello, I have integrated your binding but I get this error in Android on build:

obj\Debug\android\src\mono\com\braintreepayments\api\interfaces\TokenizationParametersListenerImplementor.java(4,8): error : error: TokenizationParametersListenerImplementor is not abstract and does not override abstract method onResult(PaymentMethodTokenizationParameters,Collection) in TokenizationParametersListener

Thanks

Help mapping old 2.x version to current

Thanks for all your work on this! Very much appreciated.

The only Xamarin Forms guide I can find is the Rendy article: https://www.xamboy.com/2020/01/28/braintree-integration-in-xamarin-forms-part-1/

I can get his code to build using the old Naxam packages he used. When I update these to the current equivalents (at least I think they are the equivalents) a lot seems to have changed. I tried adding the packages from the sample code in this project (also could not get those samples to build).

Error CS0117 'Card' does not contain a definition for 'Tokenize'
Error CS0117 'GooglePayment' does not contain a definition for 'IsReadyToPay'
Error CS0117 'GooglePayment' does not contain a definition for 'RequestPayment'
Error CS1061 'GooglePaymentRequest' does not contain a definition for 'InvokeTransactionInfo'
Error CS1061 'GooglePaymentRequest' does not contain a definition for 'InvokeTransactionInfo'
Error CS0117 'PayPal' does not contain a definition for 'AuthorizeAccount'
Error CS0103 The name 'BraintreeFragment' does not exist in the current context
Error CS0246 The type or namespace name 'BraintreeFragment' could not be found

Should I just use the old packages? Is there a straightforward way to understand how these packages have evolved so that maybe I could update the Rendy code?

Thanks again!

Drop - in UI Support

Does this support Drop in UI? if no is there any way we can achieve this easy with this package?

Thank you for this library, and any help on the above would be greatly appreciated. Thanks!

Issue Cardinal Mobile SDK (braintree-android-dropui)

General information

SDK/Library version: 5.2.0.1
Environment: Production
Android Version and Device: -
Issue description
We received an email from the Google Play Store , how to fix this issue,
please help me.

Screenshot 2022-12-05 at 12 13 25 PM

Cannot update to Lastest Xamarin forms with this package.

Hi! It seems Microsoft added an upper bound of Xamarin.Google.Android.Material to 1.3.0 in Xamarin.Forms 5.0.2083 (latest as of 09/08/2021).

Because of this I am unable to update the Xamarin.Forms package (and subsequently Xamarin.Essentials) to the latest releases and also use this library.

Would it be possible to re-release this package with Xamarin.Google.Android.Material >= 1.3.0 instead fo 1.3.0.1?

Braintree SDK v3

Hey,
Do you have any plans upgrade bindings to Braintree v3 Android sdk?

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.