From c7a88a6d155d7d4bd793ee9b91596d98e8461b0b Mon Sep 17 00:00:00 2001 From: Michael Shafrir Date: Mon, 5 Aug 2019 12:37:34 -0400 Subject: [PATCH] Create GooglePayConfig Creates a `tokenizationSpecification`[0] object configured for Stripe. [0] https://developers.google.com/pay/api/android/reference/object#gateway --- .../java/com/stripe/android/ApiRequest.java | 4 +- .../java/com/stripe/android/ApiVersion.java | 26 +++++------ .../stripe/android/EphemeralKeyManager.java | 4 +- .../com/stripe/android/GooglePayConfig.java | 43 +++++++++++++++++++ .../com/stripe/android/ApiRequestTest.java | 2 +- .../stripe/android/GooglePayConfigTest.java | 23 ++++++++++ 6 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 stripe/src/main/java/com/stripe/android/GooglePayConfig.java create mode 100644 stripe/src/test/java/com/stripe/android/GooglePayConfigTest.java diff --git a/stripe/src/main/java/com/stripe/android/ApiRequest.java b/stripe/src/main/java/com/stripe/android/ApiRequest.java index fd34fb0ef2a..7ea0c2e9ec8 100644 --- a/stripe/src/main/java/com/stripe/android/ApiRequest.java +++ b/stripe/src/main/java/com/stripe/android/ApiRequest.java @@ -26,6 +26,7 @@ final class ApiRequest extends StripeRequest { static final String ANALYTICS_HOST = "https://q.stripe.com"; @NonNull final Options options; + @NonNull private final String mApiVersion; @Nullable private final AppInfo mAppInfo; @VisibleForTesting @@ -36,6 +37,7 @@ final class ApiRequest extends StripeRequest { @Nullable AppInfo appInfo) { super(method, url, params, MIME_TYPE); this.options = options; + mApiVersion = ApiVersion.get().code; mAppInfo = appInfo; } @@ -90,7 +92,7 @@ Map createHeaders() { headers.put("Accept-Charset", CHARSET); headers.put("Accept", "application/json"); headers.put("X-Stripe-Client-User-Agent", createStripeClientUserAgent()); - headers.put("Stripe-Version", ApiVersion.getDefault().getCode()); + headers.put("Stripe-Version", mApiVersion); headers.put("Authorization", String.format(Locale.ENGLISH, "Bearer %s", options.apiKey)); if (options.stripeAccount != null) { diff --git a/stripe/src/main/java/com/stripe/android/ApiVersion.java b/stripe/src/main/java/com/stripe/android/ApiVersion.java index 0b57c9fa1aa..ada6094b426 100644 --- a/stripe/src/main/java/com/stripe/android/ApiVersion.java +++ b/stripe/src/main/java/com/stripe/android/ApiVersion.java @@ -15,34 +15,30 @@ * API changes. */ final class ApiVersion { - private static final String DEFAULT_API_VERSION = "2019-05-16"; + @NonNull private static final String API_VERSION_CODE = "2019-05-16"; - @NonNull private static final ApiVersion DEFAULT_INSTANCE = new ApiVersion(DEFAULT_API_VERSION); + @NonNull private static final ApiVersion INSTANCE = new ApiVersion(API_VERSION_CODE); - @NonNull private final String mCode; + @NonNull public final String code; @NonNull - static ApiVersion create(@NonNull String code) { - return new ApiVersion(code); - } - - @NonNull - static ApiVersion getDefault() { - return DEFAULT_INSTANCE; + static ApiVersion get() { + return INSTANCE; } private ApiVersion(@NonNull String code) { - this.mCode = code; + this.code = code; } @NonNull - String getCode() { - return mCode; + @Override + public String toString() { + return code; } @Override public int hashCode() { - return ObjectUtils.hash(mCode); + return ObjectUtils.hash(code); } @Override @@ -51,6 +47,6 @@ public boolean equals(@Nullable Object obj) { } private boolean typedEquals(@NonNull ApiVersion apiVersion) { - return ObjectUtils.equals(mCode, apiVersion.mCode); + return ObjectUtils.equals(code, apiVersion.code); } } diff --git a/stripe/src/main/java/com/stripe/android/EphemeralKeyManager.java b/stripe/src/main/java/com/stripe/android/EphemeralKeyManager.java index 862deca6faa..8257f804937 100644 --- a/stripe/src/main/java/com/stripe/android/EphemeralKeyManager.java +++ b/stripe/src/main/java/com/stripe/android/EphemeralKeyManager.java @@ -18,6 +18,7 @@ class EphemeralKeyManager { @NonNull private final KeyManagerListener mListener; private final long mTimeBufferInSeconds; @NonNull private final EphemeralKey.Factory mFactory; + @NonNull private final String mApiVersion; @Nullable private TEphemeralKey mEphemeralKey; @@ -33,6 +34,7 @@ class EphemeralKeyManager { mListener = keyManagerListener; mTimeBufferInSeconds = timeBufferInSeconds; mOverrideCalendar = overrideCalendar; + mApiVersion = ApiVersion.get().code; retrieveEphemeralKey(operationIdFactory.create(), null, null); } @@ -43,7 +45,7 @@ void retrieveEphemeralKey(@NonNull String operationId, mEphemeralKey, mTimeBufferInSeconds, mOverrideCalendar)) { - mEphemeralKeyProvider.createEphemeralKey(ApiVersion.getDefault().getCode(), + mEphemeralKeyProvider.createEphemeralKey(mApiVersion, new ClientKeyUpdateListener(this, operationId, actionString, arguments)); } else { mListener.onKeyUpdate(mEphemeralKey, operationId, actionString, arguments); diff --git a/stripe/src/main/java/com/stripe/android/GooglePayConfig.java b/stripe/src/main/java/com/stripe/android/GooglePayConfig.java new file mode 100644 index 00000000000..76c93365e5b --- /dev/null +++ b/stripe/src/main/java/com/stripe/android/GooglePayConfig.java @@ -0,0 +1,43 @@ +package com.stripe.android; + +import android.support.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; + +@SuppressWarnings("WeakerAccess") +public final class GooglePayConfig { + @NonNull private final String mPublishableKey; + @NonNull private final String mApiVersion; + + /** + * Instantiate with {@link PaymentConfiguration}. {@link PaymentConfiguration} must be + * initialized. + */ + public GooglePayConfig() { + this(PaymentConfiguration.getInstance().getPublishableKey()); + } + + public GooglePayConfig(@NonNull String publishableKey) { + mPublishableKey = ApiKeyValidator.get().requireValid(publishableKey); + mApiVersion = ApiVersion.get().code; + } + + /** + * @return a {@link JSONObject} representing a + * + * Google Pay TokenizationSpecification configured for Stripe + */ + @NonNull + public JSONObject getTokenizationSpecification() throws JSONException { + return new JSONObject() + .put("type", "PAYMENT_GATEWAY") + .put( + "parameters", + new JSONObject() + .put("gateway", "stripe") + .put("stripe:version", mApiVersion) + .put("stripe:publishableKey", mPublishableKey) + ); + } +} diff --git a/stripe/src/test/java/com/stripe/android/ApiRequestTest.java b/stripe/src/test/java/com/stripe/android/ApiRequestTest.java index 0e3e18e8747..dbbec09dc6b 100644 --- a/stripe/src/test/java/com/stripe/android/ApiRequestTest.java +++ b/stripe/src/test/java/com/stripe/android/ApiRequestTest.java @@ -51,7 +51,7 @@ public void getHeaders_withAllRequestOptions_properlyMapsRequestOptions() { assertNotNull(headerMap); assertEquals("Bearer " + ApiKeyFixtures.FAKE_PUBLISHABLE_KEY, headerMap.get("Authorization")); - assertEquals(ApiVersion.getDefault().getCode(), headerMap.get("Stripe-Version")); + assertEquals(ApiVersion.get().code, headerMap.get("Stripe-Version")); assertEquals(stripeAccount, headerMap.get("Stripe-Account")); } diff --git a/stripe/src/test/java/com/stripe/android/GooglePayConfigTest.java b/stripe/src/test/java/com/stripe/android/GooglePayConfigTest.java new file mode 100644 index 00000000000..a5c21c42055 --- /dev/null +++ b/stripe/src/test/java/com/stripe/android/GooglePayConfigTest.java @@ -0,0 +1,23 @@ +package com.stripe.android; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class GooglePayConfigTest { + + @Test + public void getTokenizationSpecification() throws JSONException { + PaymentConfiguration.init(ApiKeyFixtures.FAKE_PUBLISHABLE_KEY); + final JSONObject tokenizationSpec = new GooglePayConfig().getTokenizationSpecification(); + final JSONObject params = tokenizationSpec.getJSONObject("parameters"); + assertEquals("stripe", + params.getString("gateway")); + assertEquals(ApiVersion.get().code, + params.getString("stripe:version")); + assertEquals(ApiKeyFixtures.FAKE_PUBLISHABLE_KEY, + params.getString("stripe:publishableKey")); + } +} \ No newline at end of file