Braintree node.js w/iOS 9 Swift 2.1 - 客户端令牌错误

Posted

技术标签:

【中文标题】Braintree node.js w/iOS 9 Swift 2.1 - 客户端令牌错误【英文标题】:Braintree node.js w/ iOS 9 Swift 2.1 - client token error 【发布时间】:2016-06-11 21:05:19 【问题描述】:

我正在尝试设置一个在 node.js 上运行的相对简单的 Braintree 服务器,我的客户端是用适用于 ios 9 的 Swift 2.1 编写的,虽然我能够记录客户端令牌,但我收到以下错误:

[BraintreeSDK] ERROR Unsupported client token version. Please ensure your server is generating a valid Braintree ClientToken with a server-side SDK that is compatible with this version of Braintree iOS.

以下是我的服务器代码(改编自 BraintreeDev 存储库):

'use strict';

var express = require('express');
var app = express();

var braintree = require('braintree');

var bodyParser = require('body-parser');
var parseUrlEnconded = bodyParser.urlencoded(
  extended: false
);

var gateway = braintree.connect(
  environment: braintree.Environment.Sandbox,
  merchantId: 'xxxxxxxxxxxxx',
  publicKey: 'xxxxxxxxxxxxxxx',
  privateKey: 'xxxxxxxxxxxxxxxxxxxxxxx'
);

app.use(express.static('public'));

app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

// Creates a new token and returns it in the response.
app.get('/token', function (req, res) 
  gateway.clientToken.generate(, function (error, response) 
    res.json(response);
  );
);

app.post('/payment', function (req, res) 
  var sale = 
    amount: "10",
    payment_method_nonce: req.param('payment_method_nonce')
  ;

  gateway.transaction.sale(sale, function (error, response) 
    if (!error && response.success) 
      res.json(response);
     else 
      // do something else
    
  );
);


app.listen(process.env.PORT || 5000)

module.exports = app;

这是我的 iOS 代码:

class BaseViewController: UIViewController 

    var braintreeClient: BTAPIClient?

    override func viewDidLoad() 
        super.viewDidLoad()

        let clientTokenURL = NSURL(string: "https://my-heroku-app.herokuapp.com/token")!
        let clientTokenRequest = NSMutableURLRequest(URL: clientTokenURL)
        clientTokenRequest.setValue("text/plain", forHTTPHeaderField: "Accept")

        NSURLSession.sharedSession().dataTaskWithRequest(clientTokenRequest)  (data, response, error) -> Void in
            guard let data = data else 
                return
            

            let clientToken = String(data: data, encoding: NSUTF8StringEncoding)
            print("Client Token: \(clientToken)")
            self.braintreeClient = BTAPIClient(authorization: clientToken!)
            print(response?.description)

        .resume()
    
...

这似乎应该是非常直截了当的事情,但我无法理解为什么会出现此错误。

编辑:我正在使用最新版本的 Braintree SDK for iOS 和最新版本的 Braintree node.js 包。

【问题讨论】:

【参考方案1】:

全面披露:我在 Braintree 工作。如果您还有任何问题,请随时联系我们的support 团队。

您似乎正在序列化来自gateway.clientToken.generate 的整个响应并将其传递给BTAPIClient。您应该从响应对象中删除 clientToken,并且只将 clientToken 字符串值传递给 BTAPIClient

app.get('/token', function (req, res) 
  gateway.clientToken.generate(, function (error, response) 
    res.json(response.clientToken);
  );
);

有关详细信息,请参阅clientToken.generate 文档。

【讨论】:

不幸的是,我现在收到以下错误:[BraintreeSDK] ERROR Invalid client token. Please ensure your server is generating a valid Braintree ClientToken. 还有这个错误:ERROR BTClient could not initialize because the provided clientToken was invalid 请联系我们的support team 以获得更多帮助来解决您的问题。【参考方案2】:

上面的答案解决了我的服务器端代码问题。但是,我仍然在 iOS 应用程序中遇到错误:

ERROR BTClient could not initialize because the provided clientToken was invalid

我现在用的是Alamofire,我的功能如下:

associatedType ClientTokenResult = (clientToken: String?) -> ()

func fetchToken(completion: ClientTokenResult) 
    let parameters = [String: AnyObject]()
    Alamofire.request(Router.Get("api/token", parameters))
        .validate()
        .response  (request, response, data, error) -> Void in
            guard let data = data else 
                return
            

            if let error = error 
                print("Error: \(error.localizedDescription)")
                completion(clientToken: nil)
             else 
                let clientToken = String(data: data, encoding: NSUTF8StringEncoding)!

                // NOTE: This shouldn't be necessary, but as of right now the server is returning the token
                // with quotation marks.
                let strippedClientToken = clientToken.stringByReplacingOccurrencesOfString("\"",
                    withString: "")

                print("Client Token: \(strippedClientToken)")
                print(response?.debugDescription)

                completion(clientToken: strippedClientToken)
            
    

更新:您可以在我的 NOTE 评论中看到问题是我的服务器正在返回带有引号的令牌(我还没有弄清楚为什么)所以我不得不“从令牌中剥离它们”。现在一切正常。

【讨论】:

以上是关于Braintree node.js w/iOS 9 Swift 2.1 - 客户端令牌错误的主要内容,如果未能解决你的问题,请参考以下文章

Ionic Braintree 插件错误:应为“/* Begin”、“/* End”、“\”或 [A-Za-z0-9_.] 但找到“/”

magento 1.9 + 脑树

Node.js 9 新特性

深入浅出Node.js - 玩转进程

Node.js 9.0版本 发布了!Node.js 8 转为 LTS 状态

9.Node.js 包管理器npm