Skip to content

Commit

Permalink
feat: add transactions api (#26)
Browse files Browse the repository at this point in the history
* feat: add endpoint to find all transactions

* feat: add endpoint to find single transaction

* style: make ktlint happy
  • Loading branch information
aripiprazole authored Jul 21, 2023
1 parent 160a80f commit 3a401c0
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 7 deletions.
68 changes: 67 additions & 1 deletion src/main/kotlin/Charge.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ import io.ktor.http.*
import io.ktor.util.cio.*
import io.ktor.utils.io.*
import java.io.File
import java.util.function.Consumer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

@Serializable
public data class Charge @JvmOverloads public constructor(
public val customer: Customer? = null,
public val customer: CustomerOrId? = null,
public val value: Long,
public val identifier: String,
public val correlationID: String,
Expand All @@ -35,6 +40,67 @@ public data class Charge @JvmOverloads public constructor(
public val globalID: String,
)

@Serializable(with = CustomerOrId.CustomerOrIdSerializer::class)
public sealed class CustomerOrId {
public class Id(public val value: String) : CustomerOrId()
public class IsCustomer(public val value: Customer) : CustomerOrId()

public fun isId(): Boolean {
return this is Id
}

public fun isCustomer(): Boolean {
return this is Id
}

public fun unwrapId(): String {
return when (this) {
is Id -> value
is IsCustomer -> error("Expected Id, got Customer")
}
}

public fun unwrapCustomer(): Customer {
return when (this) {
is Id -> error("Expected Customer, got Id")
is IsCustomer -> value
}
}

public fun foldVoid(ifId: Consumer<String>, ifCustomer: Consumer<Customer>) {
return when (this) {
is Id -> ifId.accept(value)
is IsCustomer -> ifCustomer.accept(value)
}
}

public fun <T> fold(ifId: (String) -> T, ifCustomer: (Customer) -> T): T {
return when (this) {
is Id -> ifId(value)
is IsCustomer -> ifCustomer(value)
}
}

internal object CustomerOrIdSerializer : KSerializer<CustomerOrId> {
override val descriptor: SerialDescriptor = Customer.serializer().descriptor

override fun deserialize(decoder: Decoder): CustomerOrId {
return runCatching {
Id(decoder.decodeString())
}.getOrElse {
IsCustomer(decoder.decodeSerializableValue(Customer.serializer()))
}
}

override fun serialize(encoder: Encoder, value: CustomerOrId) {
when (value) {
is Id -> encoder.encodeString(value.value)
is IsCustomer -> encoder.encodeSerializableValue(Customer.serializer(), value.value)
}
}
}
}

@Serializable
public enum class ChargeType {
DYNAMIC,
Expand Down
113 changes: 113 additions & 0 deletions src/main/kotlin/Transaction.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package br.com.openpix.sdk

import io.ktor.client.call.*
import io.ktor.client.request.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
public data class Transaction @JvmOverloads public constructor(
public val charge: Charge? = null,
public val value: Int,
public val time: String,
public val payer: Customer? = null,
public val globalID: String? = null,
public val pixQrCode: PixQrCode? = null,

public val withdraw: PixWithdrawTransaction? = null,

@SerialName("endToEndID")
public val firstEndToEndId: String? = null,

@SerialName("endToEndId")
public val secondEndToEndId: String? = null,

@SerialName("infoPagador")
public val infoPayer: String? = null,

@SerialName("customer")
public val customer: Customer? = null,

@SerialName("type")
public val kind: TransactionKind,
)

@Serializable
public enum class TransactionKind {
PAYMENT,
WITHDRAW,
REFUND,
FEE,
GIFTBACK,
}

@Serializable
public data class TransactionListResponse(
public val status: String,
public val transactions: List<Transaction>,
public val pageInfo: PageInfo,
)

@Serializable
public data class TransactionResponse(public val transaction: Transaction)

@Serializable
public data class PixWithdrawTransaction @JvmOverloads public constructor(
public val value: Int? = null,
public val time: String? = null,
public val payer: Customer? = null,

@SerialName("type")
public val kind: String,

@SerialName("infoPagador")
public val infoPayer: String? = null,

@SerialName("endToEndID")
public val firstEndToEndId: String? = null,

@SerialName("endToEndId")
public val secondEndToEndId: String? = null,
)

@JvmSynthetic
public suspend fun WooviSDK.getTransaction(id: String): TransactionResponse {
return client.get("/api/v1/transaction/$id").body<TransactionResponse>()
}

@JvmSynthetic
public suspend fun WooviSDK.transactions(
/** Start date used in the query. Complies with RFC 3339. */
start: String? = null,

/** End date used in the query. Complies with RFC 3339. */
end: String? = null,

/**
* You can use the charge ID or correlation ID or transaction ID of charge to get a list of transactions
* related of this transaction
*/
charge: String? = null,

/**
* You can use the QrCode static ID or correlation ID or identifier field of QrCode static to get a list
* of QrCode related of this transaction
*/
pixQrCode: String? = null,

/**
*You can use the ID or EndToEndId of a withdrawal transaction to get all transactions related to the
* withdrawal
*/
withdrawal: String? = null,
): TransactionListResponse {
return client
.get("/api/v1/transaction") {
start?.let { parameter("start", it) }
end?.let { parameter("end", it) }
charge?.let { parameter("charge", it) }
pixQrCode?.let { parameter("pixQrCode", it) }
withdrawal?.let { parameter("withdrawal", it) }
}
.body<TransactionListResponse>()
}
58 changes: 52 additions & 6 deletions src/main/kotlin/WooviSDK.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ import kotlinx.coroutines.future.future
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json

@JvmSynthetic
public suspend fun main() {
val sdk = WooviSDK(appId = System.getenv("APP_ID"))
println(sdk.deleteWebhook("V2ViaG9vazo2NDg3NzNjY2JlYmNjZTI0NzQ3ZmIwZGM="))
}

/**
* The entrypoint of Woovi SDK for Java, Kotlin and another JVM Languages, it does take an authorization [appId].
*/
Expand Down Expand Up @@ -283,6 +277,58 @@ public class WooviSDK @JvmOverloads public constructor(
createWebhook(builder) {}
}

/**
* Returns a transaction.
*
* @param id The transaction id.
* @return The transaction response.
*/
public fun getTransactionAsync(id: String): Future<TransactionResponse> = future {
getTransaction(id)
}

/**
* Returns the transactions
*
* @param start Start date used in the query. Complies with RFC 3339.
* @param end End date used in the query. Complies with RFC 3339.
* @param charge You can use the charge ID or correlation ID or transaction ID of charge to get a list
* of transactions related of this transaction
* @param pixQrCode You can use the QrCode static ID or correlation ID or identifier field of QrCode
* static to get a list of QrCode related of this transaction
* @param withdrawal You can use the ID or EndToEndId of a withdrawal transaction to get all transactions
* related to the withdrawal
* @return The transaction list response.
*/
@JvmOverloads
public fun transactionsAsync(
/** Start date used in the query. Complies with RFC 3339. */
start: String? = null,

/** End date used in the query. Complies with RFC 3339. */
end: String? = null,

/**
* You can use the charge ID or correlation ID or transaction ID of charge to get a list of transactions
* related of this transaction
*/
charge: String? = null,

/**
* You can use the QrCode static ID or correlation ID or identifier field of QrCode static to get a list
* of QrCode related of this transaction
*/
pixQrCode: String? = null,

/**
*You can use the ID or EndToEndId of a withdrawal transaction to get all transactions related to the
* withdrawal
*/
withdrawal: String? = null,
): Future<TransactionListResponse> = future {
transactions(start, end, charge, pixQrCode, withdrawal)
}

/**
* Removes JSON specification restriction (RFC-4627) and makes parser
* more liberal to the malformed input. In lenient mode quoted boolean literals,
Expand Down

0 comments on commit 3a401c0

Please sign in to comment.