Facebook Messenger, Temporary send message failure when sending receipt - javascript

I want to send to user my receipt with dummy data.
I use this library which simplifies message sending to Facebook.
The structure of my payload is this:
var payload = {
template_type: 'receipt',
recipient_name: '#' + user.name + ' ' + user.surname,
order_number: (new Date).getTime(),
currency: 'USD',
payment_method: 'Наличными',
order_url: 'http://www.example.com',
timestamp: (new Date).getTime() + '',
elements: [
{
title: title,
subtitle: subtitle,
quantity: 1,
price: 20,
currency: 'USD',
image_url: image_url
}
],
address: {
street_1:"Nurly tau",
street_2:"",
city:"Almaty",
postal_code:"050000",
state:"KZ",
country:"KZ"
},
summary: {
subtotal: 20,
shipping_cost: 0,
total_tax: 0,
total_cost: 20
},
adjustments: []
};
I have just filled receipt fields with simple fake data. Also, Facebook tracks the uniqueness of order_numbers of all sent recepts.
When I try to send this receipt I receive an error message:
{ message: '(#1200) Temporary send message failure. Please try again later',
type: 'OAuthException',
code: 1200,
fbtrace_id: 'BHmHRCEQUC4' }
What does this error mean? Facebook's error messages are so enigmatic?

I just had the same problem and after some fiddling I figured it out! The problem is that when you construct the timestamp using (new Date).getTime() it returns the amount of miliseconds since epoch. However, Facebook requires it to be in seconds.

I had the same problem, after a lot of tries, I figured out that the problem is with the timestamp parameter passed with the JSON payload.
I have no clue about what it could be, but it worked for me removing that. (Maybe, the timestamp should be for a moment before the API call, I don't know).

Related

Find Attendees of an Event

I am trying to display events from a "public" google calendar. My requirement is to get the number of attendees (not necessarily the names of the attendees). However, when I get the events using the Calendar API (using an API Key and CalendarID); the event is missing the whole attendees section that is mentioned here.
My question: Do I need to be authenticated ? Does this mean this can't be public, and the web-pages that displays this information will need the "viewer" to authenticate to Google first?
Here is a snippet of my code (edited)...
$.ajax({
type: 'GET',
url: encodeURI('https://www.googleapis.com/calendar/v3/calendars/' + calendarId+ '/events?key=' + myKey),
dataType: 'json',
success: function (response) {
console.log(response);
//here is where I need to get the number of participants
},
error: function (error) {
console.log(error);
//tell that an error has occurred
}
Here is the output...
{kind: 'calendar#events', etag: '"p324e9j5nqabva0g"', summary: 'EDWC Schedule', description: '', updated: '2022-01-04T08:09:10.933Z', …}
accessRole: 'reader'
defaultReminders: (0) []
description: ''
etag: '""'
items: (2) [{…}, {…}]
0: {kind: 'calendar#event', etag: '""', id: '', status: 'confirmed', htmlLink:…}
1: {kind: 'calendar#event', etag: '""', id: '', status: 'confirmed', htmlLink:…}
conferenceData: {}
created: ''
creator: {}
description: ''
end: {dateTime: '2022-01-08T16:00:00+11:00', timeZone: 'Australia/Sydney'}
etag: ''
eventType: 'default'
hangoutLink: ''
htmlLink: ''
iCalUID: ''
id: ''
kind: 'calendar#event'
location: 'Australia'
organizer: {email: '', displayName: '', self: true}
sequence: 0
start: {dateTime: '2022-01-08T13:00:00+11:00', timeZone: 'Australia/Sydney'}
status: 'confirmed'
summary: ''
updated: '2022-01-04T08:09:10.933Z'
[[Prototype]]: Object
[[Prototype]]: Object
length: 2
[[Prototype]]: Array(0)
kind: 'calendar#events'
nextSyncToken: 'CIjkzLfSl_UCEAAYASCvg6XIAQ=='
summary: ''
timeZone: 'Australia/Melbourne'
updated: '2022-01-04T08:09:10.933Z'
[[Prototype]]: Object
You can accomplish this using the Google Api Node.js Client in this manner:
Google Calendar Event Attendees                                                                                
Run in Fusebit
const calendarClient = googleClient.calendar('v3');
// Update the below fields with your desired values
const calendarId = 'YOUR_CALENDAR_ID';
const eventId = 'YOUR EVENT_ID';
const response = await calendarClient.events.get({
calendarId,
eventId,
});
const attendees = response.data.attendees;
As per your question, the answer is yes. Every request sent to the Google Calendar API must include an authorization token. Now, that authorization does not always entail a consent screen, it can also be a short-lived access token or an API key (like in your example). I would encourage you to read more about the authorization process here.
As per your code snippet and response, the events list is located inside the items property of the response object. Here you can find how the response object is structured, but in a nutshell, you can access the events by looping through the items like this:
for (var event of response['items']){}

Stripe Payments Add Payment Source / Card / Method using NodeJS / Vue

I am building a simple SaaS application with recurring payments using NodeJS with Express for the API and Vue for the UI. I have code written to add a customer and link a subscription and plan as well as a few other routines. We allow users to sign up without entering a payment method so now, I need to add a way for a user to add a payment method. I have been through so much documentation that my head is spinning and Stripe support (or lack thereof) has been no help.
I have tried everything from createSource, createToken, and createPaymentMethod in the UI and then submitted that to the API where I have tried using everything from stripeapi.customers.createSource to stripe.paymentMethods.create and nothing works. Everything returns an error about either something missing in the object or the object being incorrect. I have attempted to look at the payment intents API however, this seems like overkill to just simply add a card to a customer.
Here is my latest code.
UI : Create Element
this.stripe = await loadStripe('pk_test_');
let stripeElem = this.stripe.elements();
this.card = stripeElem.create('card', { hideIcon: true, hidePostalCode: false, style: { base: { color: '#363636', fontSize: '22px', fontSmoothing: 'antialiased' }}});
this.card.mount(this.$refs.card);
UI: Submit to API
await this.stripe.createSource(this.card, { type: 'card' } ).then((source) => {
this.$http.post(`/api/route`, source).then((response) => {
if (response.status === 200) {
} else {
}
}).catch(() => {
});
API
await stripeapi.customers.createSource(customer_id, { source: card });
This code produces this object:
{ source:
{ id: 'src_1HLFsEDfvqoM1TxYXmFvlcK9',
object: 'source',
amount: null,
card:
{ exp_month: 1,
exp_year: 2022,
last4: '4242',
country: 'US',
brand: 'Visa',
address_zip_check: 'unchecked',
cvc_check: 'unchecked',
funding: 'credit',
three_d_secure: 'optional',
name: null,
address_line1_check: null,
tokenization_method: null,
dynamic_last4: null },
client_secret: 'src_client_secret_VILuqM6ZikLzp9nMq4gizfN8',
created: 1598653002,
currency: null,
flow: 'none',
livemode: false,
metadata: {},
owner:
{ address: [Object],
email: null,
name: null,
phone: null,
verified_address: null,
verified_email: null,
verified_name: null,
verified_phone: null },
statement_descriptor: null,
status: 'chargeable',
type: 'card',
usage: 'reusable' } }
This code and object produce this error:
(node:352976) UnhandledPromiseRejectionWarning: Error: The source hash must include an 'object' key indicating what type of source to create.
at Function.generate (/data/api/node_modules/stripe/lib/Error.js:39:16)
at IncomingMessage.res.once (/data/api/docroot/node_modules/stripe/lib/StripeResource.js:190:33)
at Object.onceWrapper (events.js:286:20)
at IncomingMessage.emit (events.js:203:15)
at IncomingMessage.EventEmitter.emit (domain.js:448:20)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
All I want to do is take an element, create a payment source/method (whatever it's called) and then associate that with a customer. Any help is appreciated. I have look at so many examples but nothing has worked for me. Everything seems to produce an error about the object or what not.
After more hours of development I finally figured it out! The API reference is severely lacking but this article here explains what to do: https://stripe.com/docs/payments/save-card-without-authentication
Essentially, you create and mount the element. Then, you use the createPaymentMethod in the UI and pass the card element to it. From there, you submit the paymentMethod.id string to your API and then use strip.paymentMethods.attach to attach it to a customer by passing the paymentMethod.id and the Stripe customer ID.
Front End HTML
<div ref="card" class="credit-card"></div>
Front End Create and Mount
this.stripe = await loadStripe('pk_test_YOURKEY');
let stripeElem = this.stripe.elements();
this.card = stripeElem.create('card', { hideIcon: true, hidePostalCode: false, style: { base: { color: '#363636', fontSize: '22px', fontSmoothing: 'antialiased' }}});
this.card.mount(this.$refs.card);
Front End Create Payment Method and Submit to Back End
await this.stripe.createPaymentMethod({ type: 'card', card: this.card }).then((method) => {
this.$http.post(`/users/billing/cards`, { id: method.paymentMethod.id }).then((response) => {
}).catch(() => {
});
}).catch(() => {
});
Please note: this code is NOT complete, it's just meant to give you an example for those that have struggled like I have.
The NodeJS error message reads:
The source hash must include an 'object' key indicating what type of source to create.
It can also be found here, but I'm not certain, if not this is a bogus error message. If this should indeed apply, it would be object: 'card' instead of object: 'source'; but I don't think so.
With Stripe there sometimes is more than one way to get something done:
The source should definitely be a client-side generated card token,
but your client-side doesn't have any code that would token-ize the card.
For reference, these would have to be combined:
https://stripe.com/docs/js/tokens_sources/create_token?type=cardElement
https://stripe.com/docs/api/cards/create

How to fix PayPal's 'Validation Error' in Node JS?

I'm trying to send a request to the PayPal api with an order. However, every time I send a request I'm getting this error:
Currency amount must be non-negative number, may optionally contain exactly 2 decimal places separated by '.', optional thousands separator ',', limited to 7 digits before the decimal point and currency which is a valid ISO Currency Code
I have looked at my request object, but all the values conform to the information PayPal requires. The amount.total is two digits, and the ISO Currency Code is correct, yet I'm still getting the same error.
This is the JSON I'm sending:
{
"amount":{
"total":24.51,
"currency":"USD",
"details":{
"subtotal":22.99,
"tax":0.06625
}
},
"description":"Nature Prints produced by Jonah's Photos.",
"invoice_number":"deb03d30-69e5-11e9-bc27-855d4a6ff0e2",
"payment_options":{
"allowed_payment_method":"INSTANT_FUNDING_SOURCE"
},
"item_list":{
"items":[
{
"name":"IMG_9454 | Nature Photo # 8.5\" x 11\" |",
"quantity":1,
"price":14.99,
"tax":0.06625,
"sku":"40751898403_90408c24a3",
"currency":"USD"
}
]
}
}
This is my code:
var payReq = {
intent:'order',
payer: {
payment_method: 'paypal'
},
redirect_urls:{
return_url:'http://localhost:3000/success',
cancel_url:'http://localhost:3000/cancel'
},
transactions: [{
amount: {
total: Number((((req.session.cart.totalPrice + req.session.cart.shippingPrice) / 100) + ((req.session.cart.totalPrice + req.session.cart.shippingPrice) / 100) * determineSalesTax(req.session.orderInformation.userData.state.toLowerCase())).toFixed(2)),
currency: 'USD',
details: {
subtotal: parseFloat((req.session.cart.totalPrice + req.session.cart.shippingPrice) / 100),
tax: determineSalesTax(req.session.orderInformation.userData.state.toLowerCase())
}
},
description: 'Nature Prints produced by Jonah\'s Photos.',
invoice_number: req.session.orderInformation.orderID,
payment_options: {
allowed_payment_method: 'INSTANT_FUNDING_SOURCE'
},
item_list:{
items: []
}
}]
};
I'm expecting the request to successfully completed, but I get the same error every time.
Versions
PayPal-Rest-SDK: 1.8.1

eBay Trading API addFixedPriceItem Call Error

I'm trying to make a call to addFixedPriceItem in NodeJS. I'm using the NodeJS eBay API. My code is the following:
var ebay = require('ebay-api');
ebay.ebayApiPostXmlRequest({
serviceName: 'Trading',
opType: 'AddFixedPriceItem',
devName: myDevId,
cert: myCertId,
appName: myAppId,
sandbox: true,
title: title,
params: {
'authToken': myClientAuthToken,
version: EBAY_API_VERSION,
Item: {
Country: 'EBAY-US',
Currency: 'USD',
Description: description,
ListingType: 'FixedPriceItem',
PictureDetails: picturesArray,
Quantity: '5',
StartPrice: price
},
}
}, function (error, results) {
if (error) {
console.dir(error);
process.exit(1);
}
console.dir(results);
});
Ultimately, I cannot seem to get it to call. It's not a verification issue or anything, console is stating that No Item.Country exists, and No Item.Currency exists, although I have specifically placed these in my parameters. Any clue why this would occur?
If not, how could I make a call to this in nodeJS without this API? I appreciate any help! :)
Your country code is wrong. It should be 'US' or one of the other CountryCodeType's.

Multiple Stripe Transactions Parse Background Jobs

I'm using Parse to run a background job which will query a parse class and be given a list of Stripe tokens to charge. I've got the background job to easily make one charge however there's issues when multiple payments are present within the one job because of the calling of success/error. I require each stripe charge to give a success or error return so that I can then set the parse object as being paid or unpaid. I'm pretty inexperienced with JavaScript.
I'm able to make two charges successfully however can't get the success/error methods to return on the second stripe charge. Eventually I will want to run a 'for' method to iterate through various customer tokens to make bulk charges.
Parse.Cloud.job("makeCharge", function(request, status) {
Stripe.Charges.create({
amount: 1000 * 10,
currency: "usd",
customer: "cus_customer1" client
},{
success: function() {
status.success("Purchase made!");
},
error: function() {
status.error("Uh oh, something went wrong");
}
});
Stripe.Charges.create({
amount: 100000 * 10,
currency: "usd",
customer: "cus_customer2"
},{
success: function() {
status.success("Purchase made!");
},
error: function() {
status.error("Uh oh, something went wrong");
}
});
});

Categories