Paypal Subscription Setup - html

I am trying to setup my three subscriptions using curl and im making sure the values are correct. Trying to do a request and get a response but my curl is not functioning corectly.
https://developer.paypal.com/docs/api/subscriptions/v1/#plans_create
My intention:
3 Plans to choose from: Elite (149 PHP/MONTH), Premium (349 PHP/MONTH), Luxury (549 PHP/MONTH)
1 month is 30 days as paypal said
id like to set it to auto renew monthly until the customer chooses to cancel it.
only one will be active at a time, if a user chooses another of the three while one is running, they will automatically be stopped getting billed and will be charged with the new one chosen. (eg: currently elite149, the subscription and renewal will change to 549luxury once chosen).
curl -v -X POST https://api.sandbox.paypal.com/v1/billing/plans \
-H "Content-Type: application/json" \
-H "Authorization: Basic account_clientid:account_secretcode" \
-H "PayPal-Request-Id: EPL-25012019-001" \
-d '{
"product_id": "MWC-2019EPL",
"name": "My White Card Subscription Plans",
"description": "MyWhiteCard Membership Levels",
"status": "ACTIVE",
"billing_cycles": [
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 1,
"total_cycles": 999,
"pricing_scheme": {
"fixed_price": {
"value": "149",
"currency_code": "PHP"
}
}
},
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 2,
"total_cycles": 999,
"pricing_scheme": {
"fixed_price": {
"value": "349",
"currency_code": "PHP"
}
}
},
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 3,
"total_cycles": 999,
"pricing_scheme": {
"fixed_price": {
"value": "549",
"currency_code": "PHP"
}
}
}
],
"payment_preferences": {
"auto_bill_outstanding": true,
"setup_fee": {
"value": "0",
"currency_code": "PHP"
},
"setup_fee_failure_action": "CONTINUE",
"payment_failure_threshold": 3
},
"taxes": {
"percentage": "10",
"inclusive": false
}
}'
I just took out my account's client_id:secret
Live credentials are being used
My questions and concerns:
In the access token, do I need to put the "access_token$production$" and then the code given?
Can I manually create the Paypal request id and the product id?
Will the billing cycles be all on the same command or do I have to trigger this three times?
Is the setup fee the charge if a customer subscribes? I first assumed that is the case and set it to 0.
My intention is to have the monthly subscription (30 Days) auto renew until the user unsubscribes. I set my example to 12 but will "total_cycles": NEVER be the correct input?
I am not sure how the tax part works, why am I the one that gets to modify it?
Additional Concerns:
The document does not show the live equivalent of the link https://api.sandbox.paypal.com/v1/billing/plans is it just simply https://api.live.paypal.com/v1/billing/plans?
I tried to add the above code using git bash and curl but as I run it it shows 1008{"error":"invalid_client","error_description":"Client credentials are missing"}
Do I try to run the curl code in Git bash and not change my directory? I just start git and run the curl here:
Any help will be appreciated. I just making sure everything is what needs to be because these three subscriptions will go to a live website. I have to be certain only one subscription runs at a time.
UPDATE: I tried making it to curl -v -X POST https://api.production.paypal.com/v1/billing/plans and this one is not functionning either.
UPDATE: Can anyone show an example of a working curl sample request?
UPDATE: at the -H "Authorization: Basic account_clientid:account_secretcode", just to be clear I took out my id code there since I cant just show it in public. An example that I placed there is
-H "Authorization: Basic JAKRc85nJy2eMLq3aIV:01PvLC934xMAwLHqU4JqA89as4N"
UPDATE I tried to run this curl in git after reading the answers so far and somehow I still get and error. I made sure that the api is in api.paypal.com and the client id and secret id is the live version.
curl -v -X POST https://api.paypal.com/v1/billing/plans \
-H "Content-Type: application/json" \
-H "Authorization: Basic AR7nnwwotKOt4YdcGHZc0P2RVsRT67_Gf2hyrKyDl3ZgCKsikeKbXdQ9Fj-_21v4RulkXsgAASe7_VKv:EKwsdDo1ehtOOOSZCGMu1C9903qr4cQOOZI2rgFYhvugh2SO1V04q9MWY9SXwa352zBt1mGglLuWgR4D" \
-H "PayPal-Request-Id: MWC-2501E-001" \
-d '{
"product_id": "ELITE-2501149",
"name": "Elite Membership",
"description": "Elite Membership Monthly Plan",
"status": "ACTIVE",
"billing_cycles": [
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 1,
"total_cycles": 999,
"pricing_scheme": {
"fixed_price": {
"value": "149",
"currency_code": "PHP"
}
}
}
],
"payment_preferences": {
"auto_bill_outstanding": true,
"setup_fee": {
"value": "0",
"currency_code": "PHP"
},
"setup_fee_failure_action": "CONTINUE",
"payment_failure_threshold": 3
},
"taxes": {
"percentage": "12",
"inclusive": false
}
}'
I get this error:
100 921 100 159 100 762 99 478 0:00:01 0:00:01 --:--:-- 578{"name":"INTERNAL_SERVICE_ERROR","debug_id":"1975a4fe9232","links":[{"href":"https://developer.paypal.com/docs/api/overview/#error","rel":"information_link"}]}
UPDATE
Read all the links and followed the steps, I think this is the only issue left
{"name":"NOT_AUTHORIZED","message":"Authorization failed due to insufficient permissions.","debug_id":"484a9d7460069","details":[{"issue":"PERMISSION_DENIED","description":"You do not have permission to access or perform operations on this resource"}],"links":[{"href":"https://developer.paypal.com/docs/api/v1/billing/subscriptions#NOT_AUTHORIZED","rel":"information_link","method":"GET"}]}
I checked the Paypal help center and it seems that I need someone from Paypal itself to authorize my REST.

Q1 - In the access token, do I need to put the "access_token$production$" and then the code given?
In your example, you are using Basic authentication scheme. You can use:
-H "Authorization: Bearer Access-Token" \
But to answer your question, no you don't need to specifically include the access_token text string.
Q2 - Can I manually create the Paypal request id and the product id?
Yes, request id is used so you can retry your API calls.
https://developer.paypal.com/docs/api/reference/api-requests/#http-request-headers
HOWEVER product_id should come from https://developer.paypal.com/docs/api/catalog-products/v1/#products_create
so you will need to do it first. See my update at the bottom part of this answer.
Q3 - Will the billing cycles be all on the same command or do I have to trigger this three times?
You will need to call each plan configuration to create three subscription plans. Basically, in the API doc example, it shows you it has a billing cycle created for a Trial period and the regular plan it self. It also says:
https://developer.paypal.com/docs/api/subscriptions/v1/#plans_create
An array of billing cycles for trial and regular billing. A plan can
have multiple billing cycles but only one regular billing cycle.
You also mentioned:
only one will be active at a time, if a user chooses another of the
three while one is running, they will automatically be stopped getting
billed and will be charged with the new one chosen. (eg: currently
elite149, the subscription and renewal will change to 549luxury once
chosen).
You'll need to do this programmatically on your end.
If a user unsubscribes to a plan, then you will need to cancel his subscription by calling:
https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_cancel
If you plan to change subscription, then first you need to cancel existing, then subscribe the user to the new subscription plan using: https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions_create
Q4 - Is the setup fee the charge if a customer subscribes? I first assumed that is the case and set it to 0.
The setup fee is just an add-on fee you can charge your customers. You will need to manually declare this or make it optional by making setup fee value 0.
https://developer.paypal.com/docs/api/subscriptions/v1/#definition-payment_preferences
Q5 - My intention is to have the monthly subscription (30 Days) auto renew until the user unsubscribes. I set my example to 12 but will "total_cycles": NEVER be the correct input?
The maximum value is 999. It only accepts integer.
https://developer.paypal.com/docs/api/subscriptions/v1/#definition-billing_cycle
Q6 - I am not sure how the tax part works, why am I the one that gets to modify it?
Because tax is dependent on what region or country you are in. You are using PHP or Philippine Peso as currency so it could mean that you are in the Philippines. You will need to setup your tax percentage as 12% as that is what is used for taxing goods and services
Source: https://www.full-suite.com/blog/whats-difference-vat-percentage-tax/
Paypal tax object definition: https://developer.paypal.com/docs/api/subscriptions/v1/#definition-taxes
Q7 - The document does not show the live equivalent of the link https://api.sandbox.paypal.com/v1/billing/plans is it just simply https://api.live.paypal.com/v1/billing/plans?
You can find the addresses here:
https://developer.paypal.com/docs/api/overview/#get-an-access-token
It says:
Sandbox: https://api.sandbox.paypal.com
Live: https://api.paypal.com
Q8 - I tried to add the above code using git bash and curl but as I run it it shows 1008{"error":"invalid_client","error_description":"Client credentials are missing"}
It could mean either mean that you are passing invalid credentials. Make sure that you are sending them via the headers using
Bearer <Access-Token>
or
Basic <client_id>:<secret>
And verify that your string input represents the actual values.
Also, make sure you are using Sandbox credentials as it has a different set of credentials from the production or live
https://developer.paypal.com/docs/classic/lifecycle/sb-create-accounts/#create-a-sandbox-account
Q9 - Do I try to run the curl code in Git bash and not change my directory? I just start git and run the curl here:
Do not misinterpret Git Bash as the command line interface, it is simply a versioning tool for your projects. However the Git Package for windows has built-in components that should allow you to run CURL. Since Curl is installed in the Bin directory, you should be able to run it on any directory.
You can run the curl command using different tools ideally using a scripting or programming language like PHP, Phyton, Java or even Node which has better support for curl and should allow you to write and test your program easier in a neater way.
UPDATE
I've investigated on this further. I thought I'd share it with you because it seems you haven't read the whole API document yet.
You are creating Subscription plans however you'll need to Create the products first. (I have updated my answer to Question #2)
First - Create the Product
This will create the product_id you need to create your subscription plans.
https://developer.paypal.com/docs/api/catalog-products/v1/#products_create
To go back and check the product you created an get its product id, you can use this api call:
https://developer.paypal.com/docs/api/catalog-products/v1/#products_list
Then - Create The Subscription Plan
After you have created your products, you can then create multiple subscription plans for it.
https://developer.paypal.com/docs/api/subscriptions/v1/#plans_create
Moving forward, if you want to subscribe / unsubscribe users you'll need to programatically do it as per my answer to Question #3.
About your problem with invalid credentials
Try getting the access token first. To do that follow instructions here:
https://developer.paypal.com/docs/api/get-an-access-token-curl/
curl -v https://api.sandbox.paypal.com/v1/oauth2/token \
-H "Accept: application/json" \
-H "Accept-Language: en_US" \
-u "client_id:secret" \
-d "grant_type=client_credentials"
Then get the token returned and use that to make your api calls.
It will return something like this:
{
"scope": "scope",
"access_token": "Access-Token",
"token_type": "Bearer",
"app_id": "APP-80W284485P519543T",
"expires_in": 31349,
"nonce": "nonce"
}
Here is a modified version of your code that I used to test, notice it uses Bearer token instead basic client_id:secret
curl -v -X POST https://api.sandbox.paypal.com/v1/billing/plans \
-H "Content-Type: application/json" \
-H "Authorization: Bearer Access-Token-goeshere" \
-H "PayPal-Request-Id: MWC-helper" \
-d '{
"product_id": "PROD-ELITETEST", //<---- this product id should be taken from the real product id when you created your product through product_create api.
"name": "Elite Membership",
"description": "Elite Membership Monthly Plan",
"status": "ACTIVE",
"billing_cycles": [
{
"frequency": {
"interval_unit": "MONTH",
"interval_count": 1
},
"tenure_type": "REGULAR",
"sequence": 1,
"total_cycles": 999,
"pricing_scheme": {
"fixed_price": {
"value": "149",
"currency_code": "PHP"
}
}
}
],
"payment_preferences": {
"auto_bill_outstanding": true,
"setup_fee": {
"value": "0",
"currency_code": "PHP"
},
"setup_fee_failure_action": "CONTINUE",
"payment_failure_threshold": 3
},
"taxes": {
"percentage": "12",
"inclusive": false
}
}'
It worked for me!

Related

Google Drive API: List all folders under shared drive

Question on listing the folders under shared drive.
I was able to get successful response while calling the API below by passing query parameters as:
includeTeamDriveItems=true
q=‘0AATe_aghhsdfvbdfg’ in parents and mimeType = ‘application/vnd.google-apps.folder’
supportsAllDrives=true
API: https://developers.google.com/drive/api/v3/reference/files/list?apix_params=%7B%22includeTeamDriveItems%22%3Atrue%2C%22q%22%3A%22%270AATe_aghhsdfvbdfg%27%20in%20parents%20and%20mimeType%20%3D%20%27application%2Fvnd.google-apps.folder%27%22%2C%22supportsAllDrives%22%3Atrue%7D
Successful Response:
{
"kind": "drive#fileList",
"incompleteSearch": false,
"files": [
{
"kind": "drive#file",
"id": "1E-c0rNCQMlQvXNUGTKSWdPHBOwwzjtcf",
"name": "Integration",
"mimeType": "application/vnd.google-apps.folder",
"teamDriveId": "0AATe_aghhsdfvbdfg",
"driveId": "0AATe_aghhsdfvbdfg"
},
{
"kind": "drive#file",
"id": "1QOMRSPuE1msJJmyr3yJOMZsBrn3nrtAx",
"name": "Folder1",
"mimeType": "application/vnd.google-apps.folder",
"teamDriveId": "0AATe_aghhsdfvbdfg",
"driveId": "0AATe_aghhsdfvbdfg"
}
]
}
Question: From the response, it returns existing folders under the shared drive. Is it possible to also get all the sub folders under parent folders at once instead of having to pass parent folder ID under query parameters each time ? (e.g: To get all the sub folders under parent folder ‘Integration’)
Dilip
The folders just under the parent folder can be retrieved by the search query with one API call like below. In this case, 'folderId' in parents is used as the search query.
curl \
'https://www.googleapis.com/drive/v3/files?corpora=drive&driveId=driveId&includeItemsFromAllDrives=true&q=%27folderId%27%20in%20parents&supportsAllDrives=true' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--compressed
And, when you want to retrieve the files under 2 folders, you can also use the following sample. In this case, 'folderIdA' in parents or 'folderIdB' in parents is used as the search query.
curl \
'https://www.googleapis.com/drive/v3/files?corpora=drive&driveId=driveId&includeItemsFromAllDrives=true&q=%27folderIdA%27%20in%20parents%20or%20%27folderIdB%27%20in%20parents&supportsAllDrives=true' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--compressed
From your question, I think that you have already been done above.
In the current stage, all nested subfolders under the parent folder cannot be directly retrieved.
In this case, it is required to prepare a script.
I think that this thread will be useful.
Unfortunately, in the current stage, it seems that this is the current specification at Google side.
Note:
In the most cases, includeItemsFromAllDrives=true and supportsAllDrives=true can be used. But I had the some cases that corpora=drive and driveId=### are also required. So when in your shared Drive, the files cannot be retrieved, please try to use this.
References:
Files: list
Search for files and folders

execute in bash command stored in variable [duplicate]

This question already has answers here:
Bash script: Use string variable in curl JSON Post data
(3 answers)
Closed 2 years ago.
I'm trying to script a mailing using a curl api (this is the base API, in mine the html part is changed with "xmessage":
curl -s \
-X POST \
--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
https://api.mailjet.com/v3.1/send \
-H 'Content-Type: application/json' \
-d '{
"Messages":[
{
"From": {
"Email": "pilot#mailjet.com",
"Name": "Mailjet Pilot"
},
"To": [
{
"Email": "passenger1#mailjet.com",
"Name": "passenger 1"
}
],
"Subject": "Your email flight plan!",
"TextPart": "Dear passenger 1, welcome to Mailjet! May the delivery force be with you!",
"HTMLPart": "<h3>Dear passenger 1, welcome to Mailjet!</h3><br />May the delivery force be with you!",
"CustomCampaign": "SendAPI_campaign",
"DeduplicateCampaign": true
}
]
}'
My script look like this :
...
message=$(cat ./message.txt)
message=${message//"xdate"/$courseDate}
message=${message//"xcoursecode"/$courseCode}
message=${message//"xsubtitle"/$subtitle}
message=${message//"\r"/""}
message=${message//"\r\n"/""}
message=${message//"\n"/""}
message=${message//"\""/"\\\""}
message=${message//"'"/"&apos;"}
mailJet=$(cat ./mailjet.txt) # containing my API as described as above
mailJet=${mailJet//"xmessage"/$message}
echo $mailJet
eval $mailJet
the command "eval $mailJet" does not works but if I do a copy paste in the terminal of the "echo $mailJet" output my command works
The eval $mailJet give the following error :
{"ErrorIdentifier":"5cce36c5-373c-48ca-90b8-2b6bfc5df526","ErrorCode":"mj-0031","StatusCode":400,"ErrorMessage":"Request payload contains not valid UTF-8 encoded characters"}
Something that partially worked, was to put directly the mailJet.txt content in the script
but I'm struggling to find the syntax to replace the xmessage by what's in $message.
Like this it did not worked :
...
message=$(cat ./message.txt)
message=${message//"xdate"/$courseDate}
message=${message//"xcoursecode"/$courseCode}
message=${message//"xsubtitle"/$subtitle}
message=${message//"\r"/""}
message=${message//"\r\n"/""}
message=${message//"\n"/""}
message=${message//"\""/"\\\""}
message=${message//"'"/"&apos;"}
curl -s \
-X POST \
--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
https://api.mailjet.com/v3.1/send \
-H 'Content-Type: application/json' \
-d '{
"Messages":[
{
"From": {
"Email": "pilot#mailjet.com",
"Name": "Mailjet Pilot"
},
"To": [
{
"Email": "passenger1#mailjet.com",
"Name": "passenger 1"
}
],
"Subject": "Your email flight plan!",
"TextPart": "Dear passenger 1, welcome to Mailjet! May the delivery force be with you!",
"HTMLPart": "$message", ## neither like this : "HTMLPart": "'$message'",
"CustomCampaign": "SendAPI_campaign",
"DeduplicateCampaign": true
}
]
}'
Whereas if I put any html stuff instead of $message in the curl api, the script run without any issue.
I'm stuck (and not a great bash coder or even coder at all)
Many thanks by advance for your help.
I think your problems start at
-d '{
This use of a single quote means that nothing in this section is interpreted by bash. "$message" later on will be treated as the text $ and message.
If this is the issue, then what you need to do is unquote around the variable names, but also double-quote arround them, so you write '"$message"' Or, if you need the double-quotes to appear inside the curl command "'"$message"'".
Note you can't have the ## comment either, but I assume you put that in for our benefit.

Complex object multpart json

I want to build a request in insomnia to upload person, documents and it's files
How can I put a multipart file inside a JSON object? I don't want to deal with string base64 because it's too big and too slow to travel over the network.
I have a rest api made with spring boot and kotlin that will receive this JSON file.
Here's some code for what I want to achieve:
curl --request POST \
--url http://localhost:8080/ \
--header 'content-type: multipart/form-data; boundary=--
-011000010111000001101001' \
--form 'person={
"first_name": "Foo",
"last_name": "Fighters"
}' \
--form 'document=[
{
"document_name": "test1",
"document_description":"test1",
"document_file": "multipart file1"
},
{
"document_name": "test2",
"document_description":"test2",
"document_file": "multipart file2"
},
{
"document_name": "testN",
"document_description":"testN",
"document_file": "multipart fileN"
}
]'
Where the key document_file value stands for the file itself, not a String.
Some pictures to make it clear:
Here is the overview of the multipart
Person detail:
Document detail:
I need to know what files are from what documents, and I can have 0 or many documents related to the person.
Therefore, that's why adding 1 file for each document I want to create won't work. It needs to be inside the object(just like presented in the images) that way I know that file-X is from document-X and vice-versa.
Thanks in advance!

Json to Elasticsearch via API

I am trying to add a json file to elasticsearch which has around 30.000 lines and it is not properly formatted. I'm trying to upload it via Bulk API but I can't find a way to format it properly that actually works. I'm using Ubuntu 16.04LTS.
This is the format of the json:
{
"rt": "2018-11-20T12:57:32.292Z",
"source_info": { "ip": "0.0.60.50" },
"end": "2018-11-20T12:57:32.284Z",
"severity": "low",
"duid": "5b8d0a48ba59941314e8a97f",
"dhost": "004678",
"endpoint_type": "computer",
"endpoint_id": "8e7e2806-eaee-9436-6ab5-078361576290",
"suser": "Katerina",
"group": "PERIPHERALS",
"customer_id": "a263f4c8-942f-d4f4-5938-7c37013c03be",
"type": "Event::Endpoint::Device::AlertedOnly",
"id": "83d63d48-f040-2485-49b9-b4ff2ac4fad4",
"name": "Peripheral allowed: Samsung Galaxy S7 edge"
}
I do know that the format for the Bulk API needs {"index":{"_id":*}} before each json object in the file which it'd look like this:
{"index":{"_id":1}}
{
"rt": "2018-11-20T12:57:32.292Z",
"source_info": { "ip": "0.0.60.50" },
"end": "2018-11-20T12:57:32.284Z",
"severity": "low",
"duid": "5b8d0a48ba59941314e8a97f",
"dhost": "004678",
"endpoint_type": "computer",
"endpoint_id": "8e7e2806-eaee-9436-6ab5-078361576290",
"suser": "Katerina",
"group": "PERIPHERALS",
"customer_id": "a263f4c8-942f-d4f4-5938-7c37013c03be",
"type": "Event::Endpoint::Device::AlertedOnly",
"id": "83d63d48-f040-2485-49b9-b4ff2ac4fad4",
"name": "Peripheral allowed: Samsung Galaxy S7 edge"
}
If I insert the index id manually and then use this expression curl -s -H "Content-Type: application/x-ndjson" -XPOST localhost:92100/ivc/default/bulk?pretty --data-binary #results.json it will upload it with no errors.
My question is, how can I add the index id {"index":{"_id":*}} to each line of the json to make it ready to upload? Obviously the index id has to add +1 each line, is there any way to do it from the CLI?
Sorry if this post doesn't look as it should, I read millions of posts in Stack Overflow but this is my first one! #Desperate
Thank you very much in advance!
Your problem is that Elasticsearch expects the document to be a valid json on ONE line, like this :
{"index":{"_id":1}}
{"rt":"2018-11-20T12:57:32.292Z","source_info":{"ip":"0.0.60.50"},"end":"2018-11-20T12:57:32.284Z","severity":"low","duid":"5b8d0a48ba59941314e8a97f","dhost":"004678","endpoint_type":"computer","endpoint_id":"8e7e2806-eaee-9436-6ab5-078361576290","suser":"Katerina","group":"PERIPHERALS","customer_id":"a263f4c8-942f-d4f4-5938-7c37013c03be","type":"Event::Endpoint::Device::AlertedOnly","id":"83d63d48-f040-2485-49b9-b4ff2ac4fad4","name":"Peripheral allowed: Samsung Galaxy S7 edge"}
You have to find a way to transform your input file so that you have a document per line, then you'll be good to go with Val's solution.
Thank you for all the answers, they did help to get in me in the right direction.
I've made a bash script to automate the download, formatting and upload of the logs to Elasticsearch:
#!/bin/bash
echo "Downloading logs from Sophos Central. Please wait."
cd /home/user/ELK/Sophos-Central-SIEM-Integration/log
#This deletes the last batch of results
rm result.json
cd ..
#This triggers the script to download a new batch of logs from Sophos
./siem.py
cd /home/user/ELK/Sophos-Central-SIEM-Integration/log
#Adds newline at the beginning of the logs file
sed -i '1 i\{"index":{}}' result.json
#Adds indexes
sed -i '3~2s/^/{"index":{}}/' result.json
#Adds json file to elasticsearch
curl -s -H "Content-Type: application/x-ndjson" -XPOST localhost:9200/ivc/default/_bulk?pretty --data-binary #result.json
So that's how I achieved this. There might be easier options but this one did the trick for me. Hope it can be useful for someone else!
Again thank you everyone! :D

curl API calls with array of hashes

We are using a server software offering called FreezerPro (https://www.freezerpro.com/product-tour) with an API that can be called programmatically. There are simple methods like freezers that work with curl calls like this:
freezers -- Retrive a list of freezers
Returned objects: Freezers
Required parameters: None
Optional query parameters: None
Optional control parameters: None
curl -g --insecure 'https://username:password#demo-usa.freezerpro.com/api?method=freezers' | jq . | head -n 12
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 8697 0 8697 0 0 15980 0 --:--:-- --:--:-- --:--:-- 15987
{
"Freezers": [
{
"rfid_tag": "355AB1CBC00000700000075A",
"barcode_tag": "7000001882",
"boxes": 0,
"subdivisions": 1,
"access": 0,
"description": "[1000000000]",
"name": "[1000000000]",
"id": 1882
},
Then there is a search_samples method that searches for any fields in samples given a query. E.g.:
search_samples -- search for samples:
Returned objects: Samples
Required parameters: None
Optional query parameters:
query = <filter text> optional search string to filter the results.
Optional control parameters:
start = <staring record>
limit = <limit number of records to retrieve>
sort = <sort_field>
dir = <ASC / DESC>
curl -g --insecure 'https://username:password#demo-usa.freezerpro.com/api?method=search_samples&query=111222333' | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 347 0 347 0 0 977 0 --:--:-- --:--:-- --:--:-- 977
{
"Samples": [
{
"created_at": "06/11/2018",
"owner_id": 45,
"owner": "<span ext:qtip=\"username\">username</span>",
"description": "test",
"sample_id": 53087,
"id": 53087,
"loc_id": 54018,
"type": "cfDNA",
"scount": 1,
"name": "123456AB",
"location": "ER111→Level 1→Level 2→test001 (1)",
"icon": "images/box40/i53.png"
}
],
"Total": 1
}
So far so good. The problem comes when trying to run the advanced_search query, which takes an array of hashes in the query section. Given the sample above, which has a udf called patient_id with value 111222333, and advanced_search query for udf patient_id value=111222333 should return something, but it just gives a blank result:
Example command:
curl -g --insecure 'https://username:password#demo-usa.freezerpro.com/api?method=advanced_search&subject_type=Sample&query=[{type="udf",field="patient_id",value=111222333}]'
I am using:
curl --version
curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
Is this something to do with the way curl works on interpreting/passing the query section of the URL?
Any ideas about how to construct the query? Is this a curl specific issue?
EDIT: tried curl urlencode, it complains about the query not being setup:
curl -g -G --insecure 'https://username:password#demo-usa.freezerpro.com/api' --data-urlencode 'method=advanced_search' --data-urlencode 'query=[{type="udf",field="patient_id",value=111222333}]'
{"error":true,"message":"Query or search conditions must be specified","success":false}
You must URL-encode values of your URL parameters. e.g.
curl -g --insecure 'https://username:password#demo-usa.freezerpro.com/api?method=advanced_search&subject_type=Sample&query=%5B%7Btype%3D%22udf%22%2Cfield%3D%22patient_id%22%2Cvalue%3D111222333%7D%5D'
Also please run curl with -v parameter to make it verbose, so we could at least know what HTTP status is returned.
I've found a solution using the --data flag together with the -k flag:
curl -k --header "Content-Type: application/json" --request GET --data '{"username":"user", "password":"password", "method":"advanced_search", "query":[{"type":"udf","field":"patient_id","op":"eq","value":"111222333"}], "udfs":["patient_id","other"]}' https://demo-usa.freezerpro.com/api | jq .