1👍
Since you’re code seems to be doing many uneccessary / inadvisable things, I’ll explain a normal integration baseds on the sample in the standard checkout integration guide.
// Order is created on the server and the order id is returned
createOrder() {
return fetch("/my-server/create-paypal-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
// use the "body" param to optionally pass additional order information
// like product skus and quantities
body: JSON.stringify({
cart: [
{
sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",
quantity: "YOUR_PRODUCT_QUANTITY",
},
],
}),
})
.then((response) => response.json())
.then((order) => order.id);
},
In this sample, a cart object containing an array of items and quantities (note: never $ amounts) is posted to the server when the createOrder callback is called. This occurs when a button is clicked.
The server then takes that information and uses it to create a PayPal order, using the v2/checkout/orders API.
The server then returns the v2/checkout/orders object, or a subset of it. The returned information must include the id
of the order, so that the PayPal JS can use it for the checkout. If for whatever reason a valid id
is not returned, the error in your question is the expected behavior.
Next the user proceeds with approving a payment, using whichever button they clicked on / payment method they selected. They select a shipping address during this process, very often whatever the default one is in their PayPal account.
Once final approval is given at PayPal, clicking a "Pay Now" button or equivalent, the onApprove
callback is called.
A second fetch is done to your server to capture the order. The selected shipping address is returned in the capture response, among other details.
The above flow can be adjusted if you have specific needs, but it is important to understand the default flow first and how it can best be adjusted. For example, it is possible to use user_action:'CONTINUE'
and add an order review step, retrieve selected shipping information before capture, and patch the order before capture, all of which generally result in a superior and smoother checkout than possible alternatives.
For instance, adding extra steps to collect a shipping address with your own fields, which add friction and slow the process and also still allow (by default) a payer to change that address at PayPal which is probably not what you would want if collecting your own address, although forcing the use of the address you collected would block the checkout with an error if that address is not valid for whatever reason — which (in addition to adding friction and lowering sales) is part of why this example alternative of collecting a an address with your own fields is not a good one and generally bad design.