Braintree node.js w/ iOS 9 Swift 2.1 - 客户端令牌错误
Braintree node.js w/ iOS 9 Swift 2.1 - client token error
我正在尝试在 node.js 上设置一个相对简单的 Braintree 服务器 运行,我的客户端是用 Swift 2.1 为 iOS 9 编写的,而我'我能够记录客户端令牌,但出现以下错误:
[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()
}
...
这看起来应该非常简单,但我无法理解为什么会出现此错误。
编辑:我正在为 iOS 使用最新版本的 Braintree SDK 和最新版本的 Braintree node.js 包。
完全披露:我在 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 文档。
上面的答案解决了我的服务器端代码问题。但是,我在 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
评论中看到问题是我的服务器返回带引号的令牌(我还没有弄清楚为什么)所以我不得不从令牌中 "strip them" 。现在一切正常。
我正在尝试在 node.js 上设置一个相对简单的 Braintree 服务器 运行,我的客户端是用 Swift 2.1 为 iOS 9 编写的,而我'我能够记录客户端令牌,但出现以下错误:
[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()
}
...
这看起来应该非常简单,但我无法理解为什么会出现此错误。
编辑:我正在为 iOS 使用最新版本的 Braintree SDK 和最新版本的 Braintree node.js 包。
完全披露:我在 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 文档。
上面的答案解决了我的服务器端代码问题。但是,我在 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
评论中看到问题是我的服务器返回带引号的令牌(我还没有弄清楚为什么)所以我不得不从令牌中 "strip them" 。现在一切正常。