I'm trying to use Google Pay in my Xamarin app. First I added the GooglePlayServices package from nuget
then I followed the documentation from here
here is my JSON
{
"apiVersion": 2,
"apiVersionMinor": 0,
"merchantInfo": { "merchantName": "testName" },
"allowedPaymentMethods": [
{
"type": "CARD",
"parameters": {
"allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
"allowedCardNetworks": ["AMEX", "DISCOVER", "MASTERCARD", "VISA"]
}
},
{
"type": "PAYMENT_GATEWAY",
"parameters": { "gateway": "firstdata", "gatewayMerchantId": "12365" }
}
],
"transactionInfo": {
"totalPriceStatus": "FINAL",
"totalPrice": "4.10",
"currencyCode": "USD",
"checkoutOption": "COMPLETE_IMMEDIATE_PURCHASE"
}
}
code:
paymentsClient = WalletClass.GetPaymentsClient(
Xamarin.Essentials.Platform.CurrentActivity,
new WalletClass.WalletOptions.Builder()
.SetEnvironment(WalletConstants.EnvironmentTest)
.Build());
var request = PaymentDataRequest.FromJson(json);
AutoResolveHelper.ResolveTask(paymentsClient.LoadPaymentData(request),
Xamarin.Essentials.Platform.CurrentActivity, 999);
but I get an error Code 10: Developer Error
and if I do it like this
var result = await paymentsClient.LoadPaymentDataAsync(request);
I get the following error 6: BuyFlow UI needs to be shown.
after rereviewing the documentation I realized that my json object was wrong instead of
{
"type": "CARD",
"parameters": {
"allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
"allowedCardNetworks": ["AMEX", "DISCOVER", "MASTERCARD", "VISA"]
}
},
{
"type": "PAYMENT_GATEWAY",
"parameters": { "gateway": "firstdata", "gatewayMerchantId": "12365" }
}
it needs to look like this: as tokenizationSpecification part of the payment method object
{
"type": "CARD",
"parameters": {
"allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
"allowedCardNetworks": ["AMEX", "DISCOVER", "MASTERCARD", "VISA"]
},
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": { "gateway": "firstdata", "gatewayMerchantId": "12365" }
}
what I'm wondering is why didnt it throw an error when I called PaymentDataRequest.FromJson(json)
Related
I have a simple console application and it calls a Logic App by HttpRequest.
When the Logic App fails at any step I want to get exact the error message saying why it fails.
In the Logic App I can see the error.
Example: in the image, it fails at step 2 which it can't convert a string into an int. It's saying:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
which is what's I expect.
Here is my Logic App design:
But when I debug in a console application, it gives me a message "The server did not receive a response from an upstream server. Request tracking id 'some random Ids'." which is not very useful.
Here is my console application:
var obj = new
{
Age = "Twenty",
Name = "James"
};
using (var client = new HttpClient())
{
var content = new StringContent(JsonConvert.SerializeObject(obj));
content.Headers.ContentType.MediaType = "application/json";
var response = await client.PostAsync(url, content);
var errorMessage = await response.Content.ReadAsStringAsync();
//errorMessage: {"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
}
So is there anyway to make the C# response return the error message in the step 2 of the Logic App?
What I expect is:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
Not:
{"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
Thank you in advanced.
You can use actions('<Your_Previous_Step>')['error'] in your case actions('Parse_JSON')['error'] doing so you can able to retrieve the error message of that particular action.
Here is my logic app
I'm testing this through postman. Below is the response I received in postman.
Make sure you set Configure run after options to make the flow work even after it gets failed.
Updated Answer (General Solution)
In this case you can initialise a string variable and then add Append to string variable for each step so that it can catch the previous steps error. Below is the screenshot of my logic app.
Response in my postman
NOTE: Make sure you set Configure run after property for each action.
You can use the Scope action to encase the vast majority of other actions and then if something fails, you can catch the step for which it fails at.
You can load this JSON definition into your own tenant and see a working version.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Filter_array": {
"inputs": {
"from": "#variables('Result')",
"where": "#equals(item()['status'], 'Failed')"
},
"runAfter": {
"Initialize_Result": [
"Succeeded"
]
},
"type": "Query"
},
"Initialize_Error_Message": {
"inputs": {
"variables": [
{
"name": "Error Message",
"type": "string",
"value": "#{body('Filter_array')[0]['error']['message']}"
}
]
},
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Integer_Variable": {
"inputs": {
"variables": [
{
"name": "Integer Variable",
"type": "integer",
"value": 1
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_Result": {
"inputs": {
"variables": [
{
"name": "Result",
"type": "array",
"value": "#result('Scope')"
}
]
},
"runAfter": {
"Scope": [
"Succeeded",
"FAILED"
]
},
"type": "InitializeVariable"
},
"Scope": {
"actions": {
"Set_Integer_Variable_(Step_1)": {
"inputs": {
"name": "Integer Variable",
"value": 2
},
"runAfter": {},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_2)": {
"inputs": {
"name": "Integer Variable",
"value": "#string('Test')"
},
"runAfter": {
"Set_Integer_Variable_(Step_1)": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_3)": {
"inputs": {
"name": "Integer Variable",
"value": 3
},
"runAfter": {
"Set_Integer_Variable_(Step_2)": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"runAfter": {
"Initialize_Integer_Variable": [
"Succeeded"
]
},
"type": "Scope"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Month",
"interval": 12
},
"recurrence": {
"frequency": "Month",
"interval": 12
},
"type": "Recurrence"
}
}
},
"parameters": {}
}
Naturally, it's a little more intensive and follows the same principals as a normal flow for continuing to the next step after a failure but this will help you with larger flows.
This is what the test flow looks like ...
To explain it quickly, the middle steps are simple Set Variable actions that can be changed to cause the failure.
In the definition I've given you, step 2 will fail but you can change it to step 1 or 3 and you should still see the error come out at the end regardless of the step in the scope action that fails.
I suggest playing with it and looking at the output to the scope action, which is written to variable Result in the Initialize Result step.
For reference, this is the sort of information that comes out of the Scope action that you can use to determine what has failed.
{
"variables": [
{
"name": "Result",
"type": "Array",
"value": [
{
"name": "Set_Integer_Variable_(Step_1)",
"inputs": {
"name": "Integer Variable",
"value": 2
},
"outputs": {
"body": {
"name": "Integer Variable",
"value": 2
}
},
"startTime": "2022-04-22T06:55:57.8965917Z",
"endTime": "2022-04-22T06:55:57.9281959Z",
"trackingId": "0c93fa70-a552-4776-bce1-8ac889933de9",
"clientTrackingId": "08585509963278112157168286283CU11",
"status": "Succeeded"
},
{
"name": "Set_Integer_Variable_(Step_2)",
"startTime": "2022-04-22T06:55:57.9434709Z",
"endTime": "2022-04-22T06:55:57.9434709Z",
"trackingId": "f82b494b-0ecd-412b-887a-d4b08f4a5751",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "BadRequest",
"status": "Failed",
"error": {
"code": "BadRequest",
"message": "The variable 'Integer Variable' of type 'Integer' cannot be initialized or updated with value of type 'String'. The variable 'Integer Variable' only supports values of types 'Integer'."
}
},
{
"name": "Set_Integer_Variable_(Step_3)",
"startTime": "2022-04-22T06:55:57.9590957Z",
"endTime": "2022-04-22T06:55:57.9590957Z",
"trackingId": "f761d71f-8ec0-4a29-9a8a-a39a81faf660",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "ActionSkipped",
"status": "Skipped",
"error": {
"code": "ActionConditionFailed",
"message": "The execution of template action 'Set_Integer_Variable_(Step_3)' is skipped: the 'runAfter' condition for action 'Set_Integer_Variable_(Step_2)' is not satisfied. Expected status values 'Succeeded' and actual value 'Failed'."
}
}
]
}
]
}
Take note, you still need to apply the Configure run after properties to ensure it continues on after the Scope action finishes ...
You'd need to put some more error checking in but my suggestion would be to wrap all of that functionality into another LogicApp that you can reuse across your tenant. That's the thinking anyway.
Hi,
I use Atata framework with ExtentReports, based on this project: https://github.com/atata-framework/atata-samples/tree/master/ExtentReports
Now I want switch from fluent context build to json config. My fluent context build looks like:
AtataContext.GlobalConfiguration
.UseChrome()
.WithArguments("--start-maximized")
.WithLocalDriverPath()
.WithFixOfCommandExecutionDelay()
.UseCulture("en-US")
.UseAllNUnitFeatures()
.AddDebugLogging()
.AddScreenshotFileSaving()
.WithArtifactsFolderPath()
.AddLogConsumer(new ExtentLogConsumer())
.WithMinLevel(LogLevel.Info)
.EventSubscriptions.Add(new ExtentScreenshotFileEventHandler());
AtataContext.GlobalConfiguration.AutoSetUpDriverToUse();
I can implement via json config almost all, except this line:
.EventSubscriptions.Add(new ExtentScreenshotFileEventHandler());
My config:
{
"driver": {
"type": "chrome",
"alias": "chrome",
"options": {
"arguments": [ "start-maximized" ],
"userProfilePreferences": {
"download.default_directory": "{artifacts}"
}
}
},
"culture": "en-US",
"useAllNUnitFeatures": true,
"logConsumers": [
{
"type": "nlog-file",
"folderPath": "{artifacts}",
"minLevel": "Debug"
},
{
"type": "AtataUITests1.Core.Reporting.ExtentLogConsumer, AtataUITests1",
"minLevel": "Info"
}
],
"screenshotConsumers": [
{
"type": "file",
"folderPath": "{artifacts}"
}
]
}
When I try to add new screenshotConsumer to json:
"screenshotConsumers": [
{
"type": "file",
"folderPath": "{artifacts}"
},
{
"type": "AtataUITests1.Core.Reporting.ExtentScreenshotFileEventHandler, AtataUITests1"
}
]
it shows error:
System.InvalidCastException : Unable to cast object of type 'AtataUITests1.Core.Reporting.ExtentScreenshotFileEventHandler' to type 'Atata.IScreenshotConsumer'.
My question is: is it possible to pass this custom screenshot consumer via json?
Thanks
ExtentScreenshotFileEventHandler is not a screenshot consumer but an event handler. So it should be placed in "eventSubscriptions" section as below:
"eventSubscriptions": [
{
"handlerType": "AtataUITests1.Core.Reporting.ExtentScreenshotFileEventHandler, AtataUITests1"
}
]
There is also an example on Atata.Configuration.Json / JSON Schema section.
This is the sample on Botframework v4 docs. But it does not work.
It says "Can't Render Card" on the Microsoft bot emulator.
What i'm trying to do is a carouselCard but this simple card from Microsoft's sample is already not working.
{
"type": "message",
"text": "Plain text is ok, but sometimes I long for more...",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Hello World!",
"size": "large"
},
{
"type": "TextBlock",
"text": "*Sincerely yours,*"
},
{
"type": "TextBlock",
"text": "Adaptive Cards",
"separation": "none"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"url": "http://adaptivecards.io",
"title": "Learn More"
}
]
}
}
]
}
However, if i remove the top part of the code this code works:
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Hello World!",
"size": "large"
},
{
"type": "TextBlock",
"text": "*Sincerely yours,*"
},
{
"type": "TextBlock",
"text": "Adaptive Cards",
"separation": "none"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"url": "http://adaptivecards.io",
"title": "Learn More"
}
]
}
This is how i call the card. Is there a better way to do this?
public class GetNameAndAgeDialog : WaterfallDialog
{
private readonly string _cards = #".\Resources\TryCarouselCard.json";
private static Attachment CreateAdaptiveCardAttachment(string filePath)
{
var adaptiveCardJson = File.ReadAllText(filePath);
var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
public GetNameAndAgeDialog(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps)
{
AddStep(async (stepContext, cancellationToken) =>
{
var cardAttachment = CreateAdaptiveCardAttachment(_cards);
var reply = stepContext.Context.Activity.CreateReply();
reply.Attachments = new List<Attachment>() { cardAttachment };
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
return await stepContext.ContinueDialogAsync();
});
}
}
The "top part" of the first block of JSON you posted is the card contained within an activity. The second block of JSON posted is indeed just the card itself and what you'd want to put into an Attachment.
As for your code, it looks correct to me. I might consider caching the attachment JSON as you probably don't want to hit the file system every time you want to display the card, but that would just be an optimization.
I'm unclear if you are experiencing any further problems or just looking for validation of the approach now. If you are still experiencing a problem please update the question with some more details and I'll update my answer to try and help.
I'm looking for some help formatting schema extension data in Microsoft's Graph API. I've been able to successfully send Office 365 messages in code and through the Graph Explorer using this body:
{
"message": {
"subject": "Test Subject",
"body": {
"contentType": "Text",
"content": "Test Body "
},
"toRecipients": [
{
"emailAddress": {
"address": "foo#email.com"
}
}
]
}
}
I created a schema extension and promoted it to "Available" status. I can query the extension to verify it's available and get this response body:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#schemaExtensions",
"value": [
{
"id": "extc5bnq6uk_TestExtension",
"description": "Test Extension",
"targetTypes": [
"Message"
],
"status": "Available",
"owner": "mysecretclienttenantgoeshere",
"properties": [
{
"name": "ValueOne",
"type": "String"
},
{
"name": "ValueTwo",
"type": "String"
}
]
}
]
}
So far I haven't been able to append extension data to a new message. I've tried formatting my request body like this:
{
"message": {
"subject": "Test Subject",
"body": {
"contentType": "Text",
"content": "Test Body "
},
"toRecipients": [
{
"emailAddress": {
"address": "foo#email.com"
}
}
],
"extc5bnq6uk_TestExtension": {
"ValueOne": "TestValue",
"ValueTwo": "TestValue"
}
}
}
and like this:
{
"message": {
"subject": "Test Subject",
"body": {
"contentType": "Text",
"content": "Test Body "
},
"toRecipients": [
{
"emailAddress": {
"address": "foo#email.com"
}
}
],
"extensions":[
{
"extc5bnq6uk_TestExtension" : {
"ValueOne" : "TestValue"
"ValueTwo" : "TestValue"
}
}
]
}
}
Both formats return a 400 code with response body:
{
"error": {
"code": "RequestBodyRead",
"message": "The property 'extc5bnq6uk_TestExtension' does not exist on type 'Microsoft.OutlookServices.Message'. Make sure to only use property names that are defined by the type or mark the type as open type.",
"innerError": {
"request-id": "21792fd0-44d1-42aa-8d51-f8abc92cbd04",
"date": "2018-08-14T16:39:31"
}
}
}
I'm posting to this URL in the graph explorer:
https://graph.microsoft.com/v1.0/me/sendMail
and to the "messages" and "sendMail" endpoints in code.
I found the answer in the Known Limitations of the documentation. Certain resource types, including messages, have to be done in two stages, an initial post and then a follow up patch.
Creating the message and then patching with this JSON returned a valid response.
{
"extc5bnq6uk_TestExtension": {
"ValueOne": "Test Value One",
"ValueTwo": "Test Value Two"
}
}
Unfortunately, another limitation for schema extensions on messages is that they can't be used to filter messages, which is what I was ultimately after.
Filtering on schema extension properties (using the $filter
expresssion) is not supported for Outlook entity types - contact,
event, message, or post.
Jeff
Based on your question you posted, you have created a schemaExtension successfully. I think you want to send an email with this schemaExtension, but when you send an email with this schemaExtension, we get the 400 code in the response.
Based on my test, I think we can use the request body as blow.
1.Create a schemaExtension like this:
{
"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#schemaExtensions/$entity",
"id":"{extensionId}",
"description":"sample description",
"targetTypes":[
"Message"
],
"status":"Available",
"owner":"{owner id}",
"properties":[
{
"name":"p1",
"type":"String"
},
{
"name":"p2",
"type":"String"
}
]
}
Create a message
POST https://graph.microsoft.com/v1.0/me/messages
{
"message":{
"subject":"Meet for lunch?",
"body":{
"contentType":"Text",
"content":"The new cafeteria is open."
},
"toRecipients":[
{
"emailAddress":{
"address":"{toRecipients email address}"
}
}
],
"extensions":[
{
"#odata.type":"Microsoft.Graph.OpenTypeExtension",
"extensionName":"{extensionName}",
"p1":"Wingtip Toys",
"p2":"10000"
}
]
},
"saveToSentItems":"false"
}
when we send this message with the request, we will get the 202 code. The {toRecipients email address} will receive the email.
I'm getting started with the online ArcGIS analysis services API. I've hit a dead-end with the connectOriginsToDestinations analysis task; even with a minimal request, I get a job failure with the response "Operation failed. Invalid URL (code = 400)".
Unfortunately, that's not much to go on, as I can't figure out from the error exactly which field in the job request the api is complaining about. The response from the job submission is "esriJobSubmitted", with a jobId to lookup, but when polling for job status, the first poll always gives me the failure message.
{
"type": "esriJobMessageTypeError",
"description": "Operation failed. Invalid URL (code = 400)."
}
Request parameters:
Job submission URL: >>https://analysis2.arcgis.com/arcgis/rest/services/tasks/GPServer/connectOriginsToDestinations/submitJob?
Job status poll URL : >>https://analysis2.arcgis.com/arcgis/rest/services/tasks/GPServer/connectOriginsToDestinations/jobs/jc004ad8813c14d75b4bf157c43b2149d?f=json&token=MYTOKEN
Submitted Task contents (a form-encoded POST body with the following fields):
f: json
token: <my token>
originsLayer: <json blob below>
destinationsLayer: <json blob below>
measurementType: "StraightLine"
Detail: originsLayer:
{
"layerDefinition": {
"geometryType": "esriGeometryPoint",
"fields": [
{
"name": "Id",
"type": "esriFieldTypeString",
"alias": "Id"
}
]
},
"featureSet": {
"geometryType": "esriGeometryPoint",
"spatialReference": {
"wkid": 4326
},
"features": [
{
"geometry": {
"x": -77.694145,
"y": 45.478969
},
"attributes": {
"Id": "id1"
}
}
]
}
}
Detail: destinationsLayer:
{
"layerDefinition": {
"geometryType": "esriGeometryPoint",
"fields": [
{
"name": "Id",
"type": "esriFieldTypeString",
"alias": "Id"
}
]
},
"featureSet": {
"geometryType": "esriGeometryPoint",
"spatialReference": {
"wkid": 4326
},
"features": [
{
"geometry": {
"x": -77.694145,
"y": 45.478969
},
"attributes": {
"Id": "id1"
}
},
{
"geometry": {
"x": -77.476424,
"y": 46.090899
},
"attributes": {
"Id": "id2"
}
}
]
}
}