Skip to content

Commit

Permalink
Add support for shipping in PaymentIntent confirmation (#2238)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshafrir-stripe authored Mar 2, 2020
1 parent bd4d1da commit 8e50b78
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.stripe.android.PaymentAuthConfig
import com.stripe.android.PaymentIntentResult
import com.stripe.android.SetupIntentResult
import com.stripe.android.Stripe
import com.stripe.android.model.Address
import com.stripe.android.model.ConfirmPaymentIntentParams
import com.stripe.android.model.ConfirmSetupIntentParams
import com.stripe.android.model.PaymentMethodCreateParams
Expand Down Expand Up @@ -284,8 +285,21 @@ class PaymentAuthActivity : AppCompatActivity() {
.setCvc("123")
.build()
),
paymentIntentClientSecret,
RETURN_URL
clientSecret = paymentIntentClientSecret,
returnUrl = RETURN_URL,
shipping = ConfirmPaymentIntentParams.Shipping(
address = Address.Builder()
.setCity("San Francisco")
.setCountry("US")
.setLine1("123 Market St")
.setLine2("#345")
.setPostalCode("94107")
.setState("CA")
.build(),
name = "Jenny Rosen",
carrier = "Fedex",
trackingNumber = "12345"
)
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.stripe.android.model

import android.os.Parcelable
import com.stripe.android.model.ConfirmPaymentIntentParams.SetupFutureUsage
import com.stripe.android.model.ConfirmPaymentIntentParams.Shipping
import com.stripe.android.model.ConfirmStripeIntentParams.Companion.PARAM_CLIENT_SECRET
import com.stripe.android.model.ConfirmStripeIntentParams.Companion.PARAM_MANDATE_ID
import com.stripe.android.model.ConfirmStripeIntentParams.Companion.PARAM_PAYMENT_METHOD_DATA
import com.stripe.android.model.ConfirmStripeIntentParams.Companion.PARAM_PAYMENT_METHOD_ID
import com.stripe.android.model.ConfirmStripeIntentParams.Companion.PARAM_RETURN_URL
import com.stripe.android.model.ConfirmStripeIntentParams.Companion.PARAM_USE_STRIPE_SDK
import kotlinx.android.parcel.Parcelize

data class ConfirmPaymentIntentParams internal constructor(
val paymentMethodCreateParams: PaymentMethodCreateParams? = null,
Expand Down Expand Up @@ -94,7 +97,14 @@ data class ConfirmPaymentIntentParams internal constructor(
*
* [setup_future_usage](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-setup_future_usage)
*/
private val setupFutureUsage: SetupFutureUsage? = null
private val setupFutureUsage: SetupFutureUsage? = null,

/**
* See [Shipping]
*
* [shipping](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping)
*/
private val shipping: Shipping? = null
) : ConfirmStripeIntentParams {

fun shouldSavePaymentMethod(): Boolean {
Expand Down Expand Up @@ -133,6 +143,10 @@ data class ConfirmPaymentIntentParams internal constructor(
setupFutureUsage?.let {
mapOf(PARAM_SETUP_FUTURE_USAGE to it.code)
}.orEmpty()
).plus(
shipping?.let {
mapOf(PARAM_SHIPPING to shipping.toParamMap())
}.orEmpty()
).plus(
paymentMethodParamMap
).plus(
Expand Down Expand Up @@ -206,13 +220,81 @@ data class ConfirmPaymentIntentParams internal constructor(
OffSession("off_session")
}

/**
* Shipping information for this PaymentIntent.
*
* [shipping](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping)
*/
@Parcelize
data class Shipping @JvmOverloads constructor(
/**
* [shipping.address](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping-address)
*
* Shipping address.
*/
internal val address: Address,

/**
* [shipping.name](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping-name)
*
* Recipient name.
*/
internal val name: String,

/**
* [shipping.carrier](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping-carrier)
*
* The delivery service that shipped a physical product, such as Fedex, UPS, USPS, etc.
*/
internal val carrier: String? = null,

/**
* [shipping.phone](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping-phone)
*
* Recipient phone (including extension).
*/
internal val phone: String? = null,

/**
* [shipping.tracking_number](https://stripe.com/docs/api/payment_intents/confirm#confirm_payment_intent-shipping-tracking_number)
*
* The tracking number for a physical product, obtained from the delivery service.
* If multiple tracking numbers were generated for this purchase, please separate
* them with commas.
*/
internal val trackingNumber: String? = null
) : StripeParamsModel, Parcelable {
override fun toParamMap(): Map<String, Any> {
return listOf(
PARAM_ADDRESS to address.toParamMap(),
PARAM_NAME to name,
PARAM_CARRIER to carrier,
PARAM_PHONE to phone,
PARAM_TRACKING_NUMBER to trackingNumber
).fold(emptyMap()) { acc, (key, value) ->
acc.plus(
value?.let { mapOf(key to it) }.orEmpty()
)
}
}

private companion object {
private const val PARAM_ADDRESS = "address"
private const val PARAM_NAME = "name"
private const val PARAM_CARRIER = "carrier"
private const val PARAM_PHONE = "phone"
private const val PARAM_TRACKING_NUMBER = "tracking_number"
}
}

companion object {
const val PARAM_SOURCE_DATA: String = "source_data"

internal const val PARAM_SOURCE_ID = "source"
internal const val PARAM_SAVE_PAYMENT_METHOD = "save_payment_method"
internal const val PARAM_PAYMENT_METHOD_OPTIONS = "payment_method_options"
private const val PARAM_SETUP_FUTURE_USAGE = "setup_future_usage"
private const val PARAM_SHIPPING = "shipping"

/**
* Create a [ConfirmPaymentIntentParams] without a payment method.
Expand All @@ -222,12 +304,14 @@ data class ConfirmPaymentIntentParams internal constructor(
fun create(
clientSecret: String,
returnUrl: String? = null,
extraParams: Map<String, Any>? = null
extraParams: Map<String, Any>? = null,
shipping: Shipping? = null
): ConfirmPaymentIntentParams {
return ConfirmPaymentIntentParams(
clientSecret = clientSecret,
returnUrl = returnUrl,
extraParams = extraParams
extraParams = extraParams,
shipping = shipping
)
}

Expand All @@ -250,6 +334,7 @@ data class ConfirmPaymentIntentParams internal constructor(
* @param mandateId Optional ID of the Mandate to be used for this payment.
* @param mandateData Optional details about the Mandate to create.
* @param setupFutureUsage Optional. See [SetupFutureUsage].
* @param shipping Optional. See [Shipping].
*/
@JvmOverloads
@JvmStatic
Expand All @@ -262,7 +347,8 @@ data class ConfirmPaymentIntentParams internal constructor(
paymentMethodOptions: PaymentMethodOptionsParams? = null,
mandateId: String? = null,
mandateData: MandateDataParams? = null,
setupFutureUsage: SetupFutureUsage? = null
setupFutureUsage: SetupFutureUsage? = null,
shipping: Shipping? = null
): ConfirmPaymentIntentParams {
return ConfirmPaymentIntentParams(
clientSecret = clientSecret,
Expand All @@ -273,7 +359,8 @@ data class ConfirmPaymentIntentParams internal constructor(
paymentMethodOptions = paymentMethodOptions,
mandateId = mandateId,
mandateData = mandateData,
setupFutureUsage = setupFutureUsage
setupFutureUsage = setupFutureUsage,
shipping = shipping
)
}

Expand All @@ -295,6 +382,7 @@ data class ConfirmPaymentIntentParams internal constructor(
* @param mandateId optional ID of the Mandate to be used for this payment.
* @param mandateData optional details about the Mandate to create.
* @param setupFutureUsage Optional. See [SetupFutureUsage].
* @param shipping Optional. See [Shipping].
*/
@JvmOverloads
@JvmStatic
Expand All @@ -306,7 +394,8 @@ data class ConfirmPaymentIntentParams internal constructor(
extraParams: Map<String, Any>? = null,
mandateId: String? = null,
mandateData: MandateDataParams? = null,
setupFutureUsage: SetupFutureUsage? = null
setupFutureUsage: SetupFutureUsage? = null,
shipping: Shipping? = null
): ConfirmPaymentIntentParams {
return ConfirmPaymentIntentParams(
clientSecret = clientSecret,
Expand All @@ -316,7 +405,8 @@ data class ConfirmPaymentIntentParams internal constructor(
extraParams = extraParams,
mandateId = mandateId,
mandateData = mandateData,
setupFutureUsage = setupFutureUsage
setupFutureUsage = setupFutureUsage,
shipping = shipping
)
}

Expand All @@ -334,6 +424,7 @@ data class ConfirmPaymentIntentParams internal constructor(
* This parameter only applies to the source passed in the same request
* or the current source attached to the PaymentIntent and must be
* specified again if a new source is added.
* @param shipping Optional. See [Shipping].
*/
@JvmOverloads
@JvmStatic
Expand All @@ -342,14 +433,16 @@ data class ConfirmPaymentIntentParams internal constructor(
clientSecret: String,
returnUrl: String,
savePaymentMethod: Boolean = false,
extraParams: Map<String, Any>? = null
extraParams: Map<String, Any>? = null,
shipping: Shipping? = null
): ConfirmPaymentIntentParams {
return ConfirmPaymentIntentParams(
clientSecret = clientSecret,
sourceId = sourceId,
returnUrl = returnUrl,
savePaymentMethod = savePaymentMethod,
extraParams = extraParams
extraParams = extraParams,
shipping = shipping
)
}

Expand All @@ -365,6 +458,7 @@ data class ConfirmPaymentIntentParams internal constructor(
* This parameter only applies to the source passed in the same request
* or the current source attached to the PaymentIntent and must be
* specified again if a new source is added.
* @param shipping Optional. See [Shipping].
*/
@JvmOverloads
@JvmStatic
Expand All @@ -373,14 +467,16 @@ data class ConfirmPaymentIntentParams internal constructor(
clientSecret: String,
returnUrl: String,
savePaymentMethod: Boolean = false,
extraParams: Map<String, Any>? = null
extraParams: Map<String, Any>? = null,
shipping: Shipping? = null
): ConfirmPaymentIntentParams {
return ConfirmPaymentIntentParams(
clientSecret = clientSecret,
sourceParams = sourceParams,
returnUrl = returnUrl,
savePaymentMethod = savePaymentMethod,
extraParams = extraParams
extraParams = extraParams,
shipping = shipping
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.stripe.android.model

import com.google.common.truth.Truth.assertThat
import com.stripe.android.CardNumberFixtures.VISA_NO_SPACES
import com.stripe.android.model.ConfirmPaymentIntentParams.Companion.PARAM_PAYMENT_METHOD_OPTIONS
import com.stripe.android.model.ConfirmPaymentIntentParams.Companion.PARAM_SAVE_PAYMENT_METHOD
Expand Down Expand Up @@ -310,6 +311,39 @@ class ConfirmPaymentIntentParamsTest {
)
}

@Test
fun shipping_toParamMap_shouldReturnExpectedMap() {
val shipping = ConfirmPaymentIntentParams.Shipping(
address = Address.Builder()
.setCity("San Francisco")
.setCountry("US")
.setLine1("123 Market St")
.setLine2("#345")
.setPostalCode("94107")
.setState("CA")
.build(),
name = "Jenny Rosen",
carrier = "Fedex",
trackingNumber = "12345"
)
assertThat(shipping.toParamMap())
.isEqualTo(
mapOf(
"address" to mapOf(
"line1" to "123 Market St",
"line2" to "#345",
"city" to "San Francisco",
"state" to "CA",
"postal_code" to "94107",
"country" to "US"
),
"name" to "Jenny Rosen",
"carrier" to "Fedex",
"tracking_number" to "12345"
)
)
}

private companion object {
private val FULL_FIELDS_VISA_CARD =
Card.Builder(VISA_NO_SPACES, 12, 2050, "123")
Expand Down

0 comments on commit 8e50b78

Please sign in to comment.