PayPal v2 Onboarding error with multiple products - paypal

I'm trying integrate PayPal V2 Onboarding in sandbox.
My call is :
curl -v -X POST https://api-m.sandbox.paypal.com/v2/customer/partner-referrals \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <My-Access-Token> " \
-d '{
"tracking_id": "795_123",
"operations": [
{
"operation": "API_INTEGRATION",
"api_integration_preference": {
"rest_api_integration": {
"integration_method": "PAYPAL",
"integration_type": "THIRD_PARTY",
"third_party_details": {
"features": [
"PAYMENT",
"REFUND"
]
}
}
}
}
],
"products": [
"EXPRESS_CHECKOUT",
"PPPLUS"
],
"legal_consents": [
{
"type": "SHARE_DATA_CONSENT",
"granted": true
}
]
}'
And the response is :
{
"name": "INVALID_REQUEST",
"message": "Request is not well-formed, syntactically incorrect, or violates schema.",
"debug_id": "266c1b0e09a8f",
"information_link": "",
"details": [{
"issue": "INVALID_ARRAY_LENGTH",
"description": "The number of items in an array should not be more than 1",
"field": "/products",
"location": "body"
}],
"links": []
}
Has anyone come up to this error message for "products" array, or is this a PayPal v2 Onboarding bug?

Related

Posting to orion gets me to "Attribute must be a JSON object"

I am sending this to Orion:
curl --location --request POST 'http://xx.xx.xx.xx:1026/ngsi-ld/v1/entities/' \
--header 'link: <https://smartdatamodels.org/context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": "urn:ngsi-ld:Device:01",
"type": "Device",
"description": "L9A",
"category": {
"value": ["sensor"]
},
"serialNumber": {
"value": "38479144"
},
"controlledProperty": {
"value": ["Water Supply"]
},
"owner": {
"value": ["Me"]
},
"location": {
"type": "Point",
"coordinates": [20.200416, 30.261837]
}
}'
and I get this:
Error 400: Bad Request
{
"type": "https://uri.etsi.org/ngsi-ld/errors/BadRequestData",
"title": "Attribute must be a JSON object",
"detail": "description"
}
I validated by json object and it passes. What am I doing wrong?
Look a little closer at your error message, especially:
detail": "description"
That's the name of the attribute that is not a JSON object:
"description": "L9A"
If you change it to:
"description": {
"type": "Property",
"value": "L9A"
}
that part should be OK.
But, the type member seems to be missing for all your attributes.
you'll need to add "type": "Property" to all of them, except "location" that's a GeoProperty:
"location": {
"type": "GeoProperty",
"value": {
"type": "Point",
"coordinates": [20.200416, 30.261837]
}
}
Perhaps spend some time reading the NGSI-LD specification?
https://www.etsi.org/deliver/etsi_gs/CIM/001_099/009/01.04.02_60/gs_CIM009v010402p.pdf

FIWARE Orion: return subscription id

When creating a subscription, it would be nice to return the subscription ID.
For instance, the following code doesn't return anything :
curl localhost:1026/v2/subscriptions -s -S --header 'Content-Type: application/json' \
-d #- <<EOF
{
"description": "A subscription to get info about Room1",
"subject": {
"entities": [
{
"id": "Room1",
"type": "Room"
}
],
"condition": {
"attrs": [
"pressure"
]
}
},
"notification": {
"http": {
"url": "http://localhost:1028/accumulate"
},
"attrs": [
"temperature"
]
},
"expires": "2040-01-01T14:00:00.00Z",
"throttling": 5
}
EOF
In the subscription case, the resource id is generated server-side (with difference to the entities endpoint, where the id is decided client-side).
It would be nice to return it in the POST call, is there any way to do this?
Subscription ID is retrieved in Location header in the response to the subscription creation request, eg:
Location: /v2/subscriptions/5b991dfa12f473cee6651a1a
More details in the NGSIv2 API specification (check "Create Subscription" section).

How can I use the BigQuery REST API from the command line?

Attempting to make a plain GET request to one of the BigQuery REST APIs gives an error that looks like this:
curl https://www.googleapis.com/bigquery/v2/projects/$PROJECT_ID/jobs/$JOBID
Output:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization",
...
What is the correct way to invoke one of the REST APIs from the command-line, such as the query or insert APIs? The API reference has a "Try this API", but the examples don't translate directly to something you can run from the command-line.
As a disclaimer, when working from the command-line, using the bq tool will usually be sufficient, or for more complex use cases, the BigQuery client libraries enable programming with BigQuery from multiple languages. It can still be useful sometimes to make plain requests to the REST APIs to see how certain APIs work at a low level, however.
First, make sure that you have installed the Google Cloud SDK. This should include the gcloud and bq command-line tools. If you haven't already, authorize your account by running this command from your terminal:
gcloud auth login
This should prompt you to log in and then give you an access code that you can paste into your terminal. (The exact process may change over time).
Now let's try a query using the BigQuery REST API, calling the jobs.query method. Modify this script with your own project name, which you can find from the Google Cloud Console, then paste the script into your terminal:
PROJECT="YOUR_PROJECT_NAME"
QUERY="\"SELECT 1 AS x, 'foo' AS y;\""
REQUEST="{\"kind\":\"bigquery#queryRequest\",\"useLegacySql\":false,\"query\":$QUERY}"
echo $REQUEST | \
curl -X POST -d #- -H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://www.googleapis.com/bigquery/v2/projects/$PROJECT/queries
If it worked, you should see output that looks like this:
{
"kind": "bigquery#queryResponse",
"schema": {
"fields": [
{
"name": "x",
"type": "INTEGER",
"mode": "NULLABLE"
},
{
"name": "y",
"type": "STRING",
"mode": "NULLABLE"
}
]
},
"jobReference": {
"projectId": "<your project ID>",
"jobId": "<your job ID>"
},
"totalRows": "1",
"rows": [
{
"f": [
{
"v": "1"
},
{
"v": "foo"
}
]
}
],
"totalBytesProcessed": "0",
"jobComplete": true,
"cacheHit": false
}
If you haven't set up the bq command-line tool, you can use bq init from your terminal to do so. Once you have, you can try running the same query using it:
bq query --use_legacy_sql=False "SELECT 1 AS x, 'foo' AS y;"
You can also see the REST API requests that the bq tool makes by passing the --apilog= option:
bq --apilog= query --use_legacy_sql=False "SELECT [1, 2, 3] AS x;"
Now let's try an example using the jobs.insert method instead of the query API. Run this script, replacing YOUR_PROJECT_NAME with your project name:
PROJECT="YOUR_PROJECT_NAME"
QUERY="\"SELECT 1 AS x, 'foo' AS y;\""
REQUEST="{\"configuration\":{\"query\":{\"useLegacySql\":false,\"query\":${QUERY}}}}"
echo $REQUEST | \
curl -X POST -d #- -H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://www.googleapis.com/bigquery/v2/projects/$PROJECT/jobs
Unlike the query API, which returned a response immediately, you will see a result that looks similar to this:
{
"kind": "bigquery#job",
"etag": "\"<etag string>\"",
"id": "<project name>:<job ID>",
"selfLink": "https://www.googleapis.com/bigquery/v2/projects/<project name>/jobs/<job ID>",
"jobReference": {
"projectId": "<project name>",
"jobId": "<job ID>"
},
"configuration": {
"query": {
"query": "SELECT 1 AS x, 'foo' AS y;",
"destinationTable": {
"projectId": "<project name>",
"datasetId": "<anonymous dataset>",
"tableId": "<anonymous table>"
},
"createDisposition": "CREATE_IF_NEEDED",
"writeDisposition": "WRITE_TRUNCATE",
"useLegacySql": false
}
},
"status": {
"state": "RUNNING"
},
"statistics": {
"creationTime": "<timestamp millis>",
"startTime": "<timestamp millis>"
},
"user_email": "<your email address>"
}
Notice the status:
"status": {
"state": "RUNNING"
},
If you want to check on the job now, you can use the jobs.get method. Similar to before, run this from your terminal, using the job ID from the output in the previous step:
PROJECT="YOUR_PROJECT_NAME"
JOB_ID="YOUR_JOB_ID"
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://www.googleapis.com/bigquery/v2/projects/$PROJECT/jobs/$JOB_ID
If the query is done, you'll get a response that indicates as much:
...
"status": {
"state": "DONE"
},
...
Finally, we can make a request to fetch the query results, also using the REST API.
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
https://www.googleapis.com/bigquery/v2/projects/$PROJECT/queries/$JOB_ID
The output will look similar to when we used the jobs.query method above:
{
"kind": "bigquery#getQueryResultsResponse",
"etag": "\"<etag string>\"",
"schema": {
"fields": [
{
"name": "x",
"type": "INTEGER",
"mode": "NULLABLE"
},
{
"name": "y",
"type": "STRING",
"mode": "NULLABLE"
}
]
},
"jobReference": {
"projectId": "<project ID>",
"jobId": "<job ID>"
},
"totalRows": "1",
"rows": [
{
"f": [
{
"v": "1"
},
{
"v": "foo"
}
]
}
],
"totalBytesProcessed": "0",
"jobComplete": true,
"cacheHit": true
}

List all entities resources functionality seems to be failing in API v2

If we perform <cb_url>:<cb_port>/v2/entitites/EntityId/attrs request as described in http://fiware.github.io/context.Orion/api/v2/cookbook/, we get a "service not found" error.
For this test we used the Docker image from https://hub.docker.com/r/fiware/orion/
Version information about the build:
{
"orion" : {
"version" : "1.0.0-next",
"uptime" : "1 d, 3 h, 48 m, 6 s",
"git_hash" : "b6752828f37711bed6e1ff670207d6b984bc9570",
"compile_time" : "Tue Apr 5 18:25:46 UTC 2016",
"compiled_by" : "root",
"compiled_in" : "838a42ae8431"
}
}
Steps to replicate:
Create an entity:
(curl -X POST <orion_host>:1026/v2/Entities?options=keyValues -s -S --header 'Content-Type: application/json' \
--header 'Accept: application/json' -d #- | python -mjson.tool) <<EOF
{
"type": "Review",
"id": "review-36",
"author": "AuthorId",
"itemReviewed": "LeBistro",
"reviewBody": "Body of the review",
"ratingValue": 4
}
EOF
Try to retrieve its attributes with:
curl <orion_host>:1026/v2/Entities/review-36/attrs
or
curl <orion_host>:1026/v2/Entities/review-36/attrs?options=keyValues
In both cases we get:
{
"error": "BadRequest",
"description": "service not found"
}
If we perform:
curl <orion_host>:1026/v2/Entities/review-36
We get:
{
"id": "review-36",
"type": "Review",
"author":
{
"type": "none",
"value": "AuthorId",
"metadata": {}
},
"itemReviewed":
{
"type": "none",
"value": "LeBistro",
"metadata": {}
},
"ratingValue":
{
"type": "none",
"value": 4,
"metadata": {}
},
"reviewBody":
{
"type": "none",
"value": "Body of the review",
"metadata": {}
}
}
Or if we perform :
curl <orion_host>:1026/v2/Entities/review-36?options=keyValues
We get:
{
"id": "review-36",
"type": "Review",
"author": "AuthorId",
"itemReviewed": "LeBistro",
"ratingValue": 4,
"reviewBody": "Body of the review"
}
I recommend to use reference instead of cookbook.
And in this case your problem is that the url /v2/Entities/review-36/attrs is malformed.
Possible Requests:
GET /v2/entities --> return all entities
GET /v2/entities/<id> --> return an entity associated to this id
GET /v2/entities/<id>/attrs/<attr_name> --> return only an attribute in the entity associated to this id
GET /v2/entities/<id>/attrs/<attr_name>/value --> return only the attribute value associated to an attribute into an entity with this id
I think the /attrs is not a "malformed URL" it is something not already implemented ...

Orion doesn't notify Cygnus

I followed the official documentation about cygnus and orion. All generic enablers are deployed correctly, without errors in their log files. But something strange happens, Orion never notifies Cygnus.
To test this mechanism I followed the example with Car entity provided in the official documentation.
My entity creation bash script:
(curl $1:1026/v1/updateContext -s -S --header 'Content-Type: application/json' --header 'Accept: application/json' -d #- | python -mjson.tool) <<EOF
{
"contextElements": [
{
"type": "Car",
"isPattern": "false",
"id": "Car1",
"attributes": [
{
"name": "speed",
"type": "integer",
"value": "75"
},
{
"name": "fuel",
"type": "float",
"value": "12.5"
}
]
}
],
"updateAction": "APPEND"
}
EOF
My entity subscription bash script:
(curl $1:1026/v1/subscribeContext -s -S --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Fiware-Service: vehicles' --header 'Fiware-ServicePath: /4wheels' -d #- | python -mjson.tool) <<EOF
{
"entities": [
{
"type": "Car",
"isPattern": "false",
"id": "Car1"
}
],
"attributes": [
"speed",
"oil_level"
],
"reference": "http://$2:5050/notify",
"duration": "P1M",
"notifyConditions": [
{
"type": "ONCHANGE",
"condValues": [
"speed"
]
}
],
"throttling": "PT1S"
}
EOF
My entity update bash script:
(curl $1:1026/v1/updateContext -s -S --header 'Content-Type: application/json' --header 'Accept: application/json' -d #- | python -mjson.tool) <<EOF
{
"contextElements": [
{
"type": "Car",
"isPattern": "false",
"id": "Car1",
"attributes": [
{
"name": "speed",
"type": "integer",
"value": $2
}
]
}
],
"updateAction": "UPDATE"
}
EOF
Note: Orion responds to all requests.
After executing these scripts, cygnus must receive reported information from orion and save it in the database, but nothing happens.
Neither in /var/log/cygnus/cygnus.log file or in /var/log/contextBroker/contextBroker.log file are reported any information about orion notification.
Note: If I use the notify.sh script provided in the official documentation, Cygnus works well and saves all data in the database.
Note: I read in other questions problems about open ports but those don't apply to mine.
EDIT 1
After I subscribe the orion, the response is:
{
"subscribeResponse": {
"duration": "P1M",
"subscriptionId": "563e12b4f4d8334d599753e0",
"throttling": "PT1S"
}
}
And when I update anentity, orion returns it:
{
"contextResponses": [
{
"contextElement": {
"attributes": [
{
"name": "speed",
"type": "integer",
"value": ""
}
],
"id": "Car1",
"isPattern": "false",
"type": "Car"
},
"statusCode": {
"code": "200",
"reasonPhrase": "OK"
}
}
]
}
To GET entity from orion I used the following script:
(curl $1:1026/v1/queryContext -s -S --header 'Content-Type: application/json' \
--header 'Accept: application/json' -d #- | python -mjson.tool) <<EOF
{
"entities": [
{
"type": "Car",
"isPattern": "false",
"id": "Car1"
}
]
}
EOF
Response:
{
"contextResponses": [
{
"contextElement": {
"attributes": [
{
"name": "fuel",
"type": "float",
"value": "12.5"
},
{
"name": "speed",
"type": "integer",
"value": "123"
}
],
"id": "Car1",
"isPattern": "false",
"type": "Car"
},
"statusCode": {
"code": "200",
"reasonPhrase": "OK"
}
}
]
}
Note The speed value was updated with success.
Taking into account the Fiware-Service and Fiware-ServicePath headers in subscription request, it has been performeed in the "/4wheels" service path of the service "vehicles". However, entity creation request doesn't use such headers, so it is created in the default service path ("/") of the default service. Thus, the subscription is not "covering" the entity, so updates in the entity are not triggering notifications.
One solution to the problem would be to create the entity in the same service and service path of the subscription, i.e. "/4wheels" service path of the service "vehicles".
Please, check Orion official documentation about service and service path concepts.