Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
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?
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.
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": "payinguser#example.com",
"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.
Related
I've read many 'possible duplicates' of this question and have used the code from one of them in this post but I cannot seem to see exactly what this question is asking.
As part of a much bigger project unrelated to PHP or websites I need to obtain the body of a POST request to my shared server.
Following the ideas from this SO post I have made a php file in the www folder on the server containing the following
webhook.php
<?php
error_log("webhook running");
file_put_contents("post.log", print_r($_POST, true));
?>
I then used a third party company to POST a test message to that script on my server, which was received OK, with a 200 response.
The body of that post contained
Body
{
"events": [
{
"id": "EVTESTDCQAHTYRDYM72",
"created_at": "2021-01-04T12:17:41.536Z",
"resource_type": "payments",
"action": "paid_out",
"links": {
"payment": "index_ID_1234567"
},
"details": {
"origin": "mycompanys",
"cause": "payment_paid_out",
"description": "The payment has been paid out by mycompany."
},
"metadata": {}
}
]
}
but the log file on my server contains only
Array
(
)
I'm not a PHP programmer (just do the minimum I need to in order to get the job done)
For debugging and development purposes, how should I alter my webhook.php script so that I can see all the data that was sent?
If I can do that then I can probably work out how do do the proper processing on each element, which won't always have the structure above.
PHP only populates $_POST, when the request Content-Type was either application/x-www-form-urlencoded or multipart/form-data. If you get send anything else, then you have to use php://input to read the raw POST body, and parse it yourself.
The example JSON you have shown appears to be valid - so if json_decode does not give you the expected result here, then your input data was probably not what you expected it to be in the first place.
A basic debugging mistake here is that you are only looking at the final result of multiple “compound” operations. Log what file_get_contents('php://input') returned first of all, to see if that actually is what you expected it to be. If it wasn’t to begin with, then looking only at what json_decode returned, isn’t that helpful.
Stack Overflow is full with questions like this, I'm aware of that. But none of the questions and accepted answers have solved it for me.
I'm getting a SOAP response like this:
string(402482) "ZSDSD1BKA00_DE_02DE00010000001083212550JVBERi0xLjUNJeLjz9MNCjExNCAwIG9iag08PC9MaW5lYXJpemVkIDEvTCAxMDgzMjEvTyAxMTYv RSAxODY2Mi9OIDEyL1QgMTA3Nzk3L0ggWyA1MDMgMjc2XT4+DWVuZG9iag0gICAgICAgICAgICAg DQoxMzQgMCBvYmoNPDwvRGVjb2RlUGFybXM8PC9Db2x1bW5zIDQvUHJlZGljdG9yIDEyPj4vRmls dGVyL0ZsYXRlRGVjb2RlL0lEWzwxREZGRkVGMUM4Q0E0NTI4QjBBMUYxOUEyNTMwREQ2OD48RURD QTlGRDBFNTE4N0M0N0JGRUZCOEM0MjlCRTUwMjE+XS9JbmRleFsxMTQgMzZdL0luZm8gMTEzIDAg Ui9MZW5ndGggOTMvUHJldiAxMDc3OTgvUm9vdCAxMTUgMCBSL1NpemUgMTUwL1R5cGUvWFJlZi9X WzEgMiAxXT4+c3RyZWFtDQpo3mJiZBBgYGJg/g0kGEKABONRIMHiCiSYNEASK0DEG5AEP4i4CZKI ABHiQEJIDyTWDiL+AwmuVhCLDaTDCsQtBHHZgcReIMHIwAiyg4GRIuI/Y9NngAADAOlxDEINCmVu ZHN0cmVhbQ1lbmRvYmoNc3RhcnR4cmVmDQowDQolJUVPRg0KICAgICAgICAgDQoxNDkgMCBvYmoN PDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0kgMjE3L0wgMjAxL0xlbmd0aCAxODcvUyAxNDM+PnN0cmVh bQ0KaN5iYGBgZmBg8mZgZWDg38PAx4AAfEAZVgYWBo6qZQyMDAwCDNf1/NQ/HVzCrMDAO79pAssO rrZJjgW7zB7nbQCqZvMMlpJUbfRmmsaqwzPpwFIQCyjGNI2BvaIBhBoqgIipAkyzAzFW04AG+TMw TgYZKATEwmCHtDPwMn543+ykJGjUpMDleJGnJfMAA3vLf8Y/YRmvWBhtGksgDg5gYJzyEUgDHcvQ A8TBDIxLGCF8RlGAAAMA2bs1zA0KZW5kc3RyZWFtDWVuZG9iag0xMTUgMCBvYmoNPDwvTWV0YWRh dGEgODEgMCBSL1BhZ2VMYWJlbHMgMTA4IDAgUi9QYWdlcyAxMTAgMCBSL1R5cGUvQ2F0YWxvZz4+ DWVuZG9iag0xMTYgMCBvYmoNPDwvQ29udGVudHNbMTE4IDAgUiAxMTkgMCBSIDEyMCAwIFIgMTIx IDAgUiAxMjIgMCBSIDEyMyAwIFIgMTI0IDAgUiAxMjcgMCBSXS9Dcm9wQm94WzAgMCA1OTUuMjIg ODQyXS9NZWRpYUJveFswIDAgNTk1LjIyIDg0Ml0vUGFyZW50IDExMSAwIFIvUmVzb3VyY2VzIDEz NSAwIFIvUm90YXRlIDAvVHlwZS9QYWdlPj4NZW5kb2JqDTExNyAwIG9iag08PC9GaWx0ZXIvRmxh dGVEZWNvZGUvRmlyc3QgMTE3L0xlbmd0aCA5OTUvTiAxNC9UeXBlL09ialN0bT4+c3RyZWFtDQpo 3rxX227bOBD9FT5uHxxeJFISUBhw3LproEmDStgWCPyg2lxHC10MWUHTv+8MKcqSYze+AAuC4MyQ HB6O5owk7knCCPcUETKCMSAiCGEMicdwjIinYPQZkZGEkZMogHW+IJxHOOHBIg8Fn3CJW31JhCfB 7BufaAmI53m4C7xKML9/T6dVXtXxJl1qVLbKQGDkK8ihgQHyeEw/vjSf4iZtcNWnmBtgdmZWlQ0Y k4QzAw/3Jokw0KzsG1BWVgaOlUMDxHp5qKtlrJtH+vBhRhP90tB5ka71dEG/f/nxn17iEfMCzhXS 7J4XSkIYhOo08CyiTgsAIXeaQryi0wRGyp47Hj/S+XR6m271CvYbNAswlSv9ghYbCyJ89GfutgAg Xx7Iv2m+1SDcEU7jSavGd4TdMEGTXxu9ixitNnZ+PIa9k+1Slw0JI06n6eZvna2fGsIZY/SDtlMj wRWd5el6SzzfhPf2tnp5HEl4/iOPQWLAatwSLMzsLC2y/NdfSVboLbnXP8nXqkjLd2buPi00NTMw YewP8V1ipuKm1s3yid5XdZHmxvTNovEBzLxJ82w5Kde5JozGjS7+IWF7M1yKYOts01Q1/d67hLki RhPXHDj4Y7msVlm5pt+yclJus06fZfW2mT6lNfHE3gEm+fHZfU7bJVwIGj//aBBMUj9rg6qDBr5X
... but much longer.
Then I use simplexml_load_string to convert it, resulting in an apparently empty object. Now I've learned that this object is not empty though. print_r and var_dump are of no help and I used simplexml_tree.php for help. But I'm now stuck on how I can access a property within the result. I tried a bunch of different variations, most of them left me either a blank page, or an error 500.
This is the response I expect:
Trying to access property ORBLK, like I wrote, with many variations, has not been successful. Thats my current try (resulting a blank page):
$resultRow = (string)$xml->children('soap-env', true)->Body->children('n0', true)->Z_SDB_GET_SDB_FOR_MATERIALResponse->T_SDB->item->DOKAR;
How would I be able to access the property ORBLK?
I'm currently using the "Isitup" slack slash command example authored by David McCreath (more here": https://github.com/mccreath/isitup-for-slack/blob/master/isitup.php).
Within this code, I am wondering how I would go about making the response go from appearing "only to me" to posting in to the entire channel, along with the query posted by the user. I've read the slack documentation which shows the "in_channel" parameter that needs to be added, however I am just not that strong with code so I'm really not sure where I should input this in to the code I've got.
I'm sure this is a simple fix - can someone provide assistance? I've searched everywhere and can't seem to find a comprehensive answer.
As you correctly mentioned the trick is to reply to Slack by setting the property response_type to in_channel.
The current code (as per your github link) is replaying to Slack with a simple plain text in the following line:
echo $reply;
In order to set the response_type property it needs to reply with a JSON array instead that should look like this:
{
"response_type": "in_channel",
"text": "It's 80 degrees right now."
}
All you need to do is build a PHP array with those two properties, convert it to JSON with json_encode() and send it back to Slack instead of the plain text.
I created a database customers.txt where are saved all my created customers in Stripe. Now I want to list all the customers. This is my code in php for listing customers.
$e= \Stripe\Customer::all(array(
'limit' => 3
));
echo $e;
}
But the output is weird:
IMAGE:
Can someone help me to list the customers?
Now I have got my JSON and run this:
$e=\Stripe\Customer::all(array(
"limit"=>10
));
$customers=json_decode($e,true);
var_dump($customers);
I get just NULL response!
That output is not wyrd, it's a Stripe JSON string. standing for Javascript Object Notation (website).
There's a lot of questions on Stackoverflow about JSON so ask things such as How to convert JSON string into a PHP array.
Also Stripes own documentation (which is very good), states:
JSON is returned by all API responses, including errors, although our API libraries convert responses to appropriate language-specific objects.
from the Stripe Documentation
Edit:
You can read A useful question about turning a JSON string into an object and vice versa
So now you know what JSON is
Using it to get a PHP customer object. (revised)
$e // customer JSON of all customers.
$customers = $e->__toArray(true);
//$customers = json_decode($e);
And then process the array $customers as you need to in your applicaton.
NOTE:
The value of $customers or $customersArray will be an Object or a String data type so you need to treat the appropriately, and they will not display with echo because echo is a string output function, so you need to use print_r() or var_dump() to display these values -in their raw form- on the screen.
EDIT TWO
Recommended that from your screenshot that you format the API response from Stripe into an Array of Objects. This can be done by following this Stack Overflow Answer here.
Please review my revised code above.
I've been looking around at similar topics on REST APIs but I am still having some confusion in my project, mostly with the PHP side of things.
USPS provides a REST API with functions that can be called via URL like this: https://epfws.usps.gov/ws/resources/epf/login
To make any call successfully, I have been told that a JSON object must be created and passed as a "POST parameter" with the expected values.
This is the JSON object that needs to be passed in this case:
obj=
{
"login":"loginExample",
"pword":"passwordExample"
}
I have also been given a PHP class that is supposed to manage these calls. This is the login function:
public function login ()
{
// Set up the parameters for a login attempt
$jsonData = array(
'login' => $this->loginUser,
'pword' => $this->loginPass,
);
// Make a login request
$jsonResponse = $this->pullResource
('/epf/login', 'POST', $jsonData);
return $jsonResponse;
}
So I have a few questions regarding this:
The document they sent says
"To make the request calls, a JSON object will need to be created and passed as a POST form parameter obj={jsonObject} for security reasons using content-type “application/x-www-form-urlencoded”."
I know that the login function contains the correct input values that USPS' REST API is wanting, but I'm not sure how to pass them as "obj", or how to apply the "content-type".
I have a "constant" defined at the top of my PHP script that looks like this:
const EPF_BASE_URL = 'https://epfws.usps.gov/ws/resources';
And I noticed in the actual functions that this part of the link is left out and they simply reference '/epf/login' as you can see above. Since "$this" contains lots of different values I'm wondering how it supposedly finds EPF_BASE_URL as needed. Is it similar to how 'using' directives work in C#?
What is the easiest way to call this function and display the result? This is my biggest question. Would I use a separate PHP class with an HTML form? I understand the concept of what it should do but I'm completely lost setting up a development environment for it.
I've been trying all of this with MAMP but would love to know if I'm on the right track or not.
That really depends on their API. Hopefully you get a string back that can be decoded to a JSON object (http://au.php.net/manual/en/function.json-decode.php). Some API might give a simple string that says 'SUCCESS' or 'FAIL'. You've got the code, so take a look at what $this->pullResponse() gives you.
If you've been given a PHP class that is supposed to support the API (hopefully from USPS), then it should already take care of putting the data in the form content, and ensuring is it submitted with the appropriate content-type.
A PHP const is more like a C# static string. It is very likely that the library will use the constant to create the end URL (i.e. EPF_BASE_URL . $resource). If you needed to run against a sand box environment, you could change that constant without having to change all the other code.
That's a very big question, because it depends on how you are programming your application. Procedural, MVC, existing frameworks, etc.
At the very least, you would set the loginUser and loginPass on the instantiated object, and call the login method`. You could then inspect the results, assuming the result is a JSON object, or use your favourite debugging method to see the contents.
I'm having a guess as the USPS API class name.
$uspsApi = new UspsApi();
$uspsApi->loginUser = 'username';
$uspsApi->loginPass = 'password';
$result = $uspsApi->login();
echo print_r($result, true);