问题
My issue is this: I have created an app that is supposed to accept Credit/Debit cards. And Im using Braintree 4 SDK in iOS with swift using a cocoa pod. I can present the drop in just fine but what it does is that just ask for a cc number and then disappears, why? Because I use the code in the quick-start guide and it's supposed to do that. But it doesn't say anything about when to call the nonce function or show the amount or anything! With SDK 3 is a view controller where I can put the delegate and almost everything works except remembering cards. So my question are where am I supposed to call the nonce function in iOS? Where does the total should be shown? And how do I make a payment to the server BT?.
The page is really lacking actual information for everything! Help.
My code:
// Mark - Braintree methods
func showDropIn(clientTokenOrTokenizationKey: String) {
let request = BTDropInRequest()
request.amount = "\(total)"
request.currencyCode = "MXN"
// request.
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 {
// Use the BTDropInResult properties to update your UI
// result.paymentOptionType
// result.paymentMethod
// result.paymentIcon
// result.paymentDescription
print(result)
// controller.
}
controller.dismiss(animated: true, completion: nil)
}
self.present(dropIn!, animated: true, completion: nil)
// //create paymentrequest
// let
// paymentRequest: BTPaymentRequest = BTPaymentRequest()
// paymentRequest.summaryTitle = "Lavado Automozo"
// paymentRequest.summaryDescription = "$\(totalLabel.text!) precio total de los servicios solicitados."
// paymentRequest.displayAmount = "$\(total!).00 MXN"
// paymentRequest.currencyCode = "MXN"
// paymentRequest.callToActionText = "Aceptar compra."
// paymentRequest.shouldHideCallToAction = false
// //set delegate
// let dropInViewController = BTDropInViewController(apiClient: braintreeClient!)
// dropInViewController.delegate = self
// dropInViewController.paymentRequest = paymentRequest
// //add cancel button
// dropInViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.cancel, target: self, action: #selector(ViewController.userDidCancelPayment))
//
// //present view
// let navigationController = UINavigationController(rootViewController: dropInViewController)
//
// present(navigationController, animated: true, completion: nil)
//
// let request = BTDropInRequest()
// let dropIn = BTDropInController()
// { (controller, result, error) in
// if (error != nil) {
// print("ERROR")
// } else if (result?.isCancelled == true) {
// print("CANCELLED")
// } else if let result = result {
// // Use the BTDropInResult properties to update your UI
// // result.paymentOptionType
// // result.paymentMethod
// // result.paymentIcon
// // result.paymentDescription
// }
// controller.dismiss(animated: true, completion: nil)
// }
// self.present(dropIn!, animated: true, completion: nil)
}
And Where am I supposed to call this?:
func postNonceToServer(paymentMethodNonce: String) -> Bool {
PFCloud.callFunction(inBackground: "checkout", withParameters: ["payment_method_nonce" : paymentMethodNonce, "amount" : "\(total!).00"]) {
(response, error) -> Void in
// let ratings = response as? Float
// ratings is 4.5
if error != nil {
} else {
}
print("the response \(response ?? "nil")")
print("The error: \(error?.localizedDescription)")
//self.clientToken = response as! String
// print(self.clientToken)
}
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "mmm. dd, YYYY HH:mm"
dateFormatter.timeZone = NSTimeZone.local
let fechaRegistro = dateFormatter.string(from: Date())
// displayError("Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totalLabel.text!) la fecha registrada \(fechaRegistro)")
let usuarioPagado: PFObject = PFObject(className: "Ordenes")
let location: PFGeoPoint = PFGeoPoint(latitude: ubicacion.latitude, longitude: ubicacion.longitude)
usuarioPagado["Ubicacion"] = location
usuarioPagado["NumeroExterior"] = numeroExteriorTextField.text!
usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text!
usuarioPagado["LavadoCarro"] = numeroCarrosTextField.text!
usuarioPagado["LavadoMiniVan"] = numeroMinivanTextField.text!
usuarioPagado["LavadoPickUp"] = numeroPickUpsTextField.text!
usuarioPagado["LavadoDeVan"] = numeroVansTextField.text!
usuarioPagado["LavadoAspiradoCarro"] = numeroAspiradoCarrosTextField.text!
usuarioPagado["LavadoAspiradoMiniVan"] = numeroAspiradoMinivanTextField.text!
usuarioPagado["LavadoAspiradoPickUp"] = numeroPickUpsTextField.text!
usuarioPagado["LavadoAspiradoDeVan"] = numeroAspiradoVansTextField.text!
usuarioPagado["Monto"] = totalLabel.text!
usuarioPagado["NumeroDeTelefono"] = telefonoTextField.text!
usuarioPagado["TipoDeCelular"] = "iPhone"
usuarioPagado["FechaDeOrden"] = fechaRegistro
//usuarioPagado["TipoDeCelular"]
//usuarioPagado["PaymentConfirmation"] = completedPayment.confirmation.description
//
// usuarioPagado.saveInBackground() {
// (success: Bool, error: Error?) -> Void in
//
// if error == nil {
//
// //done
// print("saved object")
//
// } else {
//
// //not done
// print("not saved because \(error?.localizedDescription)")
//
// }
// }
do {
let result = try usuarioPagado.save()
// displayError("Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totalLabel.text!) la fecha registrada \(fechaRegistro)")
//
} catch let error {
print(error.localizedDescription)
self.displayError("Error", message: "Hubo un error al guardar tu informacion, ponte ne contacto con nosotros.")
return false
}
numeroCarrosTextField.text = "0"
numeroMinivanTextField.text = "0"
numeroPickUpsTextField.text = "0"
numeroVansTextField.text = "0"
numeroAspiradoCarrosTextField.text = "0"
numeroAspiradoMinivanTextField.text = "0"
numeroAspiradoPickUpsTextField.text = "0"
numeroAspiradoVansTextField.text = "0"
totalLabel.text = "00.00"
self.lavadoSwitch.isOn = false
self.lavadoYAspiradSwitch.isOn = false
self.numeroExteriorTextField.text = ""
self.telefonoTextField.text = ""
// displayError("Exito", message: "Tu pago ha sido procesado, en unos momentos atenderemos tu orden. Total es de $\(totalLabel.text!) la fecha registrada \(fechaRegistro)")
// Update URL with your server
// let paymentURL = URL(string: "https://your-server.example.com/payment-methods")!
// 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()
return true
}
EDIT
After the dummy card it just closes.
回答1:
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
You can access the payment method nonce via the result
object within showDropIn()
. This is also where you may call postNonceToServer().
func showDropIn(clientTokenOrTokenizationKey: String) {
let request = BTDropInRequest()
request.amount = "\(total)"
request.currencyCode = "MXN"
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! // retrieve the payment method.
self.postNonceToServer(paymentMethodNonce: selectedPaymentMethod.nonce) // call postNonceToServer() with the nonce from the selected payment method.
}
controller.dismiss(animated: true, completion: nil)
}
self.present(dropIn!, animated: true, completion: nil)
}
After you successfully call postNonceToServer()
you can receive the payment method nonce and create a transaction on your server.
回答2:
Braintree is provided by PayPal
Step 1.
Most of the work of brain tree payment gateway is to be setup from your backed developer, braintree is to be deployed from both ends as well as from backend and front end.
Step 3.
Install following pod if your apps
pod 'BraintreeDropIn'
pod 'Braintree/PayPal'
Step 3.
After Setup braintree from backend ask your backend developer for the url to get the token for the transaction.
Step 4.
Pass this token to BTDropInController(They provide drop-in payment UI ) with BTDropInRequest , after calling this method we shall get a string name nonce and than send this nonce with amount to sever for the next process.
Step 5.
This API will give u status of transaction in response whether is it successful or not
来源:https://stackoverflow.com/questions/41006735/how-to-implement-a-payment-app-with-braintree-in-ios