Receiving INTERNAL_SERVICE_ERROR REST API - paypal

Using REST API, sandbox and attempting to get bearer token. Receiving the following error
{"name":"INTERNAL_SERVICE_ERROR","information_link":"https://api.sandbox.paypal.com/docs/api/#INTERNAL_SERVICE_ERROR","debug_id":"5a235c510522b"}
How can I find out what the debug id means?

The 'debug_id' is an internal identifier we can use to pull up the request within PayPal.
You may see our classic API calls refer to this as the 'correlationID'.
Unfortunately I'm not finding anything in our system for this debug_id. Can you log a ticket (www.paypal.com/mts) or email me (address in profile) with details of the call, including your full HTTP request (minus credentials) and the resources you tried to access, as well as the full HTTP response?
I suggest we close this answer as it's not strictly programming-related, but I can continue working on this via mail / ticket with you.
By the way; if you're using the 4111111111111111 credit card: this card number is currently inoperable in the Sandbox environment and may throw 'internal service error' type responses as well. You can use any other card number instead.

Related

Including a body in a GET, PUT, or POST request results in response of "You need to enable JavaScript to run this app"?

The short story: If I hit my endpoint /api/something with a PUT and no body, it goes through to my Lambda (via CF -> API GW -> Lambda). If I add a body to the request, it doesn't work and seems to die before hitting the API Gateway. I'm not sure why it would do this.
The long story:
I've set up a CloudFront distribution that sends requests to /api to our API gateway and all other requests just vend static website resources.
It has been working great so far for our simple use cases. We previously only hit the API Gateway with GET requests, but now we're going to start needing to send PUT or POST requests to the API Gateway. I had to update the CloudFront distribution "behaviors" for the /api path pattern (the one going to the API gateway) to allow all HTTP methods after that, I was able to start getting responses from the API Gateway for PUT and POST responses (previously only worked for GET).
However, I noticed that if I try to send a payload or body with the request (regardless of the request type), I don't think it actually hits the API Gateway or the Lambda that the API Gateway is routing to because I get a response of "You need to enable JavaScript to run this app". I tried looking at the logs but couldn't find anything. The heads shows "Error from cloudfront" but I'm not sure why or where to find what the error was.
Any tips on how to troubleshoot this or what the issue might be?
Update (10/8): I figured out the "enable javascript" thing was coming up because of my custom error pages for 403&404 errors. I deleted them in my development environment and now get a clearer error.
"This distribution is not configured to allow the HTTP request method
that was used for this request. The distribution supports only
cachable requests. We can't connect to the server for this app or
website at this time. There might be too much traffic or a
configuration error. Try again later, or contact the app or website
owner."
However, I still don't know what to do, as the request type (PUT) is enabled and the request works as long as I don't provide a body. Not sure how to get it to be ok with a body at the moment.

What's the REST way to verify an email?

When a user register to my web application I send an email to verify his inbox.
In the email there are a link to a resource like this:
GET /verify/{token}
Since the resource is being updated behind the scenes, doesn't it break the RESTful approach?
How can I do it in a RESTful manner?
What you are talking about is not REST. REST is for machine to machine communication and not for human to machine communication. You can develop a 1st party REST client, which sends the activation to the REST service.
You can use your verification URI in the browser to access the REST client:
# user follows a hyperlink in the browser manually
GET example.com/client/v1/verify/{token}
# asking the client to verify the token
and after that the REST client will get the hyperlink for verification from the REST service and send the POST to the service in the background.
# the REST client follows the hyperlinks given by the service automatically
# the REST client can run either on the HTTP client or server side
GET example.com/api/v1
# getting the starting page of the REST service
# getting the hyperlink for verification
POST example.com/api/v1/verification {token}
# following the verification hyperlink
If you have a server side 1st party REST client, then the HTTP requests to the REST service will run completely on the server and you won't see anything about it in the browser. If you have a client side REST client, then you can send the POST in the browser with AJAX CORS or you can try to POST directly with a HTML form (not recommended). Anyways the activation should be a POST or a PUT.
It depends on what are you trying to do.
Does it fire an email after validating the user for example? If so, it is not an idempotent method and you should use POST.
Example:
POST /users/{id}/verify/{token}
If the method doesn't have any consequence besides the update, I think you should use PUT.
Aren't you overthinking REST? With e-mail verification you want the user to be able to simply click the link from whatever mail user agent he is using, so you'll end up with a simple GET on the server (presented as a hyperlink to the user) with the token either in the path or as part of the query string:
GET http://example.com/verify-email/TOKEN
GET http://example.com/verify-email?token=TOKEN
Either is fine for this use case. It is not really a resource you are getting or creating; just a trigger for some process on the backend.
Why do you think this would run afoul of good design?

Rest PayPal API Internal Service Error

Were getting a lot of #INTERNAL_SERVICE_ERROR's through the rest PayPal API. To get more details about the error we have been going the PayPal Tech Support. We've been able to fix some of the issues but it is taking us a lot longer than we would like. I was wondering if there was an API call that I could make that would give me the full details of the error or DebugID?
I am not sure how you are currently consuming the API, but https://developer.paypal.com/webapps/developer/docs/api/ specs the error object which has the debug_id, the PayPal internal identifier used for correlation purposes. The error object has information link and error_details object which has the detailed reasons for the error
If you are using an sdk to consume, it is possible to get the debug_id in your logs: https://github.com/paypal/rest-api-sdk-nodejs#debugging and https://github.com/paypal/rest-api-sdk-python#create-payment show ways to do that in Python and Node.
I myself am looking for the same information. But it appears the debug ID is only so Paypal support can correlate the error to a transaction event. Technically there is no other information associated with the Debug ID.
See Receiving INTERNAL_SERVICE_ERROR REST API

REST API: Providing redirect URIs to external services using client app domain

Background
I have a RESTful API accessed through the domain http://restapi.com
I have a client app using http://restapi.com. The client app has the domain http://myapp.com
The way I have my HATEOAS setup is that the API presents URIs without a domain. So instead of http://restapi.com/some/resource, it contains links to resources like so /some/resource. Example API json resource below:
{"_links":{"self":{"href":"/some/resource"}}}
The benefit this has is that the API doesn't need to know about the client app, and the client app has to do very little to get the correct resource from the API and doesn't have to reformat all the URIs in the resource. For example, in the client app, the following URI would be used by the browser http://myapp.com/some/resource. When the app gets the request, it then needs to call the API to get the resource and simply swaps the domain i.e. http://restapi.com/some/resource.
This has been successful so for, and allows a lot of flexibility to have different clients use the API with the only knowledge required being the initial end point (domain) of the API. It also completely decouples the API from the client apps.
The problem I have run into is that I have started using some external services (specifically PayPal adaptive payments) where I need to provide a redirect URL for cancelled payments and successful payments. For example, the browser navigates to http://myapp.com/payment. The resource returned by http://restapi.com/payment presents a link to PayPal. Without going into too much detail, the API has to ask PayPal for a payment ID, which can then be used to create a link to a PayPal payment e.g. http://paypal.com?PayId-123456. Part of the creation process requires that URLs are provided to redirect on payment cancellation or success. Again, don't want to go into details, but when requesting a PayId from PayPal, the redirect URLs are sent as variables to PayPal, and I guess PayPal stores them against the specific PayId created.
The browser navigates to the link returned in the resource - http://paypal.com?PayId-12345. Payment is made and PayPal then uses the redirect URLs as needed to redirect back to my app e.g. on successful completion of payment, PayPal should redirect to http://myapp.com/paymentcomplete. Note: I realise that this is not a restfully named URI, but it simplifies building up the description of my problem
Problem
The problem I have may now be obvious. I need to redirect back to http://myapp.com/paymentcomplete, BUT its the API that provides the redirect URL to PayPal. It has no knowledge of the client application. Since PayPal is an external service, the full URL must be provided. The best the API can do is send http://restapi.com/paymentcomplete as the redirect URL, but if PayPal redirects to this, the resulting response will be a JSON string (the output format of my API) not the nicely formatted page of the client app.
My question is, what is a good way to correctly provide the redirect URL to PayPal?
One thought I had was to make the client application handle creating the PayPal PayId, but I don't like this option as I would like to keep the creation of the PayPal payment ID on the API side. It would also require every client app to provide its own implementation, something I also don't want.
The other option I though of was to ask the client to provide its domain in the request. Currently the request the client makes to get the resource with the link to PayPal is GET http://restapi.com/payment, but I could use POST http://restapi.com/payment with the client providing its domain as a param. The API can then use this to construct the correct redirect URL. I don't really like this idea either as its seems a bit hackish and also requires the app to know that is must fill in this field i.e. a human user wouldn't fill the domain input in.
Additional solutions, or thoughts greatly welcomed.
As you had already mentioned, PayPal is an external api that requires this additional parameter and you do not have control over it. Looks like the client is the only party that can provide the Redirect URI Information.
Couple of ideas come to mind.
The client could send the redirect uri to restapi via header and thus
keeping your rest urls intact. This is a grey area and not a violation of restful api
in my opinion. (Then again, its just my opinion).
The restapi could return the response with a placeholder for the
client to fill in before rendering. This way the API need not know
about the redirect uri and the responsibility is left to the client
which has this information.
It would be nicer if you could implement option 2 with executing couple of lines on Javascript code on the browser to fill-in the placeholder. Which is easy. Ultimately, only 2 end points of this transaction would be aware of the redirect uri - browser & paypal.
This alleviates most of your concerns. The job of handling PayPal id will continue to remain with your API.
You should be able to use the Referer header to determine the client's full URI. It might be populated automatically for you. If not, you can add it yourself. The URI class has methods to pull out the client's host for you. When the API builds the PayPal URI to return to the client, it can include the client's host.
Note that referer is not always included and sometimes gets stripped by intermediaries, as detailed on the wiki page. Since you control both the client and the server in this case, you should be able to tell everybody to play nicely.
I would keep the GET http://restapi.com/payment and pass in a query param with the client domain
GET http://restapi.com/payment?domain=http://myapp.com (of course, the "http://myapp.com" needs to be encoded)

Paypal REST Api Internal Server Error

I'm in a pickle with PayPal's new (and nice) REST Api. I am able to make many calls to the Paypal REST sandbox successfully. However, there are random times it won't work for short perdiods at all and the response code is *Internal Server Error *
Is this because I'm using a Sandbox? Or am I testing it too often? Is there a log stored for my account where I can see why the sandbox returned this error?
Here are the credit cards Im generally testing with.
4000000000000002
4417119669820331
It's sporadic, and unpredictible if it will work or not. Is anyone else having this issue?
Here is the response:
debug_id: 394271a164c9
name: INTERNAL_SERVICE_ERROR