如何在 iOS 中使用 Braintree 实现支付应用程序

How to implement a payment app with Braintree in iOS

我的问题是:我创建了一个应该接受 Credit/Debit 卡片的应用程序。我在 iOS 中使用 Braintree 4 SDK,在 swift 中使用 cocoa pod。我可以很好地展示下降,但它的作用是只要求一个抄送号码然后就消失了,为什么?因为我使用了快速入门指南中的代码,它应该这样做。但它没有说明何时调用 nonce 函数或显示金额或任何内容!使用 SDK 3 是一个视图控制器,我可以在其中放置委托,几乎所有东西都可以工作,除了记住卡片。所以我的问题是我应该在哪里调用 iOS 中的 nonce 函数?应该在哪里显示总数?以及如何支付到服务器BT?

该页面真的缺少所有内容的实际信息!帮助。

我的代码:

// 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)
    }

我应该在哪里调用它?:

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

    }

编辑

在虚拟卡之后它就关闭了。

完全披露:我在 Braintree 工作。如果您有任何其他问题,请随时联系 support

您可以通过 showDropIn() 中的 result 对象访问支付方式随机数。这也是您可以调用 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)
}

成功调用 postNonceToServer() 后,您可以 receive the payment method nonce and create a transaction 在您的服务器上。

Braintree is provided by PayPal

Step 1. brain tree 支付网关的大部分工作将由您支持的开发人员进行设置,braintree 将从两端以及后端和前端进行部署。

Step 3.

如果您的应用程序安装了以下 pod 吊舱 'BraintreeDropIn' 吊舱 'Braintree/PayPal' Step 3. 从后端设置 braintree 后,向您的后端开发人员询问 url 以获取交易令牌。

Step 4. 使用 BTDropInRequest 将此令牌传递给 BTDropInController(他们提供直接付款 UI ),在调用此方法后,我们将获得一个字符串名称 nonce,然后将此 nonce 发送至为下一个过程服务。

Step 5. 这个 API 会给出交易状态作为响应,无论它是否成功