I am creating an AWS State machine - I am getting an error:
Here is the site that the error links too: https://docs.aws.amazon.com/step-functions/latest/dg/concepts-amazon-states-language.html
I have been combing through my state machine code for hours, and I can't figure out what is wrong with it. Previously when I had errors, they showed up in the GUI - but for this, it just says there is an error with no indication of where the error is from.
Here is my state machine visualized:
Here is the code for my state machine:
{
"StartAt":"Pass",
"States":{
"Pass":{
"Type":"Pass",
"Next":"Transform 1"
},
"Send Notification 1":{
"Type":"Task",
"Resource":"arn:aws:states:::lambda:invoke",
"Parameters":{
"FunctionName":"arn:aws:lambda:us-east-1:432700302163:function:CheckInterviewStatus:$LATEST",
"Payload":{
"Input.$":"$"
}
},
"Catch":[
{
"ErrorEquals":[
"States.ALL"
],
"Next":"CatchAllFallback"
}
],
"Next":"Interview Completed 1"
},
"Send Notification 2":{
"Type":"Task",
"Resource":"arn:aws:states:::lambda:invoke",
"Parameters":{
"FunctionName":"arn:aws:lambda:us-east-1:432700302163:function:CheckInterviewStatus:$LATEST",
"Payload":{
"Input.$":"$.Payload"
}
},
"Catch":[
{
"ErrorEquals":[
"States.ALL"
],
"Next":"CatchAllFallback"
}
],
"Next":"Interview Completed 2"
},
"CatchAllFallback":{
"Type":"Pass",
"Result":"This is a fallback from any error code",
"End":false
},
"Send Notification 3":{
"Type":"Task",
"Resource":"arn:aws:states:::lambda:invoke",
"Parameters":{
"FunctionName":"arn:aws:lambda:us-east-1:432700302163:function:CheckInterviewStatus:$LATEST",
"Payload":{
"Input.$":"$.Payload"
}
},
"Catch":[
{
"ErrorEquals":[
"States.ALL"
],
"Next":"CatchAllFallback"
}
],
"Next":"Interview Completed 3"
},
"CatchAllFallback":{
"Type":"Pass",
"Result":"This is a fallback from any error code",
"End":false
},
"Send Notification 4":{
"Type":"Task",
"Resource":"arn:aws:states:::lambda:invoke",
"Parameters":{
"FunctionName":"arn:aws:lambda:us-east-1:432700302163:function:CheckInterviewStatus:$LATEST",
"Payload":{
"Input.$":"$.Payload"
}
},
"Catch":[
{
"ErrorEquals":[
"States.ALL"
],
"Next":"CatchAllFallback"
}
],
"Next":"Interview Completed 4"
},
"CatchAllFallback":{
"Type":"Pass",
"Result":"This is a fallback from any error code",
"End":false
},
"CatchAllFallback":{
"Type":"Pass",
"Result":"This is a fallback from any error code",
"End":false
},
"Interview Completed 1":{
"Type":"Choice",
"Choices":[
{
"Variable":"$.Payload.completed",
"BooleanEquals":true,
"Next":"Yes 1"
},
{
"Variable":"$.Payload.completed",
"BooleanEquals":false,
"Next":"No 1"
}
],
"Default":"No 1"
},
"No 1":{
"Type":"Pass",
"Next":"Wait 1"
},
"Yes 1":{
"Type":"Pass",
"End":true
},
"Interview Completed 2":{
"Type":"Choice",
"Choices":[
{
"Variable":"$.Payload.completed",
"BooleanEquals":true,
"Next":"Yes 2"
},
{
"Variable":"$.Payload.completed",
"BooleanEquals":false,
"Next":"No 2"
}
],
"Default":"No 2"
},
"No 2":{
"Type":"Pass",
"Next":"Wait 2"
},
"Yes 2":{
"Type":"Pass",
"End":true
},
"Interview Completed 3":{
"Type":"Choice",
"Choices":[
{
"Variable":"$.Payload.completed",
"BooleanEquals":true,
"Next":"Yes 3"
},
{
"Variable":"$.Payload.completed",
"BooleanEquals":false,
"Next":"No 3"
}
],
"Default":"No 3"
},
"No 3":{
"Type":"Pass",
"Next":"Wait 3"
},
"Yes 3":{
"Type":"Pass",
"End":true
},
"Interview Completed 4":{
"Type":"Choice",
"Choices":[
{
"Variable":"$.Payload.completed",
"BooleanEquals":true,
"Next":"Yes 4"
},
{
"Variable":"$.Payload.completed",
"BooleanEquals":false,
"Next":"No 4"
}
],
"Default":"No 4"
},
"No 4":{
"Type":"Pass",
"End":true
},
"Yes 4":{
"Type":"Pass",
"End":true
},
"Transform 1":{
"Type":"Pass",
"Result":0,
"Next":"Send Notification 1"
},
"Transform 2":{
"Type":"Pass",
"Result":2,
"Next":"Send Notification 2"
},
"Transform 3":{
"Type":"Pass",
"Result":2,
"Next":"Send Notification 3"
},
"Transform 4":{
"Type":"Pass",
"Result":1,
"Next":"Send Notification 4"
},
"Wait 1":{
"Type":"Wait",
"Seconds":1,
"Next":"Transform 2"
},
"Wait 2":{
"Type":"Wait",
"Seconds":1,
"Next":"Transform 3"
},
"Wait 3":{
"Type":"Wait",
"Seconds":1,
"Next":"Transform 4"
}
}
}
A pointer in the right direction would be extremely helpful.
I figured it out.
"CatchAllFallback":{
"Type":"Pass",
"Result":"This is a fallback from any error code",
"End":false
},
Was defined multiple times - which was causing the error.
Related
We're going to build a portal for an authorize.net merchant. A page in this portal will have a button that will navigate to an authorize.net hosted checkout page.
Is it possible to pass custom metadata to that page which will get stored in authorize.net when the payment is complete? The goal is to allow the merchant to have a reference to the customer's identity in our system.
One Authorize.net Get Accept Hosted parameter designed for this purpose would be the refId (string, up to 20 characters). Which is a merchant-assigned reference ID for the request.
If included in the request, this value is included in the response.
E.g.,
{
"getHostedPaymentPageRequest": {
"merchantAuthentication": {
"name": "LOGIN",
"transactionKey": "TRANSACTION_KEY"
},
"refId": "123456",
"transactionRequest": {
"transactionType": "authCaptureTransaction",
"amount": "20.00",
"profile": {
"customerProfileId": "123456789"
},
"customer": {
"email": "ellen#example.com"
},
"billTo": {
"firstName": "Ellen",
"lastName": "Johnson",
"company": "Souveniropolis",
"address": "14 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "US"
}
},
"hostedPaymentSettings": {
"setting": [{
"settingName": "hostedPaymentReturnOptions",
"settingValue": "{\"showReceipt\": true, \"url\": \"https://example.com/receipt\", \"urlText\": \"Continue\", \"cancelUrl\": \"https://example.com/cancel\", \"cancelUrlText\": \"Cancel\"}"
}, {
"settingName": "hostedPaymentButtonOptions",
"settingValue": "{\"text\": \"Pay\"}"
}, {
"settingName": "hostedPaymentStyleOptions",
"settingValue": "{\"bgColor\": \"blue\"}"
}, {
"settingName": "hostedPaymentPaymentOptions",
"settingValue": "{\"cardCodeRequired\": false, \"showCreditCard\": true, \"showBankAccount\": true}"
}, {
"settingName": "hostedPaymentSecurityOptions",
"settingValue": "{\"captcha\": false}"
}, {
"settingName": "hostedPaymentShippingAddressOptions",
"settingValue": "{\"show\": false, \"required\": false}"
}, {
"settingName": "hostedPaymentBillingAddressOptions",
"settingValue": "{\"show\": true, \"required\": false}"
}, {
"settingName": "hostedPaymentCustomerOptions",
"settingValue": "{\"showEmail\": false, \"requiredEmail\": false, \"addPaymentProfile\": true}"
}, {
"settingName": "hostedPaymentOrderOptions",
"settingValue": "{\"show\": true, \"merchantName\": \"G and S Questions Inc.\"}"
}, {
"settingName": "hostedPaymentIFrameCommunicatorUrl",
"settingValue": "{\"url\": \"https://example.com/special\"}"
}]
}
}
}
I am working on a solution where a state functions is suppose to fetch the required functions to be completed(based on input) and then needs to trigger those functions in parallel, so that i have a consolidated output in the end. This can be illustrated as below -
State Machine Graph
After the requirements based on the input has been fetched, the next state can be any combination of the states below but they do need to run in parallel so that i know all required tasks have been completed. I do not want to keep a bunch of choices or deciders, since the umber of required steps can grow in the future. Is it possible to to decide on which branches are required to be run in parallel and run them.
we will need a choice within each branch.
{
"StartAt":"Build Decider Step Output",
"States":{
"Build Decider Step Output":{
"Type":"Pass",
"Result":{
"firstReq":true,
"secondReq":true,
"thridReq":false
},
"ResultPath":"$.decider",
"Next":"my-parallel"
},
"my-parallel":{
"Type":"Parallel",
"End":true,
"Branches":[
{
"StartAt":"should we run first step?",
"States":{
"should we run first step?":{
"Type":"Choice",
"Choices":[
{
"Variable":"$.decider.firstReq",
"BooleanEquals":true,
"Next":"First Requirement"
}
],
"Default":"First Req Skipped"
},
"First Req Skipped":{
"Type":"Pass",
"End":true
},
"First Requirement":{
"Type":"Pass",
"End":true
}
}
},
{
"StartAt":"should we run second step?",
"States":{
"should we run second step?":{
"Type":"Choice",
"Choices":[
{
"Variable":"$.decider.secondReq",
"BooleanEquals":true,
"Next":"Second Requirement"
}
],
"Default":"Second Req Skipped"
},
"Second Req Skipped":{
"Type":"Pass",
"End":true
},
"Second Requirement":{
"Type":"Pass",
"End":true
}
}
},
{
"StartAt":"should we run thrid step?",
"States":{
"should we run thrid step?":{
"Type":"Choice",
"Choices":[
{
"Variable":"$.decider.thridReq",
"BooleanEquals":true,
"Next":"Third Requirement"
}
],
"Default":"Third Req Skipped"
},
"Third Req Skipped":{
"Type":"Pass",
"End":true
},
"Third Requirement":{
"Type":"Pass",
"End":true
}
}
}
]
}
}
}
I mocked this json in first step output
{
"firstReq":true,
"secondReq":true,
"thridReq":false
}
and resulted in below, skipping third branch.
Okay I am setting up Partial Payments via the Authorize.net API in order to enable multiple cards to be used to cover a single balance/charge.
I'm assuming thier Partial Auth feature covers my use case, but in testing, there is an issue I can show you using the API live console here: https://developer.authorize.net/api/reference/index.html#payment-transactions-charge-a-credit-card
Go to the link above and authorize partial payments with the request I edited below and you will notice when you press submit you get a splitTenderId:
{
"createTransactionRequest": {
"merchantAuthentication": {
"name": "5KP3u95bQpv",
"transactionKey": "346HZ32z3fP4hTG2"
},
"refId": "123456",
"transactionRequest": {
"transactionType": "authCaptureTransaction",
"amount": "462.25",
"payment": {
"creditCard": {
"cardNumber": "5424000000000015",
"expirationDate": "2020-12",
"cardCode": "999"
}
},
"lineItems": {
"lineItem": {
"itemId": "1",
"name": "vase",
"description": "Cannes logo",
"quantity": "18",
"unitPrice": "45.00"
}
},
"tax": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"duty": {
"amount": "8.55",
"name": "duty name",
"description": "duty description"
},
"shipping": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"poNumber": "456654",
"customer": {
"id": "99999456654"
},
"billTo": {
"firstName": "Ellen",
"lastName": "Johnson",
"company": "Souveniropolis",
"address": "14 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"shipTo": {
"firstName": "China",
"lastName": "Bayles",
"company": "Thyme for Tea",
"address": "12 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"customerIP": "192.168.1.1",
"transactionSettings": {
"setting": [
{
"settingName": "emailCustomer",
"settingValue": "true"
}, {
"settingName": "allowPartialAuth",
"settingValue": "true"
},
]
},
"userFields": {
"userField": [
{
"name": "MerchantDefinedFieldName1",
"value": "MerchantDefinedFieldValue1"
},
{
"name": "favorite_color",
"value": "blue"
}
]
}
}
}
}
This is only successful because the amount is 462.25 as the docs say to use for testing, if I use any other (real) amount the splitTenderId is not there.
Here is a new example request, you can post this again on the link above:
{
"createTransactionRequest": {
"merchantAuthentication": {
"name": "5KP3u95bQpv",
"transactionKey": "346HZ32z3fP4hTG2"
},
"refId": "123456",
"transactionRequest": {
"transactionType": "authCaptureTransaction",
"amount": "462",
"payment": {
"creditCard": {
"cardNumber": "5424000000000015",
"expirationDate": "2020-12",
"cardCode": "999"
}
},
"lineItems": {
"lineItem": {
"itemId": "1",
"name": "vase",
"description": "Cannes logo",
"quantity": "18",
"unitPrice": "45.00"
}
},
"tax": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"duty": {
"amount": "8.55",
"name": "duty name",
"description": "duty description"
},
"shipping": {
"amount": "4.26",
"name": "level2 tax name",
"description": "level2 tax"
},
"poNumber": "456654",
"customer": {
"id": "99999456654"
},
"billTo": {
"firstName": "Ellen",
"lastName": "Johnson",
"company": "Souveniropolis",
"address": "14 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"shipTo": {
"firstName": "China",
"lastName": "Bayles",
"company": "Thyme for Tea",
"address": "12 Main Street",
"city": "Pecan Springs",
"state": "TX",
"zip": "44628",
"country": "USA"
},
"customerIP": "192.168.1.1",
"transactionSettings": {
"setting": [
{
"settingName": "emailCustomer",
"settingValue": "true"
}, {
"settingName": "allowPartialAuth",
"settingValue": "true"
},
]
},
"userFields": {
"userField": [
{
"name": "MerchantDefinedFieldName1",
"value": "MerchantDefinedFieldValue1"
},
{
"name": "favorite_color",
"value": "blue"
}
]
}
}
}
}
And with the 462 amount entered this is no longer a partial auth payment and I no longer get a splitTenderId.
Can someone please help me figure out what is going on?
I have a state machine like below. If it has 1000 messages to notify, it spreads the notifications across 15 minutes.
Now, if I have a TwoHourStateMachine with exact same state flows but with its own set of lambdas, how will I reuse the states so that I dont duplicate the definition again?
State machine:
FifteenMinuteStateMachine:
Type: "AWS::StepFunctions::StateMachine"
Properties:
StateMachineName: "FifteenMinuteStateMachine"
DefinitionString:
Fn::Sub: |-
{
"Comment": "A 15 minute state machine",
"StartAt": "Initialize",
"TimeoutSeconds": 900,
"States": {
"Initialize" : {
"Type": "Task",
"Resource": "${InitFifteenMinuteLambda.Arn}",
"TimeoutSeconds": 15,
"Retry": [ {
"ErrorEquals": [ "States.Timeout", "Lambda.Unknown" ],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2
} ],
"Catch": [{
"ErrorEquals": ["States.ALL"],
"ResultPath": "$.errorOutput",
"Next": "Update Status"
}],
"Next": "Notification Job"
},
"Notification Job" : {
"Type": "Task",
"Resource": "${NotificationFifteenMinuteLambda.Arn}",
"TimeoutSeconds": 15,
"Retry": [ {
"ErrorEquals": [ "States.Timeout", "Lambda.Unknown" ],
"IntervalSeconds": 2,
"MaxAttempts": 3,
"BackoffRate": 2
} ],
"Catch": [{
"ErrorEquals": ["States.ALL"],
"ResultPath": "$.errorOutput",
"Next": "Update Status"
}],
"Next": "All Notifications sent?"
},
"All Notifications sent?": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.status",
"StringEquals": "IN_PROGRESS",
"Next": "Wait X Seconds"
},
{
"Variable": "$.status",
"StringEquals": "SUCCEEDED",
"Next": "Update Status"
}
],
"Default": "Wait X Seconds"
},
"Wait X Seconds": {
"Type": "Wait",
"SecondsPath": "$.notificationIntervalInSeconds",
"Next": "Notification Job"
},
"Update Status": {
"Type": "Task",
"Resource": "${StatusUpdateFifteenMinuteLambda.Arn}",
"TimeoutSeconds": 15,
"End": true
}
}
}
RoleArn:
Fn::GetAtt: [ StepFunctionExecutionRole, Arn ]
Ashok,
If you can frame the problem with 1 set of lambda functions I believe the solution is already done for you in your example. Are you required to call different lambda functions? Ideally you can reuse the same lambda function and reuse that in the definition. Unfortunately, you can not use ARN variables at runtime currently, which is what I believe you're asking for.
Hope this helps!
I would like to create the payment profile with the createTransactionRequest.
Here are the request parameters that i am passing.
{
"createTransactionRequest":{
"merchantAuthentication":{
"name":"***",
"transactionKey":"***"
},
"transactionRequest":{
"transactionType":"authCaptureTransaction",
"amount":"4.95",
"payment":{
"creditCard":{
"cardNumber":"5424000000000015",
"expirationDate":"1217",
"cardCode":123
}
},
"billTo":{
"firstName":"first name",
"lastName":"last name",
"address":"test address",
"city":"test city",
"state":"TX",
"zip":"12345",
"country":"USA"
},
"profile":{
"createProfile":true
}
}
}
}
and here is the response error.
{
"messages":{
"resultCode":"Error",
"message":[
{
"code":"E00003",
"text":"The element 'transactionRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'profile' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'. List of possible elements expected: 'shipTo, customerIP, cardholderAuthentication, retail, employeeId, transactionSettings, userFields, surcharge, merchantDescriptor, subMerchant, tip' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'."
}
]
}
}
The order of the fields in your request matter. They must match what is in the documentation. That means that field needs to come before the billTo field in your JSON:
{
"createTransactionRequest":{
"merchantAuthentication":{
"name":"***",
"transactionKey":"***"
},
"transactionRequest":{
"transactionType":"authCaptureTransaction",
"amount":"4.95",
"payment":{
"creditCard":{
"cardNumber":"5424000000000015",
"expirationDate":"1217",
"cardCode":123
}
},
"profile":{
"createProfile":true
},
"billTo":{
"firstName":"first name",
"lastName":"last name",
"address":"test address",
"city":"test city",
"state":"TX",
"zip":"12345",
"country":"USA"
},
}
}
}
This request yields me this response:
{
"transactionResponse": {
"responseCode": "1",
"authCode": "Y77MQH",
"avsResultCode": "Y",
"cvvResultCode": "P",
"cavvResultCode": "2",
"transId": "40007520179",
"refTransID": "",
"transHash": "94D188D090B695D7C6D47D9293840BE3",
"testRequest": "0",
"accountNumber": "XXXX0015",
"accountType": "MasterCard",
"messages": [
{
"code": "1",
"description": "This transaction has been approved."
}
],
"transHashSha2": "9768048279544EDB22BAAAC194CA3EDBA705FBC569AC9555F3A2A86E545938849CEB2D9519885A4CC69328BBB7DDC36E0852998CAD5FAC1F6CA6427599E3493B"
},
"profileResponse": {
"messages": {
"resultCode": "Error",
"message": [
{
"code": "E00102",
"text": "Customer Info is missing."
}
]
}
},
"messages": {
"resultCode": "Ok",
"message": [
{
"code": "I00001",
"text": "Successful."
}
]
}
}
Looks like you need to add the id field in the customer section:
{
"createTransactionRequest":{
"merchantAuthentication":{
"name":"***",
"transactionKey":"***"
},
"transactionRequest":{
"transactionType":"authCaptureTransaction",
"amount":"4.95",
"payment":{
"creditCard":{
"cardNumber":"5424000000000015",
"expirationDate":"1217",
"cardCode":123
}
},
"profile":{
"createProfile":true
},
"customer":{
"id":<yourIdForThisUser>
},
"billTo":{
"firstName":"first name",
"lastName":"last name",
"address":"test address",
"city":"test city",
"state":"TX",
"zip":"12345",
"country":"USA"
},
}
}
}
That yields:
{
"transactionResponse": {
"responseCode": "1",
"authCode": "SCSVNX",
"avsResultCode": "Y",
"cvvResultCode": "P",
"cavvResultCode": "2",
"transId": "40007520393",
"refTransID": "",
"transHash": "DFB7FE5B8D3FAFE0A18A6B5C125838A3",
"testRequest": "0",
"accountNumber": "XXXX0015",
"accountType": "MasterCard",
"messages": [
{
"code": "1",
"description": "This transaction has been approved."
}
],
"transHashSha2": "57C6A161A948E5A7F5303FCD2FE8CDF3E1D3C38B989161675D47FD61526F3DA9EDBD497169F978860B78A2C5FEC1B6E54807086DF4B0CE346538DDDD9E25C4A8"
},
"profileResponse": {
"messages": {
"resultCode": "Ok",
"message": [
{
"code": "I00001",
"text": "Successful."
}
]
},
"customerProfileId": "1502546960",
"customerPaymentProfileIdList": [
"1502081232"
],
"customerShippingAddressIdList": []
},
"messages": {
"resultCode": "Ok",
"message": [
{
"code": "I00001",
"text": "Successful."
}
]
}
}