0

Hello internet people,

Apparently I had the same problem of many but after searching a lot even here I could not find a reasonable answer at all!

My problem:

On shell I did enter the command: stripe invoices list --customer MY_CUSTOMER_ID_HERE

Then the following JSON appeared:

{
  "object": "list",
  "data": [
    {
      "id": "INVOICE_ID",
      "object": "invoice",
      "account_country": "COUNTRY",
      "account_name": "MY_BUSYNESS_NAME",
      "account_tax_ids": null,
      "amount_due": 1000,
      "amount_paid": 1000,
      "amount_remaining": 0,
      "application_fee_amount": null,
      "attempt_count": 1,
      "attempted": true,
      "auto_advance": false,
      "billing_reason": "subscription_create",
      "charge": "CHARGE_ID",
      "collection_method": "charge_automatically",
      "created": SOME_UNIXTIME,
      "currency": "usd",
      "custom_fields": null,
      "customer": "CUSTOMER_ID",
      "customer_address": null,
      "customer_email": "CUSTOMER_EMAIL",
      "customer_name": null,
      "customer_phone": "CUSTOMER_PHONE",
      "customer_shipping": null,
      "customer_tax_exempt": "none",
      "customer_tax_ids": [

      ],
      "default_payment_method": null,
      "default_source": null,
      "default_tax_rates": [

      ],
      "description": null,
      "discount": null,
      "discounts": [

      ],
      "due_date": null,
      "ending_balance": 0,
      "footer": null,
      "hosted_invoice_url": "INVOICE_URL_GOES_HERE",
      "invoice_pdf": "INVOICE_PDF_URL_GOES_HERE",
      "last_finalization_error": null,
      "lines": {
        "object": "list",
        "data": [
          {
            "id": "ID",
            "object": "line_item",
            "amount": 1000,
            "currency": "usd",
            "description": "PLAN_DESCRIPTION",
            "discount_amounts": [

            ],
            "discountable": true,
            "discounts": [

            ],
            "livemode": false,
            "metadata": {
            },
            "period": {
              "end": SOME_UNIXTIME,
              "start": SOME_UNIXTIME
            },
            "plan": {
              "id": "PRICE_ID_HERE",
              "object": "plan",
              "active": true,
              "aggregate_usage": null,
              "amount": 1000,
              "amount_decimal": "1000",
              "billing_scheme": "per_unit",
              "created": SOME_UNIXTIME,
              "currency": "usd",
              "interval": "month",
              "interval_count": 1,
              "livemode": false,
              "metadata": {
              },
              "nickname": null,
              "product": "PRODUCT_ID_HERE",
              "tiers_mode": null,
              "transform_usage": null,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "price": {
              "id": "MORE_ID_HERE",
              "object": "price",
              "active": true,
              "billing_scheme": "per_unit",
              "created": SOME_UNIXTIME,
              "currency": "usd",
              "livemode": false,
              "lookup_key": null,
              "metadata": {
              },
              "nickname": null,
              "product": "PRODUCT_ID_HERE",
              "recurring": {
                "aggregate_usage": null,
                "interval": "month",
                "interval_count": 1,
                "trial_period_days": null,
                "usage_type": "licensed"
              },
              "tiers_mode": null,
              "transform_quantity": null,
              "type": "recurring",
              "unit_amount": 1000,
              "unit_amount_decimal": "1000"
            },
            "proration": false,
            "quantity": 1,
            "subscription": "SUBSCRIPTION_ID_HERE",
            "subscription_item": "SUBS_ITEM_ID_HERE",
            "tax_amounts": [

            ],
            "tax_rates": [

            ],
            "type": "subscription"
          }
        ],
        "has_more": false,
        "total_count": 1,
        "url": "IV_URL_HERE"
      },
      "livemode": false,
      "metadata": {
      },
      "next_payment_attempt": null,
      "number": "NUMBER_IV_XXXX",
      "on_behalf_of": null,
      "paid": true,
      "payment_intent": "PAYMENT_INTENT_ID_HERE",
      "payment_settings": {
        "payment_method_options": null,
        "payment_method_types": null
      },
      "period_end": SOME_UNIXTIME,
      "period_start": SOME_UNIXTIME,
      "post_payment_credit_notes_amount": 0,
      "pre_payment_credit_notes_amount": 0,
      "receipt_number": null,
      "starting_balance": 0,
      "statement_descriptor": null,
      "status": "paid",
      "status_transitions": {
        "finalized_at": SOME_UNIXTIME,
        "marked_uncollectible_at": null,
        "paid_at": SOME_UNIXTIME,
        "voided_at": null
      },
      "subscription": "SUBSCRIPTION_ID_HERE",
      "subtotal": 1000,
      "tax": null,
      "total": 1000,
      "total_discount_amounts": [

      ],
      "total_tax_amounts": [

      ],
      "transfer_data": null,
      "webhooks_delivered_at": SOME_UNIXTIME
    }
  ],
  "has_more": false,
  "url": "/some_path"
}

I'm able to access the second level with this command:

stripe invoices list --customer MY_CUSTOMER_ID_HERE | [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email,.lines.data[],.paid,.status]'

Which returns a nice response, but I do want to filter few values inside data (data.lines.data[]) like id, plan and inside plan the id, currency and product for example.

My question:

Does any one knows how to do that with this kind of commands?


Just in case, those are the questions and answer that I tried but couldn't figured how to do it at all!

How to filter array of objects by element property values using jq?

How to filter arrays in json based on specific value using jq

How to filter nested arrays in JSON while maintaining structure using jq

filtering from JSON output from curl using JQ

Filtering JSON by object name using jq

How to filter JSON using jq stream (duplicate)

How to filter and replace values in json with jq

Filtering JSON list in shell using jq

I did also try a lot attempts on my own, like:

stripe invoices list --customer MY_CUSTOMER_ID_HERE | [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email,.lines.data[.id.plan[][.id,.plan[.id,.currency,.product]],.paid,.status]'

Response: jq: error (at :179): Cannot index string with string "plan"

stripe invoices list --customer MY_CUSTOMER_ID_HERE | [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email,.lines.data[][],.paid,.status]'

  • This one return a null value for the second data content.

Response:

[
  "DESIRED_ID",
  1,
  "value_retrieved_ok",
  unixtime_ok,
  "SOME_ID_OK",
  "customer_mail@ok.com",
  null, <<< ??? 
  true,
  "paid"
]

EDIT:

Desired result should look like:

[
  "DESIRED_ID",
  1,
  "value_retrieved_ok",
  unixtime_ok,
  "SOME_ID_OK",
  "customer_mail@ok.com",
  "id"             // the id inside lines.data{}
    ["id",         // the id inside lines.data.plan
     "currency",   // the currency inside lines.data.plan
     "product"     // the product inside lines.data.plan
    ]
  true,
  "paid"
]

Anyway I do hope that there's a good soul out there have mercy!

luciela
  • 61
  • 1
  • 8
  • 1
    The JSON as updated to the Q is invalid. The literal string `SOME_UNIXTIME` needs to be inside quotes – Inian Apr 28 '21 at 17:42
  • 1
    What is the _exact_ desired output. Please update it, so that its not left to speculation – Inian Apr 28 '21 at 17:44
  • Hello @Inian, I changed the original values. The desired result should look like: [ "DESIRED_ID", 1, "value_retrieved_ok", unixtime_ok, "SOME_ID_OK", "customer_mail@ok.com", "id"[ "plan_id", "currency", "product" ] true, "paid" ] But I do not know how to access the third sublevel level or lower with shell command line. – luciela Apr 28 '21 at 18:30
  • The problem isn't the JSON! The problem is **how can I filter it with JQ in sub-levels beyond the second**. To work with a short response, because I don't need all those fields. – luciela Apr 28 '21 at 18:43
  • @luciela - Have you read the [mcve] guidelines? – peak Apr 28 '21 at 19:07
  • Hi @peak, Yes! And this is the best I can do. – luciela Apr 28 '21 at 19:20
  • @luciela - Great, but it's clear you could easily do better, both with respect to the "m" (minimal) part, and with respect to the "r" (reproducible) part. In this case, especially, the JSON should be valid, and the expected output should agree exactly with the illustrative input. – peak Apr 28 '21 at 19:39
  • Sry @peak I didn't meant to be rude or disrespect any rule here. And by the way thank you for your answer was exactly what needed! Now I know how to access even deeper levels following this pattern. Thanks for the help and advice! I'll do better next time. – luciela Apr 28 '21 at 19:55

1 Answers1

1

Your requirements are a bit difficult to follow, especially since the "expected output" does not correspond exactly to the given input, but the following is either what you're looking for, or very close to it:

.data[]
| [.id,.attempt_count,.billing_reason,.created,.customer,.customer_email]
  + (.lines.data[] | [.id, [.plan.id, .plan.currency, .plan.product]])
  + [.paid,.status]
peak
  • 105,803
  • 17
  • 152
  • 177