Skip to content

Commit

Permalink
Add sourceOrder field to Source model (#1839)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshafrir-stripe authored Nov 18, 2019
1 parent 9c641f7 commit 3508d1d
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 89 deletions.
114 changes: 95 additions & 19 deletions stripe/src/main/java/com/stripe/android/model/Source.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.stripe.android.model

import androidx.annotation.Size
import androidx.annotation.StringDef
import com.stripe.android.model.Source.SourceFlow
import com.stripe.android.model.Source.SourceType
import com.stripe.android.model.StripeJsonUtils.optLong
import com.stripe.android.model.StripeJsonUtils.optString
Expand All @@ -13,28 +14,89 @@ import org.json.JSONObject
*
* See [Sources API Reference](https://stripe.com/docs/api/sources/object).
*/
data class Source private constructor(
data class Source internal constructor(
/**
* Unique identifier for the object.
*/
override val id: String?,
val amount: Long?,
val clientSecret: String?,
val codeVerification: SourceCodeVerification?,
val created: Long?,
val currency: String?,

/**
* A positive integer in the smallest currency unit (that is, 100 cents for $1.00, or 1 for ¥1,
* Japanese Yen being a zero-decimal currency) representing the total amount associated with
* the source. This is the amount for which the source will be chargeable once ready.
* Required for `single_use` sources.
*/
val amount: Long? = null,

/**
* The client secret of the source. Used for client-side retrieval using a publishable key.
*/
val clientSecret: String? = null,

/**
* Information related to the code verification flow. Present if the source is authenticated
* by a verification code (`flow` is `code_verification`).
*/
val codeVerification: SourceCodeVerification? = null,

/**
* Time at which the object was created. Measured in seconds since the Unix epoch.
*/
val created: Long? = null,

/**
* Three-letter [ISO code for the currency](https://stripe.com/docs/currencies) associated with
* the source. This is the currency for which the source will be chargeable once ready.
* Required for `single_use` sources.
*/
val currency: String? = null,

/**
* The authentication `flow` of the source.
* `flow` is one of `redirect`, `receiver`, `code_verification`, `none`.
*/
@param:SourceFlow @field:SourceFlow @get:SourceFlow
val flow: String? = null,

val isLiveMode: Boolean?,
val metaData: Map<String, String>?,
val owner: SourceOwner?,
/**
* Has the value true if the object exists in live mode or the value false if the object
* exists in test mode.
*/
val isLiveMode: Boolean? = null,

/**
* Set of key-value pairs that you can attach to an object. This can be useful for storing
* additional information about the object in a structured format.
*/
val metaData: Map<String, String>? = null,

/**
* Information about the owner of the payment instrument that may be used or required by
* particular source types.
*/
val owner: SourceOwner? = null,

/**
* Information related to the receiver flow.
* Present if the source is a receiver ([flow] is [SourceFlow.RECEIVER]).
*/
val receiver: SourceReceiver? = null,

/**
* Information related to the redirect flow. Present if the source is authenticated by a
* redirect ([flow] is [SourceFlow.REDIRECT]).
*/
val redirect: SourceRedirect? = null,

/**
* The status of the source, one of `canceled`, `chargeable`, `consumed`, `failed`,
* or `pending`. Only `chargeable` sources can be used to create a charge.
*/
@param:SourceStatus @field:SourceStatus @get:SourceStatus
val status: String?,
val status: String? = null,

val sourceTypeData: Map<String, Any?>?,
val sourceTypeModel: StripeSourceTypeModel?,
val sourceTypeData: Map<String, Any?>? = null,
val sourceTypeModel: StripeSourceTypeModel? = null,

/**
* Gets the [SourceType] of this Source, as one of the enumerated values.
Expand All @@ -55,10 +117,21 @@ data class Source private constructor(
*/
val typeRaw: String,

/**
* Either `reusable` or `single_use`. Whether this source should be reusable or not. Some source
* types may or may not be reusable by construction, while others may leave the option at
* creation. If an incompatible value is passed, an error will be returned.
*/
@param:Usage @field:Usage @get:Usage
val usage: String?,
val usage: String? = null,

private val weChatParam: WeChat? = null,

private val weChatParam: WeChat?
/**
* Information about the items and shipping associated with the source. Required for
* transactional credit (for example Klarna) sources before you can charge it.
*/
val sourceOrder: SourceOrder? = null
) : StripeModel(), StripePaymentSource {

val weChat: WeChat
Expand Down Expand Up @@ -149,6 +222,7 @@ data class Source private constructor(
private const val FIELD_OWNER: String = "owner"
private const val FIELD_RECEIVER: String = "receiver"
private const val FIELD_REDIRECT: String = "redirect"
private const val FIELD_SOURCE_ORDER: String = "source_order"
private const val FIELD_STATUS: String = "status"
private const val FIELD_TYPE: String = "type"
private const val FIELD_USAGE: String = "usage"
Expand Down Expand Up @@ -181,11 +255,10 @@ data class Source private constructor(
val sourceTypeModel = SourceCardData.fromJson(jsonObject)

return Source(
id, null, null, null,
null, null, null, null,
null, null, null, null,
null, null, sourceTypeModel, SourceType.CARD,
SourceType.CARD, null, null
id,
sourceTypeModel = sourceTypeModel,
type = SourceType.CARD,
typeRaw = SourceType.CARD
)
}

Expand Down Expand Up @@ -240,6 +313,9 @@ data class Source private constructor(
WeChat.fromJson(jsonObject.optJSONObject(FIELD_WECHAT) ?: JSONObject())
} else {
null
},
sourceOrder = jsonObject.optJSONObject(FIELD_SOURCE_ORDER)?.let {
SourceOrder.fromJson(it)
}
)
}
Expand Down
65 changes: 37 additions & 28 deletions stripe/src/test/java/com/stripe/android/model/SourceFixtures.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.stripe.android.model

import com.stripe.android.model.SourceOrderFixtures.SOURCE_ORDER_JSON
import org.json.JSONObject

internal object SourceFixtures {

@JvmField
val ALIPAY_JSON = JSONObject(
"""
{
Expand Down Expand Up @@ -43,8 +43,7 @@ internal object SourceFixtures {
""".trimIndent()
)

@JvmField
val WECHAT = Source.fromJson(JSONObject(
val WECHAT = requireNotNull(Source.fromJson(JSONObject(
"""
{
"id": "src_1F4ZSkBNJ02",
Expand Down Expand Up @@ -84,10 +83,9 @@ internal object SourceFixtures {
}
}
""".trimIndent()
))!!
)))

@JvmField
val SOURCE_CARD = Source.fromJson(JSONObject(
val SOURCE_CARD = requireNotNull(Source.fromJson(JSONObject(
"""
{
"id": "src_19t3xKBZqEXluyI4uz2dxAfQ",
Expand Down Expand Up @@ -132,10 +130,9 @@ internal object SourceFixtures {
}
}
""".trimIndent()
))!!
)))

@JvmField
val CARD = Source.fromJson(JSONObject(
val CARD = requireNotNull(Source.fromJson(JSONObject(
"""
{
"id": "card_1ELxrOCRMbs6FrXfdxOGjnaD",
Expand All @@ -162,9 +159,8 @@ internal object SourceFixtures {
"tokenization_method": null
}
""".trimIndent()
))!!
)))

@JvmField
val APPLE_PAY = JSONObject(
"""
{
Expand Down Expand Up @@ -194,8 +190,7 @@ internal object SourceFixtures {
""".trimIndent()
)

@JvmField
val SOURCE_REDIRECT_JSON = JSONObject(
private val SOURCE_REDIRECT_JSON = JSONObject(
"""
{
"return_url": "https://google.com",
Expand All @@ -205,11 +200,11 @@ internal object SourceFixtures {
""".trimIndent()
)

@JvmField
val SOURCE_REDIRECT = SourceRedirect.fromJson(SOURCE_REDIRECT_JSON)!!
val SOURCE_REDIRECT = requireNotNull(
SourceRedirect.fromJson(SOURCE_REDIRECT_JSON)
)

@JvmField
val SOURCE_CODE_VERIFICATION_JSON = JSONObject(
private val SOURCE_CODE_VERIFICATION_JSON = JSONObject(
"""
{
"attempts_remaining": 3,
Expand All @@ -218,13 +213,11 @@ internal object SourceFixtures {
""".trimIndent()
)

@JvmField
val SOURCE_CODE_VERIFICATION = SourceCodeVerification.fromJson(
SOURCE_CODE_VERIFICATION_JSON
)!!
val SOURCE_CODE_VERIFICATION = requireNotNull(
SourceCodeVerification.fromJson(SOURCE_CODE_VERIFICATION_JSON)
)

@JvmField
val SOURCE_RECEIVER_JSON = JSONObject(
private val SOURCE_RECEIVER_JSON = JSONObject(
"""
{
"address": "test_1MBhWS3uv4ynCfQXF3xQjJkzFPukr4K56N",
Expand All @@ -235,10 +228,8 @@ internal object SourceFixtures {
""".trimIndent()
)

@JvmField
val SOURCE_RECEIVER = SourceReceiver.fromJson(SOURCE_RECEIVER_JSON)!!
val SOURCE_RECEIVER = requireNotNull(SourceReceiver.fromJson(SOURCE_RECEIVER_JSON))

@JvmField
val SOURCE_OWNER_WITH_NULLS = JSONObject(
"""
{
Expand All @@ -254,7 +245,6 @@ internal object SourceFixtures {
""".trimIndent()
)

@JvmField
val SOURCE_OWNER_WITHOUT_NULLS = JSONObject(
"""
{
Expand Down Expand Up @@ -284,7 +274,6 @@ internal object SourceFixtures {
""".trimIndent()
)

@JvmField
internal val SOURCE_CARD_DATA_WITH_APPLE_PAY_JSON = JSONObject(
"""
{
Expand All @@ -303,4 +292,24 @@ internal object SourceFixtures {
}
""".trimIndent()
)

internal val SOURCE_WITH_SOURCE_ORDER = requireNotNull(Source.fromJson(JSONObject(
"""
{
"id": "src_1FfB6GKmrohBAXC",
"object": "source",
"amount": 1000,
"created": 1573848540,
"currency": "eur",
"flow": "redirect",
"livemode": false,
"metadata": {},
"source_order": $SOURCE_ORDER_JSON,
"statement_descriptor": null,
"status": "pending",
"type": "klarna",
"usage": "single_use"
}
""".trimIndent()
)))
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.json.JSONObject

internal object SourceOrderFixtures {

val SOURCE_ORDER = SourceOrder.fromJson(JSONObject(
val SOURCE_ORDER_JSON = JSONObject(
"""
{
"amount": 1000,
Expand Down Expand Up @@ -53,5 +53,46 @@ internal object SourceOrderFixtures {
}
}
""".trimIndent()
))
)

val SOURCE_ORDER = SourceOrder(
amount = 1000,
currency = "eur",
email = "[email protected]",
items = listOf(
SourceOrder.Item(
type = SourceOrder.Item.Type.Sku,
amount = 1000,
currency = "eur",
description = "shoes",
quantity = 1
),
SourceOrder.Item(
type = SourceOrder.Item.Type.Sku,
amount = 1000,
currency = "eur",
description = "socks",
quantity = 1
),
SourceOrder.Item(
type = SourceOrder.Item.Type.Shipping,
amount = 499,
currency = "eur",
description = "ground shipping"
),
SourceOrder.Item(
type = SourceOrder.Item.Type.Tax,
amount = 299,
currency = "eur",
description = "sales tax"
)
),
shipping = SourceOrder.Shipping(
address = AddressFixtures.ADDRESS,
carrier = "UPS",
name = "Jenny Rosen",
phone = "1-800-555-1234",
trackingNumber = "tracking_12345"
)
)
}
Loading

0 comments on commit 3508d1d

Please sign in to comment.