Creating a customer in BrainTree with a credit card - node.js

I'm reading the docs about creating a customer. I need to create one with a credit card, a cvc number but I get an error and I don't know how I must create it.
I show my code
if(user.local.subscription == undefined){
//creamos cliente
gateway.customer.create({
creditCard : {
number : cardnumber,
expirationDate : "12/15"
}
}, function (err, result) {
if(err){
//return res.status(500).json({ error : "Error creating customer"});
console.log(err);
}
console.log(result);
/*user.subscription = result;
userId = result.customer.id;*/
});
}

var braintree = require("braintree");
var gateway = braintree.connect({
environment: braintree.Environment.Sandbox,
merchantId: "your sanboxmerchant",
publicKey: "your sandbox public key",
privateKey: "sandbox privatekey"
});
gateway.customer.create({
creditCard : {
cardholder_name : 'james bliz',
number : "4111111111111111",
cvv : '123',
expirationDate : "12/17"
}
}, function (err, result) {
if(err){
//return res.status(500).json({ error : "Error creating customer"});
console.log(err);
}
console.log(result);
/*user.subscription = result;
userId = result.customer.id;*/
});
the answer should be somthing like this
{ customer:
{ id: '29931379',
merchantId: 'qn5442rvm794nc6q',
firstName: null,
lastName: null,
company: null,
email: null,
phone: null,
fax: null,
website: null,
createdAt: '2015-05-12T10:33:41Z',
updatedAt: '2015-05-12T10:33:42Z',
customFields: '',
creditCards: [ [Object] ],
addresses: [],
paymentMethods: [ [Object] ] },
success: true }
take the required field from it i think you will need only the customer id from tha result object.

Related

Document is not rolled back if transaction gets aborted Mongoose

In my server I'm trying to use transactions to create orders. Before saving the order with Order.create I check and modify quantities in Product records, check for payment details on buyer and seller, aborting the transaction if anything goes wrong ( I omitted that part in the code sample below), but when passing the object from the request body to Order.create as I normally do on document creation it fails not finding requested parameters for the Order schema.
I have found here https://github.com/Automattic/mongoose/issues/6761#issuecomment-437493275 and also the doc https://mongoosejs.com/docs/api.html#model_Model.create say that when inside a transaction the object needs to be passed into an array ( like await SomeModel.create([obj], { session }) ), so I suppose that as we are inside a transaction, if the transaction is aborted then the created record gets rolled back.
In my app it does create the document but it's not rolled back if I abort the transaction . In fact if I query the db with the document id just created I get the result back.
Also now my logic inside the finally statement is not working anymore. There, if the transaction is not aborted the if statement check on session.inTransaction should return true so there I commit the transaction and end the session. If instead the transaction is aborted it should return false and nothing else happens as whenever I abort the transaction I also end the session.
When using await SomeModel.create([obj], { session }) the if statement never returns true so the transaction is never committed and the session is never ended.
Can you see what's wrong with the code here below?
exports.createOrder = async (req, res) => {
const { productIdList, productPromotionList, customerId, shopId } = req.body;
// const order = req.body;
var notAvailableProducts = [];
var notAvailablePromotions = [];
// console.log('createOreder req.body is : ', order);
var amount = 0.00;
var stripeAccountId = '';
var stripeCustomerId = '';
var receiptEmail = '';
var defaultSource = '';
const session = await Order.startSession();
session.startTransaction();
try {
... omitted part
console.log('createOrder req.body is : ', req.body);
// const order =
// await
Order.create(
// req.body, // error
[ req.body], // works but doesn't get rolled back if transaction is aborted
{ session: session },
function (err, result) {
if (err) {
console.log('Mongoose createOrder error: Order.create', err);
res.status(503).send({ error: "Internal error" });
session.abortTransaction();
session.endSession();
return;
}
console.log('Mongoose createOrder: ', result);
res.status(200).send({
message: "Order created successfully!",
data: result,
missingProducts: notAvailableProducts,
missingPromotions: notAvailablePromotions
});
});
await session.abortTransaction();
session.endSession();
}
catch (error) {
console.log('Transaction error is:', error);
await session.abortTransaction();
session.endSession();
res.status(503).send({ error: "Internal error." });
// throw error;
}
finally {
if (session.inTransaction == true) {
console.log('committing session');
await session.commitTransaction();
console.log('ending session');
session.endSession();
} else {
console.log('session was aborted');
}
}
}
set of prints
createOrder req.body is : {
date: 1639251616628,
price: '12.0',
state: 'Waiting',
collectedOnDate: 0,
cancelledOnDate: null,
customerFcmToken: 'dVes2tOhSyKiOg1RJNzViE:APA91bEBPj_5y9G_uuP5lFI5Iobjv_ikpfxnbtNmx5VUY9x74Cgci8Dl8SVSoDe5Gq7x7nw5GfD7DlDo-769MsfALeHcRuiz0CdO2J_m5x1Lof92mSQh5uPy2IpwuI_M5UMZfBktR1PM',
customerId: '61af23dc02edbe24ce0344f4',
customerName: 'vincenzo calia',
shopId: '61ab9198262df7517970aed4',
shopName: 'vincenzo calia',
city: 'Bologna',
region: 'Emilia-Romagna',
country: 'Italy',
productCategoryList: [ 'Safety and locks' ],
productIdList: [ '61af8bec02edbe24ce034963' ],
productPromotionList: [ false ],
productNameList: [ null ],
productPriceList: [ '12' ],
isBuyNow: 'false'
}
session was aborted
Mongoose createOrder: [
{
city: 'Bologna',
region: 'Emilia-Romagna',
country: 'Italy',
date: 2021-12-11T19:40:16.628Z,
price: '12.0',
state: 'Waiting',
collectedOnDate: 0,
cancelledOnDate: null,
customerFcmToken: 'dVes2tOhSyKiOg1RJNzViE:APA91bEBPj_5y9G_uuP5lFI5Iobjv_ikpfxnbtNmx5VUY9x74Cgci8Dl8SVSoDe5Gq7x7nw5GfD7DlDo-769MsfALeHcRuiz0CdO2J_m5x1Lof92mSQh5uPy2IpwuI_M5UMZfBktR1PM',
customerId: '61af23dc02edbe24ce0344f4',
customerName: 'vincenzo calia',
shopId: '61ab9198262df7517970aed4',
shopName: 'vincenzo calia',
productCategoryList: [ 'Safety and locks' ],
productIdList: [ '61af8bec02edbe24ce034963' ],
productIsPromotionList: [],
productNameList: [ null ],
productPriceList: [ '12' ],
isBuyNow: false,
totalRating: 0,
ratings: 0,
_id: new ObjectId("61b4fea0d184bca49c82f2d0"),
createdAt: 2021-12-11T19:40:16.607Z,
updatedAt: 2021-12-11T19:40:16.607Z,
__v: 0,
averageRating: 0,
id: '61b4fea0d184bca49c82f2d0'
}
]
Mongoose Order.findOrderById: {
_id: new ObjectId("61b4fea0d184bca49c82f2d0"),
city: 'Bologna',
region: 'Emilia-Romagna',
country: 'Italy',
date: 2021-12-11T19:40:16.628Z,
price: '12.0',
state: 'Waiting',
collectedOnDate: 0,
cancelledOnDate: null,
customerFcmToken: 'dVes2tOhSyKiOg1RJNzViE:APA91bEBPj_5y9G_uuP5lFI5Iobjv_ikpfxnbtNmx5VUY9x74Cgci8Dl8SVSoDe5Gq7x7nw5GfD7DlDo-769MsfALeHcRuiz0CdO2J_m5x1Lof92mSQh5uPy2IpwuI_M5UMZfBktR1PM',
customerId: '61af23dc02edbe24ce0344f4',
customerName: 'vincenzo calia',
shopId: '61ab9198262df7517970aed4',
shopName: 'vincenzo calia',
productCategoryList: [ 'Safety and locks' ],
productIdList: [ '61af8bec02edbe24ce034963' ],
productIsPromotionList: [],
productNameList: [ null ],
productPriceList: [ '12' ],
isBuyNow: false,
totalRating: 0,
ratings: 0,
createdAt: 2021-12-11T19:40:16.607Z,
updatedAt: 2021-12-11T19:40:16.607Z,
__v: 0,
averageRating: 0,
id: '61b4fea0d184bca49c82f2d0'
}
As it seems that Model.create can't be undone upon aborting a transaction the only way I found to manage it ( not sure it's just a workaround or the proper business logic) is to wrap it in a if statement checking the current state of the session if (session.inTransaction()) {} as I do in the finally statement to commit the transaction or simply end the session.
exports.createOrder = async (req, res) => {
...
if (session.inTransaction()) {
const order = {
city: city,
region: region,
country: country,
date: Date.now,
price: totalOrderAmount,
state: 'Waiting',
collectedOnDate: null,
cancelledOnDate: null,
customerFcmToken: customerFcmToken,
customerId: customerId,
customerName: customerName,
shopId: shopId,
shopName: shopName,
productCategoryList: productCategoryList,
productIdList: productIdList,
productIsPromotionList: productIsPromotionList,
productNameList: productNameList,
productPriceList: productPriceList,
isBuyNow: isBuyNow,
stripePayment: stripePaymentIntent
};
await Order.create(
[order],
{ session: session },
function (err, result) {
if (err) {
console.log('Mongoose createOrder error: Order.create', err);
session.abortTransaction();
responseCode = 503;
responseMessage = 'Internal error';
return;
}
console.log('Mongoose createOrder: ', result);
responseCode = 200;
responseData = result;
message = "Order created successfully!";
}).exec();
}
}
}
catch (error) {
console.log('Transaction error is:', error);
await session.abortTransaction();
session.endSession();
res.status(503).send({ error: "Transaction error." });
// throw error;
}
finally {
if (session.inTransaction()) {
console.log('transacion wasn\'t aborted');
console.log('committing session ');
await session.commitTransaction();
} else {
console.log('transacion wasn aborted');
}
console.log('ending session ');
await session.endSession();
res.status(responseCode).send({
message: responseMessage,
data: responseData,
unavailableProducts: unavailableProducts,
unavailablePromotions: unavailablePromotions
});
}
}

stripe.confirmCardPayment is not a function

when i am creating subscription through stripe it gives err message
As i am doing subscription through stripe
i am also giving some msg about authentication in dashboard like 3d secure authenticatio.
and my cvc_check is unavailable in showing dashboard
1.first issue is 3d secure authentication.
2.cvc check unavailbel in India.
My account is also india
TypeError: stripe.confirmCardPayment is not a function
my code is pls what i am doing wrong
stripe.customers.create(
{
name: name,
email: email,
phone: reqObj.phone,
address: { "city": reqObj.address, "country": "IN",
"line1": "", "line2": "", "state":"India" },
},
function (err, customer) {
if (err) {res.json({ "status": false, "error": err })
console.log(err)
}else {
customer_id=customer.id;
stripe.tokens.create(
{
card: {
number: reqObj.card_no,
exp_month: reqObj.exp_month,
exp_year: reqObj.exp_year,
cvc: reqObj.cvc
},
},
function (err, token) {
if (err) {
res.json({ "status": false, "errorT": err})
} else {
// stripe.customers.createSource(
// customer_id,
// { source: token.id },
// function (err, card) {
// if (err) {
// res.json({ status: "false", "error": err })
// }else {
stripe.plans.list(
{ product: "prod_IMGu6PI2mJbBCi", active: true },
function (err, plans) {
if (!err) {
for(i in plans.data){
if(plans.data[i].amount==reqObj.amount){
var myId=plans.data[i].id
stripe.paymentMethods.create({
type: 'card',
card: {
number: reqObj.card_no,
exp_month: reqObj.exp_month,
exp_year: reqObj.exp_year,
cvc: reqObj.cvc
},
},function(err,result){
// console.log(err,result)
stripe.paymentMethods.attach(result.id, {
customer: customer_id,
},function(err,result1){
// console.log(err,"result1",result1)
stripe.customers.update(
customer_id,
{
invoice_settings: {
default_payment_method: result.id,
},
},function(err,res2){
// console.log(err,"res2")
stripe.subscriptions.create({
customer: customer_id,
items: [{ price: myId}],
expand: ['latest_invoice.payment_intent'],
},function(err,res3){
console.log(err,"res3",
res3.latest_invoice.payment_intent.client_secret)
a=res3.latest_invoice.payment_intent.client_secret
stripe.confirmCardPayment(
res3.latest_invoice.payment_intent.client_secret,
function(err,paymentIntent)
{
console.log(err,"paymentIntent",paymentIntent)
}
)}
);
} );
});
});
}
});
}
// asynchronously called
});
Your code is mixing up client-side and server-side code together which will not work. The stripe.confirmCardPayment() method comes from Stripe.js and should be called client-side in Javascript inside the browser, not server-side with Node.js.
The beginning of your code is updating a Customer with the right default payment method id. Then it's creating a Subscription. And then, if the creation fails to have the first invoice paid, for example if the card is declined or requires 3D Secure, you have to then go back to the client, in the browser, to run the next step which is to confirm the PaymentIntent associated with the Subscription's Invoice.
So you need to go back to the client, where you originally created the PaymentMethod id pm_123456 that you passed in result.id and then try to confirm the PaymentIntent.

Problem with ottoman not resolving the references

I have two models in my ottoman 1.0.5 setup. One holds contact info which includes an emails array of docs and then the email doc. I can insert new contacts fine as well as emails in docs and the corresponding link in the contact doc for the new email.
Here is my model
const ottoman = require("ottoman")
ottoman.bucket = require("../app").bucket
var ContactModel = ottoman.model("Contact",{
timestamp: {
type: "Date",
default: function() {return new Date()}
},
first_name : "string",
last_name : "string",
emails: [
{
ref:"Email"
}
]} )
var EmailModel = ottoman.model("Email",{
timestamp: {
type: "Date",
default: function() {return new Date()}
},
type : "string",
address : "string",
name: "string"
} )
module.exports = {
ContactModel : ContactModel,
EmailModel : EmailModel
}
Now to get an contact and all its emails i use this function
app.get("/contacts/:id", function(req, res){
model.ContactModel.getById(req.params.id,{load: ["emails"]}, function(error, contact){
if(error) {
res.status(400).json({ Success: false , Error: error, Message: ""})
}
res.status(200).json({ Success: true , Error: "", Message: "", Data : contact})
})
})
Which returns me this
{
"Success": true,
"Error": "",
"Message": "",
"Data": {
"timestamp": "2019-01-30T23:59:59.188Z",
"emails": [
{
"$ref": "Email",
"$id": "3ec07ba0-aaec-4fd4-a207-c4272cef8d66"
}
],
"_id": "0112f774-4b5d-4b73-b784-60fa9fa2f9ff",
"first_name": "Test",
"last_name": "User"
}
}
if i go and log the contact to my console i get this
OttomanModel(`Contact`, loaded, key:Contact|0112f774-4b5d-4b73-b784-60fa9fa2f9ff, {
timestamp: 2019-01-30T23:59:59.188Z,
emails: [ OttomanModel(`Email`, loaded, key:Email|3ec07ba0-aaec-4fd4-a207-c4272cef8d66, {
timestamp: 2019-01-31T00:36:01.264Z,
_id: '3ec07ba0-aaec-4fd4-a207-c4272cef8d66',
type: 'work',
address: 'test#outlook.com',
name: 'Test Outlook',
}),
OttomanModel(`Email`, loaded, key:Email|93848b71-7696-4ef5-979d-05c19be9d593, {
timestamp: 2019-01-31T04:12:40.603Z,
_id: '93848b71-7696-4ef5-979d-05c19be9d593',
type: 'work',
address: 'newTest#outlook.com',
name: 'Test2 Outlook',
}) ],
_id: '0112f774-4b5d-4b73-b784-60fa9fa2f9ff',
first_name: 'Test',
last_name: 'User',
})
This shows that emails was resolved but why does it not show up in the returned json. On the other hand if i return contact.emails i get the resolved emails just fine. So i hope someone can shed some light on what i am missing here
I asked a similar question on the couchbase forum, and I also found out the solution:
(a slight difference that the result of my search is an array not an object like in your case)
forum.couchbase.com
app.get("/assets", (req, res) => {
AssetModel.find({}, { load: ["assetModelId", "assetGroupId", "assetTypeId"] }, (err, results) => {
if (err) return res.status(400).send("no asset found");
const assets = [];
results.map(asset => {
assets.push({...asset});
});
res.status(200).send(assets)
});
});

Updating multiple sub-documents with Mongoose and Node

I have a Model wich contains an array of sub-documents. This is a Company:
{
"_id" : ObjectId(":58be7c236dcb5f2feff91ac0"),
"name" : "sky srl",
"contacts" : [
{
"_id" : ObjectId("58be7c236dcb5f2feff91ac2"),
"name": { type: String, required: true },
"company" : ObjectId("58be7c236dcb5f2feff91ac0"),
"email" : "sky#gmail.com",
"chatId" : "",
"phone" : "123456789",
"name" : "John Smith"
},
{
"_id" : ObjectId("58be7f3a6dcb5f2feff91ad3"),
"company" : ObjectId("58be7f3a6dcb5f2feff91ad1"),
"email" : "beta#gmail.com",
"chatId" : "",
"phone" : "987654321",
"name" : "Bill Gaset"
}
],
"__v" : 1
}
I have several companies, and I want to update the field chatId of all the contacts in all the companies, that matches the phone I am searching for.
My Schema definitions (simplified, for focusing on question):
var contactSchema = new Schema({
[...]
phone: { type: String, required: true },
email: { type: String },
chatId: { type: String },
company: Schema.Types.ObjectId,
});
var companySchema = new Schema({
name: { type: String, required: true },
type: { type: String, default: "company" },
contacts: [contactSchema]
});
I tried
var conditions = { "contacts.phone": req.body.phone };
var partialUpdate = req.body; //it contains 'req.body.phone' and 'req.body.chatId' attributes
Company.find(conditions).then(
function (results) {
results.map( function(companyFound) {
companyFound.contacts.forEach(function (contactContainer){
if (contactContainer.phone == partialUpdate.phone) {
contactContainer.chatId = partialUpdate.chatId;
Company.save();
companyFound.save();
contactContainer.save();
results.save();
}
//not sure of what to save, so i save everything
companyFound.save();
contactContainer.save();
results.save();
});
});
});
following this answer; but it doesn't works. It does not save anything, what I'm doing wrong?
I have never done this before, but worth a try.
Maybe you need to use $elemMatch.
// find the companies that have contacts having the phone number
Company.find().where('contacts', { $elemMatch: { phone: req.body.phone }}).exec(function (err, companies) {
if (err) {
console.log(err);
return;
}
// see if you can at least get the query to work
console.log(companies);
async.eachSeries(companies, function updateCompany(company, done) {
// find and update the contacts having the phone number
company.contacts.forEach(function (contact, i, arr) {
if (contact.phone == req.body.phone) {
arr[i].chatId = req.body.chatId;
}
});
company.save(done);
}, function allDone (err) {
console.log(err);
});
});
Note, I am using async.js to do async operations on multiple items.
Honestly, I would have simply made contacts an array of Contact references -- much easier to query and update.
Just for the records: I did this to make it work without async.js:
Company.find().where('contacts', { $elemMatch: { phone: req.body.phone } })
.exec(function (err, companies) {
if (err) {
console.log(err);
return;
}
console.log("companies: " + JSON.stringify(companies, null, 4));
companies.forEach(function (company) {
company.contacts.map(function (contact, i, arr) {
if (contact.phone == req.body.phone) {
arr[i].telegramChatId = req.body.telegramChatId;
}
});
company.save();
},
function allDone(err) {
console.log(err);
});
});`

How to perform update in mongoose

I am trying to update my record,but its not happening in my case and i am not sure about the case where it went rong,can any one suggest me help.Thanks
My mongoose code,
exports.updatestudent = function (req, res) {
var student = new Student(req.body);
var data = {};
var id = req.params;
var params = req.body;
var item = {
'name': params.name,
'rollnumber': params.rollnumber,
'class': params.class,
'city': params.city
};
Student.update({ _id: id },{ $set: item }, function (err, result) {
if (err) {
console.log('err');
}
if (result) {
data = { status: 'success', error_code: 0, result: result, message: 'Article updated successfully' };
res.json(data);
}
});
};
my schema,
var StudentSchema = new Schema({
name: {
type: String
},
rollnumber: {
type: String
},
class: {
type: String
},
city: {
type: String
},
status: {
type: String
},
_id: {
type: Schema.ObjectId
}
});
/**
* Hook a pre validate method to test the local password
*/
mongoose.model('student', StudentSchema, 'student');
my result in postman,
{
"status": "success",
"error_code": 0,
"result": {
"ok": 0,
"n": 0,
"nModified": 0
},
"message": "Article updated successfully"
}
I am trying to update my record,but its not happening in my case and i am not sure about the case where it went rong,can any one suggest me help.Thanks
It seems you forgot to specify the key.
Replace
var id = req.params;
By
var id = req.params.id;
Make sure that you are getting your id in var id = req.params;
And I am sure you will not get your id like this
check your req.params; values and give your correct id in the query
Update
var item = {};
if (params.name) {
item.name = params.name;
}
if (params.rollnumber) {
item.rollnumber = params.rollnumber
}
Student.update({
_id: id
}, {
$set: item
}, function(err, result) {
if (err) {
console.log('err');
}
if (result) {
data = {
status: 'success',
error_code: 0,
result: result,
message: 'Article updated successfully'
};
res.json(data);
}
});

Resources