0

I have this json:

{"id":"***hidden***","event_version":"1.0","create_time":"2020-07-28T04:09:33.415Z","resource_type":"checkout-order","resource_version":"2.0","event_type":"CHECKOUT.ORDER.APPROVED","summary":"An order has been approved by buyer","resource":{"update_time":"2020-07-28T04:09:05Z","create_time":"2020-07-28T04:08:53Z","purchase_units":[{"reference_id":"default","amount":{"currency_code":"CAD","value":"50.00"},"payee":{"email_address":"***hidden**","merchant_id":"***hidden***"},"custom_id":"THISVALUEIWANT","shipping":{"name":{"full_name":"John Doe"},"address":{"address_line_1":"1 Maire-Victorin","admin_area_2":"Toronto","admin_area_1":"ON","postal_code":"M5A 1E1","country_code":"CA"}},"payments":{"captures":[{"id":"***hidden***","status":"COMPLETED","amount":{"currency_code":"CAD","value":"50.00"},"final_capture":true,"seller_protection":{"status":"ELIGIBLE","dispute_categories":["ITEM_NOT_RECEIVED","UNAUTHORIZED_TRANSACTION"]},"seller_receivable_breakdown":{"gross_amount":{"currency_code":"CAD","value":"50.00"},"paypal_fee":{"currency_code":"CAD","value":"1.75"},"net_amount":{"currency_code":"CAD","value":"48.25"}},"links":[{"href":"https://api.sandbox.paypal.com/v2/payments/captures/something","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v2/payments/captures/something/refund","rel":"refund","method":"POST"},{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/something","rel":"up","method":"GET"}],"create_time":"2020-07-28T04:09:05Z","update_time":"2020-07-28T04:09:05Z"}]}}],"links":[{"href":"https://api.sandbox.paypal.com/v2/checkout/orders/something","rel":"self","method":"GET"}],"id":"something","intent":"CAPTURE","payer":{"name":{"given_name":"John","surname":"Doe"},"email_address":"sb-***hidden","payer_id":"something","address":{"country_code":"CA"}},"status":"COMPLETED"},"links":[{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something/resend","rel":"resend","method":"POST"}]}';

If i breakdown the structure, it goes like this:

{
"id":"***hidden***",
"event_version":"1.0",
"create_time":"2020-07-28T04:09:33.415Z",
"resource_type":"checkout-order",
"resource_version":"2.0",
"event_type":"CHECKOUT.ORDER.APPROVED",
"summary":"An order has been approved by buyer",
"resource":{
    "update_time":"2020-07-28T04:09:05Z",
    "create_time":"2020-07-28T04:08:53Z",
    "purchase_units":[{
        "reference_id":"default",
        "amount":{
            "currency_code":"CAD",
            "value":"50.00"
        },
        "payee":{
            "email_address":"***hidden***",
            "merchant_id":"***hidden***"},
            "custom_id":"THISISTHEVALUEIWANT",
...

I'd like to extract and store the value of custom_id in a php variable. Problem is I struggle in finding the way to extract this specific item which is, to my understanding, an object, within an array, within an object...

I've tried multiple combinations, I tried foreach loops, nothing worked so far.

The only thing that actually kind of worked is this:

$json = json_decode($jsonobj, true); // json is stored in $jsonobj variable

foreach($json as $elem)  {
   foreach ($elem['purchase_units'] as $item ) {
      echo $item['custom_id'];
   }
}

Which lets me get the value I want, but at the same time it throws me a whole bunch of E_WARNING type 2 error:

Invalid argument supplied for foreach()...

Illegal string offset 'purchase_units'...

Can you tell my how I could reach this specific value without flooding my php error log?

Thank you very much!

9
  • Do you want to retrieve it dynamically ? Because knowing the structure of the JSON which could stay the same, you can simply access it directly... Or there has something in particular you should take in condiration ? Commented Jul 29, 2020 at 2:29
  • Actually I am not sure @Hepson .. I can't tell you if this json structure will stay the same in the future. But for now, I just want to get this value. I tried accessing it directly with $json['item_3'] but it throws me an undefined index error. Also, why the downvote if I may ask? Commented Jul 29, 2020 at 3:02
  • 1
    While continuing to test everything that comes to my mind, I managed to reach item_1 value with simply: $json['item_B']['array_A'][0]['item_1']. But if I try $json['item_B']['array_A'][0]['item_2']['item_3'], I get an undefined index error. Commented Jul 29, 2020 at 3:17
  • Don't know exacly why the downvote... With your sample, i could acces the "item_3" value with $json['item_B']['array_A'][0]['item_2']['item_3'] that you've mention too. Which should be the most fragile but the easiest way. Commented Jul 29, 2020 at 3:26
  • This below gives the expected result, but if you didn't get it, something else is interfering... $jsonobj = '{"item_A": "Value A", "item_B": {"item_C": "Value C", "item_D": "Value D", "array_A": [{ "item_1": "Value 1", "item_2": { "item_3": "Value 3" } }] } }'; $json = json_decode($jsonobj, true); var_dump($json['item_B']['array_A'][0]['item_2']['item_3']); Commented Jul 29, 2020 at 3:32

1 Answer 1

2

The following should work for you. I have had to deal with a complexe object structure like this and managed to do it quite simply.

First of all, it's important to note that the original JSON you have provided does not match the formatted sample you have built based on the original. More specifically, the custom_id is not inside of payee. Instead, it's at the same level as payee. It goes like this ...

...
"purchase_units": [
  {
    "reference_id": "default",
    "amount": {
      "currency_code": "CAD",
      "value": "50.00"
    },
    "payee": {
      "email_address": "***hidden**",
      "merchant_id": "***hidden***"
    },
    "custom_id": "THISVALUEIWANT",  <--- This is what you need
    "shipping": { ...

The solution I am providing will be based on the original JSON.

<?php
$json = <<<JSON
{
  "id": "***hidden***",
  "event_version": "1.0",
  "create_time": "2020-07-28T04:09:33.415Z",
  "resource_type": "checkout-order",
  "resource_version": "2.0",
  "event_type": "CHECKOUT.ORDER.APPROVED",
  "summary": "An order has been approved by buyer",
  "resource": {
    "update_time": "2020-07-28T04:09:05Z",
    "create_time": "2020-07-28T04:08:53Z",
    "purchase_units": [
      {
        "reference_id": "default",
        "amount": {
          "currency_code": "CAD",
          "value": "50.00"
        },
        "payee": {
          "email_address": "***hidden**",
          "merchant_id": "***hidden***"
        },
        "custom_id": "THISVALUEIWANT",
        "shipping": {
          "name": {
            "full_name": "John Doe"
          },
          "address": {
            "address_line_1": "1 Maire-Victorin",
            "admin_area_2": "Toronto",
            "admin_area_1": "ON",
            "postal_code": "M5A 1E1",
            "country_code": "CA"
          }
        },
        "payments": {
          "captures": [
            {
              "id": "***hidden***",
              "status": "COMPLETED",
              "amount": {
                "currency_code": "CAD",
                "value": "50.00"
              },
              "final_capture": true,
              "seller_protection": {
                "status": "ELIGIBLE",
                "dispute_categories": [
                  "ITEM_NOT_RECEIVED",
                  "UNAUTHORIZED_TRANSACTION"
                ]
              },
              "seller_receivable_breakdown": {
                "gross_amount": {
                  "currency_code": "CAD",
                  "value": "50.00"
                },
                "paypal_fee": {
                  "currency_code": "CAD",
                  "value": "1.75"
                },
                "net_amount": {
                  "currency_code": "CAD",
                  "value": "48.25"
                }
              },
              "links": [
                {
                  "href": "https://api.sandbox.paypal.com/v2/payments/captures/something",
                  "rel": "self",
                  "method": "GET"
                },
                {
                  "href": "https://api.sandbox.paypal.com/v2/payments/captures/something/refund",
                  "rel": "refund",
                  "method": "POST"
                },
                {
                  "href": "https://api.sandbox.paypal.com/v2/checkout/orders/something",
                  "rel": "up",
                  "method": "GET"
                }
              ],
              "create_time": "2020-07-28T04:09:05Z",
              "update_time": "2020-07-28T04:09:05Z"
            }
          ]
        }
      }
    ],
    "links": [
      {
        "href": "https://api.sandbox.paypal.com/v2/checkout/orders/something",
        "rel": "self",
        "method": "GET"
      }
    ],
    "id": "something",
    "intent": "CAPTURE",
    "payer": {
      "name": {
        "given_name": "John",
        "surname": "Doe"
      },
      "email_address": "sb-***hidden",
      "payer_id": "something",
      "address": {
        "country_code": "CA"
      }
    },
    "status": "COMPLETED"
  },
  "links": [
    {
      "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something",
      "rel": "self",
      "method": "GET"
    },
    {
      "href": "https://api.sandbox.paypal.com/v1/notifications/webhooks-events/something/resend",
      "rel": "resend",
      "method": "POST"
    }
  ]
}
JSON;

$object = json_decode($json);

$purchase_units = $object->resource->purchase_units ?? [];
$custom_ids = array_column($purchase_units, 'custom_id');

print_r($custom_ids);

The output will be:

Array
(
    [0] => THISVALUEIWANT
)

Now a little explanation. After decoding the JSON object, I go straight for the property I need using $purchase_units = $object->resource->purchase_units ?? [];

The null coalesce operator will allow defaulting the $purchase_units variable to an empty array if anything in $object->resource->purchase_units is not present.

The array_column function allows extracting a specific column or property from all the items contained in an array. You can read more about it at https://www.php.net/manual/en/function.array-column.php

Sign up to request clarification or add additional context in comments.

3 Comments

It seems I never saw that curly closing bracket after merchant_id @asiby..... I'm so sorry about that. Thanks very much :)
No need to be sorry. We are all humans. I am just glad I could help.
And also many thanks for the extra info and documentation provided in your answer @asiby :) These kind of answers truly worth gold!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.