From 87c042f0f14bea486bbcd9eac074068dd39074f5 Mon Sep 17 00:00:00 2001 From: Cuong Huynh Date: Fri, 5 Apr 2024 14:22:53 +0400 Subject: [PATCH] 1.0.12 --- Example/Example/InfoView.swift | 30 +---- Example/Example/MainView.swift | 119 +++++++++++++++++- .../TamaraSDKCheckoutRepresentation.swift | 1 - TamaraSDK/TamaraSDK.podspec | 2 +- TamaraSDK/TamaraSDK/JSONCodingKeys.swift | 28 +++-- TamaraSDK/TamaraSDK/TamaraSDKCheckout.swift | 8 +- TamaraSDK/TamaraSDK/TamaraSDKPayment.swift | 53 +++++++- TamaraSDK/TamaraSDK/api/NetworkManager.swift | 5 + TamaraSDK/TamaraSDK/api/TamaraApi.swift | 8 +- .../TamaraSDK/controller/PaymentVC.swift | 11 ++ TamaraSDK/TamaraSDK/model/Order.swift | 6 +- .../model/request/PaymentOptions.swift | 31 +++++ .../model/response/AvailablePayment.swift | 24 ++++ .../response/PaymentOptionsResponse.swift | 19 +++ TamaraSDK/TamaraSDK/scenes/ViewModel.swift | 11 ++ 15 files changed, 303 insertions(+), 53 deletions(-) create mode 100644 TamaraSDK/TamaraSDK/model/request/PaymentOptions.swift create mode 100644 TamaraSDK/TamaraSDK/model/response/AvailablePayment.swift create mode 100644 TamaraSDK/TamaraSDK/model/response/PaymentOptionsResponse.swift diff --git a/Example/Example/InfoView.swift b/Example/Example/InfoView.swift index 8073aa1..3dcd62b 100644 --- a/Example/Example/InfoView.swift +++ b/Example/Example/InfoView.swift @@ -37,32 +37,10 @@ struct InfoView : View { tamara.createOrder(orderReferenceId: "A352BB0A59044C77928A7551A1EA566B", description: "String") tamara.setInstalments(instalments: 1) tamara.setLocale(locale: "en-US") - let json = "{\n" + - " \"customer_age\": 22,\n" + - " \"customer_dob\": \"31-01-2000\",\n" + - " \"customer_gender\": \"Male\", \n" + - " \"customer_nationality\": \"SA\", \n" + - " \"is_premium_customer\": true, \n" + - " \"is_existing_customer\": true, \n" + - " \"is_guest_user\": true, \n" + - " \"account_creation_date\": \"31-01-2019\", \n" + - " \"platform_account_creation_date\": \"string\", \n" + - " \"date_of_first_transaction\": \"31-01-2019\", \n" + - " \"is_card_on_file\": true, \n" + - " \"is_COD_customer\": true, \n" + - " \"has_delivered_order\": true, \n" + - " \"is_phone_verified\": true, \n" + - " \"is_fraudulent_customer\": true, \n" + - " \"total_ltv\": 501.5, \n" + - " \"total_order_count\": 12, \n" + - " \"order_amount_last3months\": 301.5, \n" + - " \"order_count_last3months\": 2, \n" + - " \"last_order_date\": \"31-01-2021\", \n" + - " \"last_order_amount\": 301.5, \n" + - " \"reward_program_enrolled\": true, \n" + - " \"reward_program_points\": 300 \n" + - "}" - tamara.setRiskAssessment(jsonData: self.$appState.riskAssessment.wrappedValue) + let riskValidate = tamara.setRiskAssessment(jsonData: self.$appState.riskAssessment.wrappedValue) + if (!riskValidate) { + //check again json + } tamara.setPaymentType(paymentType: "PAY_BY_INSTALMENTS") tamara.setCustomerInfo(firstName: "Mona", lastName: "Lisa", phoneNumber: "502223333", email: "user@gmail.com") diff --git a/Example/Example/MainView.swift b/Example/Example/MainView.swift index a688d0a..e35b0b1 100644 --- a/Example/Example/MainView.swift +++ b/Example/Example/MainView.swift @@ -13,6 +13,25 @@ struct MainView: View { @EnvironmentObject var appState: AppState var scriptCartPage: String = "" var scriptProduct: String = "" + @State private var isAuthenticating = false + @State private var isIniting = false + @State private var isInitSuccess = false + @State private var isShow = false + @State private var isError = false + @State private var isErrorMessage = false + @State private var country = "SA" + @State private var amount = "100" + @State private var currency = "SAR" + @State private var phone = "" + @State private var isVip = "false" + @State private var dataResult = "" + @State private var dataError = "" + @State private var token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhY2NvdW50SWQiOiJmY2ZiYzk3ZC0wYmIwLTRkYTItYmY3ZS02MjhlOTRkMzM0M2EiLCJ0eXBlIjoibWVyY2hhbnQiLCJzYWx0IjoiNzQxMmZkZjI1NGZiMWJhNmY5N2FmMmY1N2YxYzA1MDYiLCJpYXQiOjE2Nzc4MzIzNzQsImlzcyI6IlRhbWFyYSJ9.WVn2sf3LrW_YI3c2pNrbcOa--tRDAVm9p2GOBRdn7d671QIuqPvDgI9Gz7MNzBirUDnVLATCrL9uvMxDY_1OzXe3Sn1Gawckw-NE2EfL_Kjnl8GcNqwMcMvcin9XGxGRhbDDusgFCFzxaiEYae3DpA-pO0TpyQbEXl49ZLT4a9sEW75Taxc2ofZ-DJ_ciblImk1aJ6p9YhQowvzAVHz6yG-ZRfosxc96t8BK15bVTvTLnT9hzEnCqifqKO7vSu1e2mKEG8lC46pZHSr-ZpvfjSytrMX2QAZuXqxtlvbg3aRZeGiJ-SKVcbRdlId1wSRTZ5lntrw3pyrLS1dpxcfSOA" + @State private var apiUrl = "https://api-sandbox.tamara.co" + @State private var publishKey = "d36c6279-90c2-4239-b4e2-2c91bfda0fe4" + @State private var pushUrl = "https://tamara.co/pushnotification" + @State private var notificationToken = "aeae44a2-5f57-475e-a384-0e9b8a802326" + @State private var isSandbox = "true" init(cartPage: Binding<[String: String]>, productPage: Binding<[String: String]>) { self.scriptCartPage = cartPage.wrappedValue["script"] ?? "" @@ -24,10 +43,25 @@ struct MainView: View { VStack { Text("Tamara Checkout Example App") - RoundedButton(label: "Init", buttonAction: { - self.appState.currentPage = .Cart - }) - .padding(.top, 20) + if #available(iOS 15.0, *) { + RoundedButton(label: "Init", buttonAction: { + isIniting.toggle() + }) + .padding(.top, 20).alert("Init", isPresented: $isIniting) { + TextField("token", text:$token) + TextField("apiUrl", text: $apiUrl) + TextField("publishKey", text: $publishKey) + TextField("pushUrl", text: $pushUrl) + TextField("notificationToken", text: $notificationToken) + TextField("isSandbox", text: $isSandbox) + Button("OK", action: initValue) + } message: { + }.alert("Init success", isPresented: $isInitSuccess) { + Button("OK", role: .cancel) { } + } + } else { + // Fallback on earlier versions + } RoundedButton(label: "Test create order", buttonAction: { self.appState.currentPage = .Cart @@ -44,13 +78,42 @@ struct MainView: View { DispatchQueue.main.async { self.appState.isLoading = false - let url = "https://checkout-sandbox.tamara.co/checkout/22464256-5aa0-4497-9121-165a10ea63be?locale=en_US&orderId=c66700d8-e723-48db-9f69-f0e73ff9b4e6&show_item_images=with_item_images_shown&pay_the_difference_disclaimer=blue2&pay_in_full_value=value_secure" // self.appState.viewModel = TamaraSDKCheckoutSwiftUIViewModel(url: url, merchantURL: merchantUrl) self.appState.currentPage = AppPages.Test } // self.appState.currentPage = .Cart }) .padding(.top, 20) + if #available(iOS 15.0, *) { + RoundedButton(label: "Check payment options") { + isAuthenticating.toggle() + }.padding(.top, 20) + .alert("Check payment options", isPresented: $isAuthenticating) { + TextField("country(required)", text: $country) + .textInputAutocapitalization(.never) + TextField("amount (required)", text: $amount) + TextField("currency (required)", text: $currency) + TextField("PhoneNumber", text: $phone) + TextField("isVip", text: $isVip) + Button("OK", action: authenticate) + Button("Cancel", role: .cancel) { } + } message: { + }.popover(isPresented: self.$isError, + attachmentAnchor: .rect(.rect(CGRect(x: 0, y: 20, + width: 160, height: 100))), + arrowEdge: .top, + content: { + Text("Input required") + .padding() + }).alert(dataResult, isPresented: $isShow) { + Button("OK", role: .cancel) { } + } + .alert(dataError, isPresented: $isErrorMessage) { + Button("OK", role: .cancel) { } + } + } else { + // Fallback on earlier versions + } RoundedButton(label: "CartPage", buttonAction: { self.appState.currentPage = .CartPage @@ -77,6 +140,52 @@ struct MainView: View { .navigationBarHidden(true) .navigationBarItems(trailing: HStack{}) } + func initValue() { + let tamara = TamaraSDKPayment() + tamara.initialize(token: token, apiUrl: apiUrl, pushUrl: pushUrl, publishKey: publishKey, notificationToken: notificationToken, isSandbox: Bool(isSandbox) ?? true) + isInitSuccess = true + } + func authenticate() { + isError = false + if !country.isEmpty && !amount.isEmpty && !currency.isEmpty { + let tamara = TamaraSDKPayment() + self.appState.isLoading = true + let json = "{\n" + + "\"country\": \"\(country)\",\n" + + "\"order_value\": {\n" + + "\"amount\": \(Double(amount)!),\n" + + "\"currency\": \"\(currency)\"\n" + + "},\n" + + "\"phone_number\": \"\(phone)\",\n" + + "\"is_vip\": \(Bool(isVip)!)\n" + + "}" + tamara.checkPaymentOptions(jsonData: json) { result in + do { + self.appState.isLoading = false + switch result { + case .success(let response): + let jsonEncoder = JSONEncoder() + let decoder = JSONDecoder() + let result1 = try decoder.decode(PaymentOptionsResponse.self, from: jsonEncoder.encode(response)) + + dataResult = String(decoding: try jsonEncoder.encode(response), as: UTF8.self) + print(result1) + isShow = true + break + case.failure(let error): + isErrorMessage = true + dataError = error.localizedDescription + print(error) + break + } + } catch { + print(error) + } + } + } else { + isError = true + } + } func calculateTotal() { diff --git a/Example/Example/TamaraSDKCheckoutRepresentation.swift b/Example/Example/TamaraSDKCheckoutRepresentation.swift index b7b0402..e46f0a8 100644 --- a/Example/Example/TamaraSDKCheckoutRepresentation.swift +++ b/Example/Example/TamaraSDKCheckoutRepresentation.swift @@ -11,7 +11,6 @@ import UIKit import SwiftUI import TamaraSDK -@available(iOS 13.0, *) public struct MyViewControllerRepresentation: UIViewControllerRepresentable, TamaraCheckoutDelegate{ public func onSuccessfull() { print("onSuccessfull") diff --git a/TamaraSDK/TamaraSDK.podspec b/TamaraSDK/TamaraSDK.podspec index 9730878..5558343 100644 --- a/TamaraSDK/TamaraSDK.podspec +++ b/TamaraSDK/TamaraSDK.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = "TamaraSDK" - s.version = "1.0.11" + s.version = "1.0.12" s.summary = "SDK for tamara.co" s.description = "iOS sdk for tamara.co" s.homepage = "https://tamara.co" diff --git a/TamaraSDK/TamaraSDK/JSONCodingKeys.swift b/TamaraSDK/TamaraSDK/JSONCodingKeys.swift index 496a983..80aaf7a 100644 --- a/TamaraSDK/TamaraSDK/JSONCodingKeys.swift +++ b/TamaraSDK/TamaraSDK/JSONCodingKeys.swift @@ -30,10 +30,10 @@ extension KeyedDecodingContainer { var dictionary = [String: Any]() for key in allKeys { - if let boolValue = try? decode(Bool.self, forKey: key) { - dictionary[key.stringValue] = boolValue - } else if let intValue = try? decode(Int.self, forKey: key) { + if let intValue = try? decode(Int.self, forKey: key) { dictionary[key.stringValue] = intValue + } else if let boolValue = try? decode(Bool.self, forKey: key) { + dictionary[key.stringValue] = boolValue } else if let stringValue = try? decode(String.self, forKey: key) { dictionary[key.stringValue] = stringValue } else if let doubleValue = try? decode(Double.self, forKey: key) { @@ -57,9 +57,9 @@ extension UnkeyedDecodingContainer { var array: [Any] = [] while isAtEnd == false { - if let value = try? decode(Bool.self) { + if let value = try? decode(Int.self) { array.append(value) - } else if let value = try? decode(Int.self) { + } else if let value = try? decode(Bool.self) { array.append(value) } else if let value = try? decode(String.self) { array.append(value) @@ -95,8 +95,13 @@ extension KeyedEncodingContainerProtocol where Key == JSONCodingKeys { for (key, value) in value { let key = JSONCodingKeys(stringValue: key) switch value { - case let value as Bool: - try encode(value, forKey: key) + case is Bool: + let typeValue = type(of: value) + if typeValue == Bool.self || "\(typeValue)" == "__NSCFBoolean" { + try encode(value as! Bool, forKey: key) + } else { + try encode(value as! Int, forKey: key) + } case let value as Int: try encode(value, forKey: key) case let value as String: @@ -136,8 +141,13 @@ extension UnkeyedEncodingContainer { mutating func encode(_ value: [Any]) throws { for (index, value) in value.enumerated() { switch value { - case let value as Bool: - try encode(value) + case is Bool: + let typeValue = type(of: value) + if typeValue == Bool.self || "\(typeValue)" == "__NSCFBoolean" { + try encode(value as! Bool) + } else { + try encode(value as! Int) + } case let value as Int: try encode(value) case let value as String: diff --git a/TamaraSDK/TamaraSDK/TamaraSDKCheckout.swift b/TamaraSDK/TamaraSDK/TamaraSDKCheckout.swift index c360f4a..50d43df 100644 --- a/TamaraSDK/TamaraSDK/TamaraSDKCheckout.swift +++ b/TamaraSDK/TamaraSDK/TamaraSDKCheckout.swift @@ -23,7 +23,6 @@ public protocol TamaraCheckoutDelegate { func onCancel() } -@available(iOS 13.0.0, *) public class TamaraSDKCheckout: UIViewController { private var webView: WKWebView! private var url: String! @@ -83,7 +82,6 @@ public class TamaraSDKCheckout: UIViewController { } } -@available(iOS 13.0.0, *) extension TamaraSDKCheckout: WKNavigationDelegate { // Called when an error occurs during navigation public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { @@ -94,8 +92,8 @@ extension TamaraSDKCheckout: WKNavigationDelegate { self.present(alertVC, animated: true) } - - public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, preferences: WKWebpagePreferences, decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences) -> Void) { + + public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url else { return } @@ -112,7 +110,7 @@ extension TamaraSDKCheckout: WKNavigationDelegate { self.delegate?.onCancel() } - decisionHandler(.allow, preferences) + decisionHandler(.allow) } } diff --git a/TamaraSDK/TamaraSDK/TamaraSDKPayment.swift b/TamaraSDK/TamaraSDK/TamaraSDKPayment.swift index ce66c36..aaaa7d9 100644 --- a/TamaraSDK/TamaraSDK/TamaraSDKPayment.swift +++ b/TamaraSDK/TamaraSDK/TamaraSDKPayment.swift @@ -16,7 +16,7 @@ public class TamaraSDKPayment { private let STATE_BEGIN = 2 private let STATE_END = 3 var token: String = "" - var apiUrl: String = "http://api.tamara.co" + var apiUrl: String = "https://api.tamara.co" private var pushUrl: String = "" private var publishKey: String = "" private var notificationToken: String = "" @@ -120,6 +120,30 @@ public class TamaraSDKPayment { return true } + func validatePaymentOptions(paymentOptions: PaymentOptions?) throws-> Bool + { + var error = "" + if (paymentOptions != nil) { + if(paymentOptions?.country == nil){ + error += "country is required" + } + + if(paymentOptions?.orderValue == nil || paymentOptions?.orderValue?.amount == nil) { + if (!error.isEmpty) { + error += "\n" + } + error += "OrderValue is required" + } + } else { + error += "Data is required" + } + + if (!error.isEmpty) { + throw NSError(domain: "tamara", code: 1, userInfo: [NSLocalizedDescriptionKey: error]) + } + return true + } + func validateDataCapture(capturePayment : CapturePaymentRequest?) throws-> Bool { var error = "" @@ -241,11 +265,12 @@ public extension TamaraSDKPayment { * Set riskAssessment * @param jsonData */ - func setRiskAssessment(jsonData: String) { + func setRiskAssessment(jsonData: String)-> Bool { do { try validateStateForAddingData() - self.order?.updateRiskAssessment(from: jsonData) + return self.order?.updateRiskAssessment(from: jsonData) ?? false } catch { + return false } } @@ -577,4 +602,26 @@ public extension TamaraSDKPayment { } } } + + func checkPaymentOptions(jsonData: String, completion: @escaping (Result) -> ()) { + do { + let data = PaymentOptions(jsonData: Data(jsonData.utf8)) + let validateResult = try self.validatePaymentOptions(paymentOptions: data) + if (validateResult) { + PaymentVC.shared.checkPaymentOptions(paymentOptions: data) { result in + DispatchQueue.main.async { + switch result { + case .success(let response): + completion(.success(response)) + case .failure(let error): + completion(.failure(AppError.errorMessage(message: error.localizedDescription))) + } + } + + } + } + } catch { + completion(.failure(AppError.errorMessage(message: error.localizedDescription))) + } + } } diff --git a/TamaraSDK/TamaraSDK/api/NetworkManager.swift b/TamaraSDK/TamaraSDK/api/NetworkManager.swift index 1ac3147..d7b7789 100644 --- a/TamaraSDK/TamaraSDK/api/NetworkManager.swift +++ b/TamaraSDK/TamaraSDK/api/NetworkManager.swift @@ -11,6 +11,7 @@ import Moya protocol Networkable { var provider: MoyaProvider { get } func createOrder(order: Order?, completion: @escaping (Result) -> ()) + func checkPaymentOptions(paymentOptions: PaymentOptions?, completion: @escaping (Result) -> ()) func fetchOrderDetail(orderId: String, completion: @escaping (Result) -> ()) func authoriseOrder(orderId: String, completion: @escaping (Result) -> ()) func refunds(orderId: String, paymentRefund: PaymentRefund, completion: @escaping (Result) -> ()) @@ -26,6 +27,10 @@ class NetworkManager: Networkable { request(target: .createOrder(order: order), completion: completion) } + func checkPaymentOptions(paymentOptions: PaymentOptions?, completion: @escaping (Result) -> ()) { + request(target: .checkPaymentOptions(paymentOptions: paymentOptions), completion: completion) + } + func fetchOrderDetail(orderId: String, completion: @escaping (Result) -> ()) { request(target: .orderDetail(orderId: orderId), completion: completion) } diff --git a/TamaraSDK/TamaraSDK/api/TamaraApi.swift b/TamaraSDK/TamaraSDK/api/TamaraApi.swift index fdcbaf0..66e802b 100644 --- a/TamaraSDK/TamaraSDK/api/TamaraApi.swift +++ b/TamaraSDK/TamaraSDK/api/TamaraApi.swift @@ -11,6 +11,7 @@ import Moya enum TamaraApi { case orderDetail(orderId:String) case createOrder(order: Order?) + case checkPaymentOptions(paymentOptions: PaymentOptions?) case authoriseOrder(orderId:String) case refunds(orderId: String, paymentRefund: PaymentRefund) case capturePayment(capturePayment: CapturePaymentRequest) @@ -30,6 +31,8 @@ extension TamaraApi: TargetType { return "/orders/\(orderId)" case .createOrder: return "/checkout" + case .checkPaymentOptions: + return "/checkout/payment-options-pre-check" case .authoriseOrder(let orderId): return "/orders/\(orderId)/authorise" case .refunds(let orderId, _): @@ -45,7 +48,8 @@ extension TamaraApi: TargetType { var method: Moya.Method { switch self { - case .createOrder, .authoriseOrder, .refunds, .capturePayment, .cancelOrder: return .post + case .createOrder, .authoriseOrder, .refunds, .capturePayment, .cancelOrder, + .checkPaymentOptions : return .post case .orderDetail: return .get case .updateOrderReference: return .put } @@ -69,6 +73,8 @@ extension TamaraApi: TargetType { return .requestJSONEncodable(cancelOrder) case .updateOrderReference(_, let orderReference): return .requestJSONEncodable(orderReference) + case .checkPaymentOptions(let paymentOptions): + return .requestJSONEncodable(paymentOptions) } } diff --git a/TamaraSDK/TamaraSDK/controller/PaymentVC.swift b/TamaraSDK/TamaraSDK/controller/PaymentVC.swift index 2905cc3..c4b8b0a 100644 --- a/TamaraSDK/TamaraSDK/controller/PaymentVC.swift +++ b/TamaraSDK/TamaraSDK/controller/PaymentVC.swift @@ -21,6 +21,17 @@ extension PaymentVC { }) } + func checkPaymentOptions(paymentOptions: PaymentOptions?, completion: @escaping (Result) -> ()) { + viewModel.checkPaymentOptions(paymentOptions: paymentOptions) { result in + switch result { + case .success(let response): + completion(.success(response)) + case .failure(let error): + completion(.failure(AppError.errorMessage(message: error.localizedDescription))) + } + } + } + func authoriseOrder(orderId: String, completion: @escaping (Result) -> ()) { viewModel.authoriseOrder(orderId: orderId) { result in switch result { diff --git a/TamaraSDK/TamaraSDK/model/Order.swift b/TamaraSDK/TamaraSDK/model/Order.swift index e6f0d52..ea3ca2c 100644 --- a/TamaraSDK/TamaraSDK/model/Order.swift +++ b/TamaraSDK/TamaraSDK/model/Order.swift @@ -180,9 +180,9 @@ struct Order: Codable { } } - mutating func updateRiskAssessment(from jsonString: String) { + mutating func updateRiskAssessment(from jsonString: String) -> Bool { guard let jsonData = jsonString.data(using: .utf8) else { - return + return false } do { @@ -191,8 +191,10 @@ struct Order: Codable { riskAssessment[fieldName] = jsonElement } } + return true } catch { print("Error parsing JSON: \(error)") + return false } } } diff --git a/TamaraSDK/TamaraSDK/model/request/PaymentOptions.swift b/TamaraSDK/TamaraSDK/model/request/PaymentOptions.swift new file mode 100644 index 0000000..2864110 --- /dev/null +++ b/TamaraSDK/TamaraSDK/model/request/PaymentOptions.swift @@ -0,0 +1,31 @@ +// +// PaymentOptions.swift +// TamaraSDK +// +// Created by phong on 1/4/24. +// + +import Foundation +struct PaymentOptions: Codable { + var country: String? = nil + var orderValue: Amount? = nil + var phoneNumber: String? = nil + var isVip: Bool? = nil + + enum CodingKeys: String, CodingKey { + case country = "country" + case orderValue = "order_value" + case phoneNumber = "phone_number" + case isVip = "is_vip" + } + + init(jsonData: Data) { + let decoder = JSONDecoder() + self = try! decoder.decode(PaymentOptions.self, from: jsonData) + } + + func convertToJson() -> String { + let jsonData = try! JSONEncoder().encode(self) + return String(data: jsonData, encoding: .utf8)! + } +} diff --git a/TamaraSDK/TamaraSDK/model/response/AvailablePayment.swift b/TamaraSDK/TamaraSDK/model/response/AvailablePayment.swift new file mode 100644 index 0000000..2123901 --- /dev/null +++ b/TamaraSDK/TamaraSDK/model/response/AvailablePayment.swift @@ -0,0 +1,24 @@ +// +// AvailablePayment.swift +// TamaraSDK +// +// Created by phong on 1/4/24. +// + +import Foundation +public struct AvailablePayment: Codable { + var payment_type: String? = nil + var description: String? = nil + var description_ar: String? = nil + var instalment: Int? = 0 + + public init(jsonData: Data) { + let decoder = JSONDecoder() + self = try! decoder.decode(AvailablePayment.self, from: jsonData) + } + + func convertToJson() -> String { + let jsonData = try! JSONEncoder().encode(self) + return String(data: jsonData, encoding: .utf8)! + } +} diff --git a/TamaraSDK/TamaraSDK/model/response/PaymentOptionsResponse.swift b/TamaraSDK/TamaraSDK/model/response/PaymentOptionsResponse.swift new file mode 100644 index 0000000..1196318 --- /dev/null +++ b/TamaraSDK/TamaraSDK/model/response/PaymentOptionsResponse.swift @@ -0,0 +1,19 @@ +// +// PaymentOptionsResponse.swift +// TamaraSDK +// +// Created by phong on 1/4/24. +// + +import Foundation +public struct PaymentOptionsResponse: Codable { + var hasAvailablePaymentOptions: Bool? = false + var singleCheckoutEnabled: Bool? = false + var availablePaymentLabels: Array? = Array() + + enum CodingKeys: String, CodingKey { + case hasAvailablePaymentOptions = "has_available_payment_options" + case singleCheckoutEnabled = "single_checkout_enabled" + case availablePaymentLabels = "available_payment_labels" + } +} diff --git a/TamaraSDK/TamaraSDK/scenes/ViewModel.swift b/TamaraSDK/TamaraSDK/scenes/ViewModel.swift index a39a569..3d5099e 100644 --- a/TamaraSDK/TamaraSDK/scenes/ViewModel.swift +++ b/TamaraSDK/TamaraSDK/scenes/ViewModel.swift @@ -36,6 +36,17 @@ class ViewModel { } } + func checkPaymentOptions(paymentOptions: PaymentOptions?, completion: @escaping (Result) -> ()) { + networkManager.checkPaymentOptions(paymentOptions: paymentOptions) { result in + switch result { + case .success(let response): + completion(.success(response)) + case .failure(let error): + completion(.failure(AppError.errorMessage(message: error.localizedDescription))) + } + } + } + func authoriseOrder(orderId: String, completion: @escaping (Result) -> ()) { networkManager.authoriseOrder(orderId: orderId) { result in switch result {