Search code examples
iosrubyherokutransactionsbraintree

Braintree in iOS Swift: how to pass different transaction amounts to ruby server?


Please see below my Braintree drop-in Swift code and my ruby server code for using Braintree drop-in and creating a transaction. This works nicely to create a transaction of 1 USD and everything gets booked correctly in Braintree.

Now my question is how to alter the amount? I don't know how to pass a variable (containing any desired amount) from my swift code to my ruby server, and also I wonder if it is safe to do so or if the amount should be encrypted when passed?

As an aside, I came across a statement involving 'request.amount = "23.00"' in a Swift code I have seen (which might be an alternative to passing the amount from Swift to ruby), but, again, I don't know how to use this correctly and it's not explained on the Braintree website which I use: https://developers.braintreepayments.com/start/hello-server/python#create-a-transaction

SWIFT (in App):

func postNonceToServer(paymentMethodNonce: String) {
    let paymentURL = URL(string: "https://myexample-31423.herokuapp.com/checkout")!
    let request    = NSMutableURLRequest(url: paymentURL)
    request.httpBody   = "payment_method_nonce=\(paymentMethodNonce)".data(using: String.Encoding.utf8)
    request.httpMethod = "POST"
    URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
        // TODO: Handle success or failure
        }.resume()
}

func showDropIn(clientTokenOrTokenizationKey: String) {
    let request =  BTDropInRequest()
    let dropIn  = BTDropInController(authorization: clientTokenOrTokenizationKey, request: request)
    { (controller, result, error) in
        if (error != nil) {
            print("ERROR")
        } else if (result?.isCancelled == true) {
            print("CANCELLED")
        } else if let result = result {       
            let selectedPaymentMethod = result.paymentMethod!
            self.postNonceToServer(paymentMethodNonce: selectedPaymentMethod.nonce)
        }
        controller.dismiss(animated: true, completion: nil)
    }
    self.present(dropIn!, animated: true, completion: nil)
}

RUBY (on Heroku):

post "/checkout" do
    nonce_from_the_client  = params[:payment_method_nonce]
    result = Braintree::Transaction.sale(
                       :amount => "1.00",
                       :payment_method_nonce => nonce_from_the_client,
                       :options => {
                         :submit_for_settlement => true
                       }
    )
end

Solution

  • Ok, I worked it out myself. In Swift, use this line for example:

    let amount       = "50" as String
    request.httpBody = "payment_method_nonce=\(paymentMethodNonce)&amount=\(amount)".data(using: String.Encoding.utf8)
    

    And then in ruby, use the following.

    post "/checkout" do
        nonce_from_the_client  = params[:payment_method_nonce]
        amount                 = params[:amount]
        result = Braintree::Transaction.sale(
                                         :amount => amount,
                                         :payment_method_nonce => nonce_from_the_client,
                                         :options => {
                                         :submit_for_settlement => true
                                         }
                                         )
    end
    

    That does the job. I didn't realise two variables could simply be passed through separation by '&'.