-
Notifications
You must be signed in to change notification settings - Fork 629
/
AddressLauncher.kt
210 lines (181 loc) · 6.7 KB
/
AddressLauncher.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package com.stripe.android.paymentsheet.addresselement
import android.os.Parcelable
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.Fragment
import com.stripe.android.core.injection.InjectorKey
import com.stripe.android.core.injection.WeakMapInjectorRegistry
import com.stripe.android.paymentsheet.PaymentSheet
import kotlinx.parcelize.Parcelize
/**
* A drop-in class that presents a bottom sheet to collect a customer's address.
*/
internal class AddressLauncher internal constructor(
private val activityResultLauncher: ActivityResultLauncher<AddressElementActivityContract.Args>
) {
@InjectorKey
private val injectorKey: String =
WeakMapInjectorRegistry.nextKey(requireNotNull(AddressLauncher::class.simpleName))
/**
* Constructor to be used when launching the address element from an Activity.
*
* @param activity the Activity that is presenting the address element.
* @param callback called with the result after the address element is dismissed.
*/
constructor(
activity: ComponentActivity,
callback: AddressLauncherResultCallback
) : this(
activity.registerForActivityResult(
AddressElementActivityContract()
) {
callback.onAddressLauncherResult(it)
}
)
/**
* Constructor to be used when launching the address element from a Fragment.
*
* @param fragment the Fragment that is presenting the payment sheet.
* @param callback called with the result after the address element is dismissed.
*/
constructor(
fragment: Fragment,
callback: AddressLauncherResultCallback
) : this(
fragment.registerForActivityResult(
AddressElementActivityContract()
) {
callback.onAddressLauncherResult(it)
}
)
@JvmOverloads
fun present(
publishableKey: String,
configuration: Configuration = Configuration()
) {
activityResultLauncher.launch(
AddressElementActivityContract.Args(
publishableKey,
configuration,
injectorKey
)
)
}
/** Configuration for [AddressLauncher] **/
@Parcelize
internal data class Configuration @JvmOverloads constructor(
/**
* Configuration for the look and feel of the UI
*/
val appearance: PaymentSheet.Appearance = PaymentSheet.Appearance(),
/**
* The values to pre-populate shipping address fields with.
*/
val defaultValues: DefaultAddressDetails? = null,
/**
* A list of two-letter country codes representing countries the customers can select.
* If the list is empty (the default), we display all countries.
*/
val allowedCountries: Set<String> = emptySet(),
/**
* The title of the primary button displayed at the bottom of the screen.
* Defaults to "Save address".
*/
val buttonTitle: String? = null,
/**
* Configuration for the field that collects a phone number.
* Defaults to HIDDEN
*/
val phone: AdditionalFieldsConfiguration = AdditionalFieldsConfiguration.OPTIONAL,
/**
* Configuration for the title displayed at the top of the screen.
* Defaults to "Address"
*/
val title: String? = null,
/**
* Google Places api key used to provide autocomplete suggestions
* When null, autocomplete is disabled.
*/
val googlePlacesApiKey: String? = null,
/**
* The label of a checkbox displayed below other fields. If null, the checkbox is not displayed.
* Defaults to null
*/
val checkboxLabel: String? = null
) : Parcelable {
/**
* [Configuration] builder for cleaner object creation from Java.
*/
class Builder {
var appearance: PaymentSheet.Appearance = PaymentSheet.Appearance()
var defaultValues: DefaultAddressDetails? = null
var allowedCountries: Set<String> = emptySet()
var buttonTitle: String? = null
var phone: AdditionalFieldsConfiguration = AdditionalFieldsConfiguration.OPTIONAL
var title: String? = null
var googlePlacesApiKey: String? = null
var checkboxLabel: String? = null
fun appearance(appearance: PaymentSheet.Appearance) =
apply { this.appearance = appearance }
fun defaultValues(defaultValues: DefaultAddressDetails?) =
apply { this.defaultValues = defaultValues }
fun allowedCountries(allowedCountries: Set<String>) =
apply { this.allowedCountries = allowedCountries }
fun buttonTitle(buttonTitle: String?) =
apply { this.buttonTitle = buttonTitle }
fun phone(phone: AdditionalFieldsConfiguration) =
apply { this.phone = phone }
fun title(title: String?) =
apply { this.title = title }
fun googlePlacesApiKey(googlePlacesApiKey: String?) =
apply { this.googlePlacesApiKey = googlePlacesApiKey }
fun checkBoxLabel(checkboxLabel: String?) =
apply { this.checkboxLabel = checkboxLabel }
fun build() = Configuration(
appearance,
defaultValues,
allowedCountries,
buttonTitle,
phone,
title,
googlePlacesApiKey,
checkboxLabel
)
}
}
@Parcelize
enum class AdditionalFieldsConfiguration : Parcelable {
/**
* The field is not displayed.
*/
HIDDEN,
/**
* The field is displayed but the customer can leave it blank.
*/
OPTIONAL,
/**
* The field is displayed and the customer is required to fill it in.
*/
REQUIRED
}
@Parcelize
data class DefaultAddressDetails(
/**
* The customer's full name
*/
val name: String? = null,
/**
* The customer's address
*/
val address: PaymentSheet.Address? = null,
/**
* The customer's phone number, without formatting e.g. "5551234567"
*/
val phoneNumber: String? = null,
/**
* Whether or not your custom checkbox is intially selected.
* Note: The checkbox is displayed below the other fields when AdditionalFieldsConfiguration.checkboxLabel is set.
*/
val isCheckboxSelected: Boolean? = null
) : Parcelable
}