[paypal] can't pass the json to php

Hi guys!

I am integrating the PayPal into my own system. after I installed the smart payment button, I found I can’t pass the complete payment result to my PHP server.

my code is:

<script>
var turtle_id = document.getElementById("turtle_id");
console.log(turtle_id.value);
paypal.Buttons({
createOrder: function(data, actions) {
// This function sets up the details of the transaction, including the amount and line item details.
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01'
}
}]
});
},
onApprove: function(data, actions) {
var capture_data = actions.order.capture();

var xhr = new XMLHttpRequest();

xhr.open('POST', "https://192.168.0.100/haigui/order_consultation/" + turtle_id.value, true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.onload = function () {
console.log(this.responseText);
};
**console.log(capture_data); //OK**
**xhr.send(JSON.stringify(capture_data));**

}
}).render('#paypal-button-container');
//This function displays Smart Payment Buttons on your web page.
</script>

above code only can post a JSON like this:

{resolved: false, rejected: false, errorHandled: false, handlers: []}

but, before the line of ‘xhr.send(JSON.stringify(capture_data));’,

I can console.log a complete JSON via 'console.log(capture_data); ’ like this:

n {resolved: false, rejected: false, errorHandled: false, value: undefined, error: undefined, …}dispatching: falseerror: undefinederrorHandled: falsehandlers: []rejected: falseresolved: truestack: undefinedvalue: {create_time: "2020-07-25T08:23:35Z", update_time: "2020-07-25T08:24:23Z", id: "0YM27746DT8358617", intent: "CAPTURE", status: "COMPLETED", …}__proto__: Object

Why I couldn’t pass a complete JSON through ‘xhr.send(JSON.stringify(capture_data));’?

I also tried ‘xhr.send(capture_data);’, but I only got request payload [object object]

Hi @zhuceyouxiang88, you mean the create_time entries etc.? Some properties may have been defined as non-enumerable, in which case they won’t be included in the JSON (or any iteration over the object’s properties). What do you get when you log the property descriptors of capture_data?

console.log(Object.getOwnPropertyDescriptors(capture_data))

Hi m3g4p0p

console.log(Object.getOwnPropertyDescriptors(capture_data))

I got a json:

  1. {resolved: {…}, rejected: {…}, errorHandled: {…}, value: {…}, error: {…}, …}

  2. dispatching: {value: undefined, writable: true, enumerable: true, configurable: true}

  3. error: {value: undefined, writable: true, enumerable: true, configurable: true}

  4. errorHandled: {value: false, writable: true, enumerable: true, configurable: true}

  5. handlers: {value: Array(0), writable: true, enumerable: true, configurable: true}

  6. rejected: {value: false, writable: true, enumerable: true, configurable: true}

  7. resolved: {value: false, writable: true, enumerable: true, configurable: true}

  8. stack: {value: undefined, writable: true, enumerable: true, configurable: true}

  9. value: {value: undefined, writable: true, enumerable: true, configurable: true}

  10. proto: Object

its value is :

  1. value:

  2. configurable: true

  3. enumerable: true

  4. value: undefined

  5. writable: true

  6. proto: Object

my problem is, after ‘xhr.send(capture_data);’ I can only pass a Form data : [object object],
I get to pass a complete json that includes a value like this:

Hm okay, enumerability is not the issue then. The screenshot does not match the logs you posted though, where value is indeed undefined – are you sure this property is already set by the time you’re stringify()ing it? When just logging the object to the console, this will not give you a frozen “snapshot” but also reflect later updates; so maybe try setting a breakpoint instead to inspect the state of the object at that very point.

The screenshot does not match the logs you posted

The screenshot was the result of 'console.log(capture_data); ', but after that, I can’t send this result to my php via ‘xhr.send(capture_data);’ it only displayed a Form data : [object object] on my F12 header.

In other words:

console.log(capture_data); // OK, it can print out the value that I need.
xhr.send(capture_data); //only pass a Form data : [object object] to my php.

My problem is, how to send the result of ‘console.log(capture_data);’ to my php via ‘xhr.end()’.

You need to JSON.stringify() the data when send()ing it, otherwise you’ll just send the string representation which is indeed [object Object]:

var body = JSON.stringify(capture_data)
xhr.send(body)

var body = JSON.stringify(capture_data)
xhr.send(body)

I tried your code, but I got a json:

{resolved: false, rejected: false, errorHandled: false, handlers: }

There isn’t the “value” that I need.

Well according to your logs value is undefined, so it will be omitted. If desired, you might still include it as null or something using the replacer parameter:

function nullifyUndefined (key, value) {
  if (value === undefined) {
    return null
  }

  return value
}

var body = JSON.stringify(capture_data, nullifyUndefined)

according to your logs value is undefined ,

Sorry, if the value is undefined?
Why I can print out it with ‘console.log(capture_data);’?

image

In your previous post’s screenshot value was undefined, now there’s some data but I can’t see the request payload… so it’s hard to tell really. Did you try setting a breakpoint on the line where you are send()ing the request?

Did you try setting a breakpoint on the line where you are send() ing the request?

Yes, I did. I think you are right, the ‘console.log(capture_data);’’ printed out a "value : undefined ".

My purpose is sending a json or array that includes the ‘value’ to my php. So, based on the paypaI ducument, I changed my code to

  paypal.Buttons({
    createOrder: function(data, actions) {
      // This function sets up the details of the transaction, including the amount and line item details.
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    },
    onApprove: function(data, actions) {
      // This function captures the funds from the transaction.
      return actions.order.capture().then(function(details) {
        // This function shows a transaction success message to your buyer.
        alert('Transaction completed by ' + details.payer.name.given_name);
      });
    }
  }).render('#paypal-button-container');
  //This function displays Smart Payment Buttons on your web page.

above code gave me a response data that I need as below:

{"ack":"success","data":{"create_time":"2020-07-26T15:22:40Z","update_time":"2020-07-26T15:29:02Z","id":"3YD49222L52628232","intent":"CAPTURE","status":"COMPLETED","payer":{"email_address":"zhuceyouxiang88@gmail.com","payer_id":"HK75Y66E983QE","address":{"country_code":"C2"},"name":{"given_name":"George","surname":"Lu"}},"purchase_units":[{"reference_id":"default","soft_descriptor":"PAYPAL *SBJ2W892681","amount":{"value":"0.01","currency_code":"USD"},"payee":{"email_address":"sb-j2w892681547@personal.example.com","merchant_id":"V9NXXM9569C3W"},"shipping":{"name":{"full_name":"Lu George"},"address":{"address_line_1":"yunlong district","admin_area_2":"xuzhou","admin_area_1":"JIANGSU","postal_code":"221000","country_code":"C2"}},"payments":{"captures":[{"status":"COMPLETED","id":"0AW08492WM610151X","final_capture":true,"create_time":"2020-07-26T15:29:02Z","update_time":"2020-07-26T15:29:02Z","amount":{"value":"0.01","currency_code":"USD"},"seller_protection":{"status":"ELIGIBLE","dispute_categories":["ITEM_NOT_RECEIVED","UNAUTHORIZED_TRANSACTION"]},"links":[{"href":"https://api.sandbox.paypal.com/v2/payments/captures/0AW08492WM610151X","rel":"self","method":"GET","title":"GET"},{"href":"https://api.sandbox.paypal.com/v2/payments/captures/0AW08492WM610151X/refund","rel":"refund","method":"POST","title":"POST"},{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/3YD49222L52628232","rel":"up","method":"GET","title":"GET"}]}]}}],"links":[{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/3YD49222L52628232","rel":"self","method":"GET","title":"GET"}]},"meta":{"calc":"14188856e67a0","rlog":"rZJvnqaaQhLn%2FnmWT8cSUueWscmrtUHe5Y1Bd%2FeqyvyOTq66rSXAcoHt23K4aX7r7RV0T%2BAtZVLHG%2FvY24WQLvGzbxfzUt6q%2FVJmM6qn12U_1738bbdd811"},"server":"OvGWtaorw5pAvXLG2PRA1wMcbQNjSuEgqHmhKkvL4XUUeZcVf-kDeqezxAiz6rSCoVT42OJfYcajSeW_m4Y0OQBhMlEDwH_E2JV76-TZOY6pD6GdoCMkL9H5uLTBekjn0xXaQsi3uZ8X4nmDsG-5GHUSqDQ5h4nrQmpZcPmyxez7feDsJJSJ346ym6ADcBnRg7D9avM75gyd1Bw6U1bKKolhDtZMGrAswM1PEqgG8q9wW8kOSOvTlgFUY029Bjr10mIOGWGbsJPF3EIg62v7x0"}

But, could you please tell me how to send above data to my php?

Ah okay if capture() returns a promise that resolves with the desired data, you can send the request from there:

return actions.order.capture().then(function (details) {
  var xhr = new XMLHttpRequest()

  // Wait for the request to complete before 
  // displaying the success message
  xhr.onload = function () {
    alert('Success!')
  }

  xhr.open('POST', 'https://192.168.0.100/haigui/order_consultation/' + turtle_id.value)
  xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
  xhr.send(JSON.stringify(details))
})

I’m not familiar with the paypal API myself, but if it internally needs to wait for your request to complete as well you might chain another promise like so:

return actions.order.capture().then(function (details) {
  var xhr = new XMLHttpRequest()

  xhr.open('POST', 'https://192.168.0.100/haigui/order_consultation/' + turtle_id.value)
  xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
  xhr.send(JSON.stringify(details))

  return new Promise(function (resolve, reject) {
    xhr.onload = resolve
    xhr.onerror = reject
  })
})

Thank you so much!
It worked for me!

1 Like

Glad I could help. :-)

Naive question m3g4p0p, but is there a good reason to use XMLHttpRequest() over fetch?

Only if you need to support IE, which does not implement the fetch API… but then again you might also include a polyfill if need be. So personally I’d go with fetch if possible, and being promise based by default it would also work well with the paypal API.

1 Like

Thanks a lot.

1 Like

Here are a number of fetch polyfills, if you want to use one of them to provide IE support.

1 Like