PayPal API returns RESOURCE_NOT_FOUND / INVALID_RESOURCE_ID but the transaction is listed in the Sandbox Business account - paypal

I have a similar issue.
Setup
PayPal Sandbox environment
Two test accounts (Personal and Business account). During the tests the personal account buys a product. The transaction goes to the Business account.
I created REST API app which is connected to the Sandbox Business account above.
I logged in to: https://www.sandbox.paypal.com/ with the credentials of the Business account to generate a PayPal button. The HTML code of the button is added to my website.
Steps
I open the website and click the PayPal button.
I log into PayPal Sandbox with the credentials of the Personal account.
I complete the payment process.
I log into the Business account and I see that the transaction (order) is listed there. I can see the Transaction ID.
Issue
In all requests to the API I use the Client ID and the Secret of the REST API app which I already created for the purposes of the tests.
After that I opened Postman and I sent the following request to PayPal API to generate an access token (Doc: https://developer.paypal.com/docs/api/get-an-access-token-curl/).
curl -v https://api.sandbox.paypal.com/v1/oauth2/token \
-H "Accept: application/json" \
-H "Accept-Language: en_US" \
-u "client_id:secret" \
-d "grant_type=client_credentials"
So far, so good. Then I send an API request to PayPal APIv1 to get more details about the order. I use the Transaction Id which according to what I read is identical to Order ID.
curl -v -X GET https://api.sandbox.paypal.com/v1/checkout/orders/TRANSACTION_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token"
and I get this:
{
"http_code": 404,
"body": {
"name": "INVALID_RESOURCE_ID",
"message": "INVALID_RESOURCE_ID",
"information_link": "https://developer.paypal.com/docs/api/orders/v1/#error-INVALID_RESOURCE_ID",
"debug_id": "c02871817abba"
}
}
I tried APIv2:
curl -v -X GET https://api.sandbox.paypal.com/v1/checkout/orders/ORDER_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token"
and I get this:
{
"http_code": 404,
"body": {
"name": "RESOURCE_NOT_FOUND",
"details": [
{
"issue": "INVALID_RESOURCE_ID",
"description": "Specified resource ID does not exist. Please check the resource ID and try again."
}
],
"message": "The specified resource does not exist.",
"debug_id": "c2c24f91a44fd",
"links": [
{
"href": "https://developer.paypal.com/docs/api/orders/v2/#error-INVALID_RESOURCE_ID",
"rel": "information_link",
"method": "GET"
}
]
}
}
Confusion
The transaction is clearly listed in the Business account but the API says that there no such transaction.
Suggestions/Solutions?
Solution
The default behaviour of the payments initiated via PayPal button (generated with the Business account) is Sale but not Order. For more details about the differences between the two, read here - https://www.paypal.com/us/smarthelp/article/what-are-the-differences-between-the-express-checkout-payment-actions-ts1501
The solution is to make a request to another PayPal API method (check: https://developer.paypal.com/docs/paypal-plus/germany/how-to/show-sale/?fbclid=IwAR30yROZMjKT2LlRgSRuVBMGrjdmN1MGbuJ50rUiUBWwW11FSpGdxk5JNpY#show-sale-details)
Here is the request returning correct data.
curl -v -X GET https://api.sandbox.paypal.com/v1/payments/sale/TRANSACTION_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token"

Solution
The default behaviour of the payments initiated via PayPal button (generated with the Business account) is Sale but not Order. For more details about the differences between the two, read here.
The solution is to make a request to another PayPal API method check this
Here is the request returning correct data.
curl -v -X GET https://api.sandbox.paypal.com/v1/payments/sale/TRANSACTION_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token"

v2/orders objects are for payment approval only, they are not transactions. Their IDs should only be persisted about a month for debugging purposes, as they serve no accounting purpose and are not referenceable in PayPal.com
A PayPal transaction on the other hand is represented by a v2/payments object, returned when you capture a v2/order. You can get a capture's details again with the appropriate GET call: https://developer.paypal.com/docs/api/payments/v2/#captures_get

It is very likely something is broken on PayPal server. It is happening quite often.
They usually fix it, some time it takes longer than reasonable.
In any way to make sure you are doing everything correctly, and to check if they have problems at the time of your experiments, you can contact paypal support
https://www.paypal-support.com/

Related

Paypal API - Get the capture_id after subscription

I have a subscription button that I integrated with the Paypal API. After a subscription I get these informations:
{ orderId: "ORDERID", subscriptionId: "SUBSCRIPTIONID" }
I need to get the capture_id which is the id of the captured payment after the user subscribed.
After searching the doc and lot of chatting with chatGPT I know to get the capture_id I have to do this request:
curl -X GET https://api.paypal.com/v2/checkout/orders/<order_id> \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>"
I should have the capture_id in the purchase_units fields returned by the request, but the purchase_units field I get is an empty array.
The status of my order is "APPROVED" and I need to have the status as "CAPTURED" to get the purchase_units.
To do this I need to make this request:
curl -X POST https://api.paypal.com/v2/checkout/orders/<order_id>/capture \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>"
But when I do that I get the error: "INTERNAL_SERVER_ERROR".
Also I don't understand why the order I get has the status "APPROVED" and not directly "CAPTURED", since when I go check on the user test account I have the payment which is done:
Use the Get Subscription Details API call, and/or subscribe to the webhook PAYMENT.SALE.COMPLETED
To aid in reconciliation, add a custom_id when creating the subscription. This value will be returned in all webhook payment notifications, for both the first and future payments.

Auth0: Let user resend the Verification Email

I enabled the user/password connection in Auth0, and I would like to have the emails verified before proceeding. I enabled the corresponding rule to force the email verification and everything seems to work as expected.
Still, I noticed that the verification email is sent upon signing up. I want a button to allow sending that email again, but this doesn't seems to be possible.
How can a user, from the UI, ask for a verification email?
Calling https://<tenantName>.auth0.com/api/v2/jobs/verification-email won't do, because the token needs the update:users scope. We can get a token with that scope with a request to https://<tenantName>.auth0.com/oauth/token, but that means the client secret would be exposed.
there is a work around for this, I use it as a post email verification signal.
auth0 create a ticket and send us a link with the ticket id as query string to verify the email, the link sent is like below:
https://<domain>/u/email-verification?ticket=h7CtBxPXiej7FtaKo0UHYJtdWPazaHhs#
you can use this api to resend the email verfication link, here is an example of the request:
curl --location --request POST 'https://<domain>/api/v2/tickets/email-verification' \
--header 'Authorization: Bearer <token> \
--header 'Content-Type: application/json' \
--header 'Cookie: __cfduid=d7aa37a65221ad2c0fd17ec71c76f13eb1603727648; did=s%3Av0%3A694d6590-1a83-11eb-877d-d1f701a6b5e1.qweiCQT%2Fah2JbVlHe8mU7En5egRFtrEmjETM%2B%2BIKmzc; did_compat=s%3Av0%3A694d6590-1a83-11eb-877d-d1f701a6b5e1.qweiCQT%2Fah2JbVlHe8mU7En5egRFtrEmjETM%2B%2BIKmzc' \
--data-raw '{
"result_url": "<redirection_url>",
"user_id": <auth0_user_id>,
"ttl_sec": 0,
"includeEmailInRedirect": false,
"identity": {
"user_id": "<user_id>",
"provider": "auth0"
}
}'

Cannot call the PayPal Sync API due to Authorization Failure

I'm trying to use the relatively new PayPal Sync API to download my PayPal transactions. I'm following the Sync API guide. I started by logging into the PayPal Developer Dashboard My Apps & Credentials page, scrolling to the REST API apps section, creating an app, clicking on it, and enabling Transaction Search for both the Sandbox and Live accounts.
I then used the Sandbox account's Client ID and Secret to generate an Access Token. I confirmed that the Client ID and Secret are correct and active. My cURL command is below (note that I'm using cURL on Windows 10):
curl -v https://api.sandbox.paypal.com/v1/oauth2/token ^
-H "Accept: application/json" ^
-H "Accept-Language: en_US" ^
-u "<my-client-id>:<my-secret>" ^
-d "grant_type=client_credentials"
I received a response similar to the following (I added the formatting):
{
"scope":"https://uri.paypal.com/services/reporting/search/read
https://api.paypal.com/v1/payments/.*
https://uri.paypal.com/services/applications/webhooks
openid",
"nonce":"2018-04-04T02:20:02Z...",
"access_token":"<my-access-token>",
"token_type":"Bearer",
"app_id":"<my-app-id>",
"expires_in":32400
}
I then took the Access Token and copied it into the sample command on the Sync API guide page. Here is the command I ran:
curl -v -X GET https://api.sandbox.paypal.com/v1/reporting/transactions?transaction_id=5TY05013RG002845M&fields=all&page_size=100&page=1 ^
-H "Content-Type: application/json" ^
-H "Authorization: Bearer <my-access-token>"
I received the following error response:
< HTTP/1.1 401 Unauthorized
...
< Content-Length: 244
< Connection: close
< Content-Type: application/json
<
{
"name":"AUTHENTICATION_FAILURE",
"message":"Authentication failed due to invalid authentication credentials or a missing Authorization header.",
"links":[{
"href":"https://developer.paypal.com/docs/api/overview/#error",
"rel":"information_link"
}]
}
I tried many things to correct this error, including:
Adding a "Accept: application/json" and "Accept-Language: en_US" header to the command.
Creating a new Secret and generating a new Access Token.
Creating a new App with a new Client ID & Secret and generating a new Access Token.
Disabling Transaction Search, re-enabling it, and sending the command again.
Trying in the Live account.
Each of these attempts produced the same result. I noted that in the scope section of the access token response that it doesn't include a path similar to the stated path for the Sync API (/v1/reporting/transactions). However, that's just an observation, and I'm not sure if that is relevant.
I read through the entire Sync API guides and documentation about five times, and I searched Google and StackOverflow pretty thoroughly. I'm seeing evidence that some people are getting past the initial connection to Sync API, so I'm fairly certain this API works.
Can someone help me understand what I'm missing? Could it just be that I need to wait a day or two for their systems to catch up? PayPal's Developer documentation is not very user-friendly, and their Developer Dashboard is extremely glitchy.
I had this same issue. Putting double quotes around the URL solved it for me. The other API endpoints worked (authentication, authorizations/xyz) because they didn't have any special URL characters in them. In the transaction search, the query string delimiters were being parsed by Bash.
Your curl lines above become:
curl -v -X GET "https://api.sandbox.paypal.com/v1/reporting/transactions?transaction_id=5TY05013RG002845M&fields=all&page_size=100&page=1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <my-access-token>"
Hope that helps someone.
It appears that this error may be caused by either cURL or the way I'm using it. On a hunch, I used Hurl.it to execute this sample request, and the request was successful (HTTP 200). I then tried another request where I searched for all transactions in a given date range, and that was also successful. I'm going to mark the question answered.

update: getting 400 error 'invalid_payment', only when rides are ordered via api, ordering on phone works fine

I'm getting an "invalid_payment" error only when ordering rides via the api. I thought it may have been an account issue so checked my app but I was able to login and order manually on my phone without any problems.
Here is my request and response. Is there anything else you need?
Request:
curl -X POST \
https://api.uber.com/v1/requests \
-H 'authorization: Bearer TOKEN' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'postman-token: c2e706c0-5bde-c324-1326-8bfc43a37079' \
-d '{
"start_latitude": "43.854816",
"start_longitude": "-79.4368132",
"start_address": "9350 Yonge Street, Richmond Hill, ON L4C 5G2",
"product_id": "d1e548ac-4be5-46c0-8c86-201ac8a36fc6",
"end_latitude":"43.8656588",
"end_longitude":"-79.4411572",
"end_address": "11 Bingham Street, Richmond Hill, ON L4C 8Y6"
}'
Response:
{"meta":{},"errors":[{"status":400,"code":"invalid_payment","title":"The rider's payment method is invalid and they must update their billing info."}]}
Edit: When ordered via the API the request does not come up like it usually does when you have the app on your phone open. Additionally, the API is letting me order rides normally for some addresses, just not all (mainly Canadian) addresses.
Edit 2: I tried refreshing the token thinking it may have been a caching issue but no luck.
Edit 3: This appears to really only be happening for addresses in Canada. API can order rides successfully without invalid_payment error in the U.S.

Paypal - RestAPI - Sandbox Webhook not occurring

Using my sandbox account with the RestAPI, I've created an invoice. My buyer account got the notification, I went to the link and paid it ok. There's notifications that I received payment. However, no WebHook notification.
I added all events to my WebHook. When using the WebHook simulator, I get the POST to my API just fine. It's hosted by a Redmond based cloud provider and is https.
Under the WebHook Events link in the Sandbox section, it's showing no entries.
Where else can I go to investigate this?
list all your registered webhooks use following with your actual access-token
curl -v -X GET https://api.sandbox.paypal.com/v1/notifications/webhooks \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer <Access-Token>'
in the response, you should be able to find out what exactly were in the system for your webhooks, if not, did you created the webhooks as document says?
curl -v POST https://api.sandbox.paypal.com/v1/notifications/webhooks \
-H 'Content-Type:application/json' \
-H 'Authorization: Bearer <Access-Token>' \
-d '{
"url": "https://www.yeowza.com/paypal_webhook",
"event_types": [
{
"name": "PAYMENT.AUTHORIZATION.CREATED"
},
{
"name": "PAYMENT.AUTHORIZATION.VOIDED"
}
]
}'
From what I see on the RestAPI documentation azlankasim is correct saying that only some fundings are supported.
On the bottom of the page it says that only PayPal authorizations are supported.
https://developer.paypal.com/docs/integration/direct/rest-webhooks-overview/
"Note: Only PayPal authorizations are currently supported. Direct credit card transactions are not yet supported. We are actively working on adding more event types."
Have you tried to test using PayPal payment, to check if this is the problem?
You may need to check what are the funding sources used to create the payment. Currently webhook only sends the notification if the customer pays with an echeck. So far there are no notifications sent if the payment is made with other funding sources. Also, you may need to check the events that you have chosen. Based on this documentation , only authorizations are currently supported.