             }
             //request.timeoutInterval = 60
             request.setValue("application/json", forHTTPHeaderField: "Content-Type")
-            
+
             // fire request
-            
-            var result : BSResultCcDetails?
-            var resultError : BSCcDetailErrors?
+
+            var result: BSResultCcDetails?
+            var resultError: BSCcDetailErrors?
             //self.simulateTokenExpired = !self.simulateTokenExpired
-            
+
             let semaphore = DispatchSemaphore(value: 0)
             let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
                 if let error = error {
-                    print("error")
+                    NSLog("API error \(error.localizedDescription)")
+                    DispatchQueue.main.async {
+                        completion(nil, .unknown)
+                    }
                     return
                 }
                 let httpResponse = response as? HTTPURLResponse
-                if let httpStatusCode:Int = (httpResponse?.statusCode) {
-                    if (httpStatusCode >= 200 && httpStatusCode <= 299 && !self.simulateTokenExpired) {
-                        result = parseResultCCDetailsFromResponse(data: data)
-                        if (result == nil) {
-                            resultError = .unknown
-                        }
-                    } else if (httpStatusCode == 400 || self.simulateTokenExpired) {
-                        resultError = .unknown
-                        if let data = data {
-                            let errStr = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
-                            if (errStr == "\"EXPIRED_TOKEN\"" || self.simulateTokenExpired) {
-                                resultError = .expiredToken
-                                notifyTokenExpired()
-                            } else if (errStr == "\"INVALID_CC_NUMBER\"") {
-                                resultError = .invalidCcNumber
-                            } else if (errStr == "\"INVALID_CVV\"") {
-                                resultError = .invalidCvv
-                            } else if (errStr == "\"INVALID_EXP_DATE\"") {
-                                resultError = .invalidExpDate
-                            }
-                        }
-                    } else {
-                        print("Http error submitting CC details to BS; HTTP status = \(httpStatusCode)")
-                        resultError = .unknown
-                    }
+                if let httpStatusCode: Int = (httpResponse?.statusCode) {
+                    (result, resultError) = parseFunction(httpStatusCode, data)
                 } else {
                     NSLog("Error getting response from BS on submitting Payment details")
                 }
                 defer {
-                    semaphore.signal()
+                    DispatchQueue.main.async {
+                        completion(result, resultError)
+                    }
                 }
             }
             task.resume()
-            semaphore.wait()
-            if let resultError = resultError {
-                DispatchQueue.main.async {
-                    completion(nil, resultError)
-                }
-                return
-            }
-            DispatchQueue.main.async {
-                completion(result,nil)
-            }
-        }
-    }
-    
+
+        }
+    }
+
+    private static func parseCCResponse(httpStatusCode: Int, data: Data?) -> (BSResultCcDetails?, BSCcDetailErrors?) {
+        var result: BSResultCcDetails?
+        var resultError: BSCcDetailErrors?
+
+        if (httpStatusCode >= 200 && httpStatusCode <= 299 && !self.simulateTokenExpired) {
+            result = parseResultCCDetailsFromResponse(data: data)
+            if (result == nil) {
+                resultError = .unknown
+            }
+        } else if (httpStatusCode == 400 || self.simulateTokenExpired) {
+            resultError = .unknown
+            if let data = data {
+                let errStr = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
+                if (errStr == "\"EXPIRED_TOKEN\"" || self.simulateTokenExpired) {
+                    resultError = .expiredToken
+                    notifyTokenExpired()
+                } else if (errStr == "\"INVALID_CC_NUMBER\"") {
+                    resultError = .invalidCcNumber
+                } else if (errStr == "\"INVALID_CVV\"") {
+                    resultError = .invalidCvv
+                } else if (errStr == "\"INVALID_EXP_DATE\"") {
+                    resultError = .invalidExpDate
+                }
+            }
+        } else {
+            NSLog("Http error submitting CC details to BS; HTTP status = \(httpStatusCode)")
+            resultError = .unknown
+        }
+        return (result, resultError)
+    }
+
     private static func parseResultCCDetailsFromResponse(data: Data?) -> BSResultCcDetails? {
-        
-        var result : BSResultCcDetails?
+
+        var result: BSResultCcDetails?
         if let data = data {
             do {
                 // Parse the result JSOn object
-                if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String : AnyObject] {
+                if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject] {
                     result = BSResultCcDetails()
                     result!.ccType = json["ccType"] as? String
                     result!.last4Digits = json["last4Digits"] as? String

                return
            }
            let httpResponse = response as? HTTPURLResponse
            if let httpStatusCode:Int = (httpResponse?.statusCode) {
                if (httpStatusCode >= 200 && httpStatusCode <= 299) {
                    result = extractTokenFromResponse(httpResponse : httpResponse, domain : domain)
                    if result == nil {
                        resultError = .unknown
                    }

            throw error
        }
    }

    /**
        Return a list of currencies and their rates from BlueSnap server
     - throws BSApiErrors
    */
    static func getCurrencyRates() throws -> BSCurrencies? {

        let bsToken = getBsToken()

        if let lastCurrencyFetchDate = lastCurrencyFetchDate, let _ = bsCurrencies {
            let diff = lastCurrencyFetchDate.timeIntervalSinceNow as Double // interval in seconds
            if (diff > TIME_DIFF_TO_RELOAD) {
                return bsCurrencies
            }
        }

        let domain: String! = bsToken!.serverUrl
        let urlStr = domain + "services/2/tokenized-services/rates"
        let url = NSURL(string: urlStr)!
        var request = NSMutableURLRequest(url: url as URL)
        //request.timeoutInterval = 60
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue(bsToken!.tokenStr, forHTTPHeaderField: "Token-Authentication")

        // fire request

        var resultError: BSApiErrors?
        let semaphore = DispatchSemaphore(value: 0)
        let task = URLSession.shared.dataTask(with: request as URLRequest) { (data: Data?, response, error) in
            if let error = error {
                NSLog("Error getting BS currencies: \(error.localizedDescription)")
                resultError = .unknown
                return
            }
            let httpResponse = response as? HTTPURLResponse
            if let httpStatusCode: Int = (httpResponse?.statusCode) {
                if (httpStatusCode >= 200 && httpStatusCode <= 299) {
                    let tmp = parseCurrenciesJSON(data: data)
                    if tmp != nil {
