From f562a5e819b70223cc3c7ba72e14193197ecc253 Mon Sep 17 00:00:00 2001 From: "Bruno R. Nunes" Date: Mon, 10 May 2021 18:16:52 -0700 Subject: [PATCH 1/2] Move PaymentSheet example into its own app. --- example/AndroidManifest.xml | 3 - example/build.gradle | 3 - .../main/java/com/stripe/example/Settings.kt | 9 +-- .../example/activity/LauncherActivity.kt | 8 --- .../example/module/BackendApiFactory.kt | 33 ----------- paymentsheet-example/build.gradle | 46 +++++++++++++++- .../src/main/AndroidManifest.xml | 12 ++++ .../paymentsheet/example/MainActivity.kt | 17 +++++- .../example/PaymentSheetExampleApplication.kt | 12 ++++ .../android/paymentsheet/example/Settings.kt | 55 +++++++++++++++++++ .../activity/BasePaymentSheetActivity.kt | 11 ++-- .../LaunchPaymentSheetCompleteActivity.kt | 4 +- .../LaunchPaymentSheetCustomActivity.kt | 14 ++--- .../example/config/ConfigBottomSheet.kt | 14 ++--- .../example/repository}/DefaultRepository.kt | 6 +- .../example/repository}/Repository.kt | 4 +- .../example/service/BackendApiFactory.kt | 43 +++++++++++++++ .../example/service/CheckoutBackendApi.kt | 2 +- .../viewmodel}/PaymentSheetViewModel.kt | 14 +++-- .../src/main}/res/drawable/ic_refresh.xml | 0 .../src/main}/res/drawable/ic_settings.xml | 0 .../src/main/res/layout/activity_main.xml | 34 ++++++++++++ .../activity_payment_sheet_complete.xml | 0 .../layout/activity_payment_sheet_custom.xml | 0 .../main/res/layout/config_bottom_sheet.xml | 0 .../src/main}/res/menu/payment_sheet.xml | 0 .../main}/res/menu/payment_sheet_custom.xml | 0 .../res/xml/payment_sheet_preferences.xml | 0 28 files changed, 252 insertions(+), 92 deletions(-) create mode 100644 paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/PaymentSheetExampleApplication.kt create mode 100644 paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/Settings.kt rename {example/src/main/java/com/stripe => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet}/example/activity/BasePaymentSheetActivity.kt (91%) rename {example/src/main/java/com/stripe => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet}/example/activity/LaunchPaymentSheetCompleteActivity.kt (91%) rename {example/src/main/java/com/stripe => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet}/example/activity/LaunchPaymentSheetCustomActivity.kt (90%) rename example/src/main/java/com/stripe/example/activity/PaymentSheetConfigBottomSheet.kt => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/config/ConfigBottomSheet.kt (81%) rename {example/src/main/java/com/stripe/example/paymentsheet => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository}/DefaultRepository.kt (74%) rename {example/src/main/java/com/stripe/example/paymentsheet => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository}/Repository.kt (61%) create mode 100644 paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/service/BackendApiFactory.kt rename {example/src/main/java/com/stripe => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet}/example/service/CheckoutBackendApi.kt (91%) rename {example/src/main/java/com/stripe/example/paymentsheet => paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/viewmodel}/PaymentSheetViewModel.kt (77%) rename {example => paymentsheet-example/src/main}/res/drawable/ic_refresh.xml (100%) rename {example => paymentsheet-example/src/main}/res/drawable/ic_settings.xml (100%) rename {example => paymentsheet-example/src/main}/res/layout/activity_payment_sheet_complete.xml (100%) rename {example => paymentsheet-example/src/main}/res/layout/activity_payment_sheet_custom.xml (100%) rename example/res/layout/payment_sheet_config_bottom_sheet.xml => paymentsheet-example/src/main/res/layout/config_bottom_sheet.xml (100%) rename {example => paymentsheet-example/src/main}/res/menu/payment_sheet.xml (100%) rename {example => paymentsheet-example/src/main}/res/menu/payment_sheet_custom.xml (100%) rename {example => paymentsheet-example/src/main}/res/xml/payment_sheet_preferences.xml (100%) diff --git a/example/AndroidManifest.xml b/example/AndroidManifest.xml index 5c07c2f0d85..0f6192a16f1 100644 --- a/example/AndroidManifest.xml +++ b/example/AndroidManifest.xml @@ -107,9 +107,6 @@ - - - diff --git a/example/build.gradle b/example/build.gradle index 3514346bcbe..676cca37ad9 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -3,7 +3,6 @@ plugins { id 'kotlin-android' id 'checkstyle' id 'org.jetbrains.kotlin.plugin.parcelize' - id 'org.jetbrains.kotlin.plugin.serialization' version '1.5.0' } assemble.dependsOn('lint') @@ -70,7 +69,6 @@ dependencies { /* Used to make Retrofit easier and GSON & Rx-compatible*/ implementation 'com.google.code.gson:gson:2.8.6' implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion" - implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0" implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' @@ -78,7 +76,6 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutinesVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0" ktlint "com.pinterest:ktlint:$ktlintVersion" diff --git a/example/src/main/java/com/stripe/example/Settings.kt b/example/src/main/java/com/stripe/example/Settings.kt index 39acb452ef4..8de95c09e11 100644 --- a/example/src/main/java/com/stripe/example/Settings.kt +++ b/example/src/main/java/com/stripe/example/Settings.kt @@ -36,7 +36,7 @@ class Settings(context: Context) { .takeIf { it?.isNotBlank() == true } } - internal companion object { + private companion object { /** * Note: only necessary if not configured via `gradle.properties`. * @@ -62,13 +62,6 @@ class Settings(context: Context) { */ private val STRIPE_ACCOUNT_ID: String? = null - // Example payment sheet backend with a "/checkout" endpoint - // Remix from https://glitch.com/edit/#!/stripe-mobile-payment-sheet-test-playground-v3 - internal const val PAYMENT_SHEET_BASE_URL = "" - - // Publishable key for example payment sheet backend - internal const val PAYMENT_SHEET_PUBLISHABLE_KEY = "" - private const val METADATA_KEY_BACKEND_URL_KEY = "com.stripe.example.metadata.backend_url" private const val METADATA_KEY_PUBLISHABLE_KEY = diff --git a/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt b/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt index 9acf602cac7..26ad1f4c5c1 100644 --- a/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt +++ b/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt @@ -36,14 +36,6 @@ class LauncherActivity : AppCompatActivity() { private val activity: Activity ) : RecyclerView.Adapter() { private val items = listOf( - Item( - "Launch PaymentSheet Complete", - LaunchPaymentSheetCompleteActivity::class.java - ), - Item( - "Launch PaymentSheet Custom", - LaunchPaymentSheetCustomActivity::class.java - ), Item( activity.getString(R.string.payment_auth_example), PaymentAuthActivity::class.java diff --git a/example/src/main/java/com/stripe/example/module/BackendApiFactory.kt b/example/src/main/java/com/stripe/example/module/BackendApiFactory.kt index 55076ef94bd..96240888b6a 100644 --- a/example/src/main/java/com/stripe/example/module/BackendApiFactory.kt +++ b/example/src/main/java/com/stripe/example/module/BackendApiFactory.kt @@ -2,13 +2,8 @@ package com.stripe.example.module import android.content.Context import com.google.gson.GsonBuilder -import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.stripe.example.Settings import com.stripe.example.service.BackendApi -import com.stripe.example.service.CheckoutBackendApi -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.json.Json -import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit @@ -47,34 +42,6 @@ internal class BackendApiFactory internal constructor(private val backendUrl: St .create(BackendApi::class.java) } - @OptIn(ExperimentalSerializationApi::class) - fun createCheckout(): CheckoutBackendApi { - if (Settings.PAYMENT_SHEET_BASE_URL.isNullOrEmpty() || - Settings.PAYMENT_SHEET_PUBLISHABLE_KEY.isNullOrEmpty() - ) { - error( - "Settings.PAYMENT_SHEET_BASE_URL and Settings.PAYMENT_SHEET_PUBLISHABLE_KEY " + - "must be set for PaymentSheet example" - ) - } - - val logging = HttpLoggingInterceptor() - .setLevel(HttpLoggingInterceptor.Level.BODY) - - val httpClient = OkHttpClient.Builder() - .connectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS) - .readTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS) - .addInterceptor(logging) - .build() - - return Retrofit.Builder() - .addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) - .baseUrl(Settings.PAYMENT_SHEET_BASE_URL) - .client(httpClient) - .build() - .create(CheckoutBackendApi::class.java) - } - private companion object { private const val TIMEOUT_SECONDS = 15L } diff --git a/paymentsheet-example/build.gradle b/paymentsheet-example/build.gradle index 63c322f7335..756b697d2f3 100644 --- a/paymentsheet-example/build.gradle +++ b/paymentsheet-example/build.gradle @@ -1,21 +1,58 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'org.jetbrains.kotlin.plugin.serialization' version '1.5.0' +} + +// Read values from gradle.properties or system environment variable +def getBackendUrl() { + return getValue('STRIPE_PAYMENTSHEET_EXAMPLE_BACKEND_URL') +} + +def getPublishableKey() { + return getValue('STRIPE_PAYMENTSHEET_EXAMPLE_PUBLISHABLE_KEY') +} + +private def getValue(key) { + // first try to get the value from Gradle properties + // see https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties + final String propValue + if (hasProperty(key)) { + propValue = property(key) + } else { + propValue = null + } + + if (propValue?.trim()) { + return propValue + } else { + // Otherwise, get the value from environment variables + // see https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_environment_variables + final String envValue = System.getenv(key) + return envValue?.trim() ? envValue : "" + } } dependencies { implementation project(':stripe') + implementation "androidx.lifecycle:lifecycle-livedata-ktx:$androidLifecycleVersion" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$androidLifecycleVersion" implementation 'androidx.preference:preference-ktx:1.1.1' - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' implementation "androidx.activity:activity-ktx:1.2.3" + implementation 'com.google.android.material:material:1.3.0' + + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0" + + implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' + implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0" + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' @@ -41,6 +78,11 @@ android { versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + manifestPlaceholders = [ + BACKEND_URL: getBackendUrl(), + PUBLISHABLE_KEY: getPublishableKey() + ] } buildTypes { diff --git a/paymentsheet-example/src/main/AndroidManifest.xml b/paymentsheet-example/src/main/AndroidManifest.xml index 1dec2b7315f..77508072ed2 100644 --- a/paymentsheet-example/src/main/AndroidManifest.xml +++ b/paymentsheet-example/src/main/AndroidManifest.xml @@ -4,12 +4,21 @@ package="com.stripe.android.paymentsheet.example"> + + + + + + + \ No newline at end of file diff --git a/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/MainActivity.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/MainActivity.kt index 35c29b73b41..c526c6051fd 100644 --- a/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/MainActivity.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/MainActivity.kt @@ -1,13 +1,28 @@ package com.stripe.android.paymentsheet.example +import android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity +import com.stripe.android.paymentsheet.example.activity.LaunchPaymentSheetCompleteActivity +import com.stripe.android.paymentsheet.example.activity.LaunchPaymentSheetCustomActivity +import com.stripe.android.paymentsheet.example.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { + private val viewBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + setContentView(viewBinding.root) setSupportActionBar(findViewById(R.id.toolbar)) + + viewBinding.launchCompleteButton.setOnClickListener { + startActivity(Intent(this, LaunchPaymentSheetCompleteActivity::class.java)) + } + + viewBinding.launchCustomButton.setOnClickListener { + startActivity(Intent(this, LaunchPaymentSheetCustomActivity::class.java)) + } } } diff --git a/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/PaymentSheetExampleApplication.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/PaymentSheetExampleApplication.kt new file mode 100644 index 00000000000..0a302264e2e --- /dev/null +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/PaymentSheetExampleApplication.kt @@ -0,0 +1,12 @@ +package com.stripe.android.paymentsheet.example + +import android.app.Application +import com.stripe.android.PaymentConfiguration + +class PaymentSheetExampleApplication : Application() { + + override fun onCreate() { + super.onCreate() + PaymentConfiguration.init(this, Settings(this).publishableKey) + } +} diff --git a/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/Settings.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/Settings.kt new file mode 100644 index 00000000000..cbaa3bfe556 --- /dev/null +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/Settings.kt @@ -0,0 +1,55 @@ +package com.stripe.android.paymentsheet.example + +import android.content.Context +import android.content.pm.PackageManager + +/** + * See [Configure the app](https://github.com/stripe/stripe-android/tree/master/example#configure-the-app) + * for instructions on how to configure the example app before running it. + */ +class Settings(context: Context) { + private val appContext = context.applicationContext + private val backendMetadata = getMetadata(METADATA_KEY_BACKEND_URL_KEY) + private val publishableKeyMetadata = getMetadata(METADATA_KEY_PUBLISHABLE_KEY) + + val backendUrl: String + get() { + return backendMetadata ?: BASE_URL + } + + val publishableKey: String + get() { + return publishableKeyMetadata ?: PUBLISHABLE_KEY + } + + private fun getMetadata(key: String): String? { + return appContext.packageManager + .getApplicationInfo(appContext.packageName, PackageManager.GET_META_DATA) + .metaData + .getString(key) + .takeIf { it?.isNotBlank() == true } + } + + internal companion object { + /** + * Note: only necessary if not configured via `gradle.properties`. + * + * Set to the base URL of your test backend. If you are using + * [example-mobile-backend](https://github.com/stripe/example-mobile-backend), + * the URL will be something like `https://hidden-beach-12345.herokuapp.com/`. + */ + private const val BASE_URL = "put your base url here" + + /** + * Note: only necessary if not configured via `gradle.properties`. + * + * Set to publishable key from https://dashboard.stripe.com/test/apikeys + */ + private const val PUBLISHABLE_KEY = "pk_test_your_key_goes_here" + + private const val METADATA_KEY_BACKEND_URL_KEY = + "com.stripe.android.paymentsheet.example.metadata.backend_url" + private const val METADATA_KEY_PUBLISHABLE_KEY = + "com.stripe.android.paymentsheet.example.metadata.publishable_key" + } +} diff --git a/example/src/main/java/com/stripe/example/activity/BasePaymentSheetActivity.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/BasePaymentSheetActivity.kt similarity index 91% rename from example/src/main/java/com/stripe/example/activity/BasePaymentSheetActivity.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/BasePaymentSheetActivity.kt index 1f65abe454b..1e6bccf0e26 100644 --- a/example/src/main/java/com/stripe/example/activity/BasePaymentSheetActivity.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/BasePaymentSheetActivity.kt @@ -1,4 +1,4 @@ -package com.stripe.example.activity +package com.stripe.android.paymentsheet.example.activity import android.content.SharedPreferences import android.view.Menu @@ -9,8 +9,9 @@ import androidx.preference.PreferenceManager import com.stripe.android.PaymentConfiguration import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheetResult -import com.stripe.example.R -import com.stripe.example.paymentsheet.PaymentSheetViewModel +import com.stripe.android.paymentsheet.example.R +import com.stripe.android.paymentsheet.example.config.ConfigBottomSheet +import com.stripe.android.paymentsheet.example.viewmodel.PaymentSheetViewModel internal abstract class BasePaymentSheetActivity : AppCompatActivity() { protected val viewModel: PaymentSheetViewModel by viewModels { @@ -70,9 +71,9 @@ internal abstract class BasePaymentSheetActivity : AppCompatActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.config) { - PaymentSheetConfigBottomSheet().show( + ConfigBottomSheet().show( supportFragmentManager, - PaymentSheetConfigBottomSheet.TAG + ConfigBottomSheet.TAG ) return true } diff --git a/example/src/main/java/com/stripe/example/activity/LaunchPaymentSheetCompleteActivity.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/LaunchPaymentSheetCompleteActivity.kt similarity index 91% rename from example/src/main/java/com/stripe/example/activity/LaunchPaymentSheetCompleteActivity.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/LaunchPaymentSheetCompleteActivity.kt index f87bc9acfce..393feddd591 100644 --- a/example/src/main/java/com/stripe/example/activity/LaunchPaymentSheetCompleteActivity.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/LaunchPaymentSheetCompleteActivity.kt @@ -1,9 +1,9 @@ -package com.stripe.example.activity +package com.stripe.android.paymentsheet.example.activity import android.os.Bundle import androidx.core.view.isInvisible import com.stripe.android.paymentsheet.PaymentSheet -import com.stripe.example.databinding.ActivityPaymentSheetCompleteBinding +import com.stripe.android.paymentsheet.example.databinding.ActivityPaymentSheetCompleteBinding internal class LaunchPaymentSheetCompleteActivity : BasePaymentSheetActivity() { private val viewBinding by lazy { diff --git a/example/src/main/java/com/stripe/example/activity/LaunchPaymentSheetCustomActivity.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/LaunchPaymentSheetCustomActivity.kt similarity index 90% rename from example/src/main/java/com/stripe/example/activity/LaunchPaymentSheetCustomActivity.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/LaunchPaymentSheetCustomActivity.kt index 17cfdbcf123..4fb71651094 100644 --- a/example/src/main/java/com/stripe/example/activity/LaunchPaymentSheetCustomActivity.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/activity/LaunchPaymentSheetCustomActivity.kt @@ -1,18 +1,17 @@ -package com.stripe.example.activity +package com.stripe.android.paymentsheet.example.activity import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.core.view.isInvisible -import com.stripe.android.PaymentConfiguration import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheetResult +import com.stripe.android.paymentsheet.example.R +import com.stripe.android.paymentsheet.example.databinding.ActivityPaymentSheetCustomBinding import com.stripe.android.paymentsheet.model.PaymentOption -import com.stripe.example.R -import com.stripe.example.Settings -import com.stripe.example.databinding.ActivityPaymentSheetCustomBinding -internal class LaunchPaymentSheetCustomActivity : BasePaymentSheetActivity() { +internal class LaunchPaymentSheetCustomActivity : + com.stripe.android.paymentsheet.example.activity.BasePaymentSheetActivity() { private val viewBinding by lazy { ActivityPaymentSheetCustomBinding.inflate(layoutInflater) } @@ -23,9 +22,6 @@ internal class LaunchPaymentSheetCustomActivity : BasePaymentSheetActivity() { super.onCreate(savedInstanceState) setContentView(viewBinding.root) - // TODO(brnunes-stripe): Remove this once FlowController initialization is refactored. - PaymentConfiguration.init(this, Settings.PAYMENT_SHEET_PUBLISHABLE_KEY) - flowController = PaymentSheet.FlowController.create( this, ::onPaymentOption, diff --git a/example/src/main/java/com/stripe/example/activity/PaymentSheetConfigBottomSheet.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/config/ConfigBottomSheet.kt similarity index 81% rename from example/src/main/java/com/stripe/example/activity/PaymentSheetConfigBottomSheet.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/config/ConfigBottomSheet.kt index 649883d4250..fd7ccb25772 100644 --- a/example/src/main/java/com/stripe/example/activity/PaymentSheetConfigBottomSheet.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/config/ConfigBottomSheet.kt @@ -1,4 +1,4 @@ -package com.stripe.example.activity +package com.stripe.android.paymentsheet.example.config import android.os.Bundle import android.view.LayoutInflater @@ -7,11 +7,11 @@ import android.view.ViewGroup import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreferenceCompat import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import com.stripe.example.R -import com.stripe.example.databinding.PaymentSheetConfigBottomSheetBinding +import com.stripe.android.paymentsheet.example.R +import com.stripe.android.paymentsheet.example.databinding.ConfigBottomSheetBinding -class PaymentSheetConfigBottomSheet : BottomSheetDialogFragment() { - private var _viewBinding: PaymentSheetConfigBottomSheetBinding? = null +class ConfigBottomSheet : BottomSheetDialogFragment() { + private var _viewBinding: ConfigBottomSheetBinding? = null private val viewBinding get() = requireNotNull(_viewBinding) override fun onCreateView( @@ -19,7 +19,7 @@ class PaymentSheetConfigBottomSheet : BottomSheetDialogFragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - _viewBinding = PaymentSheetConfigBottomSheetBinding.inflate( + _viewBinding = ConfigBottomSheetBinding.inflate( requireActivity().layoutInflater, container, false @@ -61,6 +61,6 @@ class PaymentSheetConfigBottomSheet : BottomSheetDialogFragment() { } internal companion object { - val TAG = PaymentSheetConfigBottomSheet::class.java.simpleName + val TAG = ConfigBottomSheet::class.java.simpleName } } diff --git a/example/src/main/java/com/stripe/example/paymentsheet/DefaultRepository.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository/DefaultRepository.kt similarity index 74% rename from example/src/main/java/com/stripe/example/paymentsheet/DefaultRepository.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository/DefaultRepository.kt index 6f23d910225..d0bc4160d3a 100644 --- a/example/src/main/java/com/stripe/example/paymentsheet/DefaultRepository.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository/DefaultRepository.kt @@ -1,7 +1,7 @@ -package com.stripe.example.paymentsheet +package com.stripe.android.paymentsheet.example.repository -import com.stripe.example.service.CheckoutBackendApi -import com.stripe.example.service.CheckoutRequest +import com.stripe.android.paymentsheet.example.service.CheckoutBackendApi +import com.stripe.android.paymentsheet.example.service.CheckoutRequest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.withContext import kotlin.coroutines.CoroutineContext diff --git a/example/src/main/java/com/stripe/example/paymentsheet/Repository.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository/Repository.kt similarity index 61% rename from example/src/main/java/com/stripe/example/paymentsheet/Repository.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository/Repository.kt index a24fbad7584..496e304a42d 100644 --- a/example/src/main/java/com/stripe/example/paymentsheet/Repository.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/repository/Repository.kt @@ -1,6 +1,6 @@ -package com.stripe.example.paymentsheet +package com.stripe.android.paymentsheet.example.repository -import com.stripe.example.service.CheckoutResponse +import com.stripe.android.paymentsheet.example.service.CheckoutResponse import kotlinx.coroutines.flow.Flow internal interface Repository { diff --git a/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/service/BackendApiFactory.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/service/BackendApiFactory.kt new file mode 100644 index 00000000000..8ca69f05978 --- /dev/null +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/service/BackendApiFactory.kt @@ -0,0 +1,43 @@ +package com.stripe.android.paymentsheet.example.service + +import android.content.Context +import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory +import com.stripe.android.paymentsheet.example.Settings +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.json.Json +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import java.util.concurrent.TimeUnit + +/** + * Factory to generate our Retrofit instance. + */ +internal class BackendApiFactory internal constructor(private val backendUrl: String) { + + constructor(context: Context) : this(Settings(context).backendUrl) + + @OptIn(ExperimentalSerializationApi::class) + fun createCheckout(): CheckoutBackendApi { + val logging = HttpLoggingInterceptor() + .setLevel(HttpLoggingInterceptor.Level.BODY) + + val httpClient = OkHttpClient.Builder() + .connectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS) + .readTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS) + .addInterceptor(logging) + .build() + + return Retrofit.Builder() + .addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) + .baseUrl(backendUrl) + .client(httpClient) + .build() + .create(CheckoutBackendApi::class.java) + } + + private companion object { + private const val TIMEOUT_SECONDS = 15L + } +} diff --git a/example/src/main/java/com/stripe/example/service/CheckoutBackendApi.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/service/CheckoutBackendApi.kt similarity index 91% rename from example/src/main/java/com/stripe/example/service/CheckoutBackendApi.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/service/CheckoutBackendApi.kt index 88fd6ca6e5c..8c5661b4add 100644 --- a/example/src/main/java/com/stripe/example/service/CheckoutBackendApi.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/service/CheckoutBackendApi.kt @@ -1,4 +1,4 @@ -package com.stripe.example.service +package com.stripe.android.paymentsheet.example.service import kotlinx.serialization.Serializable import retrofit2.http.Body diff --git a/example/src/main/java/com/stripe/example/paymentsheet/PaymentSheetViewModel.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/viewmodel/PaymentSheetViewModel.kt similarity index 77% rename from example/src/main/java/com/stripe/example/paymentsheet/PaymentSheetViewModel.kt rename to paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/viewmodel/PaymentSheetViewModel.kt index f6098dd38c4..9e391937e90 100644 --- a/example/src/main/java/com/stripe/example/paymentsheet/PaymentSheetViewModel.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/viewmodel/PaymentSheetViewModel.kt @@ -1,19 +1,23 @@ -package com.stripe.example.paymentsheet +package com.stripe.android.paymentsheet.example.viewmodel import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.liveData -import com.stripe.example.module.BackendApiFactory -import com.stripe.example.module.StripeIntentViewModel +import com.stripe.android.paymentsheet.example.repository.DefaultRepository +import com.stripe.android.paymentsheet.example.service.BackendApiFactory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.single import kotlin.coroutines.CoroutineContext internal class PaymentSheetViewModel( application: Application, - private val repository: Repository -) : StripeIntentViewModel(application) { + private val repository: com.stripe.android.paymentsheet.example.repository.Repository +) : AndroidViewModel(application) { + val inProgress = MutableLiveData() + val status = MutableLiveData() fun prepareCheckout(customer: String, mode: String) = liveData { inProgress.postValue(true) diff --git a/example/res/drawable/ic_refresh.xml b/paymentsheet-example/src/main/res/drawable/ic_refresh.xml similarity index 100% rename from example/res/drawable/ic_refresh.xml rename to paymentsheet-example/src/main/res/drawable/ic_refresh.xml diff --git a/example/res/drawable/ic_settings.xml b/paymentsheet-example/src/main/res/drawable/ic_settings.xml similarity index 100% rename from example/res/drawable/ic_settings.xml rename to paymentsheet-example/src/main/res/drawable/ic_settings.xml diff --git a/paymentsheet-example/src/main/res/layout/activity_main.xml b/paymentsheet-example/src/main/res/layout/activity_main.xml index 911bab1db84..593a4fd1f36 100644 --- a/paymentsheet-example/src/main/res/layout/activity_main.xml +++ b/paymentsheet-example/src/main/res/layout/activity_main.xml @@ -20,4 +20,38 @@ + + +