Git Product home page Git Product logo

stripe-android's Introduction

Go Stripe

Go Reference Build Status Coverage Status

The official Stripe Go client library.

Requirements

  • Go 1.15 or later

Installation

Make sure your project is using Go Modules (it will have a go.mod file in its root if it already is):

go mod init

Then, reference stripe-go in a Go program with import:

import (
	"github.com/stripe/stripe-go/v78"
	"github.com/stripe/stripe-go/v78/customer"
)

Run any of the normal go commands (build/install/test). The Go toolchain will resolve and fetch the stripe-go module automatically.

Alternatively, you can also explicitly go get the package into a project:

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

Documentation

For a comprehensive list of examples, check out the API documentation.

See video demonstrations covering how to use the library.

For details on all the functionality in this library, see the Go documentation.

Below are a few simple examples:

Customers

params := &stripe.CustomerParams{
	Description:      stripe.String("Stripe Developer"),
	Email:            stripe.String("[email protected]"),
	PreferredLocales: stripe.StringSlice([]string{"en", "es"}),
}

c, err := customer.New(params)

PaymentIntents

params := &stripe.PaymentIntentListParams{
	Customer: stripe.String(customer.ID),
}

i := paymentintent.List(params)
for i.Next() {
	pi := i.PaymentIntent()
}

if err := i.Err(); err != nil {
	// handle
}

Events

i := event.List(nil)
for i.Next() {
	e := i.Event()

	// access event data via e.GetObjectValue("resource_name_based_on_type", "resource_property_name")
	// alternatively you can access values via e.Data.Object["resource_name_based_on_type"].(map[string]interface{})["resource_property_name"]

	// access previous attributes via e.GetPreviousValue("resource_name_based_on_type", "resource_property_name")
	// alternatively you can access values via e.Data.PrevPreviousAttributes["resource_name_based_on_type"].(map[string]interface{})["resource_property_name"]
}

Alternatively, you can use the event.Data.Raw property to unmarshal to the appropriate struct.

Authentication with Connect

There are two ways of authenticating requests when performing actions on behalf of a connected account, one that uses the Stripe-Account header containing an account's ID, and one that uses the account's keys. Usually the former is the recommended approach. See the documentation for more information.

To use the Stripe-Account approach, use SetStripeAccount() on a ListParams or Params class. For example:

// For a list request
listParams := &stripe.CustomerListParams{}
listParams.SetStripeAccount("acct_123")
// For any other kind of request
params := &stripe.CustomerParams{}
params.SetStripeAccount("acct_123")

To use a key, pass it to API's Init function:

import (
	"github.com/stripe/stripe-go/v78"
	"github.com/stripe/stripe-go/v78/client"
)

stripe := &client.API{}
stripe.Init("access_token", nil)

Google AppEngine

If you're running the client in a Google AppEngine environment, you'll need to create a per-request Stripe client since the http.DefaultClient is not available. Here's a sample handler:

import (
	"fmt"
	"net/http"

	"google.golang.org/appengine"
	"google.golang.org/appengine/urlfetch"

	"github.com/stripe/stripe-go/v78"
	"github.com/stripe/stripe-go/v78/client"
)

func handler(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	httpClient := urlfetch.Client(c)

	sc := client.New("sk_test_123", stripe.NewBackends(httpClient))

	params := &stripe.CustomerParams{
		Description: stripe.String("Stripe Developer"),
		Email:       stripe.String("[email protected]"),
	}
	customer, err := sc.Customers.New(params)
	if err != nil {
		fmt.Fprintf(w, "Could not create customer: %v", err)
	}
	fmt.Fprintf(w, "Customer created: %v", customer.ID)
}

Usage

While some resources may contain more/less APIs, the following pattern is applied throughout the library for a given $resource$:

Without a Client

If you're only dealing with a single key, you can simply import the packages required for the resources you're interacting with without the need to create a client.

import (
	"github.com/stripe/stripe-go/v78"
	"github.com/stripe/stripe-go/v78/$resource$"
)

// Setup
stripe.Key = "sk_key"

// Set backend (optional, useful for mocking)
// stripe.SetBackend("api", backend)

// Create
resource, err := $resource$.New(&stripe.$Resource$Params{})

// Get
resource, err = $resource$.Get(id, &stripe.$Resource$Params{})

// Update
resource, err = $resource$.Update(id, &stripe.$Resource$Params{})

// Delete
resourceDeleted, err := $resource$.Del(id, &stripe.$Resource$Params{})

// List
i := $resource$.List(&stripe.$Resource$ListParams{})
for i.Next() {
	resource := i.$Resource$()
}

if err := i.Err(); err != nil {
	// handle
}

With a Client

If you're dealing with multiple keys, it is recommended you use client.API. This allows you to create as many clients as needed, each with their own individual key.

import (
	"github.com/stripe/stripe-go/v78"
	"github.com/stripe/stripe-go/v78/client"
)

// Setup
sc := &client.API{}
sc.Init("sk_key", nil) // the second parameter overrides the backends used if needed for mocking

// Create
$resource$, err := sc.$Resource$s.New(&stripe.$Resource$Params{})

// Get
$resource$, err = sc.$Resource$s.Get(id, &stripe.$Resource$Params{})

// Update
$resource$, err = sc.$Resource$s.Update(id, &stripe.$Resource$Params{})

// Delete
$resource$Deleted, err := sc.$Resource$s.Del(id, &stripe.$Resource$Params{})

// List
i := sc.$Resource$s.List(&stripe.$Resource$ListParams{})
for i.Next() {
	$resource$ := i.$Resource$()
}

if err := i.Err(); err != nil {
	// handle
}

Accessing the Last Response

Use LastResponse on any APIResource to look at the API response that generated the current object:

c, err := coupon.New(...)
requestID := coupon.LastResponse.RequestID

Similarly, for List operations, the last response is available on the list object attached to the iterator:

it := coupon.List(...)
for it.Next() {
    // Last response *NOT* on the individual iterator object
    // it.Coupon().LastResponse // wrong

    // But rather on the list object, also accessible through the iterator
    requestID := it.CouponList().LastResponse.RequestID
}

See the definition of APIResponse for available fields.

Note that where API resources are nested in other API resources, only LastResponse on the top-level resource is set.

Automatic Retries

The library automatically retries requests on intermittent failures like on a connection error, timeout, or on certain API responses like a status 409 Conflict. Idempotency keys are always added to requests to make any such subsequent retries safe.

By default, it will perform up to two retries. That number can be configured with MaxNetworkRetries:

import (
	"github.com/stripe/stripe-go/v78"
	"github.com/stripe/stripe-go/v78/client"
)

config := &stripe.BackendConfig{
    MaxNetworkRetries: stripe.Int64(0), // Zero retries
}

sc := &client.API{}
sc.Init("sk_key", &stripe.Backends{
    API:     stripe.GetBackendWithConfig(stripe.APIBackend, config),
    Uploads: stripe.GetBackendWithConfig(stripe.UploadsBackend, config),
})

coupon, err := sc.Coupons.New(...)

Configuring Logging

By default, the library logs error messages only (which are sent to stderr). Configure default logging using the global DefaultLeveledLogger variable:

stripe.DefaultLeveledLogger = &stripe.LeveledLogger{
    Level: stripe.LevelInfo,
}

Or on a per-backend basis:

config := &stripe.BackendConfig{
    LeveledLogger: &stripe.LeveledLogger{
        Level: stripe.LevelInfo,
    },
}

It's possible to use non-Stripe leveled loggers as well. Stripe expects loggers to comply to the following interface:

type LeveledLoggerInterface interface {
	Debugf(format string, v ...interface{})
	Errorf(format string, v ...interface{})
	Infof(format string, v ...interface{})
	Warnf(format string, v ...interface{})
}

Some loggers like Logrus and Zap's SugaredLogger support this interface out-of-the-box so it's possible to set DefaultLeveledLogger to a *logrus.Logger or *zap.SugaredLogger directly. For others it may be necessary to write a thin shim layer to support them.

Expanding Objects

All expandable objects in stripe-go take the form of a full resource struct, but unless expansion is requested, only the ID field of that struct is populated. Expansion is requested by calling AddExpand on parameter structs. For example:

//
// *Without* expansion
//
c, _ := charge.Get("ch_123", nil)

c.Customer.ID    // Only ID is populated
c.Customer.Name  // All other fields are always empty

//
// With expansion
//
p := &stripe.ChargeParams{}
p.AddExpand("customer")
c, _ = charge.Get("ch_123", p)

c.Customer.ID    // ID is still available
c.Customer.Name  // Name is now also available (if it had a value)

How to use undocumented parameters and properties

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

Stripe sometimes launches private beta features which introduce new properties or parameters that are not immediately public. These will not have typed accessors in the stripe-go library but can still be used.

Parameters

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

	params := &stripe.CustomerParams{
		Email: stripe.String("[email protected]")
	}

	params.AddExtra("secret_feature_enabled", "true")
	params.AddExtra("secret_parameter[primary]","primary value")
	params.AddExtra("secret_parameter[secondary]","secondary value")

	customer, err := customer.Create(params)

Properties

You can access undocumented properties returned by Stripe by querying the raw response JSON object. An example of this is shown below:

customer, _ = customer.Get("cus_1234", nil);

var rawData map[string]interface{}
_ = json.Unmarshal(customer.LastResponse.RawJSON, &rawData)

secret_feature_enabled, _ := string(rawData["secret_feature_enabled"].(bool))

secret_parameter, ok := rawData["secret_parameter"].(map[string]interface{})
if ok {
	primary := secret_parameter["primary"].(string)
	secondary := secret_parameter["secondary"].(string)
} 

Webhook signing

Stripe can optionally sign the webhook events it sends to your endpoint, allowing you to validate that they were not sent by a third-party. You can read more about it here.

Testing Webhook signing

You can use stripe.webhook.GenerateTestSignedPayload to mock webhook events that come from Stripe:

payload := map[string]interface{}{
	"id":          "evt_test_webhook",
	"object":      "event",
	"api_version": stripe.APIVersion,
}
testSecret := "whsec_test_secret"

payloadBytes, err := json.Marshal(payload)

signedPayload := webhook.GenerateTestSignedPayload(&webhook.UnsignedPayload{Payload: payloadBytes, Secret: testSecret})
event, err := webhook.ConstructEvent(signedPayload.Payload, signedPayload.Header, signedPayload.Secret)

if event.ID == payload["id"] {
	// Do something with the mocked signed event
} else {
	// Handle invalid event payload
}

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(&stripe.AppInfo{
	Name:    "MyAwesomePlugin",
	URL:     "https://myawesomeplugin.info",
	Version: "1.2.34",
})

This information is passed along when the library makes calls to the Stripe API. Note that while Name is always required, URL and Version are optional.

Telemetry

By default, the library sends telemetry to Stripe regarding request latency and feature usage. These numbers help Stripe improve the overall latency of its API for all users, and improve popular features.

You can disable this behavior if you prefer:

config := &stripe.BackendConfig{
	EnableTelemetry: stripe.Bool(false),
}

Mocking clients for unit tests

To mock a Stripe client for a unit tests using GoMock:

  1. Generate a Backend type mock.
mockgen -destination=mocks/backend.go -package=mocks github.com/stripe/stripe-go/v78 Backend
  1. Use the Backend mock to initialize and call methods on the client.
import (
	"example/hello/mocks"
	"testing"

	"github.com/golang/mock/gomock"
	"github.com/stretchr/testify/assert"
	"github.com/stripe/stripe-go/v78"
	"github.com/stripe/stripe-go/v78/account"
)

func UseMockedStripeClient(t *testing.T) {
	// Create a mock controller
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()
	// Create a mock stripe backend
	mockBackend := mocks.NewMockBackend(mockCtrl)
	client := account.Client{B: mockBackend, Key: "key_123"}

	// Set up a mock call
	mockBackend.EXPECT().Call("GET", "/v1/accounts/acc_123", gomock.Any(), gomock.Any(), gomock.Any()).
		// Return nil error
		Return(nil).
		Do(func(method string, path string, key string, params stripe.ParamsContainer, v *stripe.Account) {
			// Set the return value for the method
			*v = stripe.Account{
				ID: "acc_123",
			}
		}).Times(1)

	// Call the client method
	acc, _ := client.GetByID("acc_123", nil)

	// Asset the result
	assert.Equal(t, acc.ID, "acc_123")
}

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-go use the commit notation of the go get command to point to a beta tag:

go get -u github.com/stripe/stripe-go/[email protected]

Note There can be breaking changes between beta versions.

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.APIVersion field using the stripe.AddBetaVersion function to set it:

Note The APIVersion 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 Go 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

Pull requests from the community are welcome. If you submit one, please keep the following guidelines in mind:

  1. Code must be go fmt compliant.
  2. All types, structs and funcs should be documented.
  3. Ensure that make test succeeds.

Test

The test suite needs testify's require package to run:

github.com/stretchr/testify/require

Before running the tests, make sure to grab all of the package's dependencies:

go get -t -v

It also 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

Run all tests:

make test

Run tests for one package:

go test ./invoice

Run a single test:

go test ./invoice -run TestInvoiceGet

For any requests, bug or comments, please open an issue or submit a pull request.

stripe-android's People

Contributors

acavailhez-stripe avatar amk-stripe avatar awush-stripe avatar bg-stripe avatar brandur avatar brnunes-stripe avatar bryan-stripe avatar carlosmuvi-stripe avatar ccen-stripe avatar chiuki avatar dawn-stripe avatar dependabot[bot] avatar epan-stripe avatar eurias-stripe avatar github-actions[bot] avatar jameswoo-stripe avatar jaynewstrom-stripe avatar jemerick-stripe avatar joeydong-stripe avatar ksun2-stripe avatar michelleb-stripe avatar mrmcduff-stripe avatar mshafrir-stripe avatar ob-stripe avatar samer-stripe avatar skyler-stripe avatar smaskell-stripe avatar stephen avatar stripe-android-translations[bot] avatar tillh-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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stripe-android's Issues

Failed to resolve: com.stripe:stripe-android:+

I have added this line in my build. project as described in your doc.
compile 'com.stripe:stripe-android:+'

I am getting this kind of error. why I got this? which version of your library for android working now?
Error:(14, 13) Failed to resolve: com.stripe:stripe-android:+

WalletFragmentOptions not found

hi @bct

i am using your code in eclipse and unfortunately i can not get class com.google.android.gms.wallet.fragment is there i missing something,then please guide me..

Thanks.

No model for Parent when expanding parent to SKU in fetch Order request

When requesting all orders, it's possible to add a data flag to get more information about the parent, using, for example

HashMap<String,String> data = new HashMap<>();
data.put("expand[]", "data.items.parent.product");

Usually the OrderItem object will have a member "parent" which is a String, which is the parent ID. However with the above flag we get back a more complex parent object.

There is no such complex parent object supplied in the models with this SDK, can you add this?

Card.java considers 3 digit CVV for AMEX card invalid

https://github.com/stripe/stripe-android/blob/master/stripe/src/main/java/com/stripe/android/model/Card.java

check the boolean validateCVC(); method. But in iOS SDK 3 digit CVV for AMEX cards are accepted.
refer: stripe/stripe-ios#299

Also, adding comments and a handful of formatting changes, setting public methods that don't need to be public to be package-private, and reordering methods for formatting (keeping the order public, package, private).

Upgrade to 1.0.3 causes execution error

Error:Execution failed for task ':app:transformClassesWithDexForDebug'.> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2

When I downgrade to compile 'com.stripe:stripe-android:1.0.0', everything works ok. Any ideas? I have more details on this SO post: http://stackoverflow.com/questions/34844903/stripe-android-lib-1-0-3-upgrade-causes-execution-error

Card validation fails when doing real time checks.

Related to issue #33 and Pull request #34

Unless the card is re-created from scratch any time the number changes, it's not possible to get the number validation to work properly, particularly if using AMEX cards, as type is only set once. (Ie: populating a blank card is not guaranteed to work even with correct data.)

A quick solution for this is to change validateNumber() to reference type indirectly through it's getter.

if (AMERICAN_EXPRESS.equals(getType())) {

instead of

if (AMERICAN_EXPRESS.equals(type)) {

Feature Request: Credit Card Number text formatter

Can you please provide a text formatter for the credit card numbers? It seems like cards do not always follow XXXX-XXXX-XXXX-XXXX pattern, would be really nice to have a TextWatcher or something of that nature.

Without it, CC input is a bit tedious!

Add Javadoc to public methods

There is nothing more evil than public api with no documentation.

Can you start stubbing out what your Public API actually does?

Unable to import stripe-android project in Eclipse

Hi,

I have Eclipse Luna Service Release 1a (4.4.1), Android SDK including API level 17 and Android Support Library 21.0.3. I've cloned the stripe-android/ and tried to import stripe-android/stripe/ to Eclipse as "Existing project into workspace", as outlined in https://github.com/stripe/stripe-android#eclipse, but have been unable to do it. The stripe item in "Projects" list of the "Import Projects" dialog is grayed out, it's not possible to select the project. How to use the stripe-android in my environment?

Thanks for help.

Withdrawal model/code snippet? Android.

Hello!

I have been looking and can't find anything on it. Are there any code snippets/models to implement withdrawal for users in Android?

Much oblidged.

Document proper proguard exclusions

Proguard will mangle the class names in the stripe-java API resource classes, yielding 404s upon token creation (among other things).

The docs should inform users to add the following line to their proguard.cfg:

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

requestToken() doesn't work

I'll admit I haven't actually tested this, but I'm pretty sure requestToken() doesn't work, as it issues a call to the retrieve token API endpoint with a publishable key (see here).

My best guess is that it was an undocumented behavior that was removed at some point? Anyway, the API will reject this call with "This API call cannot be made with a publishable API key."

Documentation seems out of sync with implementation

The README seems to suggest Stripe can be instantiated as a class with the publishable key and that createToken exists accepting a card and callback. I have found none of this in the Stripe Android library I installed in the manner described (i.e. compile 'com.stripe:stripe-android:+')

Stripe is an abstract class:

public abstract class Stripe

I have to set the apiKey thus:

Stripe.apiKey = "sk_test_FOO;

And creating a token offers no async callback:

Token token = Token.create(tokenParams);

I am wondering if it is me who has an older library (and thus the question is how would I get the latest) or whether the README is old.

Specifically I am not getting a CardException raised when using a Stripe payment expired card number from the test page when creating a token despite try/catching the Token.create - it goes ahead and creates a token.

Models update to reflect API changes

Customer model needs to be updated to reflect breaking changes in API update 2015-02-18.

defaultCard needs to become defaultSource
cards needs to bedome sources

The model Customer in the current SDK version is not usable now.

screen shot 2015-04-28 at 11 14 33

Rx-java support

I want to put my credit card creation inside an observable for testing purposes: and I get:

java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5694)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.ExceptionInInitializerError
            at com.stripe.android.Stripe$1.create(Stripe.java:22)
            at com.stripe.android.Stripe.createToken(Stripe.java:144)
            at com.stripe.android.Stripe.createToken(Stripe.java:127)
            at com.stripe.android.Stripe.createToken(Stripe.java:131)
            at com.pickupnow.customer.model.payment.PaymentService.lambda$createToken$59(PaymentService.java:30)
            at com.pickupnow.customer.model.payment.PaymentService.access$lambda$0(PaymentService.java)
            at com.pickupnow.customer.model.payment.PaymentService$$Lambda$1.call(Unknown Source)
            at rx.Observable$1.call(Observable.java:144)
            at rx.Observable$1.call(Observable.java:136)
            at rx.Observable$1.call(Observable.java:144)
            at rx.Observable$1.call(Observable.java:136)
            at rx.Observable$1.call(Observable.java:144)
            at rx.Observable$1.call(Observable.java:136)
            at rx.Observable.unsafeSubscribe(Observable.java:7531)
            at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
            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:841)
     Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at android.os.Handler.<init>(Handler.java:200)
            at android.os.Handler.<init>(Handler.java:114)
            at com.stripe.android.compat.AsyncTask$InternalHandler.<init>(AsyncTask.java:579)
            at com.stripe.android.compat.AsyncTask$InternalHandler.<init>(AsyncTask.java:579)
            at com.stripe.android.compat.AsyncTask.<clinit>(AsyncTask.java:189)
            at com.stripe.android.Stripe$1.create(Stripe.java:22)
            at com.stripe.android.Stripe.createToken(Stripe.java:144)
            at com.stripe.android.Stripe.createToken(Stripe.java:127)
            at com.stripe.android.Stripe.createToken(Stripe.java:131)
            at com.pickupnow.customer.model.payment.PaymentService.lambda$createToken$59(PaymentService.java:30)
            at com.pickupnow.customer.model.payment.PaymentService.access$lambda$0(PaymentService.java)
            at com.pickupnow.customer.model.payment.PaymentService$$Lambda$1.call(Unknown Source)
            at rx.Observable$1.call(Observable.java:144)
            at rx.Observable$1.call(Observable.java:136)
            at rx.Observable$1.call(Observable.java:144)
            at rx.Observable$1.call(Observable.java:136)
            at rx.Observable$1.call(Observable.java:144)
            at rx.Observable$1.call(Observable.java:136)
            at rx.Observable.unsafeSubscribe(Observable.java:7531)
            at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62)
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
            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:841)

When I execute:

public Observable<String> createToken(String number, int month, int year, String cvc, String zip) {
        return Observable.create(subscriber -> {
            Card card = new Card(number, month, year, cvc);
            card.setAddressZip(zip);

            if (card.validateCard()) {
                try {
                    Stripe stripe = new Stripe(BuildConfig.STRIPE_TOKEN);

                    stripe.createToken(card, new TokenCallback() {
                        @Override
                        public void onSuccess(final Token token) {
                            subscriber.onNext(token.getId());
                            subscriber.onCompleted();
                        }

                        @Override
                        public void onError(Exception e) {
                            subscriber.onError(e);
                        }
                    });
                } catch (AuthenticationException e) {
                    subscriber.onError(e);
                }
            } else {
                subscriber.onError(new InvalidCardException("Invalid card values"));
            }
        });
    }

your example is not working

your example is not working,
my data below:
number: 4242424242424242
expYear:2014
expMonth:12
cvc:123
PUBLISHABLE_KEY:pk_test_6pRNASCoBOKtIshFeQd4XMUh
then, i accept a error: illegalStateException! help me , thanks~~

Maven dependancy

Can this be added as an Maven dependency? Or at least gradleise it, Eclipse is dead and importing as a library option is long dead for Intellij/AndroidStudio.

card expiration validates on client and fails on server

for expiration year of 99 I get a client side success and a server side failure.

here is a snip of code....

    Card card = new Card(getCardNumber(), getExpMonth(), getExpYear(), getCvc());
    if (!card.validateNumber()) {
    } else if (!card.validateExpiryDate()) {
    } else if (!card.validateCVC()) {
    } else if (!card.validateCard()) {
    } else {
      new Stripe().createToken(card, stripeKey, this);
    }

all of those error checks are negative... then I get the server side failure in the callback:

    com.stripe.exception.CardException: Your card's expiration year is invalid.
            at com.stripe.net.APIResource.handleAPIError(APIResource.java:500)
            at com.stripe.net.APIResource._request(APIResource.java:482)
            at com.stripe.net.APIResource.request(APIResource.java:420)
            at com.stripe.model.Token.create(Token.java:92)
            at com.stripe.android.Stripe$1$1.doInBackground(Stripe.java:25)
            at com.stripe.android.Stripe$1$1.doInBackground(Stripe.java:22)
            at com.stripe.android.compat.AsyncTask$2.call(AsyncTask.java:236)

If I use an invalid month, I get a client side failure as I would expect... So it just seems like the client and the server do not validate years in the same way.

Expiration Date issue in Android

Is the validation of Expiry Date only seek to look if it is a future date or it is actual comapre the values entered with the card real values ?

how to use stripe.createToken is an asynctask?

Hi all,

I would like to use stripe.createToken in an Asynctask as I am creating the Stripe Token at the same time than other network requests.
I did look for a synchronous way to createToken but only the async mode seems to be available.

The issue is that when I try to use stripe.createToken in a custom Asynctask, it crashes. If I understood correctly the TokenCallBack expects to be in the UI Thread.

How could I do that?

Kin regards.

Are you sure that the doc is correct

I've added compile 'com.stripe:stripe-android:+' into my gradle dependencies and sync the gradle. After that I tried the codes from the doc. Unfortunately, the class Card had no contructors(only default contructor is available). I am stuck there and not sure about how to proceed with the integration. Am I missing something in the steps or doc is no more valid.

Address attributes of credit card not saved during createToken

The method hashMapFromCard in Stripe.java should have the following lines:

    cardParams.put("address_line_1", card.getAddressLine1());
    cardParams.put("address_line_2", card.getAddressLine2());
    cardParams.put("address_line_city", card.getAddressCity());
    cardParams.put("address_line_zip", card.getAddressZip());
    cardParams.put("address_line_state", card.getAddressState());
    cardParams.put("address_line_country", card.getAddressCountry());

Changed to:

    cardParams.put("address_line1", card.getAddressLine1());
    cardParams.put("address_line2", card.getAddressLine2());
    cardParams.put("address_city", card.getAddressCity());
    cardParams.put("address_zip", card.getAddressZip());
    cardParams.put("address_state", card.getAddressState());
    cardParams.put("address_country", card.getAddressCountry());

This will bring the android library in line with the ios library, and will fix the issue.

Customer does not have a linked card with ID

i got error that Customer cus_id does not have a linked card with ID

                                  **com.stripe.Stripe.apiKey = SECRET_KEY;

                                    Map<String, Object> customerParams = new HashMap<String, Object>();
                                    customerParams.put("description", "Customer111 for [email protected]");
                                    customerParams.put("card", token.getId()); // Obtained in onSuccess() method of TokenCallback
                                    // while creating token above

                                    //Create a Customer
                                    Customer cust = Customer.create(customerParams);

                                    final Map<String, Object> chargeParams = new HashMap<String, Object>();
                                    chargeParams.put("amount", 12000);
                                    chargeParams.put("currency", "usd");
                                    chargeParams.put("card", token.getId());
                                    chargeParams.put("customer", cust.getId());


                                    charge = Charge.create(chargeParams);**

Card getType() returning null

The card.getType() is always returning null on android

Stripe stripe = new Stripe(getResources().getString(R.string.stripe_app_id));
                stripe.createToken(
                        card,
                        new TokenCallback() {
                            public void onSuccess(Token token) {
                                // Send token to your server
                                activity.cardBrand = token.getCard().getType();
                                activity.userStripeId = token.getId();
                            }

                            public void onError(Exception error) {
                                // Show localized error message
                            }
                        }
                );

Using Stripe with AndroidAnnotations @Background function fails because of compat.AsyncTask

In an app using AndroidAnnotations where Stripe().createToken(...) is invoked inside a method annotated with @background, the use of com.stripe.android.compat.AsyncTask causes a crash which is solved by just using android.os.AsyncTask. Do you really anticipate people using stripe-android in an environment that doesn't have android.os.AsyncTask?

W/dalvikvm( 5086): Exception Ljava/lang/RuntimeException; thrown while initializing Lcom/stripe/android/compat/AsyncTask;
E/AndroidRuntime( 5086): FATAL EXCEPTION: pool-1-thread-1
E/AndroidRuntime( 5086): java.lang.ExceptionInInitializerError
E/AndroidRuntime( 5086):  at com.stripe.android.Stripe$1.create(Stripe.java:20)
E/AndroidRuntime( 5086):  at com.stripe.android.Stripe.createToken(Stripe.java:142)
E/AndroidRuntime( 5086):  at com.stripe.android.Stripe.createToken(Stripe.java:125)
E/AndroidRuntime( 5086):  at redacted.MainActivity.startCreditPurchase(MainActivity.java:144)
E/AndroidRuntime( 5086):  at redacted.MainActivity_.access$2(MainActivity_.java:1)
E/AndroidRuntime( 5086):  at redacted.MainActivity_$2.run(MainActivity_.java:111)
E/AndroidRuntime( 5086):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
E/AndroidRuntime( 5086):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
E/AndroidRuntime( 5086):  at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime( 5086): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
E/AndroidRuntime( 5086):  at android.os.Handler.<init>(Handler.java:197)
E/AndroidRuntime( 5086):  at android.os.Handler.<init>(Handler.java:111)
E/AndroidRuntime( 5086):  at com.stripe.android.compat.AsyncTask$InternalHandler.<init>(AsyncTask.java:579)
E/AndroidRuntime( 5086):  at com.stripe.android.compat.AsyncTask$InternalHandler.<init>(AsyncTask.java:579)
E/AndroidRuntime( 5086):  at com.stripe.android.compat.AsyncTask.<clinit>(AsyncTask.java:189)
E/AndroidRuntime( 5086):  ... 9 more

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.