How to get Paypal transactions in NodeJS - node.js

Problem description:
I go into my paypal buyer sandbox account and send 10 Pounds to my facilitator sandbox account. The transaction goes trough and all is fine. I log into my facilitator account and i see the transaction.
Now when i use the following nodejs code to get the transactions:
var paypal_api = require('paypal-rest-sdk');
var config_opts = {
'host': 'api.sandbox.paypal.com',
'port': '',
'client_id': 'HIDDEN',
'client_secret': 'HIDDEN'
};
var listPayment = {
'count': '10',
'start_index': '0'
};
paypal_api.payment.list(listPayment, config_opts, function (error, payment) {
if (error) {
throw error;
} else {
console.log("List Payments Response");
console.log(JSON.stringify(payment));
}
});
i get this in the console:
List Payments Response
{"count":0,"httpStatusCode":200}
So its not showing me any transactions.
How can i see those transactions?
I have read on another Stackoverflow thread that these might not show up because they are not done trough REST. If thats the case, would payments done trough the official PayPal mobile app appear in my NodeJS response?
Question 2:
Is there any way by using NodeJS to see transactions that are coming into my merchant account? (paid in from the PayPal app, or from their website)
Question 3:
How can i use WebHooks to see the transactions in NodeJS?
I would really appreciate your help guys, ive been looking everywhere for a response to these questions.
Thank you so much.
Alex
EDIT 1:
I have tried Webhooks and i still cant get anything to trigger when i do a transaction. An event triggers on my NodeJS side only when i use the Webhook simulator, but not when i do a normal transaction on Paypal using my sandbox accounts.
I wonder if there is any way to test things with the Paypal mobile app, does anybody know if you can do sandbox testing with the mobile app?

Click manage webhooks and Add your webhook listener URL(API endpoint), then select which event you want to get from PayPal.

Related

How to implement atomicity when working with webhooks in node?

I am working on a MERN application. I am trying to implement a stripe subscription in it.
Whenever a user tries to pay using the stripe checkout session the webhooks route is invoked and the database is updated according to the event type.
Here is my webhook controller code:
export const postStripeWebhook = async (req: ExtendedRequest, res: Response) => {
//code to determine the eventype from the stripe signature.
switch (eventType) {
case "checkout.session.completed":
subscription = event.data.object;
await prisma.users.update({
where: {
id: subscription.metadata.userId,
},
data: {
stripeUserId: subscription.customer,
subscriptionStatus: true,
},
});
break;
//other events type
}
res.sendStatus(200);
};
As one can see when the customer pays for the product, stripe sends a checkout.session.complete event. On receiving this event the subscriptionStatus of the customer is updated in the database and the product is provisioned to the user.
But what if an error occurs while updating the database? Now the user will be left with a situation where his account has been deducted with the subscription money but since the database is not updated he has not provisioned the product.
According to me, this situation can be eliminated if the whole process is made atomic i.e if the database does not change send the deducted amount to the user.
But I don't know whether this is the right way to tackle this problem. Also I don't know how to perform atomic operations in node.js.
Please guide me with the problem.

Angular/node.js Stripe Checkout Integration (1 account to facilitate payments from third party payer to third party receiver)

Man, I have been at this for some days and can't find a good solution to this. I want to use my account (via public key and private key) to facilitate payments from one account to another (nothing will be going into my account). On the front-end I have:
checkout(amount) {
const strikeCheckout = (<any>window).StripeCheckout.configure({
key: environment.PRODUCTION==='true'?stripeLiveClientId:stripeTestClientId,
locale: 'auto',
token: (stripeToken: any) => {
if(stripeToken){
console.log(stripeToken)
this.createCharge(stripeToken,amount)
}
}
});
strikeCheckout.open({
name: 'Camel Stripe',
description: 'Stripe Checkout',
amount: amount
});
}
Just a small snipet, but essentially this just captures the credit card and email and ensures it is a valid credit card and then makes a stripe token. I then pass this token to the node backend and do:
stripe.paymentIntents.create({
amount: priceInPence,
currency: 'usd',
source: stripeTokenId,
capture: false, // note that capture: false
}).then(charge => {
return res.json({ success: true, message: 'Success', result: charge })
}).catch(error => {
res.status(400).json({ success: false, status: 400, message: error });
});
//})
};
No matter how I structure it, it always end's up getting the payment to my account, the account with the public/private key. Does anyone know a way I can use this token since it has the necessary information, and send the money to another account?
You can't accept payments and move the funds into a completely different Stripe account unless you're using Connect.
To piggy back on Paul's comment, after much research on Stripe Connect I wanted to share my findings. Please note this is specific to my use case and is using angular/express.
Connect offers multi-party payments, meaning you can receive funds from 1 user, then route them into another users account. You will need a stripe connect account. After that you connect an account, aka create account. They offer 3 account types all these account types need to be
Custom: basically is if you don't want the account you're routing to to see anything stripe related, meaning it is white labeled and the user has no dashboard or view of what is going on in the background.
Standard(the one I chose): this account will have a full stripe dashboard, it has all the functionality that an account would have that you make on your own. You will get a unique account id relevant to your specific connect account environment, on their end, they will have multiple account ids depending on how many other connects they are connected to, or if it is an already existing account. You will need to use this api to get the link to have them verify information before they are integrated into your connect environment account link api
Express: they will have a slimmed down version of a dashboard, it is similar to standard with less functionality
At this point you're ready to start routing payments. I did angular on the front-end, here is an example basically this simply creates a stripeToken, which is a verification that the card data is valid. You need to pass this to a backend to make use of it, this will not create any charges.
On the backend, I used express, you use the charge api You pass the stripeToken as the source attribute. One important step is to add the stripe account id you see in your connected accounts dashboard. It should look similar to:
stripe.charges.create({
amount: priceInPence,
currency: 'usd',
source: stripeTokenId,
capture: false, // note that capture: false
},{
stripeAccount:'{{acctId}}'
})
This should be sufficient to get your payments routing to the necessary account while leveraging a simple UI checkout.
One thing to note about the charges API, this is an older API and has less functionality. For my use case (US CA only with only card payments) it is sufficient. If you have a more complicated use case, or maybe your app is for heavy prod use to many users you should look into payment intents.

Stripe TypeError: Cannot read property 'payment_intent' of undefined

I'm integrating the payment methods to the app with Stripe and Paypal and now working on Stripe integration.
The backend is Node, Sails.js, and the frontend is React.js.
I followed the guide they provided but and tested the payment processing using testing card.
But I got the error, which says TypeError: Cannot read property 'payment_intent' of undefined.
Here is my code.
- Frontend
this.props.stripe.createPaymentMethod({
type: 'card',
card: cardElement,
}).then(({paymentMethod}) => {
// API call
})
- Backend
subscribe = await stripe.subscriptions.create({
customer: customerId,
items: [
{price: plan.stripe.stripeId},
],
expand: ['latest_invoice.payment_intent']
});
Please help me to fix this issue.
In my opinion you don't have to create the PaymentIntent per subscrition.
Here is what Stripe API docs says about paymentIntent.
A PaymentIntent guides you through the process of collecting a payment from your customer. We recommend that you create exactly one PaymentIntent for each order or customer session in your system. You can reference the PaymentIntent later to see the history of payment attempts for a particular session.
So they recommend to create the paymentIntent per transaction and in subscription case, the payment is proceed in background automatically and paymentIntent is also generated in my experience.
But on the other hand in checkout option, you need to create the paymentIntent first before proceeding the payment.
I think you code was not wrong but I think you didn't follow the correct guide from Stripe or used wrong credit card.
Please refer this link:
Stripe API Payment_intents

StripeInvalidRequestError: You can only create new accounts if you've signed up for Connect

When trying to test Stripe Connect Api, I get the following error:
'StripeInvalidRequestError: You can only create new accounts if you've
signed up for Connect'
I have signed up for an account and I use my personal Secret Key so i don't know why its not letting me test this feature. Below is the code for the post request.
router.post('/api/post/create-stripe-account', async (req,res) => {
const data = req.body;
try{
var account = await stripe.accounts.create({
country: 'US',
type: 'custom',
requested_capabilities: ['card_payments', 'transfers'],
});
res.json(account)
}catch(error){
console.log(error)
}
})
Link to documentation that I followed: Using Connect with Custom Accounts
Any thoughts why stripe doesn't think I have signed up? I have used this secret key successfully with sending payments by card but stripe connect doesn't seem to like it. Thanks!
I followed these steps from stripe docs and it works.
https://stripe.com/docs/connect/collect-then-transfer-guide
You should be able to create new accounts in test mode using your test API key (starting with sk_test_). Can you confirm that's the key you're using on your server?
The error you're getting usually indicates your Connect platform application is not complete and you're trying to create an account in live mode (using your sk_live_ key). In order to create accounts in live mode you need to complete your platform profile in the Stripe Dashboard.
I resolved the issue based on Justin Michael's comment
Do you have Connect enabled in test mode here? dashboard.stripe.com/test/connect/accounts/overview Does anything seem amiss in your Connect settings here? dashboard.stripe.com/test/settings/applications –
Justin Michael
Jul 9, 2020 at 23:31
Click on get started only then you can get access to create function of stripe.

401 Error when sending data to Stripe `Customers` API

I want to create a new customer in Stripe upon form submit and add that customer's credit card to their account. As of now, I'm using the following code upon submit in my React App. The create customer call is then made separately from my server:
async submit(ev) {
let {token} = await this.props.stripe.createToken({name: "Name"});
let response = await fetch("https://api.stripe.com/v1/customers", {
method: "POST",
headers: {"Content-Type": "text/plain"},
body: token.id
});
When sending that data, I get a 401 error on the let response = ... line. I know that a 401 is an auth error, but my test API keys are definitely correct and don't have limits on how they can access my stripe account. Can anyone advise?
The issue here is that you are trying to create a Customer object client-side in raw Javascript. This API request requires your Secret API key. This means you can never do this client-side, otherwise anyone could find your API key and use it to make refunds or transfer for example.
Instead, you need to send the token to your own server. There, you will be able to create a Customer or a Charge using one of Stripe's official libraries instead of making the raw HTTP request yourself.
In my case, it's throwing the error due to a missing of stripe public key
var stripe = Stripe('{{ env("STRIPE_KEY") }}');
then I pass the public key as above, and it worked like a charm.

Resources