0

Like the title says I am using Square Reader SDK and finished setting up the app on the iPad I'm using. Looking at the code I can't seem to figure out how to have the user enter the amount themselves without the pre-defined amount. I was hoping that someone else on here has worked with Square quite a bit. The API really didn't help out much.

Here is the code I am working with:

 //
//  Copyright © 2018 Square, Inc.
//
//  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.
//

import UIKit
import SquareReaderSDK

protocol PayViewControllerDelegate: class {
    func payViewControllerDidRequestDeauthorization(_ payViewController: PayViewController)
}

/**
 * Start using Square Reader SDK!
 */
final class PayViewController: BaseViewController {
    public weak var delegate: PayViewControllerDelegate?

    private lazy var checkoutButton = PrimaryButton(title: "Charge \(format(amount: amount))", target: self, selector: #selector(checkoutButtonTapped))

    private lazy var settingsButton = SecondaryButton(title: "Settings", target: self, selector: #selector(settingsButtonTapped))

    private var authorizedLocation: SQRDLocation {
        guard let location = SQRDReaderSDK.shared.authorizedLocation else {
            fatalError("You must authorize Reader SDK before attempting to access `authorizedLocation`.")
        }
        return location
    }

    private let amount = 200

    override func viewDidLoad() {
        super.viewDidLoad()

        titleLabel.text = "Take a payment."
        buttonsStackView.addArrangedSubview(checkoutButton)
        buttonsStackView.addArrangedSubview(settingsButton)
    }

    @objc private func checkoutButtonTapped() {
        let money = SQRDMoney(amount: amount)

        // Create checkout parameters
        let checkoutParameters = SQRDCheckoutParameters(amountMoney: money)
        checkoutParameters.note = "Custom App"
        checkoutParameters.additionalPaymentTypes = [.cash]

        // Create a checkout controller
        let checkoutController = SQRDCheckoutController(parameters: checkoutParameters, delegate: self)

        // Present the Reader Settings controller from the `AppViewController` instance.
        if let presenter = parent {
            checkoutController.present(from: presenter)
        }
    }

    @objc private func settingsButtonTapped() {
        let preferredStyle: UIAlertControllerStyle = UIDevice.current.userInterfaceIdiom == .pad ? .alert : .actionSheet
        let alertController = UIAlertController(title: "Location: \(authorizedLocation.name)", message: nil, preferredStyle: preferredStyle)

        alertController.addAction(UIAlertAction(title: "Reader Settings", style: .default) { (action) in
            let readerSettingsController = SQRDReaderSettingsController(delegate: self)
            readerSettingsController.present(from: self)
        })

        if SQRDReaderSDK.shared.canDeauthorize {
            alertController.addAction(UIAlertAction(title: "Deauthorize", style: .destructive) { (action) in
                self.delegate?.payViewControllerDidRequestDeauthorization(self)
            })
        }

        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

        present(alertController, animated: true, completion: nil)
    }

    private func format(amount: Int) -> String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.currencyCode = authorizedLocation.currencyCode.isoCurrencyCode
        return formatter.string(from: NSNumber(value: Float(amount) / Float(100)))!
    }
}

extension PayViewController: SQRDCheckoutControllerDelegate {
    func checkoutController(_ checkoutController: SQRDCheckoutController, didFinishCheckoutWith result: SQRDCheckoutResult) {
        // Checkout finished, print the result.
        print(result)

        let amountString = format(amount: result.totalMoney.amount)
        showAlert(title: "\(amountString) Successfully Charged", message: "You can refund transactions from your Square Dashboard.")
    }

    func checkoutController(_ checkoutController: SQRDCheckoutController, didFailWith error: Error) {
        /**************************************************************************************************
         * The Checkout controller failed due to an error.
         *
         * Errors from Square Reader SDK always have a `localizedDescription` that is appropriate for displaying to users.
         * Use the values of `userInfo[SQRDErrorDebugCodeKey]` and `userInfo[SQRDErrorDebugMessageKey]` (which are always
         * set for Reader SDK errors) for more information about the underlying issue and how to recover from it in your app.
         **************************************************************************************************/

        guard let checkoutError = error as? SQRDCheckoutControllerError,
            let debugCode = checkoutError.userInfo[SQRDErrorDebugCodeKey] as? String,
            let debugMessage = checkoutError.userInfo[SQRDErrorDebugMessageKey] as? String else {
                return
        }

        print(debugCode)
        print(debugMessage)
        showAlert(title: "Checkout Error", message: checkoutError.localizedDescription)
    }

    func checkoutControllerDidCancel(_ checkoutController: SQRDCheckoutController) {
        print("Checkout cancelled.")
    }

    func showAlert(title: String, message: String) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
        present(alertController, animated: true, completion: nil)
    }
}

extension PayViewController: SQRDReaderSettingsControllerDelegate {
    func readerSettingsControllerDidPresent(_ readerSettingsController: SQRDReaderSettingsController) {
        print("The Reader Settings controller did present.")
    }

    func readerSettingsController(_ readerSettingsController: SQRDReaderSettingsController, didFailToPresentWith error: Error) {
        /**************************************************************************************************
         * The Reader Settings controller failed due to an error.
         *
         * Errors from Square Reader SDK always have a `localizedDescription` that is appropriate for displaying to users.
         * Use the values of `userInfo[SQRDErrorDebugCodeKey]` and `userInfo[SQRDErrorDebugMessageKey]` (which are always
         * set for Reader SDK errors) for more information about the underlying issue and how to recover from it in your app.
         **************************************************************************************************/

        guard let readerSettingsError = error as? SQRDReaderSettingsControllerError,
            let debugCode = readerSettingsError.userInfo[SQRDErrorDebugCodeKey] as? String,
            let debugMessage = readerSettingsError.userInfo[SQRDErrorDebugMessageKey] as? String else {
                return
        }

        print(debugCode)
        print(debugMessage)
        fatalError(error.localizedDescription)
    }
}
Steven Eck
  • 23
  • 5
  • I'm not super familiar with iOS development, but you should be able to set `amount` in the PayViewController from another View Controller. Switch to another view controller: https://stackoverflow.com/questions/39450124/swift-programmatically-navigate-to-another-view-controller-scene Sharing data between controllers: https://stackoverflow.com/questions/29734954/how-do-you-share-data-between-view-controllers-and-other-objects-in-swift – sjosey Aug 10 '18 at 18:34
  • Thank you for your comment. I am not too familiar with iOS development as well. As of today I have two days. I have been requested by my company to have two small apps to just take payments. He has point of sale but does not want to have to log in and out of the different companies. – Steven Eck Aug 10 '18 at 18:51
  • Did my above comment get you in the right direction, or are you still having trouble setting the amount elsewhere? – sjosey Aug 13 '18 at 15:21
  • To be honest, I still need help. If I was just using swift of Java I could figure it out easy. But with the Reader SDK sample and required framework I am not sure which view controller I should call nor do I even know how to implement it to replace the "private let amount = 200" – Steven Eck Aug 13 '18 at 17:40
  • The example is written in Swift, and it's just an example; you're free to change it anyway you like. So for instance in `payViewController` you could make sure you have an `amount` variable set at the top of the controller, `var amount : Int?`. Then, when opening the controller, just set the amount `let payViewController = PayViewController()` ... `payViewControlller.amount = 300` before showing it. You can of course create another controller to do this since this is just an example. – sjosey Aug 13 '18 at 18:03

0 Answers0