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

我试图设置一个相对简单的Braintree服务器运行在Node.js与我的客户端写在Swift 2.1 iOS 9,而我能够logging客户端令牌,我收到以下错误:

[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的最新版本的iOS和最新版本的Braintree node.js包。

充分披露:我在Braintree工作。 如果您还有其他问题,请随时联系我们的支持团队。

看起来你正在序列化来自gateway.clientToken.generate的整个响应,并将它传递给BTAPIClient 。 您应该从响应对象中删除clientToken ,并仅将clientTokenstring值传递给BTAPIClient

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

请参阅clientToken.generate文档以获取更多信息。

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

ERROR BTClient could not initialize because the provided clientToken was invalid

我现在用的是Alamofire,我的function如下:

 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注释中看到,问题是我的服务器正在用引号返回令牌(我还没弄明白为什么),所以我不得不从令牌中“去掉它们”。 现在一切正常。