From c776f9a16321cb3d5d23ce03329df4158456e921 Mon Sep 17 00:00:00 2001 From: Montcho Date: Thu, 13 Oct 2022 16:02:02 +0100 Subject: [PATCH 1/4] add serviceid and change baseUrl --- Sources/KKiaPaySDK/KKiaPay.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/KKiaPaySDK/KKiaPay.swift b/Sources/KKiaPaySDK/KKiaPay.swift index 1b22f85..be25aba 100644 --- a/Sources/KKiaPaySDK/KKiaPay.swift +++ b/Sources/KKiaPaySDK/KKiaPay.swift @@ -54,9 +54,9 @@ public struct KKiaPay: UIViewRepresentable { private func base64EncodedUrl() -> String { - let encodedData = Data("{\"amount\":\"\(amount ?? "")\",\"phone\": \"\(phone ?? "")\",\"data\": \"\(data ?? "")\",\"key\": \"\(publicAPIKey ?? "")\",\"sandbox\":\(sandbox ?? true),\"theme\": \"\(theme ?? "")\", \"name\": \"\(name ?? "")\", \"email\": \"\(email ?? "")\",\"callback\": \"\(callback ?? "")\",\"sdk\":\"ios\",\"reason\":\"\"}".utf8).base64EncodedString() + let encodedData = Data("{\"serviceId\":\"INTEGRATION\",\"amount\":\"\(amount ?? "")\",\"phone\": \"\(phone ?? "")\",\"data\": \"\(data ?? "")\",\"key\": \"\(publicAPIKey ?? "")\",\"sandbox\":\(sandbox ?? true),\"theme\": \"\(theme ?? "")\", \"name\": \"\(name ?? "")\", \"email\": \"\(email ?? "")\",\"callback\": \"\(callback ?? "")\",\"sdk\":\"ios\",\"reason\":\"\"}".utf8).base64EncodedString() - return "https://widget-v2.kkiapay.me/?="+encodedData + return "https://widget-v3.kkiapay.me/?"+encodedData } From 3715cdebbf0621792eb4414b859bbf51457245bc Mon Sep 17 00:00:00 2001 From: Montcho Date: Thu, 13 Oct 2022 20:28:10 +0100 Subject: [PATCH 2/4] Migration to the new version of the widget completed --- .idea/.gitignore | 3 ++ .idea/kkiapay-ios-sdk.iml | 9 ++++++ .idea/misc.xml | 6 ++++ .idea/modules.xml | 8 +++++ .idea/vcs.xml | 6 ++++ Sources/KKiaPaySDK/KKiaPay.swift | 53 ++++++++++++++++---------------- 6 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/kkiapay-ios-sdk.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/kkiapay-ios-sdk.iml b/.idea/kkiapay-ios-sdk.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/kkiapay-ios-sdk.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..799acfc --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Sources/KKiaPaySDK/KKiaPay.swift b/Sources/KKiaPaySDK/KKiaPay.swift index be25aba..552b218 100644 --- a/Sources/KKiaPaySDK/KKiaPay.swift +++ b/Sources/KKiaPaySDK/KKiaPay.swift @@ -18,7 +18,7 @@ public struct KKiaPay: UIViewRepresentable { Coordinator(self) } - let amount:String? + let amount:Int? let phone:String? let data:String? let publicAPIKey:String? @@ -27,10 +27,10 @@ public struct KKiaPay: UIViewRepresentable { let name:String? let email:String? let callback:String? - + @ObservedObject public var viewModel : KKiaPayViewModel - - public init(amount:String, + + public init(amount:Int, phone:String, publicAPIKey:String, data:String, @@ -51,70 +51,69 @@ public struct KKiaPay: UIViewRepresentable { self.callback=callback self.viewModel=viewModel } - + private func base64EncodedUrl() -> String { - - let encodedData = Data("{\"serviceId\":\"INTEGRATION\",\"amount\":\"\(amount ?? "")\",\"phone\": \"\(phone ?? "")\",\"data\": \"\(data ?? "")\",\"key\": \"\(publicAPIKey ?? "")\",\"sandbox\":\(sandbox ?? true),\"theme\": \"\(theme ?? "")\", \"name\": \"\(name ?? "")\", \"email\": \"\(email ?? "")\",\"callback\": \"\(callback ?? "")\",\"sdk\":\"ios\",\"reason\":\"\"}".utf8).base64EncodedString() - + + let encodedData = Data("{\"paymentMethods\":[\"momo\",\"card\",\"direct_debit\"],\"position\":\"left\",\"serviceId\":\"INTEGRATION\",\"amount\":\(amount ?? 1),\"phoneNumber\": \"\(phone ?? "")\",\"data\": \"\(data ?? "")\",\"key\": \"\(publicAPIKey ?? "")\",\"sandbox\":\(sandbox ?? true),\"theme\":\"\(theme ?? "")\",\"fullname\":\"\(name ?? "")\",\"email\": \"\(email ?? "")\",\"callback\": \"\(callback ?? "")\",\"sdk\":\"ios\",\"reason\":\"\"}".utf8).base64EncodedString() return "https://widget-v3.kkiapay.me/?"+encodedData - + } - + public func makeUIView(context: Context) -> WKWebView { - + let preferences = WKPreferences() preferences.javaScriptEnabled = true - + let configuration = WKWebViewConfiguration() configuration.preferences = preferences - + let webView = WKWebView(frame: CGRect.zero, configuration: configuration) webView.navigationDelegate = context.coordinator webView.allowsBackForwardNavigationGestures = true webView.scrollView.isScrollEnabled = true - + return webView } - + public func updateUIView(_ webView: WKWebView, context: Context) { let url = URL(string: base64EncodedUrl()) let request = URLRequest(url: url!) webView.load(request) } - + public class Coordinator : NSObject, WKNavigationDelegate { var parent: KKiaPay var valueSubscriber: AnyCancellable? = nil var webViewNavigationSubscriber: AnyCancellable? = nil - + init(_ uiWebView: KKiaPay) { self.parent = uiWebView } - + deinit { valueSubscriber?.cancel() webViewNavigationSubscriber?.cancel() } - + public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { } - + // This function is essential for intercepting every navigation in the webview public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { - + let urlString = navigationAction.request.url?.absoluteString - + if(urlString!.contains("transaction_id")){//Payment successful print("KKIAPAYSDK: PAYMENT WAS SUCCESSFUL") - + let transactionId = getQueryStringParameter(url: urlString!, param: "transaction_id") - - self.parent.viewModel.paymentData.send(KKiaPayData(amount: self.parent.amount ?? "", + + self.parent.viewModel.paymentData.send(KKiaPayData(amount: "\(self.parent.amount ?? 1)", transactionId: transactionId ?? "",isSuccessful:true)) }else{ - - self.parent.viewModel.paymentData.send(KKiaPayData(amount: self.parent.amount ?? "",transactionId: "",isSuccessful:false)) + + self.parent.viewModel.paymentData.send(KKiaPayData(amount: "\(self.parent.amount ?? 1)",transactionId: "",isSuccessful:false)) } // This allows the navigation From 645a13e474044c66c1d804bb08b551e44eaae05f Mon Sep 17 00:00:00 2001 From: Shegun MONTCHO Date: Thu, 13 Oct 2022 20:44:29 +0100 Subject: [PATCH 3/4] Update README.md --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c15815b..0d7d651 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,11 @@ struct ContentView: View { //Create a view model instance to use later @ObservedObject var viewModel = KKiaPayViewModel() @State private var showWebView = false + @State var text = "Pay Now" //Initialise the Kkiapay Instance private var kkiaPay: KKiaPay{ - KKiaPay(amount: "3000", + KKiaPay(amount: 3000, phone: "97000000", data: "Hello world", publicAPIKey: "xxxxxxxxxxxxxxxxxxx", @@ -86,20 +87,23 @@ struct ContentView: View { Button { showWebView.toggle() } label: { - Text("Pay") + Text(self.text) } .sheet(isPresented: $showWebView) { - //Get the transaction data back kkiaPay.onReceive(self.viewModel.paymentData.receive(on: RunLoop.main)){paymentData in if(paymentData.isSuccessful){ - print("The amount of the transaction is " + paymentData.amount+" with id "+paymentData.transactionId) + + self.text = "PAYMENT WAS SUCCESSFUL \n\nThe amount of the transaction is \(paymentData.amount) Fcfa with id \(paymentData.transactionId)" + + print("The amount of the transaction is \(paymentData.amount) with id \(paymentData.transactionId)") showWebView = false - }else{ + }else { print("The payment was not successful") } } + } } } @@ -129,4 +133,4 @@ struct ContentView_Previews: PreviewProvider { ### Issues and feedback Please file [issues](https://github.com/kkiapay/kkiapay-ios-sdk/issues/new) -to send feedback or report a bug. Thank you! \ No newline at end of file +to send feedback or report a bug. Thank you! From 3c90c01b438d828434f907e36f4b3bfb274c246a Mon Sep 17 00:00:00 2001 From: Montcho Date: Fri, 14 Oct 2022 14:58:17 +0100 Subject: [PATCH 4/4] Update request key ( partnerId, paymentMethods, countries ) --- README.md | 29 +++++++++++++++++++---------- Sources/KKiaPaySDK/KKiaPay.swift | 11 ++++++++++- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 0d7d651..1065314 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,13 @@ import KKiaPaySDK; ```swift private var kkiaPay: KKiaPay{ - KKiaPay(amount: "3000", - phone: "97000000", - data: "Hello world", + KKiaPay(amount: 3000, + phone: "22997000000", publicAPIKey: "xxxxxxxxxxxxxxxxxxx", + partnerId: "AxXxXXxId", + countries: ["BJ"], + paymentMethods: ["momo","card"], + data: "Hello world", sandbox: true,//set this to false in production theme: "#4E6BFC", name: "John Doe", @@ -40,7 +43,7 @@ private var kkiaPay: KKiaPay{ } ``` -##### Get the transaction data back +##### Get the transaction data back Once the payment is successful, the KKiaPayViewModel sends a KKiaPayTransactionData to the calling view via the onReceive callback. ```swift kkiaPay.onReceive(self.viewModel.paymentData.receive(on: RunLoop.main)){paymentData in @@ -54,7 +57,7 @@ kkiaPay.onReceive(self.viewModel.paymentData.receive(on: RunLoop.main)){paymentD } ``` -The onReceive function of the kkiaPay instance listens to the state of the paymentData and exposes it. +The onReceive function of the kkiaPay instance listens to the state of the paymentData and exposes it. ## Example @@ -71,9 +74,12 @@ struct ContentView: View { //Initialise the Kkiapay Instance private var kkiaPay: KKiaPay{ KKiaPay(amount: 3000, - phone: "97000000", - data: "Hello world", + phone: "22997000000", publicAPIKey: "xxxxxxxxxxxxxxxxxxx", + partnerId: "AxXxXXxId", + countries: ["BJ"], + paymentMethods: ["momo","card"], + data: "Hello world", sandbox: true,//set this to false in production theme: "#4E6BFC", name: "John Doe", @@ -91,6 +97,7 @@ struct ContentView: View { } .sheet(isPresented: $showWebView) { + //Get the transaction data back kkiaPay.onReceive(self.viewModel.paymentData.receive(on: RunLoop.main)){paymentData in if(paymentData.isSuccessful){ @@ -120,14 +127,16 @@ struct ContentView_Previews: PreviewProvider { - + - + + + - +
ArgumentTypeRequiredDetails
phoneStringYesValid mobile money number to debit. ex : 22997000000
phoneStringYesValid mobile money number to debit. ex : 22967434270
amountNumericYesAmount to debit from user account (XOF)
nameStringNoClient firstname and lastname
emailStringNoClient email address
partnerIdStringNoYour id to find transaction
countriesList of StringNoSet widget countries ex: ["CI"]
paymentMethodsList of StringNoSet widget payment methods ex: ["momo","card"]
themeStringNo the hexadecimal code of the color you want to give to your widget
apikeyStringYespublic api key
sandboxBooleanNoThe true value of this attribute allows you to switch to test mode
successCallbackFunctionNoThis function is called once the payment has been successfully made
successCallbackFunctionYesThis function is called once the payment has been successfully made
### Issues and feedback diff --git a/Sources/KKiaPaySDK/KKiaPay.swift b/Sources/KKiaPaySDK/KKiaPay.swift index 552b218..3bcbbce 100644 --- a/Sources/KKiaPaySDK/KKiaPay.swift +++ b/Sources/KKiaPaySDK/KKiaPay.swift @@ -26,6 +26,9 @@ public struct KKiaPay: UIViewRepresentable { let theme:String? let name:String? let email:String? + let partnerId:String? + let countries:[String]? + let paymentMethods:[String]? let callback:String? @ObservedObject public var viewModel : KKiaPayViewModel @@ -33,6 +36,9 @@ public struct KKiaPay: UIViewRepresentable { public init(amount:Int, phone:String, publicAPIKey:String, + partnerId:String?, + countries:[String]?, + paymentMethods:[String]?, data:String, sandbox:Bool, theme:String, @@ -43,6 +49,9 @@ public struct KKiaPay: UIViewRepresentable { self.amount=amount self.phone=phone self.publicAPIKey=publicAPIKey + self.countries=countries + self.partnerId=partnerId + self.paymentMethods=paymentMethods self.data=data self.sandbox=sandbox self.theme=theme @@ -54,7 +63,7 @@ public struct KKiaPay: UIViewRepresentable { private func base64EncodedUrl() -> String { - let encodedData = Data("{\"paymentMethods\":[\"momo\",\"card\",\"direct_debit\"],\"position\":\"left\",\"serviceId\":\"INTEGRATION\",\"amount\":\(amount ?? 1),\"phoneNumber\": \"\(phone ?? "")\",\"data\": \"\(data ?? "")\",\"key\": \"\(publicAPIKey ?? "")\",\"sandbox\":\(sandbox ?? true),\"theme\":\"\(theme ?? "")\",\"fullname\":\"\(name ?? "")\",\"email\": \"\(email ?? "")\",\"callback\": \"\(callback ?? "")\",\"sdk\":\"ios\",\"reason\":\"\"}".utf8).base64EncodedString() + let encodedData = Data("{\"paymentMethods\":\(paymentMethods ?? ["momo","card"]),\"countries\":\(countries ?? ["BJ","CI"]),\"position\":\"left\",\"partnerId\":\"\(partnerId ?? "")\",\"serviceId\":\"INTEGRATION\",\"amount\":\(amount ?? 1),\"phoneNumber\": \"\(phone ?? "")\",\"data\": \"\(data ?? "")\",\"key\": \"\(publicAPIKey ?? "")\",\"sandbox\":\(sandbox ?? true),\"theme\":\"\(theme ?? "")\",\"fullname\":\"\(name ?? "")\",\"email\": \"\(email ?? "")\",\"callback\": \"\(callback ?? "")\",\"sdk\":\"ios\",\"reason\":\"\"}".utf8).base64EncodedString() return "https://widget-v3.kkiapay.me/?"+encodedData }