Braintree - 插入式 UI - Apple Pay - Swift 3

Posted

技术标签:

【中文标题】Braintree - 插入式 UI - Apple Pay - Swift 3【英文标题】:Braintree - Drop-in UI - Apple Pay - Swift 3 【发布时间】:2018-10-23 21:47:36 【问题描述】:

我正在为信用卡、贝宝和苹果支付付款集成 Braintree Drop-in UI。 我已遵循信用卡付款的基本步骤。在沙盒中一切正常。

现在我正在实施苹果支付。

我已经完成了这里提到的配置,成功:https://developers.braintreepayments.com/guides/apple-pay/configuration/ios/v4

这是它现在在模拟器中的样子:

我写了如下代码来实现信用卡支付:

import UIKit
import BraintreeDropIn
import Braintree

class DonationPaymentViewController: UIViewController 

let toKinizationKey = "my_tokenization_key"
@IBOutlet weak var amountTextField: UITextField!

override func viewDidLoad() 
    super.viewDidLoad()

    // Do any additional setup after loading the view.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


func sendRequestPaymentToServer(nonce: String, amount: String) 
    let paymentURL = URL(string: "my_api_url")!
    var request = URLRequest(url: paymentURL)
    print("paymentMethodNonce=\(nonce)&amount=\(amount)")
    //request.httpBody = "paymentMethodNonce=\(nonce)&amount=\(amount)".data(using: String.Encoding.utf8)
    request.httpMethod = "POST"

    let token = UserDefaults.standard.object(forKey: "Token") as! String

    let params = ["paymentMethodNonce":"\(nonce)", "amount":amount] as [String : Any]

    let prettyPrinted:Bool = false
    let options = prettyPrinted ?
        JSONSerialization.WritingOptions.prettyPrinted : JSONSerialization.WritingOptions(rawValue: 0)

    request.httpBody = try! JSONSerialization.data(withJSONObject: params, options: options)
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue(token, forHTTPHeaderField: "X-API-KEY")

    URLSession.shared.dataTask(with: request)  [weak self] (data, response, error) -> Void in
        guard let data = data else 
            self?.show(message: (error?.localizedDescription)!)
            return
        

        guard let result = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let success = result?["success"] as? Bool, success == true else 
            self?.show(message: "Transaction failed. Please try again.")
            return
        

        self?.show(message: "Successfully charged. Thanks So Much :)")
        .resume()


@IBAction func pay(_ sender: Any) 
    let request =  BTDropInRequest()
    let dropIn = BTDropInController(authorization: toKinizationKey, request: request)
     [unowned self] (controller, result, error) in

        if let error = error 
            self.show(message: error.localizedDescription)


         else if (result?.isCancelled == true) 
            self.show(message: "Transaction Cancelled")

         else if let nonce = result?.paymentMethod?.nonce, let amount = self.amountTextField.text 
            self.sendRequestPaymentToServer(nonce: nonce, amount: amount)
        
        controller.dismiss(animated: true, completion: nil)
    
    self.present(dropIn!, animated: true, completion: nil)


func show(message: String) 
    DispatchQueue.main.async 
        //self.activityIndicator.stopAnimating()

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



我在编写 Apple Pay 代码方面需要帮助。 Braintree 文档没有提供关于 Braintree Drop-in UI for Apple Pay using Swift 3 的正确信息。这是我应该关注的链接:https://developers.braintreepayments.com/guides/apple-pay/client-side/ios/v4 但这似乎不适用于 Drop-in UI。对于 Apple Pay 和 paypal 的 Braintree 插件 UI 的任何帮助将不胜感激。

【问题讨论】:

在生成客户端令牌以及如何识别单击了贝宝或信用卡的所有选项后,请帮助我获取 onActivityResult 如何获取信用卡或贝宝,请帮助我 @Harsha 我已经把这行放在switch result.paymentOptionType case .applePay ,.payPal,.masterCard,.discover,.visa: 你可以通过为每个单独的案例来弄清楚 当然谢谢,我明白了。 Paytype VISA DropInResult 结果 = data.getParcelableExtra(DropInResult.EXTRA_DROP_IN_RESULT); PaymentMethodNonce nonce = result.getPaymentMethodNonce(); HashMap paramsHash = new HashMap(); paramsHash.put("数量", "2"); paramsHash.put("nonce", nonce.getNonce());发送支付(参数哈希);使用金额和随机数作为参数调用我的服务器方法 sendPayment。如果paytype-Paypal 谢谢你,如果 paytype paypal 我怎么能调用服务器结帐 api.for creditcard am pass amount and nonce.working fine.problem with paypal 请在 paypal 选择中提供一些代码请为 android 浪费太多时间为此 @Harsha For android? 【参考方案1】:

检查下面的代码,我尽可能写评论,当用户选择苹果支付时,你必须配置 paymentRequest let paymentRequest = PKPaymentRequest() 然后处理PKPaymentAuthorizationViewControllerDelegate获取nonce

func showDropIn(clientTokenOrTokenizationKey: String) 
    let request =  BTDropInRequest()
    request.applePayDisabled = false // Make sure that  applePayDisabled i sfalse

    let dropIn = BTDropInController.init(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

            switch result.paymentOptionType 
            case .applePay ,.payPal,.masterCard,.discover,.visa:
                 // Here Result success  check paymentMethod not nil if nil then user select applePay
                if let paymentMethod = result.paymentMethod
                    //paymentMethod.nonce  You can use  nonce now
             controller.dismiss(animated: true, completion: nil)
                else

                    controller.dismiss(animated: true, completion: 

                        self.braintreeClient = BTAPIClient(authorization: clientTokenOrTokenizationKey)

                        // call apple pay
                        let paymentRequest = self.paymentRequest()

                        // Example: Promote PKPaymentAuthorizationViewController to optional so that we can verify
                        // that our paymentRequest is valid. Otherwise, an invalid paymentRequest would crash our app.

                        if let vc = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest)
                            as PKPaymentAuthorizationViewController?
                        
                            vc.delegate = self
                            self.present(vc, animated: true, completion: nil)
                         else 
                            print("Error: Payment request is invalid.")
                        

                    )




                
            default:
                print("error")
                controller.dismiss(animated: true, completion: nil)
            

            // Use the BTDropInResult properties to update your UI
            // result.paymentOptionType
            // result.paymentMethod
            // result.paymentIcon
            // result.paymentDescription
        


    

    self.present(dropIn!, animated: true, completion: nil)





extension ViewController : PKPaymentAuthorizationViewControllerDelegate

    func paymentRequest() -> PKPaymentRequest 
        let paymentRequest = PKPaymentRequest()
        paymentRequest.merchantIdentifier = "merchant.com.Demo.example";
        paymentRequest.supportedNetworks = [PKPaymentNetwork.amex, PKPaymentNetwork.visa, PKPaymentNetwork.masterCard];
        paymentRequest.merchantCapabilities = PKMerchantCapability.capability3DS;
        paymentRequest.countryCode = "US"; // e.g. US
        paymentRequest.currencyCode = "USD"; // e.g. USD
        paymentRequest.paymentSummaryItems = [
            PKPaymentSummaryItem(label: "Dish", amount: NSDecimalNumber(string: "\(MyOrdersViewController.totalOrderPrice)")),

        ]
        return paymentRequest
    





    public func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, completion: @escaping (PKPaymentAuthorizationStatus) -> Swift.Void)

        // Example: Tokenize the Apple Pay payment
        let applePayClient = BTApplePayClient(apiClient: braintreeClient!)
        applePayClient.tokenizeApplePay(payment) 
            (tokenizedApplePayPayment, error) in
            guard let tokenizedApplePayPayment = tokenizedApplePayPayment else 
                // Tokenization failed. Check `error` for the cause of the failure.

                // Indicate failure via completion callback.
                completion(PKPaymentAuthorizationStatus.failure)

                return
            

            // Received a tokenized Apple Pay payment from Braintree.
            // If applicable, address information is accessible in `payment`.

            // Send the nonce to your server for processing.
            print("nonce = \(tokenizedApplePayPayment.nonce)")

            //  self.postNonceToServer(paymentMethodNonce: tokenizedApplePayPayment.nonce)
            // Then indicate success or failure via the completion callback, e.g.
            completion(PKPaymentAuthorizationStatus.success)
        
    

    func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) 
        dismiss(animated: true, completion: nil)
    



【讨论】:

我在控制台中收到此警告。 Warning: Attempt to present <PKPaymentAuthorizationViewController: 0x7fa9baf4e540> on <Project.DonationPaymentViewController: 0x7fa9baf49a20> which is already presenting (null)。我看不到任何弹出窗口。 添加应用代理dismiss(animated: true, completion: nil)

以上是关于Braintree - 插入式 UI - Apple Pay - Swift 3的主要内容,如果未能解决你的问题,请参考以下文章

Braintree:如何使用自定义 UI 选择付款方式并获取付款方式 nonce?

为啥在生产(实时)帐户 api 凭据中使用插入式表单看不到 Braintree 贝宝按钮

Braintree嵌入式贝宝结帐

iOS Braintree Dropin ui,抛出未声明的标识符“BTAppSwitch”

Braintree Dropin UI 不适用于 Ionic 框架,除非强制刷新

Braintree v.Zero Drop In UI 是不是支持 Apple Pay?