Next.js Discord

Discord Forum

PayPal API & Route Handlers

Answered
Masai Lion posted this in #help-forum
Open in Discord
Avatar
Masai LionOP
Hello!
So, basically, I'm encountering big skill issues while trying to implement the [PayPal REST API](https://developer.paypal.com/api/rest/) on my /app/api/route.tsx file, but I'm getting a real funny message

{
error: 'invalid_token',
error_description: 'The token passed in was not found in the system'
}

This shouldn't be happening, I should be getting something like the following on the terminal. (this is an example of the [PayPal Create Order Documentation](https://developer.paypal.com/docs/api/orders/v2/#orders_create).

"links": [
{
"href": "https://api-m.paypal.com/v2/checkout/orders/5O190127TN364715T",
"rel": "self",
"method": "GET"
},
{
"href": "https://www.paypal.com/checkoutnow?token=5O190127TN364715T",
"rel": "payer-action",
"method": "GET"
}
]


I really have no idea what could be wrong... I will be leaving the code below (maybe in different snippets)
Answered by Jboncz
const url = 'https://api.sandbox.paypal.com/v1/oauth2/token'; // Sandbox endpoint

const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

const options = {
  method: 'POST',
  headers: {
    Authorization: `Basic ${basicAuth}`,
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: 'grant_type=client_credentials' // Form-encoded data
};
View full answer

132 Replies

Avatar
Masai LionOP
# i will send the code through a github repo
Avatar
Masai LionOP
PLEASE DONT LET THIS POST DIE
: (
Avatar
Why are you setting the body to urlsearchparams?
Avatar
Masai LionOP
idk, looks cool
jk
no fr I was just reading some random docs and they said I had to add it
Avatar
Hmmmmm. I havent looked through the api docs but you would set that in the headers, not the body
Avatar
Masai LionOP
oh for real?
Avatar
  const orderCreate = await fetch("https://api-m.sandbox.paypal.com/v1/oauth2/token", {
    method: 'POST',
    body: params,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Authorization': 'Basic ' + Buffer.from(`${clientId}:${clientSecret}`).toString('base64'),
      'grant_type':'client_credentials'
    },
  })
https://developer.paypal.com/api/rest/authentication/ I would go through this step by step starting here
Avatar
Masai LionOP
:meow_stare:
Avatar
in the code you provided the url is also inconsistnat
Avatar
Masai LionOP
Interesting
True…
Avatar
Image
Im assuming it should all be 'sandbox' assuming its some kind of test environment they provide
Avatar
Masai LionOP
I will delete the urlsearchparams and pass the props to the post itself
Yeah, it isn’t production
Wait but…
Uhhh
Avatar
Right but your second fetch is pointed at 'live'
Avatar
Masai LionOP
Wait nvm
Wait for real?
Bro no shit
That’s true
Dammit
Avatar
Image
So no wonder your token doesnt exsist in live, because your hitting sandbox
to generate it
Im not looking super closely, just pointing out things I see.
Never used the paypal api, but hopefully that poiints you in the right direction
Avatar
Masai LionOP
But once I pass grant_type: client_credentials I have to remove the body: params right?
Avatar
sec
Avatar
Masai LionOP
Yeah lol, maybe I can use URLsearchparams, the issue was that I was trying to get the token from live when it only existed on sandbox
Avatar
I have just never seen urlSearchParams get used in the body of something your sending. its.... weird.
curl -v -X POST "https://api-m.sandbox.paypal.com/v1/oauth2/token"\
 -u "CLIENT_ID:CLIENT_SECRET"\
 -H "Content-Type: application/x-www-form-urlencoded"\
 -d "grant_type=client_credentials"
Avatar
Masai LionOP
Kinda lol…
Ye I’m deleting urlsearchparams and just passing them to the body of the post
well, not body
Headers
Avatar
Sec, im looking at their postman repo
They do indeed use urlencoded bodies
Avatar
Masai LionOP
I think it is the same as urlsearchparams?
Avatar
Yes, it is.
Avatar
Masai LionOP
Idk never used them
I mean, then I have to use them and pass them to the body, not the headers
Avatar
One moment. Im looking, never really done this.
Avatar
Masai LionOP
Nws, we are both learning
I could have used the SDK but cloudflare doesn’t like it
I already had the SDK running smoothly and with no errors
Avatar
Better to learn how to do it without the sdk in alot of cases.
It just abstracts away the complexity
Avatar
const url = 'https://api.sandbox.paypal.com/v1/oauth2/token'; // Sandbox endpoint

const basicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');

const options = {
  method: 'POST',
  headers: {
    Authorization: `Basic ${basicAuth}`,
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: 'grant_type=client_credentials' // Form-encoded data
};
Answer
Avatar
this is how I would think it works
didnt test
you dont need to urlencode it.
well, you do but dont, its already url encoded so you dont.
Avatar
Masai LionOP
:meow_stare:
Avatar
but overall I think your issue was mostly the URL
I think what you have outside of that would work.
I would add a
console.log(data)


after line 92, and run it to there. Make sure you get a token back
Avatar
Masai LionOP
I modified everything, and I still get the same “error”
Even the search url params
Avatar
Okay one sec. Let me boot up a test project
Well, I have to get a clientid and secret so maybe not lol its late.
Sec let me type this out for you to try
Avatar
Masai LionOP
Lol
Wait
Man
We got new error
I fixed a double {} I had
And now
We get something new
Let me share it with you
@Jboncz
Avatar
Sure.
Go for it
Avatar
Masai LionOP
{
name: 'INVALID_REQUEST',
message: 'Request is not well-formed, syntactically incorrect, or violates schema.',
debug_id: 'db67aead42784',
details: [
{
field: '/amount',
location: 'body',
issue: 'MALFORMED_REQUEST_JSON',
description: 'The request JSON is not well formed.'
}
],
links: [
{
href: 'https://developer.paypal.com/docs/api/orders/v2/#error-MALFORMED_REQUEST_JSON',
rel: 'information_link',
encType: 'application/json'
}
]
}
its more of a json thingy
idk but
Avatar
Okay. wait
so you got your token now
we are past that
Avatar
Masai LionOP
yeah lol, we did it
Avatar
So you need to get a little more organized here. You should abstract your authentication logic to a 'getPaypalToken(){}' function
so we are looking at one thing at a time
Avatar
Masai LionOP
alr, give me a sec
done.
json request is not well formed…
Avatar
I need to see your json then. log out 'order'
and put it here if yourable to
cause its something in your order your sending over that is causing the issue.
something it doesnt like, I cant diagnose without seeing
Avatar
Masai LionOP
Wait
Maybe it’s the products data
idk but might me
Be*
Avatar
I have no idea, lol
Avatar
Masai LionOP
I think I am not passing any info from the cart
Let me log the data and lets see
Avatar
Did you log it out and see?
Yeah, always log, when troubleshooting. Every step of the way
Image
Heres and example of a valid request to the endpoint
Obviously it generic, so you will have to make sure you have those fields
Avatar
Masai LionOP
{"intent":"CAPTURE","purchase_units":[{"items":[{"name":"product1","category":"PHYSICAL_GOODS","quantity":2,"unit_amount":{"currency_code":"USD","value":"150"}}]}],"amount":[{"currency_code":"USD","value":"450","breakdown":{"item_total":{"currency_code":"USD","value":"300"},"shipping":{"currency_code":"USD","value":"150"},"handling":{"currency_code":"USD","value":"0.00"},"tax_total":{"currency_code":"USD","value":"0.00"},"shipping_discount":{"currency_code":"USD","value":"0.00"},"insurance":{"currency_code":"USD","value":"0.00"},"discount":{"currency_code":"USD","value":"0.00"}}}],"shipping":{"type":"SHIPPING"},"application_context":{"brand_name":"MY COMPANY","landing_page":"NO_PREFERENCE","user_action":"PAY_NOW"}}
this is what came from console.log(order)
i think i dont have app_context complete
Avatar
Well... I mean.... technically this is the 'minimal' amount of data you could pass lol
{
    "intent": "CAPTURE",
    "purchase_units": [
        {
            "amount": {
                "currency_code": "USD",
                "value": "100.00"
            }
        }
    ]
}
I would legit use that link, paypals api is very thorough and now your not dealing with a nextjs issue more of a proper format issue.
Avatar
Masai LionOP
uhh i pass more than that, think so
Avatar
Yeah I know you do, im just saying thats the 'minimum' I would try just passing that and making sure it works.
Avatar
Masai LionOP
postman takes requests, i prefer to do it on my own app lol
let me try
ig
Avatar
Yes but you can use it for information, postman is doing what your doing just through an interface, its very easy to iterate.
Again, at this point your not facing an issue with nextjs, the issue is with paypal. I need to head to bed here in a minute, so I wont be able to help further.
Avatar
Masai LionOP
oh nws, you helped me a lot!
If you go here, and then on the right hand side you should see a 'node.js' tab
Image
That will get you what you need.
If you feel like this answered your question dont remember to close the post with a solution 🙂
Bigges tthing to note from what code you shared is modularizing your code to handle specific tasks, it will help a great deal in the long run.
Avatar
Masai LionOP
i was basing on that lol
ik thanks for reminding me
Avatar
Night man, take it easy
Avatar
Masai LionOP
same man