What is the structure of Stripe PHP API method response?

10,829

Solution 1

Although Stripe's API returns JSON at the HTTP level (i.e. what is actually being sent over the wire), the Stripe PHP library already handles decoding the JSON response and turning it into a PHP object.

There should be no need to pass the return value from Stripe_Customer::create to json_decode - in fact, given that it's already an object, I don't understand json_decode well enough to understand why that isn't just erroring out.

In any case, you should just interact with the returned customer object directly, e.g. $customer->description or $customer->active_card->cvc_check. You can see this, for example, in the Stripe tutorial.

Solution 2

With Evan's help, I figured out a complete answer to the second question. As Evan stated, the key is to treat the structure returned by the Stripe PHP library as an object. The elements are referenced according to the rules implicit in the JSON structure of the raw method response.

Since I have trouble reading complex JSON, particularly as the indent depth increases, I wrote a script that turns each element of a JSON structure into a complete PHP reference, like $obj->arr[index]->obj2, and so on. At www.helioza.com/decoders/explain-json.php you can paste in a JSON string, like the examples in the Stripe API reference, and get a complete list of PHP code that references each element.

Update 5/27/2014

Looking at the various comments it seems to me that there are several hidden contexts at work here. Most are over my head, so to be clear about what I do and do not know, here is how I interpret the Stripe API documentation.

Look at the example for creating a new customer, PHP code option. The following is part of the API call response.

EXAMPLE RESPONSE
{
  "object": "customer",
  "created": 1401219085,
  "id": "cus_474RjipEtz2ff7",
  "livemode": false,
  "description": "[email protected]",
  "email": null,
  "delinquent": false,
  "metadata": {
  },
  "subscriptions": {
    "object": "list",
    "total_count": 0,
    "has_more": false,
    "url": "/v1/customers/cus_474RjipEtz2ff7/subscriptions",
    "data": [

    ]
  },

Now in my experience, every web API response is an HTTP response. Somewhere the Stripe docs say it is POST. So I look at the response above and I see JSON, which is compatible with HTTP. The doc page does not actually identify the response as JSON or anything else. If this is not JSON, then please identify it and tell me how you know that. Calling it StdClass doesn't help since the PHP manual is quite obtuse on that topic and does not define the structure of the class.

This is really the essence of my original question. What is the nature of the response as Stripe has documented it? Sure looks like JSON delivered via HTTP. I want to be educated.

Yes, I am getting the results I want by treating what the Stripe library returns as an object. But cookbook solutions don't further anyone's knowledge. The most valuable answers on SO are explanatory.

Share:
10,829
Helioza
Author by

Helioza

Web software engineer, internet marketer, publisher. RoHSwell.com

Updated on June 13, 2022

Comments

  • Helioza
    Helioza about 2 years

    I am working on a Stripe integration and I am baffled by the actual responses I get from the PHP API. I started out believing that the API reference was accurate and that the response would be a JSON string as shown for each method. I quickly discovered significant differences. Most often, the id field is missing from the JSON response. Also, the response seems to be a string, an object, and maybe some other structures, all at the same time.

    Here is my debug code. I am using the latest Stripe PHP library, version 1.7.15.

    function var_dump_ret($mixed=null)
    {
      ob_start();
      var_dump($mixed);
      $content=ob_get_contents();
      ob_end_clean();
      return($content);
    }
    
    $token=$_POST['stripeToken'];
    $customer=Stripe_Customer::create(array(
      "card"=>$token,
      "plan"=>"agency")
    );
    
    $custVarDump=var_dump_ret($customer);
    $cDecoded=json_decode($customer);
    $Debug="Invidual attributes of JSON decoded customer object:"._EOL;
    $Debug.="object:".$cDecoded->object._EOL;
    $Debug.="created:".$cDecoded->created._EOL;
    $Debug.="id:".$cDecoded->id._EOL;
    $Debug.="livemode:".$cDecoded->livemode._EOL;
    $Debug.="description:".$cDecoded->description._EOL;
    $Debug.="active_card.object:".$cDecoded->active_card->object._EOL;
    $Debug.="active_card.last4:".$cDecoded->active_card->last4._EOL;
    $Debug.="active_card.type:".$cDecoded->active_card->type._EOL;
    $Debug.="active_card.exp_month:".$cDecoded->active_card->exp_month._EOL;
    $Debug.="active_card.exp_year:".$cDecoded->active_card->exp_year._EOL;
    $Debug.="active_card.fingerprint:".$cDecoded->active_card->fingerprint._EOL;
    $Debug.="active_card.country:".$cDecoded->active_card->country._EOL;
    $Debug.="active_card.name:".$cDecoded->active_card->name._EOL;
    $Debug.="active_card.address_line1:".$cDecoded->active_card->address_line1._EOL;
    $Debug.="active_card.address_line2:".$cDecoded->active_card->address_line2._EOL;
    $Debug.="active_card.address_city:".$cDecoded->active_card->address_city._EOL;
    $Debug.="active_card.address_state:".$cDecoded->active_card->address_state._EOL;
    $Debug.="active_card.address_zip:".$cDecoded->active_card->address_zip._EOL;
    $Debug.="active_card.address_country:".$cDecoded->active_card->address_country._EOL;
    $Debug.="active_card.cvc_check:".$cDecoded->active_card->cvc_check._EOL;
    $Debug.="active_card.address_line1_check:".$cDecoded->active_card->address_line1_check._EOL;
    $Debug.="active_card.address_zip_check:".$cDecoded->active_card->address_zip_check._EOL;
    $Debug.="email:".$cDecoded->email._EOL;
    $Debug.="delinquent:".$cDecoded->delinquent._EOL;
    //$Debug.="subscription:".$cDecoded->subscription._EOL;
    $Debug.="discount:".$cDecoded->discount._EOL;
    $Debug.="account_balance:".$cDecoded->account_balance._EOL;
    $Debug.="unaltered response from Stripe_Customer::create:"._EOL.$customer._EOL.
        "var dump of response:"._EOL.$custVarDump._EOL.
        "print_r of json_decode of response:"._EOL.print_r($cDecoded,true)._EOL;
    
    file_put_contents(_LOGFILE,$Debug,FILE_APPEND);
    

    Below are the contents of my debug file for the invidual attributes of the JSON decoded customer object. When executed, the code posted a notice.

    Notice: Undefined property: stdClass::$id in stripe/subscription.php on line 51

    Also note that I had to comment out the line that added 'subscription' to the debug string due to a fatal error regarding stdClass.

    object:customer
    created:1365951909
    id:
    livemode:
    description:
    active_card.object:card
    active_card.last4:4242
    active_card.type:Visa
    active_card.exp_month:7
    active_card.exp_year:2013
    active_card.fingerprint:WTXPLgKDCXyp9xpD
    active_card.country:US
    active_card.name:charlie
    active_card.address_line1:
    active_card.address_line2:
    active_card.address_city:
    active_card.address_state:
    active_card.address_zip:
    active_card.address_country:
    active_card.cvc_check:pass
    active_card.address_line1_check:
    active_card.address_zip_check:
    email:
    delinquent:
    discount:
    account_balance:0
    

    Most notably absent is the customer ID. It does not exist in the JSON response. However, as seen in some of the Stripe example programs, it can be accessed using $customer->id. Furthermore, the var_dump output indicates even more atributes are present in a structure I cannot figure out. The entire debug file is at http://www.helioza.com/stripe/debug.txt. I have only shown the customer create method, but I am experiencing similar problems with invoices and cannot find the invoice id anywhere in the Stripe_Invoice::all or Stripe_Invoice::upcoming responses.

    Questions

    1) How can the value returned by Stripe_Customer::create be both a string and an object at the same time?

    2) Where can I find documentation that describes the API method return values, including how to access each attribute?

  • Helioza
    Helioza about 11 years
    Thanks Evan. That helps with some of my puzzle. I still don't understand why I can echo the object and get valid text out. Normally, PHP just reports 'object' and refuses to echo anything else. I'm also still struggling to figure out the structure of the response. Trial and error takes a long time. It sure would be helpful if there were a document of the return structure for each method.
  • Madbreaks
    Madbreaks about 11 years
    You should not be looking at JSON at all - Stripe's PHP SDK guarantees you're working with PHP stdClass objects, plain and simple. I would suggest accepting the answer posted by @EvanBroder.
  • Helioza
    Helioza about 11 years
    Basically, I am looking at JSON because that is what is available in the Stripe API reference to document the return parameters. If you (@Madbreaks) know of a better reference, please post a link to it.
  • Charlie Schliesser
    Charlie Schliesser over 10 years
    All of the object's properties are protected which is why you're not seeing them. The PHP SDK actually implements the ArrayAccess PHP interface which allows you to access the needed data via $response['some_key'], where the keys are all of the options listed at stripe.com/docs/api?lang=php#charges. It's pretty easy that way.
  • David Meister
    David Meister about 10 years
    @Madbreaks This is not true. The Stripe PHP SDK does not use StdClass objects, it has its own Stripe_Customer class. Try adding a new property to a Stripe_Customer object and you'll get fatal errors, which is not something StdClass objects do.
  • Madbreaks
    Madbreaks about 10 years
    @DavidMeister Stripe may very well reconstitute the JSON into its own classes, however it's irrelevant. Those classes provide access to the data op is trying to get at, there's no reason to be examining the JSON directly.