Facebook chatbot with multiple keywords - bots

I have done a tutorial how to setup a Facebook chatbot for a fanpage.
It works perfect and we also can change the keyword and the message that pops up in case a user types exact the keyword.
Now the only thing is, we do not figure out, how to add multiple keywords with answers.
var express = require('express')
var bodyParser = require('body-parser')
var request = require('request')
var app = express()
app.set('port', (process.env.PORT || 5000))
// Process application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))
// Process application/json
app.use(bodyParser.json())
// Index route
app.get('/', function (req, res) {
res.send('Hello world, I am a chat bot')
})
// for Facebook verification
app.get('/webhook/', function (req, res) {
if (req.query['hub.verify_token'] === 'token') {
res.send(req.query['hub.challenge'])
}
res.send('Error, wrong token')
})
// Spin up the server
app.listen(app.get('port'), function() {
console.log('running on port', app.get('port'))
})
// API End Point -
app.post('/webhook/', function (req, res) {
messaging_events = req.body.entry[0].messaging
for (i = 0; i < messaging_events.length; i++) {
event = req.body.entry[0].messaging[i]
sender = event.sender.id
if (event.message && event.message.text) {
text = event.message.text
if (text === 'hi') {
sendGenericMessage(sender)
continue
}
sendTextMessage(sender, "parrot: " + text.substring(0, 200))
}
if (event.postback) {
text = JSON.stringify(event.postback)
sendTextMessage(sender, "Postback received: "+text.substring(0, 200), token)
continue
}
}
res.sendStatus(200)
})
var token = " enter token here"
// function to echo back messages
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending messages: ', error)
} else if (response.body.error) {
console.log('Error: ', response.body.error)
}
})
}
// Send an test message back as two cards.
function sendGenericMessage(sender) {
messageData = {
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"elements": [{
"title": "title 1",
"subtitle": "subtitle",
"image_url": "url of image",
"buttons": [{
"type": "web_url",
"url": "https://www.facebook.com/",
"title": "Facebook"
}, {
"type": "web_url",
"url": "https://www.reddit.com",
"title": "Reddit"
},{
"type": "web_url",
"url": "https://twitter.com/",
"title": "Twitter"
}],
}, {
"title": "Title 2 ",
"subtitle": "Subtitle",
"image_url": "imgurl",
"buttons": [{
"type": "postback",
"title": "title",
"payload": "payload",
},{
"type": "postback",
"title": "title",
"payload": "payload",
}, {
"type": "postback",
"title": "title",
"payload": "payload",
}],
}, {
"title": "title",
"subtitle": "subtitle",
"image_url": "http://www.google.com",
"buttons": [{
"type": "postback",
"title": "title",
"payload": "payload",
},{
"type": "postback",
"title": "title",
"payload": "payload",
}, {
"type": "postback",
"title": "title",
"payload": "payload",
}],
}]
}
}
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending messages: ', error)
} else if (response.body.error) {
console.log('Error: ', response.body.error)
}
})
}

Do you mean to say - You need to handle multiple keywords for same answer? If that is the case, then facebook sends the message as text on webhook. You need to catch it and send message back to facebook accordingly.
As in the code you've sent, [if (text === 'hi')], you need sample messages(hi in this case) to be stored in system and map the answer.

Related

Dialogflow custom payload not posting message in facebook messenger

I have a custom payload message carousel as one of my intents response in Dialogflow. It looks like this.
{
"facebook": {
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"elements": [
{
"title": "Welcome!",
"subtitle": "We have the right hat for everyone.We have the right hat for everyone.We have the right hat for everyone.",
"imageUrl": "https://www.stepforwardmichigan.org/wp-content/uploads/2017/03/step-foward-fb-1200x628-house.jpg",
"buttons": [
{
"postback": "https://f1948e04.ngrok.io",
"text": "View Website"
},
{
"text": "Start Chatting",
"postback": "PAYLOAD EXAMPLE"
}
]
},
{
"title": "Welcome!",
"imageUrl": "https://www.stepforwardmichigan.org/wp-content/uploads/2017/03/step-foward-fb-1200x628-house.jpg",
"subtitle": "We have the right hat for everyone.We have the right hat for everyone.We have the right hat for everyone.",
"buttons": [
{
"postback": "https://f1948e04.ngrok.io",
"text": "View Website"
},
{
"text": "Start Chatting",
"postback": "PAYLOAD EXAMPLE"
}
]
}
]
}
}
}
}
I use the following code inside my node.js webhook to handle messages.
function handleCardMessages(messages, sender) {
let elements = [];
for (var m = 0; m < messages.length; m++) {
let message = messages[m];
let buttons = [];
for (var b = 0; b < message.card.buttons.length; b++) {
let isLink = (message.card.buttons[b].postback.substring(0, 4) === 'http');
let button;
if (isLink) {
button = {
"type": "web_url",
"title": message.card.buttons[b].text,
"url": message.card.buttons[b].postback
}
} else {
button = {
"type": "postback",
"title": message.card.buttons[b].text,
"payload": message.card.buttons[b].postback
}
}
buttons.push(button);
}
let element = {
"title": message.card.title,
"image_url":message.card.imageUri,
"subtitle": message.card.subtitle,
"buttons": buttons
};
elements.push(element);
}
sendGenericMessage(sender, elements);
}
function sendGenericMessage(recipientId, elements) {
var messageData = {
recipient: {
id: recipientId
},
message: {
attachment: {
type: "template",
payload: {
template_type: "generic",
elements: elements
}
}
}
};
callSendAPI(messageData);
}
function callSendAPI(messageData) {
request({
uri: 'https://graph.facebook.com/v3.2/me/messages',
qs: {
access_token: config.FB_PAGE_TOKEN
},
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}
So, everytime the intent is called. Dialogflow is supposed to post the custom payload message to the user's messenger app. But, i don't know why the message is not being posted.
If I use Dialogflow's quickreply/card messages response option under it's facebook messenger response option. Everything works fine. But, if i want to send a quickreply/card message using custom payload, the message is not displayed in the user's messenger when the intent is called. Logs looks fine. Don't know what i am doing wrong. Help will be appreciated.
hi here is how it should be formated like if your are using a custom webhook
{
"fulfillmentMessages": [
{
"payload": {
"facebook": {
"attachment": {
"type": "template",
"payload": {
"template_type":"generic",
"elements":[
{
"title":"Welcome!",
"image_url":"https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png",
"subtitle":"We have the right hat for everyone.",
"default_action":{
"type":"web_url",
"url":"https://www.google.com/",
"webview_height_ratio":"tall"
},
"buttons":[
{
"type":"web_url",
"url":"https://www.google.com/",
"title":"View Website"
},
{
"type":"postback",
"title":"Start Chatting",
"payload":"DEVELOPER_DEFINED_PAYLOAD"
}
]
},
{
"title":"Welcome!",
"image_url":"https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png",
"subtitle":"We have the right hat for everyone.",
"default_action":{
"type":"web_url",
"url":"https://www.google.com/",
"webview_height_ratio":"tall"
},
"buttons":[
{
"type":"web_url",
"url":"https://www.google.com/",
"title":"View Website"
},
{
"type":"postback",
"title":"Start Chatting",
"payload":"DEVELOPER_DEFINED_PAYLOAD"
}
]
}
]}
}
}
}
}
]
}
if you want to use the build in one it should be like this
from other answer in here
{
"facebook": {
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"elements": [
{
"title": "Welcome!",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/7/70/Example.png",
"subtitle": "We have the right hat for everyone.",
"default_action": {
"type": "web_url",
"url": "https://commons.wikimedia.org/wiki/File:Example.png",
"messenger_extensions": false,
"webview_height_ratio": "tall",
"fallback_url": "https://website.com/"
},
"buttons": [
{
"type": "web_url",
"url": "https://commons.wikimedia.org/wiki/File:Example.png",
"title": "View Website"
},
{
"type": "postback",
"title": "Start Chatting",
"payload": "DEVELOPER_DEFINED_PAYLOAD"
}
]
}
]
}
}
}
}

Cannot see the location permission in Dialogflow

I am trying to retrieve the location of user in Dialogfow. Following docs and blogs, this is what I have written in index.js file of fulfilment.
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const {Permission} = require('actions-on-google');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
//const agent = new dialogflow();
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
const requestPermission = (agent) => {
//agent.add("Locaation access!");
//agent.add(new Permission({permissions:'NAME', context:''}));
agent.requestSource = agent.ACTIONS_ON_GOOGLE;
const conv = agent.conv();
conv.ask(new Permission({
context: '',
permissions: 'DEVICE_PRECISE_LOCATION',
}));
console.log(conv);
agent.add(conv);
agent.add("Apple");
};
const userInfo = (agent) => {
if(agent.isPermissionGranted()){
const address = agent.getDeviceLocation().address;
if (address){
agent.add("You are at ${address}");
}
else{
agent.add("Cannot locate you");
}
}
else{
agent.add("Cannot locate you");
}
};
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('request_permission',requestPermission);
intentMap.set('user_info', userInfo);
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
EDIT
This is JSON response I get.
Raw API response:
{
"responseId": "RESPONSE-ID",
"queryResult": {
"queryText": "locate",
"action": "request_permission",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"platform": "ACTIONS_ON_GOOGLE",
"simpleResponses": {
"simpleResponses": [
{
"textToSpeech": "Apple",
"displayText": "Apple"
}
]
}
}
],
"webhookPayload": {
"google": {
"systemIntent": {
"intent": "actions.intent.PERMISSION",
"data": {
"optContext": "",
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"permissions": [
"DEVICE_PRECISE_LOCATION"
]
}
},
"expectUserResponse": true
}
},
"intent": {
"name": "projects/MY_PROJECT_NAME",
"displayName": "request_permission"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 3564
},
"languageCode": "en"
},
"webhookStatus": {
"message": "Webhook execution successful"
}
}
Fulfillment request:
{
"responseId": "RESPONSE-ID",
"queryResult": {
"queryText": "locate",
"action": "request_permission",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"intent": {
"name": "PROJECT-NAME",
"displayName": "request_permission"
},
"intentDetectionConfidence": 1,
"languageCode": "en"
},
"originalDetectIntentRequest": {
"payload": {}
},
"session": "SESSION-ID"
}
Fulfillment response:
illmentMessages": [
{
"platform": "ACTIONS_ON_GOOGLE",
"simpleResponses": {
"simpleResponses": [
{
"textToSpeech": "Apple",
"displayText": "Apple"
}
]
}
}
],
"payload": {
"google": {
"expectUserResponse": true,
"systemIntent": {
"intent": "actions.intent.PERMISSION",
"data": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "",
"permissions": [
"DEVICE_PRECISE_LOCATION"
]
}
}
}
},
"outputContexts": []
}
This response is correct I think. But nothing is added on screen. It shows this on screen,
There are not any errors in console as well. But I am not getting anything when I try the agent.
In raw response, the action.intent.PERMISSION is present but why it is not added or agent asked for yes/no?
The location permissions only work if you're using Actions on Google with the Google Assistant. You also need to test it using the Actions on Google simulator - click where it says "See how it works in Google Assistant".
It doesn't work with the other Dialogflow integrations (such as Facebook or Slack) and won't work with the Dialogflow simulator (the simulator on the right hand side of the page).

Dialogflow detect intent "payload" not working

I want to send custom parameters to the webhook. According to the documentation I set it under "payload" parameter. But I don't see values I set on response object.
https://dialogflow.com/docs/reference/api-v2/rpc/google.cloud.dialogflow.v2#google.cloud.dialogflow.v2.QueryParameters
Here is my code
function detectIntent(query, sessionId, contextData, callback) {
let projectId = config.get('projectId');
let languageCode = 'en-US';
let sessionPath = sessionClient.sessionPath(projectId, sessionId);
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: languageCode,
}
},
queryParams: {
contexts: [
contextData
],
payload: { foo: "bar" }
},
};
sessionClient
.detectIntent(request)
.then(responses => {
const result = responses[0].queryResult;
callback(null, result);
})
.catch(err => {
callback(err, null);
});
}
Here is the response I'm getting
{
"fulfillmentMessages": [
{
"platform": "PLATFORM_UNSPECIFIED",
"text": {
"text": [
""
]
},
"message": "text"
}
],
"outputContexts": [
{
"name": "projects/ddddd-102d1/agent/sessions/blvy6skjngu4kvt/contexts/blvy6skjngu4kvu",
"lifespanCount": 2,
"parameters": {
"fields": {
"msisdn": {
"stringValue": "773959698",
"kind": "stringValue"
}
}
}
},
{
"name": "projects/ddddd-102d1/agent/sessions/blvy6skjngu4kvt/contexts/actionshow_card-followup",
"lifespanCount": 2,
"parameters": null
}
],
"queryText": "internet slow",
"speechRecognitionConfidence": 0,
"action": "action.show_card",
"parameters": {
"fields": {}
},
"allRequiredParamsPresent": true,
"fulfillmentText": "",
"webhookSource": "",
"webhookPayload": null,
"intent": {
"inputContextNames": [],
"events": [],
"trainingPhrases": [],
"outputContexts": [],
"parameters": [],
"messages": [],
"defaultResponsePlatforms": [],
"followupIntentInfo": [],
"name": "projects/ddddd-102d1/agent/intents/e378b17a-d899-4e69-8dfd-4b938b0222a5",
"displayName": "action.show_card",
"priority": 0,
"isFallback": false,
"webhookState": "WEBHOOK_STATE_UNSPECIFIED",
"action": "",
"resetContexts": false,
"rootFollowupIntentName": "",
"parentFollowupIntentName": "",
"mlDisabled": false
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"fields": {
"webhook_latency_ms": {
"numberValue": 161,
"kind": "numberValue"
}
}
},
"languageCode": "en-us"
}
I tried with formatting the payload json by doing structjson.jsonToStructProto({foo: 'bar'}) as mention in following link
Send parameters to webhook on dialogflow sdk v2
but no success.

GeoJSON parse node

I am getting an 500 error 'unexpected problem has occurred' when I parse the GeoJSON data from this weather API site using node app.
The code is a simple proxy server to receive request from client for weather info on a particular site and process an async request to the weatherAPI, when the response is received its send to the client. When I replace the URL with something that returns JSON it works. The issue is when the response data is GeoJSON.
Appreciate if anyone help shed some light on how to parse the GeoJSON response in node JavaScript.
Thank you in advance.
Here is my node app code:
function initialize() {
// Setting URL and headers for request
var options = {
url: 'https://api.weather.xxx/points/39.7456,-97.0892',
headers: {
'User-Agent': 'request'
}
};
// Return new promise
return new Promise(function(resolve, reject) {
// Do async job
request.get(options, function(err, resp, body) {
if (err) {
reject(err);
} else {
resolve(JSON.parse(body));
}
})
})
}
http.createServer(function (req, res) {
var initializePromise = initialize();
initializePromise.then(function(result) {
var geoDetails = result;
console.log("Initialized Geo details");
// Use user details from here
console.log(geoDetails);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied!' + '\n' +
JSON.stringify(geoDetails, true, 2));
res.end();
}, function(err) {
console.log(err);
})
}).listen(9000);
Here is the GeoJSON data :
{
"#context": [
"...",
{
"wx": "...",
"s": "...",
"geo": "...",
"unit": "...",
"#vocab": "...",
"geometry": {
"#id": "s:GeoCoordinates",
"#type": "geo:wktLiteral"
},
"city": "s:addressLocality",
"state": "s:addressRegion",
"distance": {
"#id": "s:Distance",
"#type": "s:QuantitativeValue"
},
"bearing": {
"#type": "s:QuantitativeValue"
},
"value": {
"#id": "s:value"
},
"unitCode": {
"#id": "s:unitCode",
"#type": "#id"
},
"forecastOffice": {
"#type": "#id"
},
"forecastGridData": {
"#type": "#id"
},
"publicZone": {
"#type": "#id"
},
"county": {
"#type": "#id"
}
}
],
"id": "...api.weather.xxx/points/39.7456,-97.0892",
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-97.0892,
39.7456
]
},
"properties": {
"#id": "...api.weather.xxx/points/39.7456,-97.0892",
"#type": "wx:Point",
"cwa": "TOP",
"forecastOffice": "...api.weather.xxx/offices/TOP",
"gridX": 31,
"gridY": 80,
...
"relativeLocation": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-97.086661,
39.679376
]
},
"properties": {
"city": "Linn",
"state": "KS",
"distance": {
"value": 7366.9851976444,
"unitCode": "unit:m"
},
"bearing": {
"value": 358,
"unitCode": "unit:degrees_true"
}
}
},
...
}
}
I am interested in getting all the Properties in plain text or JSON.
Modify your headers to accept JSON.
var options = {
url: 'https://api.weather.gov/points/39.7456,-97.0892',
headers: {
'user-agent': 'request',
'accept': 'application/json'
}
};

Payment Authorization & Capture the Payment (Future) using PayPal-node-SDK (PayPal Express Checkout)

I'm working with PayPal Express Checkout and and what i need to do is Authorize and Capture the payment later separately, my current PayPal flow is,
1) I create a payment using following code:
var paypal = require('paypal-rest-sdk');
function createPayPal(req, res, itemsArray, redirectsTos) {
var payment = {
"intent": "sale",
"payer": {},
"transactions": [{
"amount": {
"currency": sails.config.currency,
"total": itemsArray.totalArrayAmount,
"details": {
"subtotal": itemsArray.totalArrayAmount,
"fee": sails.config.PayPalCreateFee
}
},
"invoice_number": req.session.invNum,
"item_list": {
"items": itemsArray.itemsArray
}
}]
};
sails.log.info('payment obj :', JSON.stringify(payment))
payment.payer.payment_method = sails.config.PayPalPaymentMethod;
payment.redirect_urls = {
"return_url": res.locals.return_url_buy,
"cancel_url": res.locals.cancel_url_buy
};
paypal.payment.create(payment, function(error, payment) {
if (error) {
sails.log.error(error);
redirectsTos(({
message: 'failure',
redirect: '/paypal/error'
}), null);
} else {
sails.log.info('Payment ID = ', payment.id);
sails.log.info('User ID = ', req.session.userSession);
var redirectUrl;
for (var i = 0; i < payment.links.length; i++) {
var link = payment.links[i];
if (link.method === 'REDIRECT') {
redirectUrl = link.href;
sails.log.info('goto:', redirectUrl)
redirectsTos(null, ({
message: 'success',
redirect: redirectUrl
}));
}
}
}
});
}
and Paypal returns me the order information and the redirect urls and i redirected the user to the href in links object. then when the payflow returns to me website it sends me
{
paymentId: 'PAY-5FB60654T5508144abcxyzZLQ',
token: 'EC-26U68825EW2123428',
PayerID: 'QSABTRW6AHYH6'
}
and then i executed the payment using following code.
function executePayPal(req, paymentId, payerId, executedPayPal) {
sails.log.info('in executedPayPal');
var details = {
"payer_id": payerId
};
var payment = paypal.payment.execute(paymentId, details, function(error, payment) {
if (error) {
sails.log.error('error in payment id in executePayPal function of paypal controller', error);
var err = JSON.stringify(error);
var errParsed = JSON.parse(err);
crashHandlingService.appCrash(errParsed, 101202);
executedPayPal(({
message: 'failure',
redirect: '/paypal/error/'
}), null);
} else {
executedPayPal(({
message: 'success',
redirect: '/paypal/success/'
}), null);
}
});
}
Now what this code basically do is
Create the payment,
Redirect the user to paypal page C
Capture the payment.
and what i actually want to achieve is
authorize the payment ->
capturing the payment so that i can capture the payment some later time in some cronJob or service.
And redirect the user to paypal page in the middle of above flow, i really don't know how to authorize, redirect and then capture payment.
So please guide me in this regards.
Note: i've read the following paypal documentation but not able to understand. and please keep in mind that i need to show payment detail on paypal page and also the coupon code and its discount on the payment page.
https://developer.paypal.com/docs/integration/direct/capture-payment/#authorize-the-payment
https://developer.paypal.com/docs/classic/express-checkout/ht_ec-singleAuthPayment-curl-etc/
Thanks in advance :) .
Finally I've found the solution and i thought i should post it here so that it could be helpful for other.
So there are basically 4 following steps and one have to you use PayPal Node SDK
Create Payment.
Redirect User to PayPal.
Execute Authorized Payment.
Capture Authorized Payment.
To Create Payment you can use payment.create method of PayPal Node sdk here.
.Create Method will return url links in "href" to redirect user to PayPal page so redirect the user to PayPal page.
After returning from pay PayPal page you have to run .execute method of PayPal Node SDK here, using payer_id and paymentId recived from PayPal.
and finally when you need to capture the amount of the authorized transaction you had to .authorization.capture method of PayPal Node SDK here, by providing amount and the 17 digits authorization id recived in execute authorize response.
Code & Response sample are provided below in case if the links doesn't works in future.
.create Code
var create_payment_json = {
"intent": "authorize",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://return.url",
"cancel_url": "http://cancel.url"
},
"transactions": [{
"item_list": {
"items": [{
"name": "item",
"sku": "item",
"price": "1.00",
"currency": "USD",
"quantity": 1
}]
},
"amount": {
"currency": "USD",
"total": "1.00"
},
"description": "This is the payment description."
}]
};
paypal.payment.create(create_payment_json, function (error, payment) {
if (error) {
console.log(error.response);
throw error;
} else {
for (var index = 0; index < payment.links.length; index++) {
//Redirect user to this endpoint for redirect url
if (payment.links[index].rel === 'approval_url') {
console.log(payment.links[index].href);
}
}
console.log(payment);
}
});
Response Sample
{
"id": "PAY-17S8410768582940NKEE66EQ",
"create_time": "2013-01-31T04:12:02Z",
"update_time": "2013-01-31T04:12:04Z",
"state": "approved",
"intent": "authorize",
"payer": {
"payment_method": "credit_card",
"funding_instruments": [
{
"credit_card": {
"type": "visa",
"number": "xxxxxxxxxxxx0331",
"expire_month": "11",
"expire_year": "2018",
"first_name": "Betsy",
"last_name": "Buyer",
"billing_address": {
"line1": "111 First Street",
"city": "Saratoga",
"state": "CA",
"postal_code": "95070",
"country_code": "US"
}
}
}
]
},
"transactions": [
{
"amount": {
"total": "7.47",
"currency": "USD",
"details": {
"tax": "0.03",
"shipping": "0.03"
}
},
"description": "This is the payment transaction description.",
"related_resources": [
{
"sale": {
"id": "4RR959492F879224U",
"create_time": "2013-01-31T04:12:02Z",
"update_time": "2013-01-31T04:12:04Z",
"state": "completed",
"amount": {
"total": "7.47",
"currency": "USD"
},
"parent_payment": "PAY-17S8410768582940NKEE66EQ",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/4RR959492F879224U",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/4RR959492F879224U/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-17S8410768582940NKEE66EQ",
"rel": "parent_payment",
"method": "GET"
}
]
}
}
]
}
],
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-17S8410768582940NKEE66EQ",
"rel": "self",
"method": "GET"
}
]
}
.execute Code
var paymentId = 'PAYMENT id created in previous step';
paypal.payment.execute(paymentId, execute_payment_json, function (error, payment) {
if (error) {
console.log(error.response);
throw error;
} else {
console.log("Get Payment Response");
console.log(JSON.stringify(payment));
}
});
Response Sample
{
"id": "PAY-34629814WL663112AKEE3AWQ",
"create_time": "2013-01-30T23:44:26Z",
"update_time": "2013-01-30T23:44:28Z",
"state": "approved",
"intent": "aurthorize",
"payer": {
"payment_method": "paypal",
"payer_info": {
"email": "bbuyer#example.com",
"first_name": "Betsy",
"last_name": "Buyer",
"payer_id": "CR87QHB7JTRSC"
}
},
"transactions": [
{
"amount": {
"total": "7.47",
"currency": "USD",
"details": {
"tax": "0.04",
"shipping": "0.06"
}
},
"description": "This is the payment transaction description.",
"related_resources": [
{
"sale": {
"id": "1KE4800207592173L",
"create_time": "2013-01-30T23:44:26Z",
"update_time": "2013-01-30T23:44:28Z",
"state": "completed",
"amount": {
"currency": "USD",
"total": "7.47"
},
"transaction_fee": {
"value": "0.50",
"currency": "USD"
},
"parent_payment": "PAY-34629814WL663112AKEE3AWQ",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/1KE4800207592173L",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/sale/1KE4800207592173L/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-34629814WL663112AKEE3AWQ",
"rel": "parent_payment",
"method": "GET"
}
]
}
}
]
}
],
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-34629814WL663112AKEE3AWQ",
"rel": "self",
"method": "GET"
}
]
}
.authorization.capture Code
var capture_details = {
"amount": {
"currency": "USD",
"total": "4.54"
},
"is_final_capture": true
};
paypal.authorization.capture("5RA45624N3531924N", capture_details, function (error, capture) {
if (error) {
console.error(error);
} else {
console.log(capture);
}
});
Response Sample
{
"id": "6BA17599X0950293U",
"create_time": "2013-05-06T22:32:24Z",
"update_time": "2013-05-06T22:32:25Z",
"amount": {
"total": "4.54",
"currency": "USD"
},
"is_final_capture": true,
"state": "completed",
"parent_payment": "PAY-44664305570317015KGEC5DI",
"links": [
{
"href": "https://api.sandbox.paypal.com/v1/payments/capture/6BA17599X0950293U",
"rel": "self",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/capture/6BA17599X0950293U/refund",
"rel": "refund",
"method": "POST"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/authorization/5RA45624N3531924N",
"rel": "authorization",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-44664305570317015KGEC5DI",
"rel": "parent_payment",
"method": "GET"
}
]
}
You can get more information from REST API Reference And PayPal-node-SDK.
Forgive me if the response sample are somehow a little bit change because i've copied it from PayPal web.
Thanks.

Resources