Got Http response code 400 when implementing Paypal Sandbox refund - paypal-rest-sdk

I am trying to implement Sandbox Paypal Payment Gateway refund functionality. I am using Laravel 5.6.12 and Package: "paypal/rest-api-sdk-php": "^1.13"
I have no issue in doing payment. Below is the response received after successful payment done.
{
"id": "PAY-94141048LX592642PLLYUVMA",
"transactions": [
{
"related_resources": [
{
"sale": {
"id": "0KH341752J2209342",
"state": "completed",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/0KH341752J2209342",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/0KH341752J2209342/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-94141048LX592642PLLYUVMA",
"rel": "parent_payment",
"method": "GET"
}
],
"soft_descriptor": "PAYPAL *PANKAJGARGS"
}
}
]
}
]
}
From the above JSON, I took Sale_ID = 0KH341752J2209342 and wrote the below code to implement refund.
$refund = new Refund();
$refund->setAmount(200);
$sale = new Sale();
$sale->setId("0KH341752J2209342");
try {
$apiContext = $this->_api_context;
$refundedSale = $sale->refund($refund, $apiContext);
} catch (Exception $ex) {
\Log::info($ex);
exit(1);
}
and got the below error.
Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/sale/0KH341752J2209342/refund.
Can you please suggest something if there is anything wrong? Please let me know if you need more info. I removed some unnecessary sections from above JSON to make it short
Error Details.
Status Code : 400 Response: {"name":"MALFORMED_REQUEST","message":"Incoming JSON request does not map to API request","information_link":"developer.paypal.com/webapps/developer/docs/api/…;}PayPal\Exception\PayPalConnectionException: Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/sale/3FM030155Y9829603/refund

You should add the following catch, so you can see the real error message:
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode();
echo $ex->getData(); // Prints the detailed error message
die($ex);
}

I added below three lines
$amt = new Amount();
$amt->setTotal(10)
->setCurrency('INR');
in the below code and everything is working now.
$refund = new Refund();
$refund->setAmount($amt);
$sale = new Sale();
$sale->setId("0KH341752J2209342");
try {
$apiContext = $this->_api_context;
$refundedSale = $sale->refund($refund, $apiContext);
} catch (Exception $ex) {
\Log::info($ex);
exit(1);
}

Related

getting error response for the Update api

I am new to this swagger and i created a small demo project in node-js to see how swagger will really works. I created 5 api's which 4 are working perfectly and when it comes to PUT api I am getting error ,but when i tried in postman it is working. Please look at the code below.
export let updateUser = async(req: Request, resp: Response) => {
try{
const use = await User.findById(req.params.id);
use.name = req.body.name;
// use.email = req.body.email;
const a1 = await use.save();
resp.json("successfully updated");
} catch(err) {
resp.send('Error')
}
}
this is the api which is calling above method in app.ts
//put-request
app.put('/user/update/:id',controller.updateUser);
This is the the swagger json of put API
"/user/update/{id}": {
"put": {
"tags": [
"Update-Api"
],
"summary": "Update-user",
"description": "To updatre the particular user",
"operationId": "updateUser",
"consumes": ["application/json"],
"parameters":[
{
"name":"Id",
"in":"path",
"description":"enter the id of the user",
"required":true,
"type":"string"
},
{
"name":"body",
"in":"body",
"description":"Enter the update value",
"required":true,
"$schema": {
"type": "#/definations/User"
}
}
],
"responses": {
"400": {
"description": "Invalid user supplied"
},
"404": {
"description": "User not found"
}
}
}
}
If you paste your API definition into https://editor.swagger.io, it will flag 2 syntax errors in the PUT operation. Make sure to fix these errors before testing your API.
In the parameter definition, change "name":"Id" to "name":"id" (lowercase id) to match the parameter letter case in the path template.
In the body parameter, change $schema to schema.

Convert postman api call to Node.js call

I'm getting some troubles when trying to make a post request to an API made with swagger 2.0 (not by me).
I've imported a collection to postman, and when i perform a post request it works perfect. However in Node.js it outputs a 400 error with swagger library, and a 500 with axios.
Heres the schema that the collection provides in postman:
{
"workflowFunctionID": 1,
"workflowActionParameters": [
{
"name": "Description",
"value": "Probando y wea2",
"workflowFunctionParameterId": 2
},
{
"name": "Price",
"value": "25000",
"workflowFunctionParameterId": 3
}
]
}
As i mentioned it works perfectly. And this is the current code that am using Node.js:
main = async() => {
try {
const token = await acquireTokenWithClientCredentials(RESOURCE, CLIENT_APP_Id, CLIENT_SECRET, AUTHORITY);
const request = {
url: `${WORKBENCH_API_URL}/api/v1/contracts?workflowId=1&contractCodeId=1&connectionId=1`,
method: "POST",
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token.access_token}` },
body: {
workflowActionInput: {
workflowFunctionID: 1,
workflowActionParameters: [{
"name": "description",
"value": "cualkier wea"
},
{
"name": "price",
"value": "20000000"
}
]
}
}
}
let res = await Swagger.http(request);
console.log(res);
}
catch (err) {
console.error(err);
}
}
main();
How should i pass the body/form-data to the post request, or maybe using another package or code? Thanks in advance for any help.
When you have api running in postman, just see this button named "code" i marked with black
click on this button
select language as node.js
It will show you code in node.js for that api, just copy that code and paste where required.
Here i am attaching picture kindly see this

Facebook Messenger Bot Persistent Menu

I am generating my first bot working with node.js and heroku but finding some difficulties to understand the persistent menu functionalities.
Question 1) How do can I attach event as callbacks?
function persistentMenu(sender){
request({
url: 'https://graph.facebook.com/v2.6/me/thread_settings',
qs: {access_token:token},
method: 'POST',
json:{
setting_type : "call_to_actions",
thread_state : "existing_thread",
call_to_actions:[
{
type:"postback",
title:"FAQ",
payload:"DEVELOPER_DEFINED_PAYLOAD_FOR_HELP"
},
{
type:"postback",
title:"I Prodotti in offerta",
payload:"DEVELOPER_DEFINED_PAYLOAD_FOR_HELP"
},
{
type:"web_url",
title:"View Website",
url:"https://google.com/"
}
]
}
}, function(error, response, body) {
console.log(response)
if (error) {
console.log('Error sending messages: ', error)
} else if (response.body.error) {
console.log('Error: ', response.body.error)
}
})
}
Question 2) The only way I have found for empty the persistent menu and generating a new one is with a delete request via terminal ("as Facebook documented")m is there a possibily to clear inserting a refresh function on my app.js file?
curl -X DELETE -H "Content-Type: application/json" -d '{"setting_type":"call_to_actions","thread_state":"existing_thread"}' "https://graph.facebook.com/v2.6/me/thread_settingsaccess_token=PAGE_ACCESS_TOKEN"
The FB example robot is not well structured for call backs. I haven't found a good way to structure the example in Node callback or promise model. I'm sure a Node expert can reorg it.
As for the persistent menu, if you send an empty call_to_actions array the menu will disappear. The menu seems a bit 'sticky' however as it does not immediately appear/disappear when the message is sent.
I incorporated your snippet into my example robot. You can see it at
https://messenger.com/t/dynamicmemorysolutions
The source is at:
https://github.com/matthewericfisher/fb-robot
See the add/remove menu commands and functions.
EDIT: The persistent menu API has been updated. See this question for more details.
this worked for me:
function menuButton() {
var messageData = {
setting_type : "call_to_actions",
composerinputdisabled :"TRUE",
thread_state : "existing_thread",
call_to_actions:[
{
type:"postback",
title:"¿Tiempo de espera?",
payload:"ACTUALIZAR"
},
{
type:"postback",
title:"Ver Promociones",
payload:"DEVELOPER_DEFINED_PAYLOAD_FOR_START_ORDER"
}
]
}
request({
uri: 'https://graph.facebook.com/v2.6/me/thread_settings',
qs: { access_token: PAGE_ACCESS_TOKEN },
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
console.log("Successfully sent generic message with id %s to recipient %s",
messageId, recipientId);
} else {
console.error("Unable to send message.");
console.error(response);
console.error(error);
}
});
}
And I call this function at the beggining
app.post('/webhook', function(req, res){
var data = req.body;
if (data.object == 'page') {
menuButton();
data.entry.forEach(function(entry) {
var pageID = entry.id;
var timeOfEvent = entry.time;
// Iterate over each messaging event
entry.messaging.forEach(function(event) {
if (event.message) {
receivedMessage(event);
}else if (event.postback) {
receivedPostback(event);
} else {
console.log("Webhook received unknown event: ", event);
}
});
});
res.sendStatus(200);
}
})
What I have not being able to do is to remove the option of free text input. Facebook claimed now is possible yet have found no instructions or examples on how to do it. Any clues?
If you want to disable the free text input, you shoud add the following parameter to your persistent menu request:
"composer_input_disabled": true
and not
composerinputdisabled :"TRUE"
The FB API document states that the API link to hit for applying persistent menu to the page specific bot is:
https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>
Notice the me after version number i.e v2.6 in this specific case. However, this did not worked for a lot of people
There is small change in the API link to hit:
graph.facebook.com/v2.6/Page ID/messenger_profile?access_token=PAGE ACCESS TOKEN
Notice that me is replaced with the fb Page Id.
And the sample payload can still be the same:
{
"get_started": {
"payload": "Get started"
},
"persistent_menu": [
{
"locale": "default",
"composer_input_disabled": false,
"call_to_actions": [
{
"title": "Subscribe",
"type": "postback",
"payload": "subscribe"
},
{
"title": "Stop notifications",
"type": "nested",
"call_to_actions": [
{
"title": "For 1 week",
"type": "postback",
"payload": "For_1_week"
},
{
"title": "For 1 month",
"type": "postback",
"payload": "For_1_month"
},
{
"title": "For 1 year",
"type": "postback",
"payload": "For_1_year"
}
]
},
{
"title": "More",
"type": "nested",
"call_to_actions": [
{
"title": "Fresh jobs",
"type": "postback",
"payload": "fresh jobs"
},
{
"title": "Like us",
"type": "web_url",
"url": "https://www.facebook.com/onlysoftwarejobs/"
},
{
"title": "Feedback",
"type": "web_url",
"url": "https://docs.google.com/forms/d/e/1FAIpQLScjgFRbfBLznO55kFIskcH_eFc23zRSUUxzIgv_o44uj0GMpw/viewform"
}
]
}
]
}
]
}
Notice that it is mandatory to configure get_started button before setting up the persistent_menu.

Resolve issue in jira by using rest api

Can I resolve the issue in JIRA?
I made some trials with REST API as;
var url = "https://hibernate.atlassian.net/rest/api/2/issue/WEBSITE-1/transitions";
var message = [{
"update": {
"comment": [
{
"add": {
"body": "some text for body"
}
}
]
},
"fields": {
"assignee": {
"name": "name1"
},
"resolution": {
"name": "Fix"
}
},
"transition": {
"id": "1"
}
}];
request({
url: url,
method: "POST",
json: true,
body: message,
}, function (error){});
Url(https://hibernate.atlassian.net/rest/api/2/issue/WEBSITE-1/transitions) gives me;
{"expand":"transitions","transitions":[]}
How can I resolve an issue in JIRA? Am I doing wrong?
You've got the right approach, but you need to authenticate your requests with a user that has permission to execute the transition.
Because you execute your requests anonymously, JIRA gives you a response that does not contain any transitions you can execute and will not allow you to perform a transition.
Take a look at the documentation for the request module or another example.
To get the full list of transitions, append the string ?expand=transitions.fields to your existing url. So in this case it would look like
var url = "https://hibernate.atlassian.net/rest/api/2/issue/WEBSITE-1/transitions?expand=transitions.fields";

Getting started with FortuneJS

Evening All,
I'm hoping that this is me making a school-boy error. Trying to 'get started' with fortuneJS but having an issue whilst trying to create a new resource.
So, I've setup fortune as described on their homepage. I've opted to use their JSON API plugin, again setup as per their repo.
I'm using Postman to test out the server I've created and I can create a 'user' resource no problem with the following:
{
"data": {
"type": "user",
"attributes": {
"name": "Andrew"
}
}
}
That works fine and I get a response as follows:
{
"data": {
"type": "users",
"id": "37446bbc",
"attributes": {
"name": "Andrew"
},
"relationships": {
"posts": {
"links": {
"self": "http://localhost:1337/users/37446bbc/relationships/posts",
"related": "http://localhost:1337/users/37446bbc/posts"
},
"data": []
}
},
"links": {
"self": "http://localhost:1337/users/37446bbc"
}
}
}
Now, I need to try and create the 'post' resource. Following the JSON API specification I'm posting the following payload:
{
"data": {
"type": "posts",
"attributes": {
"message": "This is my first post"
},
"relationships": {
"author": {
"data": { "type": "users", "id": "37446bbc" }
}
}
}
}
All I get back from that is:
{
"errors": [
{
"title": "Error",
"detail": "An internal server error occurred."
}
]
}
I've debugged by placing a console log of the 'error' on line 118 in node_modules/fortune/dist/lib/dispatch/index.js which shows this error:
[TypeError: Cannot set property 'user' of undefined]
Any advice or guidance you can offer would be greatly appreciated. Hopefully it's just me!
I'm using babel-node app.js to get this running. To save you time, I've thrown up the code onto a public repo
It seems that the actual error message needs to be relayed to the client. You can do so by attaching a catch to the HTTP listener:
const server = http.createServer((request, response) =>
fortune.net.http(store)(request, response)
.catch(error => console.log(error.stack)))
What I found when I recreated the steps was this:
Error: A related record for the field "author" was not found.
However, since it is a generic Error and not a typed error that Fortune uses internally, it is hidden from the client.
So by setting the correct value for the author id, it was able to create a record with that association successfully.
Future versions will be patched so that this informative error message gets shown.
The originally posted question works fine, the version of node was causing an error. Upgrading to v4.2.1 resolved the issue.

Resources