From 6dfc0b06b0740730943ac30685dbca1299d95b41 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 21:44:46 +0300 Subject: [PATCH 01/11] Fix spelling mistake in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 615b3f46..debd3d1e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ The SDK offers the following functionalities from the Daraja API: - [ ] Business To Customer (B2C) - Transact between an M-Pesa short code to a phone number registered on M-Pesa. - [x] Transaction Status - Check the status of a transaction. -- [ ] Account Balanace - Enquire the balance on an M-Pesa BuyGoods (Till Number) +- [ ] Account Balance - Enquire the balance on an M-Pesa BuyGoods (Till Number) - [ ] Reversal - Reverses an M-Pesa transaction. - [ ] Tax Remittance - This API enables businesses to remit tax to Kenya Revenue Authority (KRA). - [ ] Business Pay Bill - Pay bills directly from your business account to a pay bill number, or a From 18a738d98969d285ba9c5dfe3c169e50a65e5678 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 22:14:44 +0300 Subject: [PATCH 02/11] Created account balance request and response body --- .../network/models/AccountBalanceRequest.kt | 31 +++++++++++++++++++ .../network/models/AccountBalanceResponse.kt | 19 ++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt create mode 100644 daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt new file mode 100644 index 00000000..71b79f8c --- /dev/null +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt @@ -0,0 +1,31 @@ +package com.vickbt.darajakmp.network.models + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class AccountBalanceRequest( + @SerialName("Initiator") + val initiator: String, + + @SerialName("SecurityCredential") + val securityCredential: String, + + @SerialName("CommandID") + val commandId: String, + + @SerialName("PartyA") + val partyA: Int, + + @SerialName("IdentifierType") + val identifierType: Int, + + @SerialName("Remarks") + val remarks: String, + + @SerialName("QueueTimeOutURL") + val queueTimeOutURL: String, + + @SerialName("ResultURL") + val resultURL: String +) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt new file mode 100644 index 00000000..0c528d79 --- /dev/null +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt @@ -0,0 +1,19 @@ +package com.vickbt.darajakmp.network.models + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class AccountBalanceResponse( + @SerialName("OriginatorConversationID") + val originatorConversationId: String, + + @SerialName("ConversationID") + val conversationId: String, + + @SerialName("ResponseCode") + val responseCode: String, + + @SerialName("ResponseDescription") + val responseDescription: String +) From 8ba5350f021b4bdf4a657dd5e64cbd69785ca910 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 23:12:55 +0300 Subject: [PATCH 03/11] Added account balance endpoint --- .../kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt index 0721477f..117388df 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt @@ -16,8 +16,6 @@ package com.vickbt.darajakmp.utils -// ToDo: Add documentation - internal object DarajaEndpoints { const val PROD_BASE_URL = "api.safaricom.co.ke" const val SANDBOX_BASE_URL = "sandbox.safaricom.co.ke" @@ -28,6 +26,7 @@ internal object DarajaEndpoints { const val C2B_REGISTRATION_URL = "mpesa/c2b/v1/registerurl" const val INITIATE_C2B = "mpesa/c2b/v1/simulate" const val DYNAMIC_QR = "mpesa/qrcode/v1/generate" + const val ACCOUNT_BALANCE = "mpesa/accountbalance/v1/query" } enum class DarajaTransactionType { From 2d3d4bd9cfb091be410747bb0d2b0ebbcb4e89e7 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 23:13:15 +0300 Subject: [PATCH 04/11] Added ktor request to request account balance --- .../darajakmp/network/DarajaApiService.kt | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt index 9ce5f3da..f3b1c5e2 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt @@ -16,6 +16,8 @@ package com.vickbt.darajakmp.network +import com.vickbt.darajakmp.network.models.AccountBalanceRequest +import com.vickbt.darajakmp.network.models.AccountBalanceResponse import com.vickbt.darajakmp.network.models.C2BRegistrationRequest import com.vickbt.darajakmp.network.models.C2BRequest import com.vickbt.darajakmp.network.models.C2BResponse @@ -85,6 +87,18 @@ internal class DarajaApiService( }.body() } + internal suspend fun generateDynamicQr(dynamicQrRequest: DynamicQrRequest): DarajaResult = + darajaSafeApiCall { + val accessToken = inMemoryCache.get(1) { + fetchAccessToken().getOrThrow() + } + + return@darajaSafeApiCall httpClient.post(urlString = DarajaEndpoints.DYNAMIC_QR) { + headers { append(HttpHeaders.Authorization, "Bearer ${accessToken.accessToken}") } + setBody(dynamicQrRequest) + }.body() + } + /**Initiate API call using the [httpClient] provided by Ktor to query the status of an Mpesa Express payment transaction*/ internal suspend fun queryTransaction(darajaTransactionRequest: DarajaTransactionRequest): DarajaResult = darajaSafeApiCall { @@ -121,15 +135,21 @@ internal class DarajaApiService( }.body() } - internal suspend fun generateDynamicQr(dynamicQrRequest: DynamicQrRequest): DarajaResult = + internal suspend fun accountBalance( + accountBalanceRequest: AccountBalanceRequest, + initiatorPassword: String? = null + ): DarajaResult = darajaSafeApiCall { val accessToken = inMemoryCache.get(1) { fetchAccessToken().getOrThrow() } - return@darajaSafeApiCall httpClient.post(urlString = DarajaEndpoints.DYNAMIC_QR) { + val key = accountBalanceRequest.initiator + initiatorPassword + val securityCredential = key.encodeBase64() + + return@darajaSafeApiCall httpClient.post(urlString = DarajaEndpoints.ACCOUNT_BALANCE) { headers { append(HttpHeaders.Authorization, "Bearer ${accessToken.accessToken}") } - setBody(dynamicQrRequest) + setBody(accountBalanceRequest.copy(securityCredential = securityCredential)) }.body() } } From 917383699ea6acf2f43022dc234f104ecfbefb49 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 23:13:23 +0300 Subject: [PATCH 05/11] Update DarajaHttpClientFactory.kt --- .../darajakmp/network/DarajaHttpClientFactory.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt index e57ee3ee..3e9bb28c 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt @@ -34,13 +34,11 @@ import io.ktor.serialization.kotlinx.json.json import kotlinx.serialization.json.Json /**Initialize Ktor Http Client responsible for handling network operations*/ -internal class DarajaHttpClientFactory constructor(private val environment: DarajaEnvironment) { +internal class DarajaHttpClientFactory(private val environment: DarajaEnvironment) { - private val baseURL = if (environment == DarajaEnvironment.SANDBOX_ENVIRONMENT) { - DarajaEndpoints.SANDBOX_BASE_URL - } else { - DarajaEndpoints.PROD_BASE_URL - } + private val baseURL = + if (environment == DarajaEnvironment.SANDBOX_ENVIRONMENT) DarajaEndpoints.SANDBOX_BASE_URL + else DarajaEndpoints.PROD_BASE_URL /**Initialize Ktor Http Client responsible for handling network operations*/ internal fun createDarajaHttpClient() = HttpClient { From b949c2847a3ef2b99ee5e2b33ae5a8b0d9e143a6 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 23:47:03 +0300 Subject: [PATCH 06/11] Created DarajaIdentifierType enum --- .../com/vickbt/darajakmp/utils/DarajaConfigs.kt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt index 117388df..7a9e4bc2 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/utils/DarajaConfigs.kt @@ -42,15 +42,19 @@ enum class C2BResponseType { } /** - * BG: Pay Merchant (Buy Goods). + * @param [BG] Pay Merchant (Buy Goods). * - * WA: Withdraw Cash at Agent Till. + * @param [WA]: Withdraw Cash at Agent Till. * - * PB: Paybill or Business number. + * @param [PB]: Paybill or Business number. * - * SM: Send Money(Mobile number) + * @param [SM]: Send Money(Mobile number) * - * SB: Sent to Business. Business number CPI in MSISDN format.*/ + * @param [SB]: Sent to Business. Business number CPI in MSISDN format.*/ enum class DarajaTransactionCode { BG, WA, PB, SM, SB } + +enum class DarajaIdentifierType { + TILL_NUMBER, SHORT_CODE +} From de2dcb9a2fd40a70a8079f88aa584a339cc49bd1 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 23:47:17 +0300 Subject: [PATCH 07/11] Code clean up --- .../kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt index f3b1c5e2..a310f4c9 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt @@ -144,12 +144,9 @@ internal class DarajaApiService( fetchAccessToken().getOrThrow() } - val key = accountBalanceRequest.initiator + initiatorPassword - val securityCredential = key.encodeBase64() - return@darajaSafeApiCall httpClient.post(urlString = DarajaEndpoints.ACCOUNT_BALANCE) { headers { append(HttpHeaders.Authorization, "Bearer ${accessToken.accessToken}") } - setBody(accountBalanceRequest.copy(securityCredential = securityCredential)) + setBody(accountBalanceRequest) }.body() } } From 45e4aaa4eff52e4f47fa8038f81ae0791155003c Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 23:47:35 +0300 Subject: [PATCH 08/11] Added function to fetch account balance --- .../kotlin/com/vickbt/darajakmp/Daraja.kt | 102 ++++++++++++------ 1 file changed, 68 insertions(+), 34 deletions(-) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt index 6cdee668..de2ef4b2 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt @@ -18,6 +18,8 @@ package com.vickbt.darajakmp import com.vickbt.darajakmp.network.DarajaApiService import com.vickbt.darajakmp.network.DarajaHttpClientFactory +import com.vickbt.darajakmp.network.models.AccountBalanceRequest +import com.vickbt.darajakmp.network.models.AccountBalanceResponse import com.vickbt.darajakmp.network.models.C2BRegistrationRequest import com.vickbt.darajakmp.network.models.C2BRequest import com.vickbt.darajakmp.network.models.C2BResponse @@ -30,6 +32,7 @@ import com.vickbt.darajakmp.network.models.MpesaExpressRequest import com.vickbt.darajakmp.network.models.MpesaExpressResponse import com.vickbt.darajakmp.utils.C2BResponseType import com.vickbt.darajakmp.utils.DarajaEnvironment +import com.vickbt.darajakmp.utils.DarajaIdentifierType import com.vickbt.darajakmp.utils.DarajaResult import com.vickbt.darajakmp.utils.DarajaTransactionCode import com.vickbt.darajakmp.utils.DarajaTransactionType @@ -37,6 +40,7 @@ import com.vickbt.darajakmp.utils.getDarajaPassword import com.vickbt.darajakmp.utils.getDarajaPhoneNumber import com.vickbt.darajakmp.utils.getDarajaTimestamp import io.ktor.client.HttpClient +import io.ktor.util.encodeBase64 import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO import kotlinx.coroutines.runBlocking @@ -178,6 +182,44 @@ class Daraja( darajaApiService.initiateMpesaExpress(mpesaExpressRequest = mpesaExpressRequest) } + /**Generate a dynamic qr code to initiate payment + * + * @param [merchantName] Name of the company/M-Pesa merchant name + * @param referenceNumber Transaction reference + * @param amount The total amount for the sale/transaction. + * @param transactionCode Transaction Type. The supported types are: + * BG: Pay Merchant (Buy Goods). + * + * WA: Withdraw Cash at Agent Till. + * + * PB: Paybill or Business number. + * + * SM: Send Money(Mobile number) + * + * SB: Sent to Business. Business number CPI in MSISDN format. + * @param cpi Credit Party Identifier. Can be a mobile number, business number, agent till, paybill or business number, or merchant buy goods. + * @param size Size of the QR code image in pixels. QR code image will always be a square image. + * */ + fun generateDynamicQr( + merchantName: String, + referenceNumber: String, + amount: Int, + transactionCode: DarajaTransactionCode, + cpi: String, + size: Int + ): DarajaResult = runBlocking(Dispatchers.IO) { + val dynamicQrRequest = DynamicQrRequest( + merchantName = merchantName, + referenceNumber = referenceNumber, + amount = amount, + transactionCode = transactionCode.name, + cpi = cpi, + size = size.toString() + ) + + darajaApiService.generateDynamicQr(dynamicQrRequest = dynamicQrRequest) + } + /**Request the status of an Mpesa payment transaction * * @param [businessShortCode] This is organizations shortcode (Paybill or Buygoods - A 5 to 7 digit account number) used to identify an organization and receive the transaction. @@ -250,41 +292,33 @@ class Daraja( darajaApiService.c2b(c2bRequest = c2bRequest) } - /**Generate a dynamic qr code to initiate payment - * - * @param [merchantName] Name of the company/M-Pesa merchant name - * @param referenceNumber Transaction reference - * @param amount The total amount for the sale/transaction. - * @param transactionCode Transaction Type. The supported types are: - * BG: Pay Merchant (Buy Goods). - * - * WA: Withdraw Cash at Agent Till. - * - * PB: Paybill or Business number. - * - * SM: Send Money(Mobile number) - * - * SB: Sent to Business. Business number CPI in MSISDN format. - * @param cpi Credit Party Identifier. Can be a mobile number, business number, agent till, paybill or business number, or merchant buy goods. - * @param size Size of the QR code image in pixels. QR code image will always be a square image. - * */ - fun generateDynamicQr( - merchantName: String, - referenceNumber: String, - amount: Int, - transactionCode: DarajaTransactionCode, - cpi: String, - size: Int - ): DarajaResult = runBlocking(Dispatchers.IO) { - val dynamicQrRequest = DynamicQrRequest( - merchantName = merchantName, - referenceNumber = referenceNumber, - amount = amount, - transactionCode = transactionCode.name, - cpi = cpi, - size = size.toString() + fun accountBalance( + initiator: String, + initiatorPassword: String, + commandId: String = "AccountBalance", + partyA: Int, + identifierType: DarajaIdentifierType, + remarks: String = "Account balance request", + queueTimeOutURL: String, + resultURL: String + ): DarajaResult = runBlocking(Dispatchers.IO) { + val key = initiator + initiatorPassword + val securityCredential = key.encodeBase64() + + val accountBalanceRequest = AccountBalanceRequest( + initiator = initiator, + securityCredential = securityCredential, + commandId = commandId, + partyA = partyA, + identifierType = if (identifierType == DarajaIdentifierType.TILL_NUMBER) 2 else 4, + remarks = remarks, + queueTimeOutURL = queueTimeOutURL, + resultURL = resultURL ) - darajaApiService.generateDynamicQr(dynamicQrRequest = dynamicQrRequest) + darajaApiService.accountBalance( + accountBalanceRequest = accountBalanceRequest, + initiatorPassword = initiatorPassword + ) } } From 2162fd04da174cc3be6f66071889cefb5cf6d02c Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Sun, 5 May 2024 23:57:46 +0300 Subject: [PATCH 09/11] Added code documentation for account balance request --- .../kotlin/com/vickbt/darajakmp/Daraja.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt index de2ef4b2..f2cb3468 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt @@ -199,6 +199,8 @@ class Daraja( * SB: Sent to Business. Business number CPI in MSISDN format. * @param cpi Credit Party Identifier. Can be a mobile number, business number, agent till, paybill or business number, or merchant buy goods. * @param size Size of the QR code image in pixels. QR code image will always be a square image. + * + * @return [DynamicQrResponse] * */ fun generateDynamicQr( merchantName: String, @@ -292,6 +294,19 @@ class Daraja( darajaApiService.c2b(c2bRequest = c2bRequest) } + /**Request the account balance of a short code. This can be used for both B2C, buy goods and pay bill accounts. + * + * @param [initiator] This is the credential/username used to authenticate the transaction request + * @param [initiatorPassword] This is the credential/password used to authenticate the account balance request + * @param [commandId] A unique command is passed to the M-PESA system. Max length is 64. + * @param [partyA] The shortcode of the organization querying for the account balance. + * @param [identifierType] Type of organization querying for the account balance. + * @param [remarks] Comments that are sent along with the transaction + * @param [queueTimeOutURL] The end-point that receives a timeout message. + * @param [resultURL] It indicates the destination URL which Daraja should send the result message to. + * + * @return [AccountBalanceResponse] + * */ fun accountBalance( initiator: String, initiatorPassword: String, From 6ba700d216b2cabea654c99e28ee88968d3b7fad Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Mon, 6 May 2024 00:06:13 +0300 Subject: [PATCH 10/11] Added documentation in readme --- README.md | 47 ++++++++++++++++++- .../kotlin/com/vickbt/darajakmp/Daraja.kt | 5 +- .../darajakmp/network/DarajaApiService.kt | 5 +- .../network/models/AccountBalanceRequest.kt | 2 +- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index debd3d1e..cb8121ee 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ supports integration with your Android(Kotlin/Java), iOS(Swift) and JVM applicat - [Dynamic QR](#generate-dynamic-qr-code) - [Query M-Pesa Transaction](#query-m-pesa-transaction) - [Customer To Business(C2B)](#customer-to-businessc2b) + - [Account Balance](#account-balance) - [iOS - Swift](#ios---swift) - [Setting Up](#setting-up-1) - [Request Access Token](#request-access-token) @@ -34,6 +35,7 @@ supports integration with your Android(Kotlin/Java), iOS(Swift) and JVM applicat - [Dynamic QR](#generate-dynamic-qr-code) - [Query M-Pesa Transaction](#query-m-pesa-transaction-1) - [Customer To Business(C2B)](#customer-to-businessc2b) + - [Account Balance](#account-balance) ## Prerequisite @@ -55,7 +57,7 @@ The SDK offers the following functionalities from the Daraja API: - [ ] Business To Customer (B2C) - Transact between an M-Pesa short code to a phone number registered on M-Pesa. - [x] Transaction Status - Check the status of a transaction. -- [ ] Account Balance - Enquire the balance on an M-Pesa BuyGoods (Till Number) +- [x] Account Balance - Enquire the balance on an M-Pesa BuyGoods (Till Number) - [ ] Reversal - Reverses an M-Pesa transaction. - [ ] Tax Remittance - This API enables businesses to remit tax to Kenya Revenue Authority (KRA). - [ ] Business Pay Bill - Pay bills directly from your business account to a pay bill number, or a @@ -234,6 +236,28 @@ c2bResponse.onSuccess { } ``` +### Account Balance + +Request the account balance of a short code. This can be used for both B2C, buy goods and pay bill +accounts. + +```kotlin + val accountBalanceResponse = daraja.accountBalance( + initiator = "testapi", + initiatorPassword = "Safaricom999!*!", + partyA = 600987, + identifierType = DarajaIdentifierType.TILL_NUMBER, + queueTimeOutURL = "https://mydomain.com/AccountBalance/queue/", + resultURL = "https://mydomain.com/AccountBalance/result/" +) + +accountBalanceResponse.onSuccess { + // Successfully request account balance +}.onFailure { + // Failed to request account balance +} +``` + # iOS - Swift ### Setting Up @@ -337,5 +361,26 @@ darajaTransactionResponse.onSuccess(action: { data in }).onFailure(action: { error in // Failure fetching M-pesa transaction status }) +``` + +### Account Balance + +Request the account balance of a short code. This can be used for both B2C, buy goods and pay bill +accounts. + +```swift + var accountBalanceResponse = daraja.accountBalance( + initiator = "testapi", + initiatorPassword = "Safaricom999!*!", + partyA = 600987, + identifierType = DarajaIdentifierType.TILL_NUMBER, + queueTimeOutURL = "https://mydomain.com/AccountBalance/queue/", + resultURL = "https://mydomain.com/AccountBalance/result/" +) +accountBalanceResponse.onSuccess(action: { data in + // Successfully request account balance +}).onFailure(action: { error in + // Failed to request account balance +}) ``` diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt index f2cb3468..8c4d988e 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/Daraja.kt @@ -331,9 +331,6 @@ class Daraja( resultURL = resultURL ) - darajaApiService.accountBalance( - accountBalanceRequest = accountBalanceRequest, - initiatorPassword = initiatorPassword - ) + darajaApiService.accountBalance(accountBalanceRequest = accountBalanceRequest) } } diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt index a310f4c9..ee7a5845 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaApiService.kt @@ -135,10 +135,7 @@ internal class DarajaApiService( }.body() } - internal suspend fun accountBalance( - accountBalanceRequest: AccountBalanceRequest, - initiatorPassword: String? = null - ): DarajaResult = + internal suspend fun accountBalance(accountBalanceRequest: AccountBalanceRequest): DarajaResult = darajaSafeApiCall { val accessToken = inMemoryCache.get(1) { fetchAccessToken().getOrThrow() diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt index 71b79f8c..268eafe5 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -data class AccountBalanceRequest( +internal data class AccountBalanceRequest( @SerialName("Initiator") val initiator: String, From 93cfb6d6c1dbf91fbd426b9e2a0d9fe25387db62 Mon Sep 17 00:00:00 2001 From: Victor Kabata Date: Mon, 6 May 2024 00:08:29 +0300 Subject: [PATCH 11/11] Linting --- .../darajakmp/network/DarajaHttpClientFactory.kt | 7 +++++-- .../network/models/AccountBalanceRequest.kt | 16 ++++++++++++++++ .../network/models/AccountBalanceResponse.kt | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt index 3e9bb28c..b86cc4b2 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/DarajaHttpClientFactory.kt @@ -37,8 +37,11 @@ import kotlinx.serialization.json.Json internal class DarajaHttpClientFactory(private val environment: DarajaEnvironment) { private val baseURL = - if (environment == DarajaEnvironment.SANDBOX_ENVIRONMENT) DarajaEndpoints.SANDBOX_BASE_URL - else DarajaEndpoints.PROD_BASE_URL + if (environment == DarajaEnvironment.SANDBOX_ENVIRONMENT) { + DarajaEndpoints.SANDBOX_BASE_URL + } else { + DarajaEndpoints.PROD_BASE_URL + } /**Initialize Ktor Http Client responsible for handling network operations*/ internal fun createDarajaHttpClient() = HttpClient { diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt index 268eafe5..72a97333 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceRequest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2024 Daraja Multiplatform + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.vickbt.darajakmp.network.models import kotlinx.serialization.SerialName diff --git a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt index 0c528d79..a75db78f 100644 --- a/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt +++ b/daraja/src/commonMain/kotlin/com/vickbt/darajakmp/network/models/AccountBalanceResponse.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2024 Daraja Multiplatform + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.vickbt.darajakmp.network.models import kotlinx.serialization.SerialName