Braintree ios + java transaction API returns 403 - braintree

Just started the project. The client side app is the Braintree demo app. I modified it to point to my server running on localhost
Here is what I'm doing.
ios app makes an request to server to get a token
server uses method below to get a token from Braintree and sends back to server
BraintreeGateway gateway = new BraintreeGateway(
Environment.SANDBOX,
merchantAccountId,
".........",
"............."
);
String token = gateway.clientToken().generate(); // Braintree did return a token
ios demo app creates a nonce with the drop-in view
ios demo app sends the nonce to the server
// nonce sends to server 71a89c9d-6ca7-4804-a895-b0e7564425c6
server calls Braintree API with code below
TransactionRequest request = new TransactionRequest()
.amount(new BigDecimal(19.0f))
.merchantAccountId(merchantAccountId)
.paymentMethodNonce(nonce)
.options()
.submitForSettlement(true)
.done()
.channel("MyShoppingCartProvider");
Result<Transaction> result = gateway.transaction().sale(request);
return result;
The last step got 403 com.braintreegateway.exceptions.AuthorizationException exception from Braintree. The xml from the error stream is Unauthorized. The input stream from Braintree says "Server returned HTTP response code: 403 for URL: https://api.sandbox.braintreegateway.com:443/merchants/vb38crtnzn77b9ys/transactions"
Thanks for the help

It turns out that there are two IDs. One is merchantId and the other merchantAccountId. The server sends back the merchantId back to client. And later for charging, use merchantAccountId.

Related

Youtube Data Api Search Endpoint 401 Error

I'm trying to use the Youtube search endpoint, which does not seem to require an OAuth token. I've read a few tutorials and they only pass an API key. I'm getting a "Failed to load resource: the server responded with a status of 401 ()" error in my console in Chrome Dev Tools. Specifically, looking at the Network tab I get this:
I notice it says that there is an error: "invalid_token" but I pass the api key so they must be talking about the OAuth token? I'm confused because it shouldn't need one, especially because I'm just doing a query for public data. Even the Try This API portion of the endpoint documentation does not need one. Most importantly, my call in Postman works and just pasting the endpoint in my browser directly works. Why doesn't it work? This is using an axios call from a ReactJS frontend.
const apiKey = 'MY_API_KEY';
const url = 'https://www.googleapis.com/youtube/v3/search';
const response = await axios.get(url, {
params: {
part: 'snippet',
maxResults: 5,
q: songName,
key: apiKey
}
});
What was happening was that I was using axios.defaults.headers.common['Authorization'] =Bearer ${params.access_token}; in other calls for another API. This causes default everything to have this access token! So what I did for now is delete axios.defaults.headers.common["Authorization"]; -- the solution is pretty obvious, just make sure you have no extra headers because Search is not a OAuth endpoint!

Google APIs OAuth refresh token url return 401 on http redirect uri?

I had implemented the code to received authorization code as described in this step:
https://developers.google.com/android-publisher/authorization#generating_a_refresh_token
We deployed this code to one server that has "https://..." domain and this works well. We can get the access_token, refresh_token...
But now we need to deploy the same code to a dev server that has no "https".
I created a new OAuth client id with redirect uri using the dev server (no https, the rest /api/v1/... is the same as the previous working server)
Now anytime I tried to go to this url and Allow access
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=http://dev_server/api/v1/...&client_id=dev_server_client_id
I got 401 Unauthorized.
I'm not sure why, but the only difference I can see is "https" vs "http".
Any idea why?
Thank you very much.
Actually I forgot to update the corresponding values in my code
const oauth2Client = new OAuth2(
config.googleApi.clientId,
config.googleApi.clientSecret,
config.googleApi.redirectUri // <= Especially this value
);
These values need to be updated to (beside values on google console).

What's the best practice to renew a token for a WebSocket connection

This might be opinion based, but I still wonder is there a best practice since I'm almost clueless about websocket practices
I have a SPA that gets a JWT token from my own OP. It then uses that JWT to connect to other services I own using both REST and WebSockets.
As far as it goes for REST, it's pretty straightforward:
The REST API validates the JWT (sent in Authorization: Bearer ...) and provides access to the protected resource or responds with a 401, letting the SPA know it needs to request a new token.
Now with websockets :
During the load of the SPA, once I got a token, I'm opening a WS to my webservice. First message I send is a login_message with my JWT, which then I keep on server's websocket instance to know who's sending the messages.
Each subsequent message I receive, I validate the JWT to see if it's expired.
Once it has expired as far as I understand, I'm facing two options :
Drop the websocket with a token_expired error of some kind and force the browser to establish a new websocket connection once the token get refreshed.
Keep the websocket open, return an error message and send a new login message (once token is refreshed)
Don't use a login message but just send the JWT in each request.
Question : Which method would you recommend and why? In terms of security, and performance. Are there any other common practice I did not listed?
Quite an old question I've asked, so I'd be happy to share our chosen practice:
Once the client gets his JWT for the first time (when the application starts), a WebSocket is opened.
To authenticate the channel, we send a message that we define as part of our protocol, called authMessage which contains that JWT.
The server stores this data on the socket's instance and verifies it's validity/expiry before sending data down the wire or receiving from the client.
The token gets refreshed silently in web application minutes before it is expired and another authMessage is issued to the server (repeat from step 2).
If for whatever reason it gets expired before getting renewed, the server closes that socket.
This is roughly what we have implemented in our application (without optimization) and worked really well for us.
Oauth2 flow has two options to renew the token. As you said on of these options is prompt a message to the use to enforce a new login process.
The other option is to use the refresh_token in which you will avoid this login process to your user, every time the session expires and renew the token in a silent way.
In both case, you need to store the jwt in the client (commonly after login) and update it (after interactive login or silent regeneration). Localstorage, store or just a simple global variable are alternatives to handle the store and update the jwt in he client.
As we can see, jwt regeneration is solved following oauth2 spec and is performed at client side, SPA in your case.
So the next question is: How can I pass this jwt (new or renewed) to the external resources (classic rest api or your websocket)?
Classic Rest Api
In this case as probably you know, send the jwt is easy using http headers. In each http invocation we can send the old/valid jwt or the renewed jwt as header, commonly Authorization: Bearer ...
Websocket
In this case it's not so easy because according to a quickly review, there are not a clear way to update headers or any other "metadata" once the connection was established:
how to pass Authorization Bearer access token in websocket javascript client
HTTP headers in Websockets client API
What's more, there is no concept of headers, so you need to send this information (jwt in your case) to your websocket using:
protocols
var ws = new WebSocket("ws://example.com/path", ["protocol1", "protocol2"]);
cookies
document.cookie = 'MyJwt=' + jwt + ';'
var ws = new WebSocket(
'wss://localhost:9000/wss/'
);
simple get parameters
var ws = new WebSocket("ws://example.com/service?key1=value1&key2=value2");
Websocket only receive text
And according to the following links, websocket can extract header, get parameters and protocol just at the stabilization stage:
https://medium.com/hackernoon/implementing-a-websocket-server-with-node-js-d9b78ec5ffa8
https://www.pubnub.com/blog/nodejs-websocket-programming-examples/
https://medium.com/#martin.sikora/node-js-websocket-simple-chat-tutorial-2def3a841b61
After that, websocket server only receive text:
const http = require('http');
const WebSocketServer = require('websocket').server;
const server = http.createServer();
server.listen(9898);
const wsServer = new WebSocketServer({
httpServer: server
});
wsServer.on('request', function(request) {
const connection = request.accept(null, request.origin);
connection.on('message', function(message) {
//I can receive just text
console.log('Received Message:', message.utf8Data);
connection.sendUTF('Hi this is WebSocket server!');
});
connection.on('close', function(reasonCode, description) {
console.log('Client has disconnected.');
});
});
Send jwt in each request
Having analyzed the previous topics, the only way to send the new o renew token to your websocker backend is sending it in each request:
const ws = new WebSocket('ws://localhost:3210', ['json', 'xml']);
ws.addEventListener('open', () => {
const data = {
jwt: '2994630d-0620-47fe-8720-7287036926cd',
message: 'Hello from the client!'
}
const json = JSON.stringify(data);
ws.send(json);
});
Not covered topics
how perform a jwt regeneration using refresh_token
how handle silent regeneration
Let me know if you need this not covered topics.

Standalone Token Registration

Sending a request using the Test URL for Standalone Token Registration, I am faced with an internal server error with no indication as to what the problem is.
HTTP Status Code: 500:
HTTP Status Message: The request was
unsuccessful due to an unexpected condition encountered by the server.
The Test URL I'm POSTing to is:
https://test.sagepay.com/gateway/service/token.vsp
And the POST parameters are as follows:
VPSProtocol = 3.00
TxType = TOKEN
Vendor = MyVendor
VendorTxCode = UniqueVenderTxCode
Currency = GBP
NotificationURL = Publicly facing url
I can confirm that the Vendor is correct because I can successfully POST to the "Part of a Transaction Token Registration" URL, which returns a NextURL that I use to display the payment portal/entry.
I'm sending all of the required POST parameters, so I'm not sure where I've gone wrong. I hope someone can point me in the right direction.
EDIT: It was me being silly. I neglected to check the response from the HttpWebRequest (You'd think this would be my first port of call). It turns out that the vendor I'm using doesn't currently support a TxType of TOKEN. I'll have to contact SagePay support in order to get this enabled.

Get the URI the MPNS to returns to the push client when creating a notification channel Windows Phone 7

/*Get the URI that the Microsoft Push Notification Service returns to the Push Client when creating a notification channel.
Normally, a web service would listen for URIs coming from the web client and maintain a list of URIs to send
notifications out to. */
string subscriptionUri = TextBoxUri.Text.ToString();
Further information on how the pushclient would then sync the URI with a webservice lacks in the description given on MSDN.
So, does anyone know how to make my app send its URI to the MPNS using the push notification client of the Windows Phone, iso having to manually copy-paste them into my web application?
Greetz GP
See MSDN Windows Phone Code Samples at:
http://msdn.microsoft.com/en-us/library/ff431744(v=vs.92).aspx
The following code snippet from the 'sdkToastNotificationCS' example show a possible location to store the uri or send to your webservice:
void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
// Display the new URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
System.Diagnostics.Debug.WriteLine(e.ChannelUri.ToString());
MessageBox.Show(String.Format("Channel Uri is {0}",
e.ChannelUri.ToString()));
// Instead of showing the URI in a message box, POST to your web service
});
}
Execute an HTTP POST request to send the URI and an identifier for you push user. Receive this POST data on your web service and store the user/URI so you can push notifications to that user from your web service.
You just need an endpoint on your server that the app can send the PNS uri (and any other relevant information) to.

Resources