From 5fa47937856d269376eab1322f107be3a20a373b Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Fri, 30 Aug 2024 15:39:48 +0300
Subject: [PATCH 01/14] Added koin bom and koin android
---
samples/android/app/build.gradle.kts | 6 ++++++
samples/android/gradle/libs.versions.toml | 4 ++++
2 files changed, 10 insertions(+)
diff --git a/samples/android/app/build.gradle.kts b/samples/android/app/build.gradle.kts
index 6f0f9e7d..d6168ab5 100644
--- a/samples/android/app/build.gradle.kts
+++ b/samples/android/app/build.gradle.kts
@@ -59,11 +59,17 @@ dependencies {
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
+
+ implementation(platform(libs.koin.bom))
+ implementation(libs.koin.android)
+
testImplementation(libs.junit)
+
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
+
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
\ No newline at end of file
diff --git a/samples/android/gradle/libs.versions.toml b/samples/android/gradle/libs.versions.toml
index d4d4d6c2..eddd3b74 100644
--- a/samples/android/gradle/libs.versions.toml
+++ b/samples/android/gradle/libs.versions.toml
@@ -8,6 +8,7 @@ espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.4"
activityCompose = "1.9.1"
composeBom = "2024.04.01"
+koinBom = "3.5.6"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -25,6 +26,9 @@ androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-man
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
+koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koinBom" }
+koin-android = { module = "io.insert-koin:koin-androidx-compose" }
+
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
From a5dfb7ab5cd7881941add86d3badb71b46a18fda Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Fri, 30 Aug 2024 15:41:25 +0300
Subject: [PATCH 02/14] Added daraja lib
---
samples/android/app/build.gradle.kts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/samples/android/app/build.gradle.kts b/samples/android/app/build.gradle.kts
index d6168ab5..fe2b2e9e 100644
--- a/samples/android/app/build.gradle.kts
+++ b/samples/android/app/build.gradle.kts
@@ -62,7 +62,9 @@ dependencies {
implementation(platform(libs.koin.bom))
implementation(libs.koin.android)
-
+
+ implementation("io.github.victorkabata:daraja-multiplatform:0.9.5")
+
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
From 7f291f5ec69cbf41d6d182c9c67cdd973e8fa261 Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Fri, 30 Aug 2024 16:43:53 +0300
Subject: [PATCH 03/14] Update publish_kmp_lib.yml
---
.github/workflows/publish_kmp_lib.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/publish_kmp_lib.yml b/.github/workflows/publish_kmp_lib.yml
index b94f564d..19fa1e66 100644
--- a/.github/workflows/publish_kmp_lib.yml
+++ b/.github/workflows/publish_kmp_lib.yml
@@ -32,7 +32,7 @@ jobs:
run: ./gradlew :daraja:allTests --stacktrace
- name: Sign and Publish Android Library
- run: ./gradlew :daraja:publishAllPublicationsToSonatypeRepository --max-workers 1 --stacktrace
+ run: ./gradlew clean publishAllPublicationsToSonatypeRepository --max-workers 1 --stacktrace
env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
From 32b60920cbe0965707a730dedd73f2d99f339c12 Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Mon, 2 Sep 2024 08:44:13 +0300
Subject: [PATCH 04/14] Update daraja kmp version from v0.9.5 to v0.9.6
---
samples/android/app/build.gradle.kts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/samples/android/app/build.gradle.kts b/samples/android/app/build.gradle.kts
index fe2b2e9e..ef1554c9 100644
--- a/samples/android/app/build.gradle.kts
+++ b/samples/android/app/build.gradle.kts
@@ -63,7 +63,7 @@ dependencies {
implementation(platform(libs.koin.bom))
implementation(libs.koin.android)
- implementation("io.github.victorkabata:daraja-multiplatform:0.9.5")
+ implementation("io.github.victorkabata:daraja-multiplatform:0.9.6")
testImplementation(libs.junit)
From b257af3d762a5d7af9f7d4099ade5e27566ff0ab Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Mon, 2 Sep 2024 09:47:40 +0300
Subject: [PATCH 05/14] Set up singleton instance of Daraja
---
.../com/vickbt/daraja/android/di/AppModule.kt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt
diff --git a/samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt b/samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt
new file mode 100644
index 00000000..78a5e801
--- /dev/null
+++ b/samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt
@@ -0,0 +1,16 @@
+package com.vickbt.daraja.android.di
+
+import com.vickbt.darajakmp.Daraja
+import org.koin.dsl.module
+
+val appModule = module {
+ // Provide a single instance of Daraja
+ single {
+ Daraja.Builder()
+ .setConsumerKey("")
+ .setConsumerSecret("")
+ .setPassKey("")
+ .isSandbox()
+ .build()
+ }
+}
\ No newline at end of file
From 49b8bfe9f7688ad56c924e31a3ded0dc33a90822 Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Mon, 2 Sep 2024 09:49:06 +0300
Subject: [PATCH 06/14] Set up artifact_id in deployment workflow
---
.github/workflows/publish_kmp_lib.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/publish_kmp_lib.yml b/.github/workflows/publish_kmp_lib.yml
index 19fa1e66..80a975f1 100644
--- a/.github/workflows/publish_kmp_lib.yml
+++ b/.github/workflows/publish_kmp_lib.yml
@@ -40,6 +40,7 @@ jobs:
POM_NAME: ${{ secrets.POM_NAME }}
POM_DESCRIPTION: ${{ secrets.POM_DESCRIPTION }}
POM_GROUPID: ${{ secrets.POM_GROUPID }}
+ POM_ARTIFACTID: ${{secrets.POM_ARTIFACTID}}
POM_URL: ${{ secrets.POM_URL }}
POM_DEVELOPER_ID: ${{ secrets.POM_DEVELOPER_ID }}
POM_DEVELOPER_NAME: ${{ secrets.POM_DEVELOPER_NAME }}
From 0b56ecde4d14ccbeb0dac5ee73e0a90497c647fd Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Mon, 2 Sep 2024 14:54:24 +0300
Subject: [PATCH 07/14] Set up base android sample
---
.../android/app/src/main/AndroidManifest.xml | 3 ++
.../android/DarajaAndroidApplication.kt | 20 ++++++++++++
.../android/ui/screen/MpesaExpressScreen.kt | 31 ++++++++++++-------
3 files changed, 42 insertions(+), 12 deletions(-)
create mode 100644 samples/android/app/src/main/java/com/vickbt/daraja/android/DarajaAndroidApplication.kt
diff --git a/samples/android/app/src/main/AndroidManifest.xml b/samples/android/app/src/main/AndroidManifest.xml
index 5885a0c1..1408c004 100644
--- a/samples/android/app/src/main/AndroidManifest.xml
+++ b/samples/android/app/src/main/AndroidManifest.xml
@@ -2,7 +2,10 @@
+
+
Date: Mon, 2 Sep 2024 15:13:41 +0300
Subject: [PATCH 08/14] Set up mpesa express screen functionality
---
.../com/vickbt/daraja/android/di/AppModule.kt | 6 +-
.../android/ui/screen/MpesaExpressScreen.kt | 71 +++++++++++++------
2 files changed, 51 insertions(+), 26 deletions(-)
diff --git a/samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt b/samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt
index 78a5e801..26e938f6 100644
--- a/samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt
+++ b/samples/android/app/src/main/java/com/vickbt/daraja/android/di/AppModule.kt
@@ -7,9 +7,9 @@ val appModule = module {
// Provide a single instance of Daraja
single {
Daraja.Builder()
- .setConsumerKey("")
- .setConsumerSecret("")
- .setPassKey("")
+ .setConsumerKey("consumer_key")
+ .setConsumerSecret("consumer_secret")
+ .setPassKey("pass_key")
.isSandbox()
.build()
}
diff --git a/samples/android/app/src/main/java/com/vickbt/daraja/android/ui/screen/MpesaExpressScreen.kt b/samples/android/app/src/main/java/com/vickbt/daraja/android/ui/screen/MpesaExpressScreen.kt
index 3add0dba..e40ce14c 100644
--- a/samples/android/app/src/main/java/com/vickbt/daraja/android/ui/screen/MpesaExpressScreen.kt
+++ b/samples/android/app/src/main/java/com/vickbt/daraja/android/ui/screen/MpesaExpressScreen.kt
@@ -2,7 +2,10 @@
package com.vickbt.daraja.android.ui.screen
+import android.util.Log
+import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
@@ -11,6 +14,7 @@ import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.Send
+import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.FloatingActionButtonDefaults
@@ -27,23 +31,29 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.vickbt.darajakmp.Daraja
import com.vickbt.darajakmp.utils.DarajaTransactionType
+import com.vickbt.darajakmp.utils.onFailure
+import com.vickbt.darajakmp.utils.onSuccess
import org.koin.compose.koinInject
@Composable
fun MpesaExpressScreen(modifier: Modifier = Modifier, daraja: Daraja = koinInject()) {
+ val context = LocalContext.current
+
val tillNumber by remember { mutableStateOf("174379") }
var amount by remember { mutableIntStateOf(1) }
var phoneNumber by remember { mutableStateOf("") }
+ var isLoading by remember { mutableStateOf(false) }
+
Column(
modifier = modifier.wrapContentSize(),
verticalArrangement = Arrangement.spacedBy(
@@ -86,29 +96,44 @@ fun MpesaExpressScreen(modifier: Modifier = Modifier, daraja: Daraja = koinInjec
// keyboardActions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done)
)
- FloatingActionButton(
- modifier = Modifier,
- shape = CircleShape,
- containerColor = MaterialTheme.colorScheme.primary,
- contentColor = MaterialTheme.colorScheme.onPrimary,
- elevation = FloatingActionButtonDefaults.elevation(),
- onClick = {
- daraja.mpesaExpress(
- businessShortCode = tillNumber,
- amount = amount,
- phoneNumber = phoneNumber,
- transactionType = DarajaTransactionType.CustomerPayBillOnline,
- transactionDesc = "Empty transaction to test SDK",
- callbackUrl = "https://mydomain.com",
- accountReference = "CompanyX"
+ Log.e("VicKbt", "Is loading: $isLoading")
+
+ Box(modifier = Modifier){
+ FloatingActionButton(
+ modifier = Modifier.align(Alignment.Center),
+ shape = CircleShape,
+ containerColor = MaterialTheme.colorScheme.primary,
+ contentColor = MaterialTheme.colorScheme.onPrimary,
+ elevation = FloatingActionButtonDefaults.elevation(),
+ onClick = {
+ isLoading = true
+
+ daraja.mpesaExpress(
+ businessShortCode = tillNumber,
+ amount = amount,
+ phoneNumber = phoneNumber,
+ transactionType = DarajaTransactionType.CustomerPayBillOnline,
+ transactionDesc = "Empty transaction to test SDK",
+ callbackUrl = "https://mydomain.com",
+ accountReference = "CompanyX"
+ ).onSuccess {
+ Toast.makeText(context, "Success: $it", Toast.LENGTH_SHORT).show()
+ }.onFailure {
+ Toast.makeText(context, "Error: ${it.errorMessage}", Toast.LENGTH_SHORT).show()
+ }
+
+ },
+ ) {
+ Icon(
+ modifier = Modifier.size(28.dp),
+ imageVector = Icons.AutoMirrored.Rounded.Send,
+ contentDescription = "Pay"
)
- },
- ) {
- Icon(
- modifier = Modifier.size(28.dp),
- imageVector = Icons.AutoMirrored.Rounded.Send,
- contentDescription = "Pay"
- )
+ }
+
+ if (isLoading){
+ CircularProgressIndicator(modifier = Modifier.align(Alignment.Center), trackColor = MaterialTheme.colorScheme.onPrimary)
+ }
}
}
}
From 634bb056a0c4c2a3c95c77bc4badf8eeeae82a4d Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Wed, 4 Sep 2024 10:26:02 +0300
Subject: [PATCH 09/14] Fix github security warning
---
.github/workflows/publish_swift_package.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/publish_swift_package.yml b/.github/workflows/publish_swift_package.yml
index 0be89cf1..7d2013e8 100644
--- a/.github/workflows/publish_swift_package.yml
+++ b/.github/workflows/publish_swift_package.yml
@@ -44,7 +44,7 @@ jobs:
uses: actions/checkout@v4
- name: Download directory with swift package
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
name: swiftpackage
path: swiftpackage
From d7d276fd9da8b930cf9b0a3c1f91b1c395076d1c Mon Sep 17 00:00:00 2001
From: Victor Kabata <39780120+VictorKabata@users.noreply.github.com>
Date: Tue, 17 Sep 2024 11:07:18 +0300
Subject: [PATCH 10/14] Create LICENSE
---
LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 201 insertions(+)
create mode 100644 LICENSE
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..319a0d1a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2022 Victor Kabata
+
+ 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.
From 23b1dcc99f13e9bfcb69b722ac84d4e3654b5c86 Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Tue, 17 Sep 2024 11:08:32 +0300
Subject: [PATCH 11/14] Update readme doc
---
README.md | 378 +-------------------------------------------------
docs/index.md | 24 ++--
mkdocs.yml | 2 +-
3 files changed, 20 insertions(+), 384 deletions(-)
diff --git a/README.md b/README.md
index 14940062..e777bf0d 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,6 @@
-## ⚠️Work in progress - Sandbox Mode⚠️
-
[Kotlin multiplatform](https://kotlinlang.org/docs/multiplatform.html) wrapper for Mpesa API
dubbed [_Daraja API_](https://developer.safaricom.co.ke/) (Daraja means bridge in Swahili) that
supports integration with your Android(Kotlin/Java), iOS(Swift) and JVM applications.
@@ -16,27 +14,16 @@ supports integration with your Android(Kotlin/Java), iOS(Swift) and JVM applicat
> M-PESA is a mobile money transfer service in Kenya that allows users to store and transfer money
> through their mobile phones.
+> > [!WARNING]
+> Daraja Multiplatform is under heavy development and, despite being heavily tested, its API isn't yet stabilized; _breaking changes
+> might happen on minor releases._ However, we will always provide migration guides.
+>
+> Report any issue or bug in the GitHub repository.
+
## Table of Content
- [Prerequisite](#prerequisite)
- [Features](#features)
-- [Usage](#usage)
- - [Android - Kotlin](#android---kotlin)
- - [Setting Up](#setting-up)
- - [Request Access Token](#request-access-token)
- - [Initiate M-Pesa Express STK Request](#initiate-m-pesa-express-stk-request)
- - [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)
- - [Initiate M-Pesa Express STK Request](#initiate-m-pesa-express-stk-request-1)
- - [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
@@ -67,358 +54,7 @@ The SDK offers the following functionalities from the Daraja API:
- [ ] Business Buy Goods - Pay for goods and services directly from your business account to a till
number or merchant store number.
-## Usage
-
-# Android - Kotlin
-
-### Setting Up
-
-- In your android application project-level gradle file add the following dependency:
-
-
-Kotlin
-
-```Kotlin
- dependencies {
- implementation("io.github.victorkabata:daraja-multiplatform:0.9.3")
-}
-```
-
-
-
-
-Groovy
-
-```Groovy
- dependencies {
- implementation 'io.github.victorkabata:daraja-multiplatform:0.9.3'
-}
-```
-
-
-
-- Add your consumer secret, consumer key and pass key to your project. You can get them from
- the [Daraja API portal](https://developer.safaricom.co.ke/MyApps).
-
-> You should not add your daraja API environment variables in a production application because it is
-> a vulnerability to expose your environment secrets/variables in your version control system.
-> Ideally, you should add them to your `local.properties` files as demonstrated in
-> the [sample](https://github.com/VictorKabata/DarajaMultiplatform/tree/main/app-android) android
-> application.
-
-- Create an instance of the Daraja object by passing the daraja environment variables. The daraja
- object provides functions to request for an access token and initiate M-Pesa express STK request.
-
-```Kotlin
-val daraja: Daraja = Daraja.Builder()
- .setConsumerSecret("your_consumer_secret")
- .setConsumerKey("your_consumer_key")
- .setPassKey("your_pass_key")
- .isProduction() // Optional. Will default to sandbox_mode = true
- .build()
-```
-
-> Network logging is enabled by default when using Daraja Multiplatform. in sandbox/testing mode.
-> The logs can be accessed from the logcat in Android Studio under the `Daraja Multiplatform` tag.
-
-> Network logs are disabled in production mode.
-
-### Request Access Token
-
-- To request an access token from Daraja API, invoke the `authorization` function:
-
-```Kotlin
-val accessTokenResult: DarajaResult = daraja.authorization()
-
-accessTokenResult
- .onSuccess { accessToken ->
- // Successfully fetched daraja access token
- }
- .onFailure { error ->
- // Failure fetching daraja access token
- }
-```
-
-### Initiate M-Pesa Express STK Request
-
-- To initiate M-Pesa Express(Lipa na M-Pesa Online) STK request, invoke the `mpesaExpress` function:
-
-```kotlin
-val darajaPaymentResponse: DarajaResult = daraja.mpesaExpress(
- businessShortCode = "174379",
- amount = 1,
- phoneNumber = "07xxxxxxxx",
- transactionDesc = "M-Pesa payment",
- callbackUrl = "your_callback_url",
- accountReference = "CompanyName"
-)
-
-darajaPaymentResponse.onSuccess { paymentResponse ->
- // Successfully requested M-Pesa STK request
-}.onFailure { error ->
- // Failed to request M-Pesa STK
-}
-```
-
-### Query M-Pesa Express STK
-
-- To check the status of M-Pesa Express(Lipa na M-Pesa Online) STK request, invoke the `mpesaExpressQuery` function:
-
-```kotlin
-val darajaMpesaExpressQuery:DarajaResult = daraja.mpesaExpressQuery(
- businessShortCode = "174379",
- timeStamp = "20160216165627",
- checkOutRequestID = "ws_CO_260520211133524545"
-)
-
-darajaMpesaExpressQuery.onSuccess{ mpesaExpressQuery->
- // Successfully request M-Pesa STK request status
-}.onFailure{ error->
- // Failed to request M-Pesa STK status
-}
-```
-
-
-
-
-
-### Customer To Business(C2B)
-
-- To register the C2B validation and confirmation URL, invoke the `c2bRegistration` function:
-
-```kotlin
-val darajaC2BRegistrationResponse: DarajaResult = daraja.c2bRegistration(
- confirmationURL = "https://mydomain.com/confirmation",
- responseType = C2BResponseType.COMPLETED, // C2BResponseType.CANCELLED
- businessShortCode = 600981,
- validationURL = "https://mydomain.com/validation"
-)
-
-darajaC2BRegistrationResponse.onSuccess {
- // Successfully registered confirmation and validation URL
-}.onFailure {
- // Failure registering confirmation and validation URL
-}
-
-```
-
-- To initiate a Customer to Business paybill, invoke the `c2b` function:
-
-```kotlin
-val c2bResponse: DarajaResult = daraja.c2b(
- amount = 1,
- billReferenceNumber = "600977",
- transactionType = DarajaTransactionType.CustomerBuyGoodsOnline, // DarajaTransactionType.CustomerPayBillOnline
- phoneNumber = "0708374149",
- businessShortCode = "600977" //Optional when using CustomerBuyGoodsOnline
-)
-
-c2bResponse.onSuccess {
- // Successfully invoked C2B request
-}.onFailure {
- // Failure invoking C2B request
-}
-```
-
-### 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
-
-- To add **_DarajaMultiplatform_** package to your Xcode Project, open your Xcode project, navigate
- to the File tab within the macOS bar and click **Select Packages** then **Add Package Dependency
- **. Enter the package name ie. DarajaMultiplatform or the URL package GitHub URL:
-
-```curl
-https://github.com/VictorKabata/DarajaSwiftPackage.git
-```
-
-https://github.com/VictorKabata/DarajaSwiftPackage/assets/39780120/b9283612-3c5e-4100-aff8-c2c0d9f31863
-
-- Create an instance of the Daraja object by passing the daraja environment variables. The daraja
- object provides functions to request for an access token and initiate M-Pesa express STK request.
-
-```swift
-var daraja=Daraja(
- consumerKey: "your_consumer_key",
- consumerSecret: "your_customer_secret",
- passKey:"your_pass_key",
- environment: DarajaEnvironment.sandboxEnvironment
- )
-```
-
-> Network logging is enabled by default when using Daraja Multiplatform. in sandbox/testing mode.
-> The logs can be accessed from the logs in XCode IDE
-
-> Network logs are strictly disabled in production mode ie. DarajaEnvironment.productionEnvironment
-
-### Request Access Token
-
-- To request an access token from Daraja API, invoke the `authorization` function:
-
-```swift
-var accessTokenResult = daraja.authorization()
-
-accessTokenResult.onSuccess(action: { accessToken in
- // Successfully fetched daraja access token
- // Successfully fetched the access token
- }).onFailure(action: { error in
- // Failure fetching daraja access token
- })
-```
-
-### Initiate M-Pesa Express STK Request
-
-- To initiate M-Pesa Express(Lipa na M-Pesa Online) STK request, invoke the `mpesaExpress` function:
-
-```swift
-var darajaResponse = daraja.mpesaExpress(
- businessShortCode: "174379",
- amount: 1,
- phoneNumber: "07xxxxxxxx",
- transactionType: DarajaTransactionType.customerpaybillonline, transactionDesc: "M-Pesa payment",
- callbackUrl: "https://mydomain.com/path",
- accountReference: "Company name")
-
- darajaResponse.onSuccess(action: { data in
- // Successfully requested M-Pesa STK request
- })
- .onFailure(action: { error in
- // Failed to request M-Pesa STK
- })
-
-```
-
-### Query M-Pesa Express STK
-
-- To check the status of M-Pesa Express(Lipa na M-Pesa Online) STK request, invoke the `mpesaExpressQuery` function:
-
-```swift
-var mpesaExpressQuery = daraja.mpesaExpressQuery(
- businessShortCode: "174379",
- timestamp: "20160216165627",
- checkoutRequestID: "ws_CO_260520211133524545"
-)
-
-mpesaExpressQuery.onSuccess(action:{ data in
-// Successfully requested M-Pesa STK request status
-})
-.onFailure(action: {error in
-// Failed to request M-Pesa STK status
-})
-```
-
-
-
-
-
-
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index ff324186..48bfceab 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -16,19 +16,19 @@ Currently, Daraja Multiplatform supports Kotlin and Swift applications.
Core features include:
-* [x] Authorization - Gives you a time bound access token to call allowed APIs.
-- [x] M-Pesa Express - Merchant initiated online payments.
-- [x] M-Pesa Express Query - Check the status of a Lipa Na M-Pesa Online Payment(M-Pesa Express).
-- [ ] Dynamic QR - Generates a dynamic M-PESA QR code.
-- [ ] Customer To Business (C2B)
-- [ ] Business To Customer (B2C) - Transact between an M-Pesa short code to a phone number
+* Authorization - Gives you a time bound access token to call allowed APIs.
+- M-Pesa Express - Merchant initiated online payments.
+- M-Pesa Express Query - Check the status of a Lipa Na M-Pesa Online Payment(M-Pesa Express).
+- Dynamic QR - Generates a dynamic M-PESA QR code.
+- Customer To Business (C2B)
+- Business To Customer (B2C) - Transact between an M-Pesa short code to a phone number
registered on M-Pesa.
-- [ ] Transaction Status - Check the status of a transaction.
-- [ ] 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
+- Transaction Status - Check the status of a transaction.
+- 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
paybill store.
-- [ ] Business Buy Goods - Pay for goods and services directly from your business account to a till number or merchant store number.
+- Business Buy Goods - Pay for goods and services directly from your business account to a till number or merchant store number.
diff --git a/mkdocs.yml b/mkdocs.yml
index faf9731d..043b417b 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -11,7 +11,7 @@ remote_branch: gh-pages
nav:
- Overview: index.md
- Kotlin SDK: kotlin.md
- - Swift SDK: swift.md
+# - Swift SDK: swift.md
theme:
name: material
From 5e4214fecc095213d369dcce0a245492726f9b9d Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Tue, 17 Sep 2024 11:24:22 +0300
Subject: [PATCH 12/14] Update mkdocs theme
---
mkdocs.yml | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/mkdocs.yml b/mkdocs.yml
index 043b417b..d3aa1c01 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -16,6 +16,9 @@ nav:
theme:
name: material
language: en
+ font:
+ text: Roboto
+ code: Roboto Mono
features:
- navigation.tabs
- navigation.sections
@@ -29,18 +32,18 @@ theme:
- scheme: default
media: "(prefers-color-scheme: light)"
toggle:
- icon: material/brightness-7
+ icon: material/weather-night
name: Switch to dark theme
- primary: teal
- accent: purple
+ primary: green
+ accent: green
- scheme: slate
media: "(prefers-color-scheme: dark)"
toggle:
- icon: material/brightness-4
+ icon: material/weather-sunny
name: Switch to light theme
- primary: teal
- accent: lime
+ primary: green
+ accent: green
markdown_extensions:
- pymdownx.highlight:
From e4639c91552a0259fab3b0deb090a98b937a97dd Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Tue, 17 Sep 2024 11:30:05 +0300
Subject: [PATCH 13/14] Create documentation workflow
---
.github/workflows/documentation.yml | 37 +++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 .github/workflows/documentation.yml
diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
new file mode 100644
index 00000000..33d9bac0
--- /dev/null
+++ b/.github/workflows/documentation.yml
@@ -0,0 +1,37 @@
+name: Deploy Documentation
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+permissions:
+ contents: write
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: 3.x
+
+ - name: Set up cache
+ uses: actions/cache@v2
+ with:
+ key: ${{ github.ref }}
+ path: .cache
+
+ - name: Install MkDocs-Material
+ run: pip install mkdocs-material
+
+ - name: Install Pillow CairoSVG
+ run: pip install pillow cairosvg
+
+ - name: Deploy GH-Page
+ run: mkdocs gh-deploy --force
\ No newline at end of file
From ef266e34b5718d3953ce286689bcf48a879c1b40 Mon Sep 17 00:00:00 2001
From: Victor Kabata
Date: Tue, 17 Sep 2024 11:31:51 +0300
Subject: [PATCH 14/14] Linting
---
.github/workflows/documentation.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index 33d9bac0..635c36d4 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -7,7 +7,7 @@ on:
- main
permissions:
contents: write
-
+
jobs:
deploy:
runs-on: ubuntu-latest