MPGS (mastercard): How to tokenize a transaction (how to create token)? - postman

I'm trying to create token with MPGS.
I'm following this guide:
https://sample-sub.domain.mastercard.com/api/documentation/integrationGuidelines/supportedFeatures/pickAdditionalFunctionality/tokenization/tokenization.html?locale=en_US#x_tokenConfiguration
In the section "Token Operations" > "Tokenize", it says:
You can use this operation to create or update a token by storing
payment details against the token. ...
I'm posting this to help people who are frustrating like me with MPGS. I faced series of issues, and pulled my hair off many times. So here's the issues I faced and how to solve them (I'm stuck with issue #4).
Issue #1: Invalid credentials.
Fix: Make sure you're hitting the correct URL.
https://example-subdomain.mastercard.com/..
https://some.other-example.mastercard.com/..
https://MILLION-OTHER-POSSIBILITIES.mastercard.com/..
Even the documentation guide link have these same sub-domains, so make sure you're hitting the correct URL, and make sure you're following the correct documentation link.
Issue #2: Invalid parameters, or server asking for parameters although you've provided them.
Fix: If using Postman, make sure you set the parameters in "Body" > "raw" as JSON, like so:
{
"sourceOfFunds": {
"provided": {
"card": {
"expiry": {
"month": "05",
"year": "21"
},
"number": "5123456789012346"
}
},
"type": "CARD"
}
}
Issue #3: Authorization required
Fix: If using Postman, click on "Authorization", set "Type" it to Basic Auth, for "Username" set it to merchant.YOUR_MERCHANT_ID, for "Password" set it to YOUR_API_PASSWORD
Issue #4 (stuck here): Value '9999999999999999' is invalid. Card token must not be supplied
Method: PUT
URL: https://test-my.sample.gateway.mastercard.com/api/rest/version/46/merchant/MY_MERCHANT_ID/token/9999999999999999
Authorization: set correctly in Authorization tab
Body > raw:
{
"sourceOfFunds": {
"provided": {
"card": {
"expiry": {
"month": "05",
"year": "21"
},
"number": "5123456789012346"
}
},
"type": "CARD"
}
}
Response:
{
"error": {
"cause": "INVALID_REQUEST",
"explanation": "Value '9999999999999999' is invalid. Card token must not be supplied",
"field": "tokenid",
"validationType": "INVALID"
},
"result": "ERROR"
}
Q: Not sure what to do to tokenize the transaction..?! I'm stuck with issue #4.

Ok, finally figured it out. MPGS has 2 ways to create/update tokens:
Tokenization where YOU provide the token (notice: PUT method)
Tokenization where MPGS generate the token for you (notice: POST method)
They're very similar.
I got it working with the 2nd option.
Note: This is POST method !!
Method: POST
URL: https://SUBDOMAIN_YOU_SHOULD_BE_USING.mastercard.com/api/rest/version/50/merchant/YOUR_MERCHANT_ID/token
In postman, set Authorization (as described in the question, in issue #3).
Sample data to send (in postman, this should be in Body > raw):
{
"sourceOfFunds": {
"provided": {
"card": {
"expiry": {
"month": "05",
"year": "21"
},
"number": "5123456789012346"
}
},
"type": "CARD"
}
}
Sample response:
{
"repositoryId": "1000000000002",
"response": {
"gatewayCode": "BASIC_VERIFICATION_SUCCESSFUL"
},
"result": "SUCCESS",
"sourceOfFunds": {
"provided": {
"card": {
"brand": "MASTERCARD",
"expiry": "0521",
"fundingMethod": "CREDIT",
"issuer": "BANCO DEL PICHINCHA, C.A.",
"number": "512345xxxxxx2346",
"scheme": "MASTERCARD"
}
},
"type": "CARD"
},
"status": "VALID",
"token": "9717501974559694",
"usage": {
"lastUpdated": "2019-02-25T09:36:54.928Z",
"lastUpdatedBy": "1015",
"lastUsed": "2019-02-25T09:36:54.928Z"
},
"verificationStrategy": "BASIC"
}

Related

'TypeError: Cannot initialize connector undefined: Cannot read property 'root' of undefined'

I'm using loopback3.x. I want to integrate 3rd party APIs with loopback. For that while using loopback-connector-rest shows the error 'TypeError: Cannot initialize connector undefined: Cannot read property 'root' of undefined'. How to fix it?
Datasource configuration
"restDataSource": {
"name": "restDataSource",
"baseURL": "",
"crud": true,
"connector": "rest",
"debug": false,
"options": {
"headers": {
"accept": "application/json",
"content-type": "application/json",
"authorization": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
"strictSSL": false
},
"operations": [{
"template": {
"method": "POST",
"url": "https://fcm.googleapis.com/fcm/send",
"options": {
"strictSSL": true,
"useQuerystring": true
}
},
"functions": {
"notify": ["title", "text", "click_action", "keyname", "to"]
}
}]
}
Error
TypeError: Cannot create data source "restDataSource": Cannot initialize connector "rest": Cannot read property 'root' of undefined
at /home/veena-msl/Documents/care-doc-api/node_modules/loopback-connector-rest/lib/rest-connector.js:93:28
at Array.forEach (<anonymous>)
at /home/veena-msl/Documents/care-doc-api/node_modules/loopback-connector-rest/lib/rest-connector.js:87:22
at Array.forEach (<anonymous>)
at Function.initializeDataSource [as initialize] (/home/veena-msl/Documents/care-doc-api/node_modules/loopback-connector-rest/lib/rest-connector.js:52:25)
at DataSource.setup (/home/veena-msl/Documents/care-doc-api/node_modules/loopback-datasource-juggler/lib/datasource.js:493:19)
at new DataSource (/home/veena-msl/Documents/care-doc-api/node_modules/loopback-datasource-juggler/lib/datasource.js:138:8)
at Registry.createDataSource (/home/veena-msl/Documents/care-doc-api/node_modules/loopback/lib/registry.js:364:12)
at dataSourcesFromConfig (/home/veena-msl/Documents/care-doc-api/node_modules/loopback/lib/application.js:570:19)
at Function.app.dataSource (/home/veena-msl/Documents/care-doc-api/node_modules/loopback/lib/application.js:269:14)
at /home/veena-msl/Documents/care-doc-api/node_modules/loopback-boot/lib/executor.js:191:9
at /home/veena-msl/Documents/care-doc-api/node_modules/loopback-boot/lib/executor.js:282:5
at Array.forEach (<anonymous>)
at forEachKeyedObject (/home/veena-msl/Documents/care-doc-api/node_modules/loopback-boot/lib/executor.js:281:20)
at setupDataSources (/home/veena-msl/Documents/care-doc-api/node_modules/loopback-boot/lib/executor.js:181:3)
at execute (/home/veena-msl/Documents/care-doc-api/node_modules/loopback-boot/lib/executor.js:39:3)
In the functions section, you have defined a function notify accepting several input arguments: title, text, click_action, keyname, to. However, the template section does not provide any information on how to map those arguments to an HTTP request. For example, is the title supposed to be sent via URL query or in the request body?
IIUC, you are trying to use the legacy Firbase Cloud Messaging HTTP API as described here: https://firebase.google.com/docs/cloud-messaging/http-server-ref Based on that documentation, I think all arguments of your function should be sent in the request body.
It looks like LoopBack's REST connector is not correctly detecting and handling the situation when an input argument is not mapped to any HTTP source. It should not be crashing, feel free to open a bug report in https://github.com/strongloop/loopback-connector-rest/issues
Here is a configuration that does not crash the server. I don't have a Firebase account to verify that it's working as expected.
"template": {
"method": "POST",
"url": "https://fcm.googleapis.com/fcm/send",
"options": {
"strictSSL": true,
"useQuerystring": true
},
"body": {
"title": "{title:string}",
"text": "{text:string}",
"click_action": "{click_action:string}",
"keyname": "{keyname:string}",
"to": "{to:string}"
}
},
You can learn more about different ways how to configure input arguments in the connector documentation: https://loopback.io/doc/en/lb3/REST-connector.html#defining-a-custom-method-using-a-template

API Gateway Mapping Template for context.requestTime is Blank

I'm attempting to to have an API Gateway act as a proxy to DynamoDB and I'm currently testing with a simple POST call to append the $context.requestId and $context.requestTime to my table. I am getting the following error message:
{
"__type": "com.amazon.coral.validate#ValidationException",
"message": "One or more parameter values were invalid: An AttributeValue may not contain an empty string"
}
and what is sent is:
Mon Apr 15 19:10:24 UTC 2019 : Endpoint request body after transformations: {
"TableName": "BurgerOrders",
"Item": {
"OrderId": {
"S": "1f54a90b-5fb2-11e9-8b31-c9003bb71ec2"
},
"RequestTime": {
"S": ""
}
}
}
The mapping template within Integration Request that I have is:
{
"TableName": "BurgerOrders",
"Item": {
"OrderId": {
"S": "$context.requestId"
},
"RequestTime": {
"S": "$context.requestTime"
},
}
}
I've tried to change $context.requestTime to $context.requestTimeEpoch and I get the same error.
I know this was posted a while back, but according to an AWS dev:
"At this time, [$context.requestTime] is only available when the API has been deployed and API call was invoked to deployed stage."
Source: https://forums.aws.amazon.com/thread.jspa?messageID=697652

How to PATCH a version of an item in BIM360 on Postman

https://forge.autodesk.com/blog/how-patch-apis-work-and-some-tips-using-patch-apis
https://forge.autodesk.com/en/docs/data/v2/reference/http/projects-project_id-versions-version_id-PATCH/
I have followed the two links above explaining how to PATCH a version of an item and update the name of it but I am getting errors. Below is what I inputted into Postman (version_id inside the URI has been already encoded):
URI: https://developer.api.autodesk.com/data/v1/projects/:project_id/versions/:version_id
Authorization: Bearer *****************************
Content-Type: application/vnd.api+json
Body:
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "versions",
"id": *********************************************,
"attributes": {
"name": "AAA - My PDF file.pdf",
"displayName": "AAA - My PDF file.pdf"
}
}
}
The item version I am trying to update is already named AAA - My PDF file.pdf so nothing should be updated. But when I send the request I get the following error.
Error:
{
"jsonapi": {
"version": "1.0"
},
"errors": [
{
"id": "30043cce-cfbe-4766-933c-fd9d888e574d",
"status": "400",
"code": "BAD_INPUT",
"title": "One or more input values in the request were bad",
"detail": "Request input is invalid for this operation."
}
]
}
Are there any ideas why I am getting this error and how can I fix it?
Unfortunately at the moment PATCHing for BIM360 Doc items is unsupported and hence the error. The error message could have been more specific rather than a general validation failure message and I will let Engineering know to update accordingly.
Try PATCHing with A360 hub and it should work as expected.

How to make Swashbuckle generate correct OpenAPI schema for a Dictionary parameter?

I have an ASP.NetCore action method that is defined as:
[HttpGet]
public async Task<IActionResult> Get([FromQuery]Dictionary<string,string> values)
{
return Ok(JsonConvert.SerializeObject(values));
}
The expected query would be something like:
http://localhost:36541/api?values[someProperty]=123&values[someOther]=234
When I use Swashbuckle the resulting swagger.json file would end up like:
{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "Test API"
},
"paths": {
"/api/Api": {
"get": {
"tags": [
"Api"
],
"operationId": "ApiApiGet",
"consumes": [],
"produces": [],
"parameters": [{
"name": "values",
"in": "query",
"required": false,
"type": "object"
}],
"responses": {
"200": {
"description": "Success"
}
}
}
}
},
"definitions": {}
}
But this doesn't validate using autorest or http://editor.swagger.io/
The error is:
Schema error at paths['/api/Api'].get.parameters[0]
should NOT have additional properties
additionalProperty: type, name, in, required
Jump to line 14
Schema error at paths['/api/Api'].get.parameters[0].required
should be equal to one of the allowed values
allowedValues: true
Jump to line 14
Schema error at paths['/api/Api'].get.parameters[0].in
should be equal to one of the allowed values
allowedValues: body, header, formData, path
Jump to line 15
Schema error at paths['/api/Api'].get.parameters[0].type
should be equal to one of the allowed values
allowedValues: string, number, boolean, integer, array, file
Jump to line 17
It seems that it's missing the additionalProperties property according to https://swagger.io/docs/specification/data-models/dictionaries/
How can I make this query parameter be a valid OpenAPI / Swagger definition?
Following up on the comment from #Helen
Swashbuckle does not support the OpenAPI Specification (OAS) 3.0 yet, so you should not have objects (such as dictionaries) on the query string.
My recommendation change that action to a Post and get the values from the Body, also since your response is IActionResult consider using SwaggerResponse something like this:
[HttpPost]
[SwaggerResponse(200, typeof(Dictionary<string, string>), "This returns a dictionary.")]
public async Task<IActionResult> Post([FromBody]Dictionary<string,string> values)
{
return Ok(JsonConvert.SerializeObject(values));
}
Update:
I was also looking into the possibility of sending the GET with a body, and there seems to be a lot of debate about it:
HTTP GET with request body

Alexa Skill ARN - The remote endpoint could not be called, or the response it returned was invalid

I've created a simple Lambda function to call a webpage, this works fine when I test it from the functions page however when trying to create a skill to call this function I end up with a "The remote endpoint could not be called, or the response it returned was invalid." error.
Lambda Function
var http = require('http');
exports.handler = function(event, context) {
console.log('start request to ' + event.url)
http.get(event.url, function(res) {
console.log("Got response: " + res.statusCode);
context.succeed();
}).on('error', function(e) {
console.log("Got error: " + e.message);
context.done(null, 'FAILURE');
});
console.log('end request to ' + event.url);
}
The Test Event code looks like this:
{
"url": "http://mywebsite.co.uk"
}
and I've added a trigger for the "Alexa Skills Kit".
The ARN for this function is showing as:
arn:aws:lambda:us-east-1:052516835015:function:CustomFunction
Alexa Skill (Developer Portal)
I've then created a skill with a simple Intent:
{
"intents": [
{
"intent": "CustomFunction"
}
]
}
and created an Utterance as:
CustomFunction execute my custom function
In the Configuration section for my skill I have selected the "AWS Lambda ARN (Amazon Resource Name)" option and entered the ARN into the box for North America.
In the Test -> Service Simulator section, I've added "execute my custom function" as the Text and this changes the Lambda Request to show:
{
"session": {
"sessionId": "SessionId.a3e8aee0-acae-4de5-85df-XXXXXXXXX",
"application": {
"applicationId": "amzn1.ask.skill.XXXXXXXXX"
},
"attributes": {},
"user": {
"userId": "amzn1.ask.account.XXXXXXXXX"
},
"new": true
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.445267bd-2b4a-45ef-8566-XXXXXXXXX",
"locale": "en-GB",
"timestamp": "2016-11-27T22:54:07Z",
"intent": {
"name": "RunWOL",
"slots": {}
}
},
"version": "1.0"
}
but when I run the test I get the following error:
The remote endpoint could not be called, or the response it returned was invalid.
Does anyone have any ideas on why the skill can't connect to the function?
Thanks
The Service Simulator built into the Amazon Alexa Developer Console has known issues. Try copying the JSON generated by the Simulator and pasting it into your lambda function's test event. To access lambda's test events first find the blue 'Test' button. Next to that button select the (Actions Drop down menu) -> (Configure Test Event) -> Paste the provided JSON into the code area -> (Save and Test). Lambda's built in testing features are much more reliable than Alexa's.
If this does not solve the problem lambda's testing event returns a complete stackTrace and error codes. It becomes much easier to trouble shoot when every error isn't "The remote endpoint could not be called, or the response it returned was invalid."
{
"session": {
"sessionId": "SessionId.a3e8aee0-acae-4de5-85df-XXXXXXXXX",
"application": {
"applicationId": "amzn1.ask.skill.XXXXXXXXX"
},
"attributes": {},
"user": {
"userId": "amzn1.ask.account.XXXXXXXXX"
},
"new": true
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.445267bd-2b4a-45ef-8566-XXXXXXXXX",
"locale": "en-GB",
"timestamp": "2016-11-27T22:54:07Z",
"intent": {
"name": "RunWOL",
"slots": {}
}
},
"version": "1.0"
}
​While uploading .zip, do not compress the folder into .zip.
Instead, go into the folder, select package.json, index.js and node modules & then compress them and then upload the .zip.
This error message is very broad and may imply a lot of different issues. I was getting this error and in my case it was a timeout issue. How long does that website you are pinging taking to respond? The timeout doesn't seem to be properly documented, see my original question here: Troubleshooting Amazon's Alexa Skill Kit (ASK) Lambda interaction