├── android-stripe-connect
├── lint.xml
├── libs
│ ├── gson-2.2.2.jar
│ └── stripe-java-1.10.0.jar
├── res
│ ├── drawable
│ │ ├── icon.png
│ │ └── button_stripe_connect.xml
│ ├── drawable-hdpi
│ │ ├── outline.png
│ │ ├── outline_light.png
│ │ ├── button_stripe.9.png
│ │ ├── button_stripe_icon.png
│ │ └── button_stripe_selected.9.png
│ ├── drawable-xhdpi
│ │ ├── outline.png
│ │ ├── outline_light.png
│ │ ├── button_stripe.9.png
│ │ ├── button_stripe_icon.png
│ │ └── button_stripe_selected.9.png
│ ├── drawable-mdpi
│ │ ├── button_stripe.9.png
│ │ ├── button_stripe_icon.png
│ │ └── button_stripe_selected.9.png
│ ├── drawable-xxhdpi
│ │ └── button_stripe_icon.png
│ ├── layout
│ │ └── main.xml
│ └── values
│ │ └── strings.xml
├── src
│ └── com
│ │ └── github
│ │ └── thiagolocatelli
│ │ └── stripe
│ │ ├── StripeConnectListener.java
│ │ ├── Main.java
│ │ ├── AppLog.java
│ │ ├── StripeUtils.java
│ │ ├── StripeSession.java
│ │ ├── StripeButton.java
│ │ ├── StripeApp.java
│ │ ├── StripeActivity.java
│ │ └── StripeDialog.java
├── project.properties
└── AndroidManifest.xml
├── android-stripe-connect-sample
├── lint.xml
├── ic_launcher-web.png
├── libs
│ └── android-support-v4.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-w820dp
│ │ └── dimens.xml
│ ├── values-v14
│ │ └── styles.xml
│ ├── menu
│ │ └── main.xml
│ └── layout
│ │ ├── fragment_main.xml
│ │ └── activity_main.xml
├── src
│ └── com
│ │ └── github
│ │ └── thiagolocatelli
│ │ └── stripe
│ │ └── sample
│ │ ├── ApplicationData.java
│ │ └── MainActivity.java
├── project.properties
├── proguard-project.txt
└── AndroidManifest.xml
├── resources
├── drawable_left_hdpi.pxm
├── drawable_left_mdpi.pxm
├── drawable_left_xhdpi.pxm
├── drawable_left_xxhdpi.pxm
└── screenshots
│ ├── screenshot1.png
│ ├── screenshot2.png
│ └── screenshot3.png
├── .gitignore
└── README.md
/android-stripe-connect/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/resources/drawable_left_hdpi.pxm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/resources/drawable_left_hdpi.pxm
--------------------------------------------------------------------------------
/resources/drawable_left_mdpi.pxm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/resources/drawable_left_mdpi.pxm
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings
4 | bin
5 | gen
6 | target
7 |
8 | local.properties
9 | build.xml
10 | proguard.cfg
--------------------------------------------------------------------------------
/resources/drawable_left_xhdpi.pxm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/resources/drawable_left_xhdpi.pxm
--------------------------------------------------------------------------------
/resources/drawable_left_xxhdpi.pxm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/resources/drawable_left_xxhdpi.pxm
--------------------------------------------------------------------------------
/resources/screenshots/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/resources/screenshots/screenshot1.png
--------------------------------------------------------------------------------
/resources/screenshots/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/resources/screenshots/screenshot2.png
--------------------------------------------------------------------------------
/resources/screenshots/screenshot3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/resources/screenshots/screenshot3.png
--------------------------------------------------------------------------------
/android-stripe-connect/libs/gson-2.2.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/libs/gson-2.2.2.jar
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable/icon.png
--------------------------------------------------------------------------------
/android-stripe-connect-sample/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect-sample/ic_launcher-web.png
--------------------------------------------------------------------------------
/android-stripe-connect/libs/stripe-java-1.10.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/libs/stripe-java-1.10.0.jar
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-hdpi/outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-hdpi/outline.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-xhdpi/outline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-xhdpi/outline.png
--------------------------------------------------------------------------------
/android-stripe-connect-sample/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect-sample/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-hdpi/outline_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-hdpi/outline_light.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-xhdpi/outline_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-xhdpi/outline_light.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-hdpi/button_stripe.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-hdpi/button_stripe.9.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-mdpi/button_stripe.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-mdpi/button_stripe.9.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-xhdpi/button_stripe.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-xhdpi/button_stripe.9.png
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect-sample/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect-sample/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect-sample/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-hdpi/button_stripe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-hdpi/button_stripe_icon.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-mdpi/button_stripe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-mdpi/button_stripe_icon.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-xhdpi/button_stripe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-xhdpi/button_stripe_icon.png
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect-sample/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-xxhdpi/button_stripe_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-xxhdpi/button_stripe_icon.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-hdpi/button_stripe_selected.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-hdpi/button_stripe_selected.9.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-mdpi/button_stripe_selected.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-mdpi/button_stripe_selected.9.png
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable-xhdpi/button_stripe_selected.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thiagolocatelli/android-stripe-connect/HEAD/android-stripe-connect/res/drawable-xhdpi/button_stripe_selected.9.png
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android-stripe-connect/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Stripe Connect Sample
5 | Hello world!
6 | Settings
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/src/com/github/thiagolocatelli/stripe/sample/ApplicationData.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe.sample;
2 |
3 | public class ApplicationData {
4 | public static final String CLIENT_ID = "";
5 | public static final String SECRET_KEY = "";
6 | public static final String CALLBACK_URL = "";
7 | }
8 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/StripeConnectListener.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | public interface StripeConnectListener {
4 |
5 | public abstract void onConnected();
6 |
7 | public abstract void onDisconnected();
8 |
9 | public abstract void onError(String error);
10 |
11 | }
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android-stripe-connect/res/drawable/button_stripe_connect.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/Main.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import com.github.thiagolocatelli.stripe.R;
6 |
7 | public class Main extends Activity {
8 |
9 | @Override
10 | public void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | setContentView(R.layout.main);
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 | 64dp
9 |
10 |
11 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/android-stripe-connect/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | android-stripe-connect
5 | Connect with Stripe
6 | Disconnect from Stripe
7 |
8 | Yes
9 | No
10 |
11 | Disconnect from Stripe?
12 |
13 |
14 |
--------------------------------------------------------------------------------
/android-stripe-connect/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | android.library=true
14 | # Project target.
15 | target=android-16
16 |
--------------------------------------------------------------------------------
/android-stripe-connect/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-19
15 | android.library.reference.1=../android-stripe-connect
16 | android.library.reference.2=../../../adt-bundle-mac/sdk/extras/android/support/v7/appcompat
17 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/layout/fragment_main.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/AppLog.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import android.util.Log;
4 |
5 | public class AppLog {
6 |
7 | private static boolean DEBUG = BuildConfig.DEBUG;
8 |
9 | private static final String APP_TAG = "StripeConnect";
10 |
11 | public static void d(String clazz, String method, String message) {
12 | if(DEBUG)
13 | Log.d(APP_TAG, clazz + "." + method + "(): " + message);
14 | }
15 |
16 | public static void i(String clazz, String method, String message) {
17 | if(DEBUG)
18 | Log.i(APP_TAG, clazz + "." + method + "(): " + message);
19 | }
20 |
21 | public static void e(String clazz, String method, String message) {
22 | if(DEBUG)
23 | Log.e(APP_TAG, clazz + "." + method + "(): " + message);
24 | }
25 |
26 | public static void w(String clazz, String method, String message) {
27 | if(DEBUG)
28 | Log.w(APP_TAG, clazz + "." + method + "(): " + message);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/android-stripe-connect-sample/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
21 |
27 |
28 |
34 |
35 |
41 |
42 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/StripeUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.DataOutputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.io.InputStreamReader;
8 | import java.io.UnsupportedEncodingException;
9 | import java.net.HttpURLConnection;
10 | import java.net.URL;
11 | import java.net.URLDecoder;
12 | import java.util.LinkedHashMap;
13 | import java.util.Map;
14 |
15 | import android.content.Context;
16 | import android.webkit.CookieManager;
17 | import android.webkit.CookieSyncManager;
18 |
19 | public class StripeUtils {
20 |
21 | public static void removeAllCookies(Context context) {
22 | CookieSyncManager.createInstance(context);
23 | CookieManager cookieManager = CookieManager.getInstance();
24 | cookieManager.removeAllCookie();
25 | }
26 |
27 | public static Map splitQuery(String query) {
28 | Map query_pairs = new LinkedHashMap();
29 | try {
30 | String[] pairs = query.split("&");
31 | for (String pair : pairs) {
32 | int idx = pair.indexOf("=");
33 | query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"),
34 | URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
35 | }
36 | }
37 | catch(UnsupportedEncodingException e) {
38 | query_pairs.put("error", "UnsupportedEncodingException");
39 | query_pairs.put("error_description", e.getMessage());
40 | }
41 |
42 | return query_pairs;
43 | }
44 |
45 | public static String executePost(String url, String parameters) throws IOException {
46 |
47 | URL request = new URL(url);
48 | HttpURLConnection connection = (HttpURLConnection) request.openConnection();
49 | connection.setDoOutput(true);
50 | connection.setDoInput(true);
51 | connection.setInstanceFollowRedirects(false);
52 | connection.setRequestMethod("POST");
53 | connection.setRequestProperty("User-Agent", "StripeConnectAndroid");
54 | connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
55 | connection.setRequestProperty("charset", "utf-8");
56 | connection.setRequestProperty("Content-Length", "" + Integer.toString(parameters.getBytes().length));
57 | connection.setUseCaches (false);
58 |
59 | DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
60 | wr.writeBytes(parameters);
61 | wr.flush();
62 | wr.close();
63 |
64 | String response = streamToString(connection.getInputStream());
65 | connection.disconnect();
66 | return response;
67 |
68 | }
69 |
70 | private static String streamToString(InputStream is) throws IOException {
71 | String str = "";
72 |
73 | if (is != null) {
74 | StringBuilder sb = new StringBuilder();
75 | String line;
76 |
77 | try {
78 | BufferedReader reader = new BufferedReader(
79 | new InputStreamReader(is));
80 |
81 | while ((line = reader.readLine()) != null) {
82 | sb.append(line);
83 | }
84 |
85 | reader.close();
86 | } finally {
87 | is.close();
88 | }
89 |
90 | str = sb.toString();
91 | }
92 |
93 | return str;
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/StripeSession.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import android.content.SharedPreferences;
4 | import android.content.SharedPreferences.Editor;
5 | import android.content.Context;
6 | import android.util.Log;
7 |
8 | /**
9 | *
10 | * @author Thiago Locatelli
11 | *
12 | */
13 | public class StripeSession {
14 |
15 | private SharedPreferences sharedPref;
16 | private Editor editor;
17 |
18 | private static final String SHARED = "_StripeAccount_Preferences";
19 | private static final String API_ACCESS_TOKEN = "access_token";
20 | private static final String API_REFRESH_TOKEN = "refresh_token";
21 | private static final String API_TOKEN_TYPE = "token_type";
22 | private static final String API_USER_ID = "user_id";
23 | private static final String API_PUBLISHABLE_KEY = "publishable_key";
24 | private static final String API_LIVE_MODE = "live_mode";
25 |
26 | public StripeSession(Context context, String accountName) {
27 | Log.i("StripeSession", "StripeSession[accountName]: " + accountName);
28 | sharedPref = context.getSharedPreferences(accountName + SHARED, Context.MODE_PRIVATE);
29 | }
30 |
31 | public void storeAccessToken(String accessToken) {
32 | editor = sharedPref.edit();
33 | editor.putString(API_ACCESS_TOKEN, accessToken);
34 | editor.commit();
35 | }
36 |
37 | public void storeRefreshToken(String refreshToken) {
38 | editor = sharedPref.edit();
39 | editor.putString(API_REFRESH_TOKEN, refreshToken);
40 | editor.commit();
41 | }
42 |
43 | public void storePublishableKey(String publishableKey) {
44 | editor = sharedPref.edit();
45 | editor.putString(API_PUBLISHABLE_KEY, publishableKey);
46 | editor.commit();
47 | }
48 |
49 | public void storeUserid(String userId) {
50 | editor = sharedPref.edit();
51 | editor.putString(API_USER_ID, userId);
52 | editor.commit();
53 | }
54 |
55 | public void storeTokenType(String tokenType) {
56 | editor = sharedPref.edit();
57 | editor.putString(API_TOKEN_TYPE, tokenType);
58 | editor.commit();
59 | }
60 |
61 | public void storeLiveMode(boolean liveMode) {
62 | editor = sharedPref.edit();
63 | editor.putBoolean(API_LIVE_MODE, liveMode);
64 | editor.commit();
65 | }
66 |
67 | public String getAccessToken() {
68 | return sharedPref.getString(API_ACCESS_TOKEN, null);
69 | }
70 |
71 | public String getRefreshToken() {
72 | return sharedPref.getString(API_REFRESH_TOKEN, null);
73 | }
74 |
75 | public String getPublishableKey() {
76 | return sharedPref.getString(API_PUBLISHABLE_KEY, null);
77 | }
78 |
79 | public String getUserId() {
80 | return sharedPref.getString(API_USER_ID, null);
81 | }
82 |
83 | public String getTokenType() {
84 | return sharedPref.getString(API_TOKEN_TYPE, null);
85 | }
86 |
87 | public Boolean getLiveMode() {
88 | return sharedPref.getBoolean(API_LIVE_MODE, false);
89 | }
90 |
91 | public void resetAccessToken() {
92 | editor = sharedPref.edit();
93 | editor.remove(API_ACCESS_TOKEN);
94 | editor.remove(API_REFRESH_TOKEN);
95 | editor.remove(API_PUBLISHABLE_KEY);
96 | editor.remove(API_USER_ID);
97 | editor.remove(API_TOKEN_TYPE);
98 | editor.remove(API_LIVE_MODE);
99 | editor.clear();
100 | editor.commit();
101 | }
102 |
103 | }
--------------------------------------------------------------------------------
/android-stripe-connect-sample/src/com/github/thiagolocatelli/stripe/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe.sample;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.ActionBarActivity;
6 | import android.view.Menu;
7 | import android.view.MenuItem;
8 | import android.widget.TextView;
9 | import android.widget.Toast;
10 |
11 | import com.github.thiagolocatelli.stripe.sample.R;
12 | import com.github.thiagolocatelli.stripe.StripeApp;
13 | import com.github.thiagolocatelli.stripe.StripeApp.CONNECT_MODE;
14 | import com.github.thiagolocatelli.stripe.StripeButton;
15 | import com.github.thiagolocatelli.stripe.StripeConnectListener;
16 | import com.stripe.Stripe;
17 |
18 | public class MainActivity extends ActionBarActivity {
19 |
20 | private StripeApp mApp, mApp2;
21 | private TextView tvSummary;
22 | private StripeButton mStripeButton, mStripeButton2;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_main);
28 |
29 | mApp = new StripeApp(this, "StripeAccount", ApplicationData.CLIENT_ID,
30 | ApplicationData.SECRET_KEY, ApplicationData.CALLBACK_URL);
31 |
32 | tvSummary = (TextView) findViewById(R.id.tvSummary);
33 | if (mApp.isConnected()) {
34 | tvSummary.setText("Connected as " + mApp.getAccessToken());
35 | }
36 |
37 | mStripeButton = (StripeButton) findViewById(R.id.btnConnect1);
38 | mStripeButton.setStripeApp(mApp);
39 | mStripeButton.addStripeConnectListener(new StripeConnectListener() {
40 |
41 | @Override
42 | public void onConnected() {
43 | tvSummary.setText("Connected as " + mApp.getAccessToken());
44 | }
45 |
46 | @Override
47 | public void onDisconnected() {
48 | tvSummary.setText("Disconnected");
49 | }
50 |
51 | @Override
52 | public void onError(String error) {
53 | Toast.makeText(MainActivity.this, error, Toast.LENGTH_SHORT).show();
54 | }
55 |
56 | });
57 |
58 | mApp2 = new StripeApp(this, "StripeAccount", ApplicationData.CLIENT_ID,
59 | ApplicationData.SECRET_KEY, ApplicationData.CALLBACK_URL);
60 | mStripeButton2 = (StripeButton) findViewById(R.id.btnConnect2);
61 | mStripeButton2.setStripeApp(mApp2);
62 | mStripeButton2.setConnectMode(CONNECT_MODE.ACTIVITY);
63 |
64 | Stripe.apiKey = mApp.getAccessToken();
65 |
66 | }
67 |
68 | @Override
69 | public boolean onCreateOptionsMenu(Menu menu) {
70 |
71 | //getMenuInflater().inflate(R.menu.main, menu);
72 | return true;
73 | }
74 |
75 | @Override
76 | public boolean onOptionsItemSelected(MenuItem item) {
77 | // Handle action bar item clicks here. The action bar will
78 | // automatically handle clicks on the Home/Up button, so long
79 | // as you specify a parent activity in AndroidManifest.xml.
80 | int id = item.getItemId();
81 | if (id == R.id.action_settings) {
82 | return true;
83 | }
84 | return super.onOptionsItemSelected(item);
85 | }
86 |
87 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
88 |
89 | switch(resultCode) {
90 | case StripeApp.RESULT_CONNECTED:
91 | tvSummary.setText("Connected as " + mApp.getAccessToken());
92 | break;
93 | case StripeApp.RESULT_ERROR:
94 | String error_description = data.getStringExtra("error_description");
95 | Toast.makeText(MainActivity.this, error_description, Toast.LENGTH_SHORT).show();
96 | break;
97 | }
98 |
99 | }
100 |
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | android-stripe-connect
2 | ======================
3 |
4 | Android Library for integrating with Stripe using [Stripe Connect Oauth](https://stripe.com/docs/connect/reference).
5 |
6 |
7 | 
8 | 
9 | 
10 |
11 |
12 | ## Usage
13 |
14 | You can add the Stripe Connect button to your layout using the following XML code:
15 |
16 |
17 | ```XML
18 |
24 | ```
25 |
26 | You can create an utility class where you can define your application credentials, like the one below (This is obvilously insecure, make sure you keep all this information stored in a way its impossible to decompile):
27 |
28 | ```Java
29 | public class ApplicationData {
30 | public static final String CLIENT_ID = "";
31 | public static final String CLIENT_SECRET = "";
32 | public static final String CALLBACK_URL = "";
33 | }
34 | ```
35 |
36 | Inside your Activity, you can manipulate the button and change its properties. You can either launch a Dialog to start the authentication or start a Activity. By default, the scope is **read_only**, if you want to give write permissions, you gotta use StripeApp object and pass "read_write" as scope.
37 |
38 | ```Java
39 | StripeAppmApp = new StripeApp(this, ApplicationData.CLIENT_ID,
40 | ApplicationData.SECRET_KEY, ApplicationData.CALLBACK_URL);
41 |
42 | mStripeButton = (StripeButton) findViewById(R.id.btnStripeConnect);
43 | mStripeButton.setStripeApp(mApp);
44 | mStripeButton.addStripeConnectListener(new StripeConnectListener() {
45 |
46 | @Override
47 | public void onConnected() {
48 | tvSummary.setText("Connected as " + mApp.getAccessToken());
49 | }
50 |
51 | @Override
52 | public void onDisconnected() {
53 | tvSummary.setText("Disconnected");
54 | }
55 |
56 | @Override
57 | public void onError(String error) {
58 | Toast.makeText(MainActivity.this, error, Toast.LENGTH_SHORT).show();
59 | }
60 |
61 | });
62 | ```
63 |
64 | By default, when the Stripe Connect button is clicked, an Android Dialog will open and display the Stripe authentication page. If you would like to open an Activity instead of a Dialog, you can use **setConnectMode** to change such behavior.
65 |
66 | ```Java
67 | mStripeButton = (StripeButton) findViewById(R.id.btnStripeConnect);
68 | mStripeButton.setStripeApp(mApp);
69 | mStripeButton.setConnectMode(CONNECT_MODE.ACTIVITY);
70 | ```
71 | You also need to add to your AndroidManifest.xml the following line, which will allow the Stripe Connect button to start the authentication Activity.
72 |
73 | ```XML
74 |
75 | ```
76 |
77 | Once the authentication is finished, you can use the helper methods from the object StripeApp to get the data you need, like the oauth access token required to make calls using the [Stripe Java library](https://github.com/stripe/stripe-java).
78 |
79 | ```JAVA
80 | Stripe.apiKey = mApp.getAccessToken();
81 | ```
82 |
83 | Download the sample application and git it a try.
84 |
85 | License
86 | =======
87 |
88 | Copyright 2013, Inc.
89 |
90 | Licensed under the Apache License, Version 2.0 (the "License");
91 | you may not use this file except in compliance with the License.
92 | You may obtain a copy of the License at
93 |
94 | http://www.apache.org/licenses/LICENSE-2.0
95 |
96 | Unless required by applicable law or agreed to in writing, software
97 | distributed under the License is distributed on an "AS IS" BASIS,
98 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99 | See the License for the specific language governing permissions and
100 | limitations under the License.
101 |
102 |
103 | ## Contact
104 |
105 | If you have any questions, please drop me a line: "thiago:locatelli$gmail:com".replace(':','.').replace('$','@')
106 |
107 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/StripeButton.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import com.github.thiagolocatelli.stripe.StripeApp.CONNECT_MODE;
4 | import com.github.thiagolocatelli.stripe.StripeApp.OAuthAuthenticationListener;
5 |
6 | import android.app.Activity;
7 | import android.app.AlertDialog;
8 | import android.content.Context;
9 | import android.content.DialogInterface;
10 | import android.content.Intent;
11 | import android.graphics.Typeface;
12 | import android.graphics.drawable.Drawable;
13 | import android.util.AttributeSet;
14 | import android.util.DisplayMetrics;
15 | import android.util.Log;
16 | import android.view.View;
17 | import android.widget.Button;
18 | import android.widget.LinearLayout;
19 | import android.widget.LinearLayout.LayoutParams;
20 | import android.widget.Toast;
21 |
22 | public class StripeButton extends Button {
23 |
24 | private StripeApp mStripeApp;
25 | private Context mContext;
26 | private StripeConnectListener mStripeConnectListener;
27 | private CONNECT_MODE mConnectMode = CONNECT_MODE.DIALOG;
28 |
29 | public StripeButton(Context context) {
30 | super(context);
31 | mContext = context;
32 | setupButton();
33 | }
34 |
35 | public StripeButton(Context context, AttributeSet attrs, int defStyle) {
36 | super(context, attrs, defStyle);
37 | mContext = context;
38 | setupButton();
39 | }
40 |
41 | public StripeButton(Context context, AttributeSet attrs) {
42 | super(context, attrs);
43 | mContext = context;
44 | setupButton();
45 | }
46 |
47 | private void setupButton() {
48 |
49 | if(mStripeApp == null) {
50 | setButtonText(R.string.btnConnectText);
51 | }
52 |
53 | setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
54 |
55 | setClickable(true);
56 | setBackgroundResource(R.drawable.button_stripe_connect);
57 | Drawable img = getContext().getResources().getDrawable(R.drawable.button_stripe_icon);
58 | img.setBounds( 0, 0, dpToPx(32), dpToPx(32) );
59 | setCompoundDrawables(img, null, null, null);
60 |
61 | setTextColor(getResources().getColor(android.R.color.white));
62 | setTypeface(Typeface.DEFAULT_BOLD);
63 |
64 | setOnClickListener(new OnClickListener() {
65 |
66 | @Override
67 | public void onClick(View v) {
68 |
69 | if(mStripeApp == null) {
70 | Toast.makeText(mContext,
71 | "StripeApp obect needed. Call StripeButton.setStripeApp()",
72 | Toast.LENGTH_SHORT).show();
73 | return;
74 | }
75 |
76 | if(mStripeApp.isConnected()) {
77 | final AlertDialog.Builder builder = new AlertDialog.Builder(
78 | mContext);
79 | builder.setMessage(
80 | getResources().getString(R.string.dialogDisconnectText))
81 | .setCancelable(false)
82 | .setPositiveButton(getResources().getString(R.string.btnDialogYes),
83 | new DialogInterface.OnClickListener() {
84 | public void onClick(DialogInterface dialog, int id) {
85 | mStripeApp.resetAccessToken();
86 | setButtonText(R.string.btnConnectText);
87 | mStripeApp.getOAuthAuthenticationListener().onSuccess();
88 | }
89 | })
90 | .setNegativeButton(getResources().getString(R.string.btnDialogNo),
91 | new DialogInterface.OnClickListener() {
92 | public void onClick(DialogInterface dialog, int id) {
93 | dialog.cancel();
94 | }
95 | });
96 | final AlertDialog alert = builder.create();
97 | alert.show();
98 | }
99 | else {
100 | if(mConnectMode == CONNECT_MODE.DIALOG) {
101 | mStripeApp.displayDialog();
102 | }
103 | else {
104 | Activity parent = (Activity) mContext;
105 | Intent i = new Intent(getContext(), StripeActivity.class);
106 | i.putExtra("url", mStripeApp.getAuthUrl());
107 | i.putExtra("callbackUrl", mStripeApp.getCallbackUrl());
108 | i.putExtra("tokenUrl", mStripeApp.getTokenUrl());
109 | i.putExtra("secretKey", mStripeApp.getSecretKey());
110 | i.putExtra("accountName", mStripeApp.getAccountName());
111 | parent.startActivityForResult(i, StripeApp.STRIPE_CONNECT_REQUEST_CODE);
112 | }
113 | }
114 |
115 | }
116 |
117 | });
118 |
119 | }
120 |
121 | private void setButtonText(int resourceId) {
122 | setText(resourceId);
123 | }
124 |
125 | /**
126 | *
127 | * @param connectMode
128 | */
129 | public void setConnectMode(CONNECT_MODE connectMode) {
130 | mConnectMode = connectMode;
131 | }
132 |
133 | /**
134 | *
135 | * @param stripeApp
136 | */
137 | public void setStripeApp(StripeApp stripeApp) {
138 | mStripeApp = stripeApp;
139 | mStripeApp.setListener(getOAuthAuthenticationListener());
140 |
141 | if(mStripeApp.isConnected()) {
142 | setButtonText(R.string.btnDisconnectText);
143 | }
144 | else {
145 | setButtonText(R.string.btnConnectText);
146 | }
147 | }
148 |
149 |
150 | /**
151 | *
152 | * @param stripeConnectListener
153 | */
154 | public void addStripeConnectListener(StripeConnectListener stripeConnectListener) {
155 | mStripeConnectListener = stripeConnectListener;
156 | if(mStripeApp != null) {
157 | mStripeApp.setListener(getOAuthAuthenticationListener());
158 | }
159 | }
160 |
161 | private OAuthAuthenticationListener getOAuthAuthenticationListener() {
162 |
163 | return new OAuthAuthenticationListener() {
164 |
165 | @Override
166 | public void onSuccess() {
167 | Log.d("StripeButton", "Calling OAuthAuthenticationListener.onSuccess()");
168 | if(mStripeConnectListener != null) {
169 | if(mStripeApp.isConnected()) {
170 | Log.d("StripeButton", "Connected");
171 | setButtonText(R.string.btnDisconnectText);
172 | Log.d("StripeButton", "Calling mStripeConnectListener.onConnected()");
173 | mStripeConnectListener.onConnected();
174 | }
175 | else {
176 | Log.d("StripeButton", "Disconnected");
177 | Log.d("StripeButton", "Calling mStripeConnectListener.onDisconnected()");
178 | setButtonText(R.string.btnConnectText);
179 | mStripeConnectListener.onDisconnected();
180 | }
181 | }
182 | else {
183 | Log.d("StripeButton", "mStripeConnectListener is null");
184 | }
185 | }
186 |
187 | @Override
188 | public void onFail(String error) {
189 | Log.i("StripeButton", "Calling OAuthAuthenticationListener.onFail()");
190 | if(mStripeConnectListener != null) {
191 | mStripeConnectListener.onError(error);
192 | }
193 | }
194 | };
195 | }
196 |
197 | public int dpToPx(int dp) {
198 | DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
199 | int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
200 | return px;
201 | }
202 |
203 | public int pxToDp(int px) {
204 | DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
205 | int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
206 | return dp;
207 | }
208 |
209 | }
210 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/StripeApp.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import java.net.URL;
4 | import java.util.Map;
5 |
6 | import org.json.JSONObject;
7 |
8 | import android.annotation.SuppressLint;
9 | import android.app.ProgressDialog;
10 | import android.content.Context;
11 | import android.os.Handler;
12 | import android.os.Message;
13 | import com.github.thiagolocatelli.stripe.StripeDialog.OAuthDialogListener;
14 | import com.stripe.Stripe;
15 | import com.stripe.model.Account;
16 |
17 | /**
18 | *
19 | * @author Thiago Locatelli
20 | *
21 | */
22 | public class StripeApp {
23 |
24 | public static enum CONNECT_MODE { DIALOG, ACTIVITY }
25 |
26 | public static final int STRIPE_CONNECT_REQUEST_CODE = 1;
27 | public static final int RESULT_CONNECTED = 1;
28 | public static final int RESULT_ERROR = 2;
29 |
30 | private StripeSession mSession;
31 | private StripeDialog mDialog;
32 | private OAuthAuthenticationListener mListener;
33 | private ProgressDialog mProgress;
34 |
35 | private String mCallbackUrl;
36 | private String mAuthUrl;
37 | private String mSecretKey;
38 | private String mAccountName;
39 |
40 | private static int SUCCESS = 0;
41 | private static int ERROR = 1;
42 | private static int PHASE1 = 1;
43 | private static int PHASE2 = 2;
44 | private static final String AUTH_URL = "https://connect.stripe.com/oauth/authorize?";
45 | private static final String TOKEN_URL = "https://connect.stripe.com/oauth/token";
46 | private static final String SCOPE = "read_only";
47 |
48 | private static final String TAG = "StripeApp";
49 |
50 | public StripeApp(Context context, String accountName, String clientId, String clientKey, String callbackUrl, String scope) {
51 | mSession = new StripeSession(context, accountName);
52 | mAccountName = accountName;
53 | mSecretKey = clientKey;
54 | mCallbackUrl = callbackUrl;
55 | mAuthUrl = AUTH_URL + "client_id=" + clientId
56 | + "&scope=" + ((scope == null) ? SCOPE : scope)
57 | + "&response_type=code"
58 | + "&stripe_landing=login"
59 | + "&redirect_uri="+ mCallbackUrl ;
60 |
61 | OAuthDialogListener listener = new OAuthDialogListener() {
62 | @Override
63 | public void onComplete(Map parameters) {
64 | getAccessToken(parameters.get("code"));
65 | }
66 |
67 | @Override
68 | public void onError(Map parameter) {
69 | mListener.onFail("Authorization failed");
70 | }
71 | };
72 |
73 | mDialog = new StripeDialog(context, mAuthUrl, mCallbackUrl, listener);
74 | mProgress = new ProgressDialog(context);
75 | mProgress.setCancelable(false);
76 | }
77 |
78 | public StripeApp(Context context, String accountName, String clientId, String clientKey, String callbackUrl) {
79 | this(context, accountName, clientId, clientKey, callbackUrl, null);
80 | }
81 |
82 | private void getAccessToken(final String code) {
83 | mProgress.setMessage("Connecting with Stripe");
84 | mProgress.show();
85 |
86 | new Thread() {
87 | @Override
88 | public void run() {
89 | int what = SUCCESS;
90 |
91 | try {
92 |
93 | URL url = new URL(TOKEN_URL);
94 | String urlParameters = "code=" + code
95 | + "&client_secret=" + mSecretKey
96 | + "&grant_type=authorization_code";
97 | AppLog.i(TAG, "getAccessToken", "Getting access token with code:" + code);
98 | AppLog.i(TAG, "getAccessToken", "Opening URL " + url.toString() + "?" + urlParameters);
99 |
100 | String response = StripeUtils.executePost(TOKEN_URL, urlParameters);
101 | JSONObject obj = new JSONObject(response);
102 |
103 | AppLog.i(TAG, "getAccessToken", "String data[access_token]: " + obj.getString("access_token"));
104 | AppLog.i(TAG, "getAccessToken", "String data[livemode]: " + obj.getBoolean("livemode"));
105 | AppLog.i(TAG, "getAccessToken", "String data[refresh_token]: " + obj.getString("refresh_token"));
106 | AppLog.i(TAG, "getAccessToken", "String data[token_type]: " + obj.getString("token_type"));
107 | AppLog.i(TAG, "getAccessToken", "String data[stripe_publishable_key]: " + obj.getString("stripe_publishable_key"));
108 | AppLog.i(TAG, "getAccessToken", "String data[stripe_user_id]: " + obj.getString("stripe_user_id"));
109 | AppLog.i(TAG, "getAccessToken", "String data[scope]: " + obj.getString("scope"));
110 |
111 | mSession.storeAccessToken(obj.getString("access_token"));
112 | mSession.storeRefreshToken(obj.getString("refresh_token"));
113 | mSession.storePublishableKey(obj.getString("stripe_publishable_key"));
114 | mSession.storeUserid(obj.getString("stripe_user_id"));
115 | mSession.storeLiveMode(obj.getBoolean("livemode"));
116 | mSession.storeTokenType(obj.getString("token_type"));
117 |
118 | }
119 | catch (Exception ex) {
120 | what = ERROR;
121 | ex.printStackTrace();
122 | }
123 |
124 | mHandler.sendMessage(mHandler.obtainMessage(what, PHASE2, 0));
125 | }
126 | }.start();
127 | }
128 |
129 | private void getAccountData() {
130 | mProgress.setMessage("Finalizing ...");
131 |
132 | new Thread() {
133 | @Override
134 | public void run() {
135 | AppLog.i(TAG, "getAccountData", "Fetching user info");
136 | int what = SUCCESS;
137 |
138 | try {
139 |
140 | Stripe.apiKey = mSession.getAccessToken();
141 | Account account = Account.retrieve();
142 |
143 | if(account != null) {
144 |
145 | }
146 |
147 | } catch (Exception ex) {
148 | what = ERROR;
149 | ex.printStackTrace();
150 | }
151 |
152 | mHandler.sendMessage(mHandler.obtainMessage(what, PHASE2, 0));
153 | }
154 | }.start();
155 | }
156 |
157 | @SuppressLint("HandlerLeak")
158 | private Handler mHandler = new Handler() {
159 | @Override
160 | public void handleMessage(Message msg) {
161 | if (msg.arg1 == PHASE1) {
162 | if (msg.what == SUCCESS) {
163 | getAccountData();
164 | } else {
165 | mProgress.dismiss();
166 | mListener.onFail("Failed to get access token");
167 | }
168 | } else {
169 | AppLog.i(TAG, "mHandler.handleMessage", "Calling mListener.onSuccess()");
170 | mProgress.dismiss();
171 | mListener.onSuccess();
172 | }
173 | }
174 | };
175 |
176 | public void setListener(OAuthAuthenticationListener listener) {
177 | mListener = listener;
178 | }
179 |
180 | public OAuthAuthenticationListener getOAuthAuthenticationListener() {
181 | return mListener;
182 | }
183 |
184 | public void displayDialog() {
185 | mDialog.show();
186 | }
187 |
188 | public void resetAccessToken() {
189 | if (isConnected()) {
190 | mSession.resetAccessToken();
191 | mListener.onSuccess();
192 | }
193 | }
194 |
195 | public boolean isConnected() {
196 | return getAccessToken() != null;
197 | }
198 |
199 | public String getAccessToken() {
200 | return mSession.getAccessToken();
201 | }
202 |
203 | public StripeSession getStripeSession() {
204 | return mSession;
205 | }
206 |
207 | public String getAccountName() {
208 | return mAccountName;
209 | }
210 |
211 | protected String getAuthUrl() {
212 | return mAuthUrl;
213 | }
214 |
215 | protected String getCallbackUrl() {
216 | return mCallbackUrl;
217 | }
218 |
219 | protected String getTokenUrl() {
220 | return TOKEN_URL;
221 | }
222 |
223 | protected String getSecretKey() {
224 | return mSecretKey;
225 | }
226 |
227 | public interface OAuthAuthenticationListener {
228 | public abstract void onSuccess();
229 | public abstract void onFail(String error);
230 | }
231 |
232 | }
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/StripeActivity.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import java.net.URL;
4 | import java.util.LinkedHashMap;
5 | import java.util.Map;
6 |
7 | import org.json.JSONObject;
8 |
9 | import android.annotation.SuppressLint;
10 | import android.app.Activity;
11 | import android.app.ProgressDialog;
12 | import android.content.Intent;
13 | import android.graphics.Bitmap;
14 | import android.os.Bundle;
15 | import android.view.ViewGroup;
16 | import android.view.Window;
17 | import android.webkit.WebView;
18 | import android.webkit.WebViewClient;
19 | import android.widget.FrameLayout;
20 | import android.widget.LinearLayout;
21 |
22 | public class StripeActivity extends Activity {
23 |
24 | private static final String TAG = "StripeActivity";
25 |
26 | private ProgressDialog mSpinner;
27 | private WebView mWebView;
28 | private LinearLayout mContent;
29 | private String mUrl;
30 | private String mCallBackUrl;
31 | private String mTokenUrl;
32 | private String mSecretKey;
33 | private String mAccountName;
34 |
35 | static final FrameLayout.LayoutParams FILL = new FrameLayout.LayoutParams(
36 | ViewGroup.LayoutParams.MATCH_PARENT,
37 | ViewGroup.LayoutParams.MATCH_PARENT);
38 |
39 | @Override
40 | protected void onCreate(Bundle savedInstanceState) {
41 | super.onCreate(savedInstanceState);
42 |
43 | mUrl = getIntent().getStringExtra("url");
44 | mCallBackUrl = getIntent().getStringExtra("callbackUrl");
45 | mTokenUrl = getIntent().getStringExtra("tokenUrl");
46 | mSecretKey = getIntent().getStringExtra("secretKey");
47 | mAccountName = getIntent().getStringExtra("accountName");
48 |
49 | setUpWebView();
50 |
51 | }
52 |
53 | @SuppressWarnings("deprecation")
54 | @SuppressLint({ "SetJavaScriptEnabled", "NewApi" })
55 | private void setUpWebView() {
56 |
57 | mSpinner = new ProgressDialog(this);
58 | mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
59 | mSpinner.setMessage("Loading...");
60 |
61 | mWebView = new WebView(this);
62 | mWebView.setVerticalScrollBarEnabled(false);
63 | mWebView.setHorizontalScrollBarEnabled(false);
64 | mWebView.setWebViewClient(new OAuthWebViewClient());
65 | mWebView.getSettings().setJavaScriptEnabled(true);
66 | mWebView.loadUrl(mUrl);
67 | mWebView.setLayoutParams(FILL);
68 |
69 | mContent = new LinearLayout(this);
70 | mContent.setOrientation(LinearLayout.VERTICAL);
71 | mContent.addView(mWebView);
72 |
73 | int currentapiVersion = android.os.Build.VERSION.SDK_INT;
74 | if(currentapiVersion >= android.os.Build.VERSION_CODES.FROYO) {
75 | addContentView(mContent, new LinearLayout.LayoutParams(
76 | LinearLayout.LayoutParams.MATCH_PARENT,
77 | LinearLayout.LayoutParams.MATCH_PARENT));
78 | }
79 | else {
80 | addContentView(mContent, new LinearLayout.LayoutParams(
81 | LinearLayout.LayoutParams.FILL_PARENT,
82 | LinearLayout.LayoutParams.FILL_PARENT));
83 | }
84 |
85 | StripeUtils.removeAllCookies(this);
86 |
87 | }
88 |
89 | private class OAuthWebViewClient extends WebViewClient {
90 |
91 | @Override
92 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
93 | AppLog.d(TAG, "OAuthWebViewClient.shouldOverrideUrlLoading", "Redirecting URL " + url);
94 | if (url.startsWith(mCallBackUrl)) {
95 |
96 | String queryString = url.replace(mCallBackUrl + "/?", "");
97 | AppLog.d(TAG, "OAuthWebViewClient.shouldOverrideUrlLoading", "queryString:" + queryString);
98 | Map parameters = StripeUtils.splitQuery(queryString);
99 | if(!url.contains("error")) {
100 | onComplete(parameters);
101 | }
102 | else {
103 | onError(parameters);
104 | }
105 | return true;
106 | }
107 | return false;
108 | }
109 |
110 | @Override
111 | public void onReceivedError(WebView view, int errorCode,
112 | String description, String failingUrl) {
113 | AppLog.e(TAG, "OAuthWebViewClient.onReceivedError", "Page error[errorCode="+errorCode+"]: " + description);
114 |
115 | super.onReceivedError(view, errorCode, description, failingUrl);
116 | Map error = new LinkedHashMap();
117 | error.put("error", String.valueOf(errorCode));
118 | error.put("error_description", description);
119 | onError(error);
120 | }
121 |
122 | @Override
123 | public void onPageStarted(WebView view, String url, Bitmap favicon) {
124 | super.onPageStarted(view, url, favicon);
125 | AppLog.d(TAG, "OAuthWebViewClient.onPageStarted", "url: " + url);
126 | mSpinner.show();
127 | }
128 |
129 | @Override
130 | public void onPageFinished(WebView view, String url) {
131 | super.onPageFinished(view, url);
132 | AppLog.d(TAG, "OAuthWebViewClient.onPageFinished", "url: " + url);
133 | mSpinner.dismiss();
134 | }
135 |
136 | }
137 |
138 | private void getAccessToken(String code) {
139 | try {
140 |
141 | URL url = new URL(mTokenUrl);
142 | String urlParameters = "code=" + code
143 | + "&client_secret=" + mSecretKey
144 | + "&grant_type=authorization_code";
145 | AppLog.i(TAG, "getAccessToken", "Getting access token with code:" + code);
146 | AppLog.i(TAG, "getAccessToken", "Opening URL " + url.toString() + "?" + urlParameters);
147 |
148 | String response = StripeUtils.executePost(mTokenUrl, urlParameters);
149 | AppLog.i(TAG, "getAccessToken", "response: " + response);
150 | JSONObject obj = new JSONObject(response);
151 |
152 | AppLog.i(TAG, "getAccessToken", "String data[access_token]: " + obj.getString("access_token"));
153 | AppLog.i(TAG, "getAccessToken", "String data[livemode]: " + obj.getBoolean("livemode"));
154 | AppLog.i(TAG, "getAccessToken", "String data[refresh_token]: " + obj.getString("refresh_token"));
155 | AppLog.i(TAG, "getAccessToken", "String data[token_type]: " + obj.getString("token_type"));
156 | AppLog.i(TAG, "getAccessToken", "String data[stripe_publishable_key]: " + obj.getString("stripe_publishable_key"));
157 | AppLog.i(TAG, "getAccessToken", "String data[stripe_user_id]: " + obj.getString("stripe_user_id"));
158 | AppLog.i(TAG, "getAccessToken", "String data[scope]: " + obj.getString("scope"));
159 |
160 | StripeSession mSession = new StripeSession(this, mAccountName);
161 | mSession.storeAccessToken(obj.getString("access_token"));
162 | mSession.storeRefreshToken(obj.getString("refresh_token"));
163 | mSession.storePublishableKey(obj.getString("stripe_publishable_key"));
164 | mSession.storeUserid(obj.getString("stripe_user_id"));
165 | mSession.storeLiveMode(obj.getBoolean("livemode"));
166 | mSession.storeTokenType(obj.getString("token_type"));
167 |
168 | }
169 | catch (Exception e) {
170 | e.printStackTrace();
171 | Map query_pairs = new LinkedHashMap();
172 | query_pairs.put("error", "UnsupportedEncodingException");
173 | query_pairs.put("error_description", e.getMessage());
174 | onError(query_pairs);
175 | }
176 | }
177 |
178 | private void onComplete(Map parameters) {
179 |
180 | String code = parameters.get("code");
181 | getAccessToken(code);
182 |
183 | Intent returnIntent = new Intent();
184 | setResult(StripeApp.RESULT_CONNECTED, returnIntent);
185 | finish();
186 | }
187 |
188 | private void onError(Map parameters) {
189 | Intent returnIntent = new Intent();
190 | returnIntent.putExtra("error", parameters.get("error"));
191 | returnIntent.putExtra("error_description", parameters.get("error_description"));
192 | setResult(StripeApp.RESULT_ERROR, returnIntent);
193 | finish();
194 | }
195 |
196 | }
197 |
--------------------------------------------------------------------------------
/android-stripe-connect/src/com/github/thiagolocatelli/stripe/StripeDialog.java:
--------------------------------------------------------------------------------
1 | package com.github.thiagolocatelli.stripe;
2 |
3 | import java.util.LinkedHashMap;
4 | import java.util.Map;
5 |
6 | import android.annotation.SuppressLint;
7 | import android.app.Dialog;
8 | import android.app.ProgressDialog;
9 | import android.content.Context;
10 | import android.graphics.Bitmap;
11 | import android.graphics.Color;
12 | import android.graphics.Point;
13 | import android.graphics.Typeface;
14 | import android.os.Build;
15 | import android.os.Bundle;
16 | import android.util.DisplayMetrics;
17 | import android.view.Display;
18 | import android.view.ViewGroup;
19 | import android.view.Window;
20 | import android.view.WindowManager;
21 | import android.webkit.WebView;
22 | import android.webkit.WebViewClient;
23 | import android.widget.FrameLayout;
24 | import android.widget.LinearLayout;
25 | import android.widget.TextView;
26 |
27 | /**
28 | * Display Stripe Connect authentication dialog.
29 | *
30 | * @author Thiago Locatelli
31 | *
32 | */
33 | public class StripeDialog extends Dialog {
34 |
35 | static final int[] DIMENSIONS_LANDSCAPE = { 60, 60 };
36 | static final int[] DIMENSIONS_PORTRAIT = { 30, 60 };
37 |
38 | static final FrameLayout.LayoutParams FILL = new FrameLayout.LayoutParams(
39 | ViewGroup.LayoutParams.MATCH_PARENT,
40 | ViewGroup.LayoutParams.MATCH_PARENT);
41 | static final int MARGIN = 4;
42 | static final int PADDING = 2;
43 |
44 | private String mUrl;
45 | private String mCallbackUrl;
46 |
47 | private OAuthDialogListener mListener;
48 | private ProgressDialog mSpinner;
49 | private WebView mWebView;
50 | private LinearLayout mContent;
51 | private TextView mTitle;
52 |
53 | private static final String TAG = "StripeConnectAPI";
54 |
55 | public StripeDialog(Context context, String url, String callbackUrl, OAuthDialogListener listener) {
56 | super(context);
57 | mUrl = url;
58 | mCallbackUrl = callbackUrl;
59 | mListener = listener;
60 | }
61 |
62 | @Override
63 | protected void onCreate(Bundle savedInstanceState) {
64 | super.onCreate(savedInstanceState);
65 |
66 | mSpinner = new ProgressDialog(getContext());
67 | mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
68 | mSpinner.setMessage("Loading...");
69 | mContent = new LinearLayout(getContext());
70 | mContent.setOrientation(LinearLayout.VERTICAL);
71 | setUpTitle();
72 | setUpWebView();
73 |
74 | int pixelsWidth = getScreenWidthPixes();
75 | int pixelsHeight = getScreenHeightPixes();
76 | int dpWidth = pxToDp(pixelsWidth);
77 | int dpHeight = pxToDp(pixelsHeight);
78 |
79 | int[] dimensions = (pixelsWidth < pixelsHeight) ? DIMENSIONS_PORTRAIT
80 | : DIMENSIONS_LANDSCAPE;
81 |
82 | int dpNewWidth = dpWidth - dimensions[0];
83 | int dpNewHeight = dpHeight - dimensions[1];
84 | int pixelsNewWidth = dpToPx(dpNewWidth);
85 | int pixelsNewHeight = dpToPx(dpNewHeight);
86 | addContentView(mContent, new FrameLayout.LayoutParams(pixelsNewWidth, pixelsNewHeight));
87 |
88 | StripeUtils.removeAllCookies(getContext());
89 | }
90 |
91 | private void setUpTitle() {
92 | requestWindowFeature(Window.FEATURE_NO_TITLE);
93 | mTitle = new TextView(getContext());
94 | mTitle.setText("Stripe Connect");
95 | mTitle.setTextColor(Color.WHITE);
96 | mTitle.setTypeface(Typeface.DEFAULT_BOLD);
97 | mTitle.setBackgroundColor(Color.BLACK);
98 | mTitle.setPadding(MARGIN + PADDING, MARGIN, MARGIN, MARGIN);
99 | mContent.addView(mTitle);
100 | }
101 |
102 | @SuppressLint("SetJavaScriptEnabled")
103 | private void setUpWebView() {
104 | mWebView = new WebView(getContext());
105 | mWebView.setVerticalScrollBarEnabled(false);
106 | mWebView.setHorizontalScrollBarEnabled(false);
107 | mWebView.setWebViewClient(new OAuthWebViewClient());
108 | mWebView.getSettings().setJavaScriptEnabled(true);
109 | mWebView.loadUrl(mUrl);
110 | mWebView.setLayoutParams(FILL);
111 | mContent.addView(mWebView);
112 | }
113 |
114 | private class OAuthWebViewClient extends WebViewClient {
115 |
116 | @Override
117 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
118 | AppLog.d(TAG, "OAuthWebViewClient.shouldOverrideUrlLoading", "Redirecting URL " + url);
119 |
120 | if (url.startsWith(mCallbackUrl)) {
121 |
122 | String queryString = url.replace(mCallbackUrl + "/?", "");
123 | AppLog.d(TAG, "OAuthWebViewClient.shouldOverrideUrlLoading", "queryString:" + queryString);
124 | Map parameters = StripeUtils.splitQuery(queryString);
125 | if(!url.contains("error")) {
126 | mListener.onComplete(parameters);
127 | }
128 | else {
129 | mListener.onError(parameters);
130 | }
131 | StripeDialog.this.dismiss();
132 | return true;
133 | }
134 | return false;
135 | }
136 |
137 | @Override
138 | public void onReceivedError(WebView view, int errorCode,
139 | String description, String failingUrl) {
140 | AppLog.e(TAG, "OAuthWebViewClient.onReceivedError", "Page error[errorCode="+errorCode+"]: " + description);
141 |
142 | super.onReceivedError(view, errorCode, description, failingUrl);
143 | Map error = new LinkedHashMap();
144 | error.put("error", String.valueOf(errorCode));
145 | error.put("error_description", description);
146 | mListener.onError(error);
147 | StripeDialog.this.dismiss();
148 | }
149 |
150 | @Override
151 | public void onPageStarted(WebView view, String url, Bitmap favicon) {
152 | super.onPageStarted(view, url, favicon);
153 | AppLog.d(TAG, "OAuthWebViewClient.onPageStarted", "url: " + url);
154 | mSpinner.show();
155 | }
156 |
157 | @Override
158 | public void onPageFinished(WebView view, String url) {
159 | super.onPageFinished(view, url);
160 | AppLog.d(TAG, "OAuthWebViewClient.onPageFinished", "url: " + url);
161 | mSpinner.dismiss();
162 | String title = mWebView.getTitle();
163 | if (title != null && title.length() > 0) {
164 | mTitle.setText(title);
165 | }
166 | }
167 |
168 | }
169 |
170 | public interface OAuthDialogListener {
171 | public abstract void onComplete(Map parameters);
172 | public abstract void onError(Map parameters);
173 | }
174 |
175 | @SuppressLint("InlinedApi")
176 | public int dpToPx(int dp) {
177 | DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
178 | int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
179 | return px;
180 | }
181 |
182 | @SuppressLint("InlinedApi")
183 | public int pxToDp(int px) {
184 | DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
185 | int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
186 | return dp;
187 | }
188 |
189 | @SuppressWarnings("deprecation")
190 | @SuppressLint("NewApi")
191 | private int getScreenWidthPixes() {
192 | Point size = new Point();
193 | WindowManager w = getWindow().getWindowManager();
194 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
195 | w.getDefaultDisplay().getSize(size);
196 | return size.x;
197 | }
198 | else {
199 | Display d = w.getDefaultDisplay();
200 | return d.getWidth();
201 | }
202 | }
203 |
204 | @SuppressWarnings("deprecation")
205 | @SuppressLint("NewApi")
206 | private int getScreenHeightPixes() {
207 | Point size = new Point();
208 | WindowManager w = getWindow().getWindowManager();
209 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
210 | w.getDefaultDisplay().getSize(size);
211 | return size.y;
212 | }
213 | else {
214 | Display d = w.getDefaultDisplay();
215 | return d.getHeight();
216 | }
217 | }
218 |
219 | }
--------------------------------------------------------------------------------