Paypal webhooks no longer sending in sandbox mode - paypal-rest-sdk

I used the following link to create a plan and then used the app id from my sandbox rest API panel instead of the provided one. I did this in order to receive webhooks to my backend which is totally separate at the moment. Yesterday it was working perfectly many times, and then all of a sudden it stopped sending all webhooks after a successful payment on the frontend. If I use the webhook simulator it works, and I am able debug the webhook in Laravel. I am using ngrok, in order to test it in a local environment, which also shows a full log of webhooks, so the mock ones work, but the ones from the browser dont.
Edit:
I created a new login, everything from zero. And below you can see the webhook event, but still not received by backend.
https://www.sandbox.paypal.com/billing/plans
<div id="paypal-button-container"></div>
<script src="https://www.paypal.com/sdk/js?client-id=CUSTOM_APP_CLIENT_ID&vault=true" data-sdk-integration-source="button-factory"></script>
<script>
paypal.Buttons({
style: {
shape: 'rect',
color: 'gold',
layout: 'vertical',
label: 'subscribe',
},
createSubscription: function(data, actions) {
return actions.subscription.create({
'plan_id': 'PLAN_ID'
});
},
onApprove: function(data, actions) {
alert(data.subscriptionID);
}
}).render('#paypal-button-container');
</script>

PayPal is attempting to send those webhooks, but they will remain 'Pending' so long as the connection to your Webhook URL listener times out or doesn't respond with a 200 level HTTP status

Related

Fetch event never gets triggered in Chrome extension service worker. Is this expected?

What I want to do
I'm trying to intercept a third party website's fetch events and modify its request body in a Chrome extension. Modifying the request body is not allowed by the chrome.webRequest.onBeforeRequest event handler. But it looks like regular service workers do have the ability to listen for and modify fetch events and manually respond to the request using my own response, which means I should be able to intercept the request, modify the body, send the modified request to the API, and then respond to the original request with my modified request's response.
The problem
It looks like neither of these event handlers ever get triggered, despite plenty of fetch events being triggered by the website, as I can see in the Network panel.
// background.js
self.onfetch = (event) => console.log(event.request); // never shows
// or
self.addEventListener("fetch", (event) => {
console.log(event.request); // never shows
});
I can verify that the service worker is running by seeing other console.logs appearing in the service worker console, both top-level logs as well as logs triggered by the "install" event
// background.js
console.log(self); // works
self.addEventListener("install", (event) => {
console.log(event); // works
});
Hypothesis
Do the fetch event handlers not get triggered because extension service workers are not allowed access to these for security reasons? That would make sense, I just haven't seen this documented anywhere explicitly so it would be good to know if this is indeed a platform limitation or if I'm doing something wrong.
Alternate solutions?
If this is indeed a limitation of the extensions platform, is there any way other way I can use a Chrome extension to modify request bodies on a third party website?

how does users.watch (in gmail google api) listen for notifications?

I am confused as to how should the watch feature in the gmail API be implemented to recieve the push notificatons inside a node.js script. Should I call the method inside an infinite loop or something so that it doesn't stop listening for notifications for email once after the call is made?
Here's the sample code that I've written in node.js:
const getEmailNotification = () => {
return new Promise(async (resolve, reject) => {
try{
let auth = await authenticate();
const gmail = google.gmail({version: 'v1', auth});
await gmail.users.stop({
userId: '<email id>'
});
let watchResponse = await gmail.users.watch({
userId: '<email id>',
labelIds: ['INBOX'],
topicName: 'projects/<projectName>/topics/<topicName>'
})
return resolve(watchResponse);
} catch(err){
return reject(`Some error occurred`);
}
})
Thank you!
Summary
To receive push notifications through PUB/SUB you need to create a web-hook to receive them. What does this mean? You need a WEB application or any kind of service that exposes a URL where notifications can be received.
As stated in the Push subscription documentation:
The Pub/Sub server sends each message as an HTTPS request to the subscriber application at a pre-configured endpoint.
The endpoint acknowledges the message by returning an HTTP success status code. A non-success response indicates that the message should be resent.
Setup a channel for watch the notifications could be summarized in the following steps (the documentation you refer to indicates them):
Select/Create a project within the Google Cloud Console.
Create a new PUB/SUB topic
Create a subscription (PUSH) for that topic.
Add the necessary permissions, in this case add gmail-api-push#system.gserviceaccount.com as Pub/Sub Publisher.
Indicate what types of mail you want it to listen for via Users.watch() method (which is what you are doing in your script).
Example
I give you an example using Apps Script (it is an easy way to visualize it, but this could be achieved from any kind of WEB application, as you are using Node.js I suppose that you are familiarized with Express.js or related frameworks).
First I created a new Google Apps Script project, this will be my web-hook. Basically I want it to make a log of all HTTP/POST requests inside a Google Doc that I have previously created. For it I use the doPost() equal to app.post() in Express. If you want to know more about how Apps Script works, you can visit this link), but this is not the main topic.
Code.gs
const doPost = (e) => {
const doc = DocumentApp.openById(<DOC_ID>)
doc.getBody().appendParagraph(JSON.stringify(e, null, 2))
}
Later I made a new implementation as a Web App where I say that it is accessible by anyone, I write down the URL for later. This will be similar to deploying your Node.js application to the internet.
I select a project in the Cloud Console, as indicated in the Prerequisites of Cloud Pub/Sub.
Inside this project, I create a new topic that I call GmailAPIPush. After, click in Add Main (in the right bar of the Topics section ) and add gmail-api-push#system.gserviceaccount.com with the Pub/Sub Publisher role. This is a requirement that grants Gmail privileges to publish notification.
In the same project, I create a Subscription. I tell it to be of the Push type and add the URL of the Web App that I have previously created.
This is the most critical part and makes the difference of how you want your application to work. If you want to know which type of subscription best suits your needs (PUSH or PULL), you have a detailed documentation that will help you choose between these two types.
Finally we are left with the simplest part, configuring the Gmail account to send updates on the mailbox. I am going to do this from Apps Script, but it is exactly the same as with Node.
const watchUserGmail = () => {
const request = {
'labelIds': ['INBOX'],
'topicName': 'projects/my_project_name/topics/GmailAPIPush'
}
Gmail.Users.watch(request, 'me')
}
Once the function is executed, I send a test message, and voila, the notification appears in my document.
Returning to the case that you expose, I am going to try to explain it with a metaphor. Imagine you have a mailbox, and you are waiting for a very important letter. As you are nervous, you go every 5 minutes to check if the letter has arrived (similar to what you propose with setInterval), that makes that most of the times that you go to check your mailbox, there is nothing new. However, you train your dog to bark (push notification) every time the mailman comes, so you only go to check your mailbox when you know you have new letters.

Stripe Connect Express Webhook - How to get Stripe webhook to fire once user has completed Stripe Connect Express form and is redirected

so I've spent a fair amount of time (weeks) with this issue however still have not been able to figure out how to resolve it. I believe I've narrowed it down to the issue of trying to get a Stripe Connect webhook to fire once a user has completed the signup form through the Stripe Connect Express process. Here's the example Stripe gives with their RocketRides.io demo. I've submitted an issue to stripe but am waiting to hear back. I was hoping to get there quicker with the help of the SO community.
I've previously created other questions as I chase the proverbial rabbits down their various holes as I go through the trial and error process of trying to narrow down the issue so bear with me. You can find these other links at the bottom of this question post.
The snippet below displays my Stripe CLI Log when I am "listening" with stripe listen.
This snippet displays the stripe logs tail
The customer.created is fired when a user signs up for my app, which is supposed to happen using the code below. I am not sure if this is supposed to be used when trying to use a Stripe Connect Account which is my intention. I'm still figuring out Stripe. The bottom line is I need to have payout and subscription capability, and from the research I've done, Stripe Connect is the direction to go.
exports.createStripeCustomerHTTPSCall = functions.firestore.document('Users/{userName}').onCreate((change, context) =>{
console.log("Stripe Customer profile for " + context.params.userName + " created.");
return stripeToken.customers.create(
{
description: 'My First Test Customer (created for API docs)',
email: context.params.userName,
},
(err, customer) => {
// asynchronously called
console.log("Creating Stripe customer failed because: " + err.toString())
}
)
Once a user signs up for the App and is logged in the FirebaseDatabase as a user, they will be directed to the Stripe Connect Express form.
The issue now I'm running into is getting stripe to fire a Connect Webhook which would trigger Step 4, a Cloud Functions version of a cURL request to the redirected URL with the Authentication code, and potentially a state code. The account.application.authorized event only occurs in my listener only after I have sent in a cURL request (I think is called a GET Request? I'm not a formally trained programmer)
I believe the issue lies in setting up a webhook to fire once a user has completed the form and is redirected which I think should be account.updated?
Here is my webhook setup:
Here is my Node.js code. I'm not sure if its relevant since I can't even get the webhook to fire but just in case:
exports.stripeCreateOathResponseToken = functions.https.onRequest((req, res) => {
console.log("rawbody: " + rawbody); // <-- usually comes back with req.rawbody
console.log("request.body: " + req.body); // <-- returns undefined
console.log("request.query.code: " + req.query.code); // <-- returns undefined
console.log("request.query.body: " + req.query.body); // <-- returns undefined
console.log("request.query.state: " + req.query.state); // <-- returns undefined
return stripeToken.oauth.token({
grant_type: 'authorization_code',
code: req.query.code,
}).then(function(response) {
// asynchronously called
return res.send(response)
// var connected_account_id = response.stripe_user_id;
})
.catch(error=> {
res.send(error)
})
});
In case its relevant, here is android kotlin code for when user decides to sign up for payouts capabilities. AKA Stripe Connect Express
openURL.data = Uri.parse(
"https://connect.stripe.com/express/oauth/authorize?" +
"redirect_uri=http://XXXXXXXXXXXXXX.com&" +
"client_id=ca_XXXXXXXXXXXXXXXXXXXX" + // how to hide client id? maybe look at how to access from stripe CLI
"state=" + mAuth.currentUser!!.uid +
"&stripe_user[email]=" + userEmail +
"&stripe_user[business_type]=individual" +
"&stripe_user[phone_number]=" + userPhoneNumberStripped +
"#/")
startActivity(openURL)
Previous Questions
Stripe Firebase Cloud Functions - res.send() is not a function
Cloud Firebase Stripe Connect - Retrieve Authorization Code / Access Token, State, etc
Firebase Cloud Functions - Stripe Connect Webhook not firing
Android Stripe Connect WebView - Create Account Form NOT loading
In this case a webhook won't work; you'll instead want to redirect the user - after they complete the OAuth process - to a Cloud Functions URL that runs the Node.js code you've supplied there (and then redirects them to whatever your next step is from there).
You'll also want to make sure that the URL you're redirecting to is listed as a redirect URL in your dashboard's Platform Settings, per here: https://stripe.com/docs/connect/express-accounts#integrating-oauth
In terms of redirecting in GCF, this might help: https://stackoverflow.com/a/45897350/379538

Twilio client js status busy/cancelled no fired

I'm using the Twilio client js in my browser in order to make calls.
In the server I build the Twiml:
const dial = twiml.dial({
/*action: `http://270311bb.ngrok.io/twilio/callend`,*/
callerId: availableNum.phoneNumber || availableNumbers[0].phoneNumber
}, (n) => {
n.number(request.body.number, {
statusCallback: `http://270311bb.ngrok.io/twilio/${request.body.agentId}/status`
});
});
I also tried with the 'action' parameter.
In my status/callend route I get the callstatus only as completed or no-answer, even if the called number is busy, or not connected.
Twilio developer evangelist here.
The StatusCallbackEvent's that you can receive from a call are only initiated, ringing, answered, or completed. Busy or not connected calls are also completed calls. Can you try querying the call from the API when you receive the completed event and see what status the actual call in.

emitting a nodejs event when an event on google calendar is added or updated

Is this possible to emit a nodejs event when a Google calendar event is added or modified? On my nodejs server, I can get/list all the events on the calendar. But I would like to retrieve the events based on the nodejs event rather than checking it manually after a regular interval. Appreciate any ideas!
Actually, it is possible, as stated here: https://developers.google.com/google-apps/calendar/v3/push
You can register a callback URL so you app receives information when your event changes or gets modified. With the Node.JS API it's something like:
calendar.events.watch({
auth:jwtClient,
resource: {
id: "yourChannelId",
type: 'web_hook',
address: "https://www.yoursite.com/notifications"
},
calendarId: "yourcalendarId"
}, function(error, response) {
if (error) {
console.log(error);
return;
}
console.log(response);
});
Not possible. Something like that would require Google to know about your app (to send events or push data to). Google's APIs is only for meant to be accessed. It cannot "tell" your app anything. Your app has to be the one that "asks" Google whether or not something it wants exists or has happened.

Resources