JSON format in KnockoutJS - sql

I am getting JSON format like below:
[
{
"moduleName": null,
"bundleKey": "title",
"bundleValue": "Manage cost code",
"id": 4,
"createdBy": 0,
"modifiedBy": 0,
"createdDate": "0001-01-01T00:00:00",
"modifiedDate": "0001-01-01T00:00:00",
"rowVersion": null,
"isDeleted": false
},
{
"moduleName": null,
"bundleKey": "name",
"bundleValue": "steve",
"id": 5,
"createdBy": 0,
"modifiedBy": 0,
"createdDate": "0001-01-01T00:00:00",
"modifiedDate": "0001-01-01T00:00:00",
"rowVersion": null,
"isDeleted": false
}]
I would like to format that as a key-value pair, like the following:
[{"title":"Manage cost code", "name":"steve"}]
Whether it is possible to format JSON like this.
Or is it possible to get data directly from a database in the format below?
I do not want to query the column name, only its values should be queried.

If you want to do it clientside, just use a simple reduce function
var src = [...];
var result = src.reduce( function(prev, current) {
prev[current.bundleKey] = current.bundleValue;
return prev;
}, {} );

Related

convert list of value in nested dictionary to dataframe

i have a dictionary in the form
req_rep = {
"enrichments": [
{
"data": {
"Company_name": "tester",
"Company_CXO_Count__c": null,
"fbm__Company_Employee_Size__c": "11-50",
"fbm__Person_Title__c": "instructor",
"fbm__Professional_Email__c": "small#tester.com",
"fbm__Status__c": "Completed"
},
"id": "t1",
"status": "COMPLETED"
},
{
"data": {
"Company_name": "test3",
"Company_CXO_Count__c": null,
"fbm__Company_Employee_Size__c": "11-50",
"fbm__Person_Title__c": "driver",
"fbm__Professional_Email__c": "big#test3.com",
"fbm__Status__c": "Completed"
},
"id": "t2",
"status": "COMPLETED"
},
{
"data": {
"Company_name": "tryiu",
"Company_CXO_Count__c": null,
"fbm__Company_Employee_Size__c": null,
"fbm__Person_Title__c": null,
"fbm__Professional_Email__c": "dar#tryiu.co",
"fbm__Status__c": "Completed"
},
"id": "t2",
"status": "COMPLETED"
}
],
"expiry_date": "2022-03-11 11:24:35",
"remaining_requests": 19106,
"request_id": "16642740180563593e3c",
"total_requests": 20000
}
i wish to create a new dataframe off enrichments key value pairs to look like the table below.
i have tried a few results off my search here on stack overflow but i'm yet to get the expected result i am looking for.
df_2 = pd.DataFrame([{
'Company_name': "tester",
'Company_CXO_Count__c': null,
'fbm__Company_Employee_Size__c': "11-50",
'fbm__Person_Title__c': "instructor",
'fbm__Professional_Email__c': "big#test3.com",
'fbm__Status__c': "Completed"},
{'Company_name': "tester",
'Company_CXO_Count__c': null,
'fbm__Company_Employee_Size__c': "11-50",
'fbm__Person_Title__c': "instructor",
'fbm__Professional_Email__c': "small#tester.com",
'fbm__Status__c': "Completed"},
{ 'Company_name': "tryiu",
'Company_CXO_Count__c': null,
'fbm__Company_Employee_Size__c': null,
'fbm__Person_Title__c': null,
'fbm__Professional_Email__c': "dar#tryiu.com",
'fbm__Status__c': "Completed"}])
any help would be greatly appreciated
You need to apply pd.Series to enrichments and data:
df = pd.DataFrame(req_rep)
final_df = df['enrichments'].agg(pd.Series)['data'].agg(pd.Series)
use:
df=pd.DataFrame(req_rep['enrichments'])
final = pd.json_normalize(df["data"])
try json_normalize
df2 = pd.json_normalize(data=req_rep["enrichments"])
df2.columns = df2.columns.str.split(".").str[-1]
df2 = df2.drop(columns=["id", "status"])

Powershell Json object from object

I have a method that returns a Json object from a query using the FOR JOSN PATH approach.
Example:
SELECT State, COUNT(*) AS Items
FROM dbo.States
WHERE SomeFilterColumn = #FilterParam
GROUP BY State
FOR JSON PATH
This returns
[
{
"State": "Pending",
"Items": 23
},
{
"State": "Finished",
"Items", 7736
}
]
I also have a function in Powershell that returns the result. However I have issues how it is returned.
function Get-Json-From-Query {
param(
[Int32]$filterParam
)
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
...
$SqlCmd = $SqlConnection.CreateCommand();
$SqlCmd.CommandText = $Query #The query shown above
$SqlCmd.Parameters.Add("#FilterParam", $filterParam);
$SqlCmd.ExecuteScalar()
}
However I do not know how to get the result of my query properly added to a JSON value.
I tried many things like:
#{
States = (Get-Json-From-Query -filterParam 1234)
}
However this gives me also the param information which I do not want:
Expecting
{ "States": [... The Array show above ... ] }
Actual
{
"States": [
{
"CompareInfo": 0,
"XmlSchemaCollectionDatabase": "",
"XmlSchemaCollectionOwningSchema": "",
"XmlSchemaCollectionName": "",
"ForceColumnEncryption": false,
"DbType": 11,
"LocaleId": 0,
"ParameterName": "#FilterParam",
"Precision": 0,
"Scale": 0,
"SqlDbType": 8,
"SqlValue": "1234",
"UdtTypeName": "",
"TypeName": "",
"Value": 1234,
"Direction": 1,
"IsNullable": false,
"Offset": 0,
"Size": 0,
"SourceColumn": "",
"SourceColumnNullMapping": false,
"SourceVersion": 512
},
"[{\"State\":\"Pending\",\"Items\":23},{\"State\":\"Finished\",\"Items\":7763}]"
]
}
How do I get the right data in my Json object?

ASPNET Core 3.x - Appending data to all API responses

I've been googling for past 3 hours and I couldn't find anything helpful.
I'm trying to transform all my requests to a specific RESTful standard.
Right now, each and every controller returns data in this format:
[
{
"id": 3,
"title": "Test",
"content": "Content Test",
"userId": 1,
"user": null,
"categoryId": null,
"category": null,
"comments": null,
"tags": null,
"createdOn": null,
"updatedOn": null
}
]
What I want is to wrap all of these responses in a container, that also consists of metadata - as seen below:
{
"statusCode": 200,
"statusMessage": "success",
"meta":
{
"count": 1,
"total": 1,
"pagination":
{
"page": 1,
"pages": 1,
"limit": 20
},
"filters": [],
"sorters": []
},
"data":
{
[
{
"id": 3,
"title": "Test",
"content": "Content Test",
"userId": 1,
"user": null,
"categoryId": null,
"category": null,
"comments": null,
"tags": null,
"createdOn": null,
"updatedOn": null
}
]
}
}
Is the proper approach to just make a class called ResponseContainer and make all controllers return it? Because I feel like that's a viable solution.
In one of my projects, I used a generic class as response, such as MyApiResponse<T>. This class contains properties for meta data like the HttpStatusCode of the response, error messages, etc. They are set upon each response.
Within this class, I have a List<T> called Data.
Each API method returns MyApiResponse<T> where T is being the concrete data class. For instance, it could be MyApiResponse<Weather> where Data would store a List<Weather.
I'll definetly use this approach for my next API project as well.

Json_value and Json_query cannot find specified path

I am trying to parse data from the following JSON. I know there are differences between JSON_VALUE and JSON_QUERY but I am trying to just get the path structure correct. I am using the STRICT option to validate my path's and so far other then string$ for JSON Query everything fails by not finding the path. As soon as I add the .data.taskData the path seems to blow up. Any help would be greatly appreciated.
I am setting the following JSON to #json
declare #json nvarchar(max)
SELECT JSON_VALUE(#json, 'strict$.data.taskData.startedLocation') as json
select JSON_QUERY(#json, 'strict$.data.taskData.startedLocation') as json
Below is the JSON I am trying to parse
{"data.taskData":{"startedAtUtc":"2019-08-28T20:21:29.025Z","startedLocation":{"lat":60.7348366,"lon":-124.9856841},"additionalData":[],"bols":[{"number":"1234","product":{"id":"COFFEE","description":"GROUND COFFE 5LB CAN","plannedQuantity":1352,"uom":"PCS","supplier":"WALMART ","accountOf":"","class":"UNKNOWN","loadedQuantity":6600,"netQuantity":9993},"net":"9993"}],"compartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"1","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1000","bol":"1234"}],"loadedQuantity":1000,"productID":"COFFEE"},{"id":"2","capacity":2000,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"2","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2000","bol":"1234"}],"loadedQuantity":2000,"productID":"COFFEE"},{"id":"3","capacity":1100,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"3","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1100","bol":"1234"}],"loadedQuantity":1100,"productID":"COFFEE"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":0,"tankID":"4","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2500","bol":"1234"}],"loadedQuantity":2500,"productID":"COFFEE"}],"detention":{"minutes":null,"reasonCode":null,"notes":null},"initialCompartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"1"},{"id":"2","capacity":2000,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"2"},{"id":"3","capacity":1100,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"3"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"4"}],"loadingComplete":"yes","loadingCompleteTime":"2019-08-28T20:23:05.453Z","uom":{"key":"PCS","category":"volume","shortDisplay":"p","longDisplay":"Pieces","conversionFactors":{"gal":0.0625,"L":0.2365882365,"c":4.2267528377}},"variances":[],"completedAtUtc":"2019-08-28T20:23:06.703Z","completedLocation":{"lat":61.7348308,"lon":-124.9856879},"finalCompartments":[{"id":"1","capacity":3400,"productID":"COFFEE","loadedQuantity":1000,"consignee":"KSUAC","tankID":"1"},{"id":"2","capacity":2000,"productID":"COFFEE","loadedQuantity":2000,"consignee":"KSUAC","tankID":"2"},{"id":"3","capacity":1100,"productID":"COFFEE","loadedQuantity":1100,"consignee":"KSUAC","tankID":"3"},{"id":"4","capacity":2700,"productID":"COFFEE","loadedQuantity":2500,"consignee":null,"tankID":"4"}]}}
Try this out. After the code I'll comment about the specialities:
DECLARE #json NVARCHAR(MAX)=N'{
"data.taskData": {
"startedAtUtc": "2019-08-28T20:21:29.025Z",
"startedLocation": {
"lat": 60.7348366,
"lon": -124.9856841
},
"additionalData": [],
"bols": [
{
"number": "1234",
"product": {
"id": "COFFEE",
"description": "GROUND COFFE 5LB CAN",
"plannedQuantity": 1352,
"uom": "PCS",
"supplier": "WALMART ",
"accountOf": "",
"class": "UNKNOWN",
"loadedQuantity": 6600,
"netQuantity": 9993
},
"net": "9993"
}
],
"compartments": [
{
"id": "1",
"capacity": 3400,
"commodity": null,
"consignee": "KSUAC",
"plannedQuantity": 0,
"tankID": "1",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "1000",
"bol": "1234"
}
],
"loadedQuantity": 1000,
"productID": "COFFEE"
},
{
"id": "2",
"capacity": 2000,
"commodity": null,
"consignee": "KSUAC",
"plannedQuantity": 0,
"tankID": "2",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "2000",
"bol": "1234"
}
],
"loadedQuantity": 2000,
"productID": "COFFEE"
},
{
"id": "3",
"capacity": 1100,
"commodity": null,
"consignee": "KSUAC",
"plannedQuantity": 0,
"tankID": "3",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "1100",
"bol": "1234"
}
],
"loadedQuantity": 1100,
"productID": "COFFEE"
},
{
"id": "4",
"capacity": 2700,
"commodity": null,
"consignee": null,
"plannedQuantity": 0,
"tankID": "4",
"additionalData": [],
"allLoadsValid": true,
"complete": true,
"error": false,
"locked": false,
"loads": [
{
"isFirst": true,
"quantity": "2500",
"bol": "1234"
}
],
"loadedQuantity": 2500,
"productID": "COFFEE"
}
],
"detention": {
"minutes": null,
"reasonCode": null,
"notes": null
},
"initialCompartments": [
{
"id": "1",
"capacity": 3400,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "1"
},
{
"id": "2",
"capacity": 2000,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "2"
},
{
"id": "3",
"capacity": 1100,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "3"
},
{
"id": "4",
"capacity": 2700,
"commodity": null,
"consignee": null,
"plannedQuantity": null,
"tankID": "4"
}
],
"loadingComplete": "yes",
"loadingCompleteTime": "2019-08-28T20:23:05.453Z",
"uom": {
"key": "PCS",
"category": "volume",
"shortDisplay": "p",
"longDisplay": "Pieces",
"conversionFactors": {
"gal": 0.0625,
"L": 0.2365882365,
"c": 4.2267528377
}
},
"variances": [],
"completedAtUtc": "2019-08-28T20:23:06.703Z",
"completedLocation": {
"lat": 61.7348308,
"lon": -124.9856879
},
"finalCompartments": [
{
"id": "1",
"capacity": 3400,
"productID": "COFFEE",
"loadedQuantity": 1000,
"consignee": "KSUAC",
"tankID": "1"
},
{
"id": "2",
"capacity": 2000,
"productID": "COFFEE",
"loadedQuantity": 2000,
"consignee": "KSUAC",
"tankID": "2"
},
{
"id": "3",
"capacity": 1100,
"productID": "COFFEE",
"loadedQuantity": 1100,
"consignee": "KSUAC",
"tankID": "3"
},
{
"id": "4",
"capacity": 2700,
"productID": "COFFEE",
"loadedQuantity": 2500,
"consignee": null,
"tankID": "4"
}
]
}
}';
--The query
SELECT FirstLevel.StartedAtUtc
,JSON_VALUE(FirstLevel.startedLocation,'$.lat') AS startedLocation_Lat
,JSON_VALUE(FirstLevel.startedLocation,'$.lon') AS startedLocation_Lon
,FirstLevel.additionalData
,FirstLevel.bols
,Sub_Compartments.id
,Sub_Compartments.capacity
,FirstLevel.loadingComplete
FROM OPENJSON(#json,'$."data.taskData"')
WITH(startedAtUtc DATETIME2
,startedLocation NVARCHAR(MAX) AS JSON
,additionalData NVARCHAR(MAX) AS JSON
,bols NVARCHAR(MAX) AS JSON
--compartments seems to be a 1:n related node
,compartments NVARCHAR(MAX) AS JSON
,loadingComplete NVARCHAR(10)
--and more
) FirstLevel
OUTER APPLY OPENJSON(FirstLevel.compartments)
WITH (id INT
,capacity INT
--more columns
) Sub_Compartments;
The idea in short:
Your JSON is a fully blown deeply nested structure with various data. Returnin the whole and everything would lead to a very redundant flat table. It will be a good idea to query this JSON with a question as narrow as possible.
As you were told already we can use one of these:
JSON_VALUE() to retrieve a scalar value from a given path. Nested JSON will be returned as a string type.
JSON_QUERY() to extract a fragment of the JSON and proceed with it as JSON
OPENJSON is needed to dive into a JSON with repeated elements in order to return the fragments as a derived set row-by-row. Very important is the WITH-clause, which allows to change OPENJSON's default output to a side-by-side of columns (similar to PIVOT).
In this case we can use OPENJSON to dive into the first level and return the objects found there. Some of them are scalar values and can be returned as a typed value, others are JSON objects. In this case we have to use NVARCHAR(MAX) as data type and we must sepcify AS JSON in order to proceed with the return values.
In your JSON the compartments are a 1:n related set. We can use a cascade of OPENJSON calls, using the fragment returned by the first as input and use another WITH-clause to extract the compartement's columns.
I hope, that this exampe will give you enough hints, that you can query any place of your JSON. Good luck!
This works:
select JSON_QUERY(#json, 'strict$."data.taskData".startedLocation') as json
SELECT JSON_VALUE(#json, 'strict$."data.taskData".startedLocation.lat') as json
You need to consider the following:
When you want to extract JSON object or scalar value and your path begins with a dollar sign $ or has special characters in the keys, you need to surround it with quotes ""
Function JSON_QUERY extracts an object or an array from a JSON string. If the value is not an object or an array, the result is NULL in lax mode and an error in strict mode.
Function JSON_VALUE extracts a scalar value from a JSON string. If the path points to not a scalar value, the result is NULL in lax mode and an error in strict mode
When you want to parse JSON string and get results as table, use OPENJSON table-valued function.
With your sample data, you may try the following example:
DECLARE #json nvarchar(max) = N'{"data.taskData":{"startedAtUtc":"2019-08-28T20:21:29.025Z","startedLocation":{"lat":60.7348366,"lon":-124.9856841},"additionalData":[],"bols":[{"number":"1234","product":{"id":"COFFEE","description":"GROUND COFFE 5LB CAN","plannedQuantity":1352,"uom":"PCS","supplier":"WALMART ","accountOf":"","class":"UNKNOWN","loadedQuantity":6600,"netQuantity":9993},"net":"9993"}],"compartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"1","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1000","bol":"1234"}],"loadedQuantity":1000,"productID":"COFFEE"},{"id":"2","capacity":2000,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"2","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2000","bol":"1234"}],"loadedQuantity":2000,"productID":"COFFEE"},{"id":"3","capacity":1100,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"3","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1100","bol":"1234"}],"loadedQuantity":1100,"productID":"COFFEE"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":0,"tankID":"4","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2500","bol":"1234"}],"loadedQuantity":2500,"productID":"COFFEE"}],"detention":{"minutes":null,"reasonCode":null,"notes":null},"initialCompartments":[{"id":"1","capacity":3400,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"1"},{"id":"2","capacity":2000,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"2"},{"id":"3","capacity":1100,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"3"},{"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":null,"tankID":"4"}],"loadingComplete":"yes","loadingCompleteTime":"2019-08-28T20:23:05.453Z","uom":{"key":"PCS","category":"volume","shortDisplay":"p","longDisplay":"Pieces","conversionFactors":{"gal":0.0625,"L":0.2365882365,"c":4.2267528377}},"variances":[],"completedAtUtc":"2019-08-28T20:23:06.703Z","completedLocation":{"lat":61.7348308,"lon":-124.9856879},"finalCompartments":[{"id":"1","capacity":3400,"productID":"COFFEE","loadedQuantity":1000,"consignee":"KSUAC","tankID":"1"},{"id":"2","capacity":2000,"productID":"COFFEE","loadedQuantity":2000,"consignee":"KSUAC","tankID":"2"},{"id":"3","capacity":1100,"productID":"COFFEE","loadedQuantity":1100,"consignee":"KSUAC","tankID":"3"},{"id":"4","capacity":2700,"productID":"COFFEE","loadedQuantity":2500,"consignee":null,"tankID":"4"}]}}'
SELECT
JSON_QUERY(#json, 'strict $."data.taskData".startedLocation') AS StartedLocation,
JSON_VALUE(#json, 'strict $."data.taskData".startedLocation.lat') as Lat,
JSON_VALUE(#json, 'strict $."data.taskData".startedLocation.lon') as Lon
SELECT *
FROM OPENJSON(#json, 'strict $."data.taskData".compartments') AS Compartments
Output:
----------------------------------------------------------------
StartedLocation Lat Lon
----------------------------------------------------------------
{"lat":60.7348366,"lon":-124.9856841} 60.7348366 -124.9856841
----------------
key value type
----------------
0 {"id":"1","capacity":3400,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"1","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1000","bol":"1234"}],"loadedQuantity":1000,"productID":"COFFEE"} 5
1 {"id":"2","capacity":2000,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"2","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2000","bol":"1234"}],"loadedQuantity":2000,"productID":"COFFEE"} 5
2 {"id":"3","capacity":1100,"commodity":null,"consignee":"KSUAC","plannedQuantity":0,"tankID":"3","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"1100","bol":"1234"}],"loadedQuantity":1100,"productID":"COFFEE"} 5
3 {"id":"4","capacity":2700,"commodity":null,"consignee":null,"plannedQuantity":0,"tankID":"4","additionalData":[],"allLoadsValid":true,"complete":true,"error":false,"locked":false,"loads":[{"isFirst":true,"quantity":"2500","bol":"1234"}],"loadedQuantity":2500,"productID":"COFFEE"} 5

Access subscription details with Stripes Webhooks PHP

I haven't been able to find any details for this with PHP, so I am hoping somebody can help me complete this script?
I am searching for the Subscription details from the Stripe API Webhook event. The event I am working on is invoice.payment_succeeded although I am struggling to access the subscription information from this. Here is the test event in full:
{
"id": "evt_19HdmRL346436RYAmvgxkr",
"object": "event",
"api_version": "2016-07-06",
"created": 1479580899,
"data": {
"object": {
"id": "in_19HdmRLniq434634643dO2gU",
"object": "invoice",
"amount_due": 700,
"application_fee": null,
"attempt_count": 1,
"attempted": true,
"charge": "ch_19Hdm3463464365IDDXX",
"closed": true,
"currency": "gbp",
"customer": "315464619",
"date": 1479580899,
"description": null,
"discount": null,
"ending_balance": 0,
"forgiven": false,
"lines": {
"object": "list",
"data": [
{
"id": "sub_9apRC346346CMNg",
"object": "line_item",
"amount": 700,
"currency": "gbp",
"description": null,
"discountable": true,
"livemode": false,
"metadata": {
"website_ref": "Z8ckRo2x",
"user_id": "1"
},
"period": {
"start": 1479580899,
"end": 1482172899
},
"plan": {
"id": "AdFree",
"object": "plan",
"amount": 700,
"created": 1479261871,
"currency": "gbp",
"interval": "month",
"interval_count": 1,
"livemode": false,
"metadata": {},
"name": "AdFree",
"statement_descriptor": "SNAPPYSITES ADFREE",
"trial_period_days": null
},
"proration": false,
"quantity": 1,
"subscription": null,
"type": "subscription"
}
],
"has_more": false,
"total_count": 1,
"url": "/v1/invoices/in_19HdmRLn34353465dO2gU/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"paid": true,
"period_end": 1479580899,
"period_start": 1479580899,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": null,
"subscription": "sub_9a2552OA5553MNg",
"subtotal": 700,
"tax": null,
"tax_percent": null,
"total": 700,
"webhooks_delivered_at": null
}
},
"livemode": false,
"pending_webhooks": 1,
"request": "req_9apRx9555ZVm55",
"type": "invoice.payment_succeeded"
}
I am currently listening with this unfinished script:
$input = #file_get_contents("php://input");
$event_json = json_decode($input);
$event_id = $event_json->id;
$event = \Stripe\Event::retrieve($event_id);
if($event->type == 'invoice.payment_succeeded'){
$invoice = $event->data->object;
$subscription = $invoice->lines->data->plan;
$customer = \Stripe\Customer::retrieve($invoice->customer);
print_r($subscription);
}
Unfortunately I'm not getting any response from the $subscription array. And I have attempted various methods, such as; $subscription = $invoice->plan; or $subscription = $invoice->data->plan; etc...
I do receive data for $invoice & $customer so I know they both function correctly. My main focus is to retrieve the Metadata information:
"metadata": {
"website_ref": "Z8ckRo2x",
"user_id": "1"
}
So I know which account this payment relates to. Hoping somebody might know what I'm doing wrong.
Have you tried $invoice->lines->data->Metadata->website_ref to get the metadata you are after?
Your Invoice consists of a list of subscriptions, in this case just 1. Each subscription is a result of the user selecting a plan. The metadata is stored at the subscription level as it's specific for the customer, not on the plan.