I'm trying to call a mint function from js using web3.js and I get unknown account.
this is my smart contract function
function assign(string calldata tokenURI, bytes calldata bytesId) public {
uint256 _tokenId = abi.decode(bytesId, (uint256));
_mint(msg.sender, _tokenId);
_setTokenURI(_tokenId, tokenURI);
emit Assigned(_tokenId, msg.sender, bytesId);
}
This is my js code
Contract.setProvider("https://rpc.ankr.com/polygon_mumbai");
const contract = new Contract(CONTRACT_NFT_ABI, CONTRACT_NFT_ADDRESS);
await contract.methods.assign(tokenURI, plotID)
.send({from: userAddress}, function(error, transactionHash){
if (transactionHash){
res.status(200).send({
res: "OK",
msg: transactionHash
});
}
if (error) {
res.status(200).send({
res: "KO",
msg: error
});
}
});
Everyone can mint. I use Metamask to get address.
Anyone can help me??
Thanks
Related
Hi I am trying to deploy my react native function to Firebase. The pre-conigured firebase function (helloWorld)seems to deploy correctly so I am definitely connected to Firebase. I am trying to deploy my own function which is the chatGPT API and followed the syntax of the initial pre-configured function. The function is a node environment which receives data and sends the data to the chatGPT API which is the completetion function below in the code. It seems that 'await' is already a reserved keyword so I have tried putting 'async' in multiple places but can't seem to deploy this to firebase
const functions = require("firebase-functions"); // Firebase initial function
const OpenAIApi = require("openai") // ChatGPT dependency
const Configuration = require("openai")// ChatGPT dependency
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
// // Create and deploy your first functions
// // https://firebase.google.com/docs/functions/get-started
//
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", {structuredData: true});
response.send("Hello from Firebase!");
});
exports.firebasePromptReceiver = functions.https.onRequest((request, response) => {
if (!configuration.apiKey) {
res.status(500).json({
error: {
message:
'OpenAI API key not configured, please follow instructions in README.md',
},
});
return;
}
const prompt = request.body.prompt || '';
if (prompt.trim().length === 0) {
res.status(400).json({
error: {
message: 'Please enter a valid prompt',
},
});
return;
}
try {
const completion = await openai.createCompletion({ //ChatGPT API
model: 'text-davinci-003',
prompt: generatePrompt(prompt),
temperature: 0.9,
max_tokens: 2048,
});
response.status(200).json({result: completion.data.choices[0].text});
console.log(completion);
} catch (error) {
// Consider adjusting the error handling logic for your use case
if (error.response) {
console.error(error.response.status, error.response.data);
res.status(error.response.status).json(error.response.data);
} else {
console.error(`Error with OpenAI API request: ${error.message}`);
res.status(500).json({
error: {
message: 'An error occurred during your request.',
},
});
}
}
});
Please any help is greatly appreciated
functions.https.onRequest(async(request, response) => {..}
await operator sould be used in async function
AWS lambda function get timeout without any error message When it connect S3 SDK sometimes.
When try to S3.getObject(), Lambda function stop until timeout without any error message.
Only sometimes, I get this happen even I use same parameter, same code.
I used try catch code already. If something wrong, the code make error msg but, It was not.
The point is that the lambda function makes problems 'sometimes'.
Normally, It works well. But, It stop suddenly.
Please help me this problem
enter image description here
enter image description here
enter image description here
2020-07-30T16:45:22.003+09:00
START RequestId: 2c1dcd43-41f6-5d95-a862-9adf3d267ecf Version: $LATEST
2020-07-30T16:45:22.009+09:00
2020-07-30T07:45:22.009Z 2c1dcd43-41f6-5d95-a862-9adf3d267ecf INFO fileKeys : [ '701bcf80-ed63-46d4-9524-d38a14a74fe0.dwg' ]
2020-07-30T16:45:22.009+09:00
2020-07-30T07:45:22.009Z 2c1dcd43-41f6-5d95-a862-9adf3d267ecf INFO getObject drawingFile 701bcf80-ed63-46d4-9524-d38a14a74fe0.dwg
2020-07-30T16:45:22.019+09:00
2020-07-30T07:45:22.018Z 2c1dcd43-41f6-5d95-a862-9adf3d267ecf INFO before getObject
2020-07-30T16:45:22.020+09:00
2020-07-30T07:45:22.020Z 2c1dcd43-41f6-5d95-a862-9adf3d267ecf INFO before createReadStream
2020-07-30T16:45:22.021+09:00
2020-07-30T07:45:22.021Z 2c1dcd43-41f6-5d95-a862-9adf3d267ecf INFO before pipe
2020-07-30T16:45:52.032+09:00
END RequestId: 2c1dcd43-41f6-5d95-a862-9adf3d267ecf
2020-07-30T16:45:52.032+09:00
REPORT RequestId: 2c1dcd43-41f6-5d95-a862-9adf3d267ecf Duration: 30027.38 ms Billed Duration: 30000 ms Memory Size: 3008 MB Max Memory Used: 31 MB
2020-07-30T16:45:52.032+09:00
2020-07-30T07:45:52.032Z 2c1dcd43-41f6-5d95-a862-9adf3d267ecf Task timed out after 30.03 seconds
Here is the code
exports.getObject = async (type, fileKey) => {
try {
const config = env[type]();
const s3 = new AWS.S3();
return new Promise((resolve, reject) => {
const fileName = `/tmp/${fileKey}`;
const fileStream = fs.createWriteStream(fileName, 'binary');
const s3Stream = s3
.getObject({
Bucket: config.origin,
Key: fileKey,
})
.createReadStream();
s3Stream
.on('error', function (err) {
console.error('s3Stream : ', err);
fileStream.end();
reject(err);
})
.on('data', (data) => {
// console.log('data stream...');
})
.on('end', () => {
console.log('s3Stream read end');
});
fileStream
.on('error', function (err) {
console.error('fileStream : ', err);
fileStream.end();
reject(err);
})
.on('close', function () {
console.log('fileStream Done.');
resolve('success');
});
s3Stream.pipe(fileStream)
.on('error', function (err) {
console.error('File Stream:', err);
reject(err);
})
.on('close', function () {
console.log('Pipe Done.');
});;
});
} catch (error) {
throw (error);
}
};
It sounds like your Lambda function is connected to a mixture of private and public subnets.
When calling AWS services, Internet access is required. This can either be obtained via:
Connecting the Lambda function to private subnets and having a NAT Gateway in the public subnet(s), with the Route Table of the private subnets sending traffic destined for 0.0.0.0/0 to the NAT Gateway, or
Use VPC Endpoints within the VPC to allow direct connectivity to the AWS service(s)
If the Lambda function connects to a public subnet, it will not be able to use the NAT Gateway. This will cause connections to AWS to timeout. The random behaviour might be related to which subnet the Lambda function is using.
I am trying to implement Razorpay Payment Integration with Firebase Cloud Functions API in Android. Every is working fine but when verifying the payment on the server Firebase Functions Throw an Internal Error as FirebaseFunctionsEceptions.InternalError.
This is my server side code
exports.confirmPayment = functions.https.onCall((data, context) => {
if (context.auth) {
const amount = data.amount;
const text = data.razorpay_order_id + "|" + data.razorpay_payment_id;
var signature = crypto
.createHmac("sha256", key_secret)
.update(text)
.digest("hex");
if (signature === data.razorpay_signature) {
console.log("PAYMENT SUCCESSFUL");
return { text: "PAYMENT_SUCCESSFUL" };
} else {
throw new functions.https.HttpsError('Invalid Pack Bought', 'Your payment was unsuccessful due to invalid pack purchasing!')
}
}else{
throw new functions.https.HttpsError('Unauthenticated User', 'Unable to confirm Payment!')
}
});
And my Android Studio Java Code is
When Payment Is Successful Razorpay's onPaymentSuccess is thrown and after the payment I have to verify if the payment made is authentic and has same amount. which is done by verifyPayment method which is given below
#Override
public void onPaymentSuccess(String s, PaymentData paymentData) {
Toast.makeText(this, "Payment Successful verifying now!", Toast.LENGTH_SHORT).show();
Task<String> results = verifyPayment(paymentData);
results.addOnCompleteListener(new OnCompleteListener<String>() {
#Override
public void onComplete(#NonNull Task<String> task) {
if (task.isSuccessful()) {
Snackbar.make(btnBuy.getRootView(), "Points have been added to your balance!", Snackbar.LENGTH_SHORT).show();
} else {
Toast.makeText(BuyPointsActivity.this, "" + task.getException(), Toast.LENGTH_LONG).show();
}
}
});
}
Payment Verification Method is Called Via This Method
private Task<String> verifyPayment(PaymentData data) {
Map<String, Object> data1 = new HashMap<>();
data1.put("razorpay_payment_id", data.getPaymentId());
data1.put("razorpay_order_id", data.getOrderId());
data1.put("amount", amount);
data1.put("razorpay_signature", data.getSignature());
data1.put("push", true);
return functions
.getHttpsCallable("confirmPayment")
.call(data1)
.continueWith(new Continuation<HttpsCallableResult, String>() {
#Override
public String then(#NonNull Task<HttpsCallableResult> task) throws Exception {
// This continuation runs on either success or failure, but if the task
// has failed then getResult() will throw an Exception which will be
// propagated down.
String result = (String) task.getResult().getData();
return result;
}
});
}
This is the Cloud Functions Log
confirmPayment
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","authenticationInfo":{"principalEmail":"mmbestonbest#gmail.com"},"requestMetadata":{"callerIp":"47.30.174.168","callerSuppliedUserAgent":"FirebaseCLI/8.0.1,gzip(gfe),gzip(gfe)","requestAttributes":{"time":"2020-04-05T03:49:42.041Z","auth":{}},"destinationAttributes":{}},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","authorizationInfo":[{"resource":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","permission":"cloudfunctions.functions.update","granted":true,"resourceAttributes":{}}],"resourceName":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","request":{"updateMask":"sourceUploadUrl,name,labels,runtime,httpsTrigger","#type":"type.googleapis.com/google.cloud.functions.v1.UpdateFunctionRequest","function":{"runtime":"nodejs8","name":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","httpsTrigger":{},"labels":{"deployment-callable":"true","deployment-tool":"cli-firebase"},"sourceUploadUrl":"https://storage.googleapis.com/gcf-upload-us-central1-2535687d-781c-43d3-8bb1-6cdc1434531f/0cdb81e8-551c-4de7-83c0-8fe50f5a97bb.zip?GoogleAccessId=service-615941328944#gcf-admin-robot.iam.gserviceaccount.com&Expires=1586060376&Signature=rF3FqDJFIbAXSLK8DiemM6X%2BfTvMhv6RMpSvFCaHFjSfQ1kEf%2B5jV92LColV1k0szPt98HsExV2u2HGHRBSobobloyY8oAyh94WYHQTkVQZfhRGCOTvSliuhIhE98kRLVLOEPOjkyhNlz1v9kz48z1tq%2BRYyFB224joiU6qx4Qa58a08QZ3a1Ty4yQAuYedz2lgj3auKoJj10MzGf9T9YW3ffvN9vy4fF1z10erVaNMspgrZoU43NnJGWt%2B185ZRT9Gx%2B6mfxYinkXlfeVj3b8WOKwcYGbtN1FnFaUf8wGX3fAb%2B6FRB2n5ATIchyNHnr1F7E6sbdpmG5cCDZE1kbQ%3D%3D"}},"resourceLocation":{"currentLocations":["us-central1"]}}
9:20:10.642 AM
confirmPayment
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","status":{},"authenticationInfo":{"principalEmail":"mmbestonbest#gmail.com"},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","resourceName":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment"}
9:21:23.540 AM
confirmPayment
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","authenticationInfo":{"principalEmail":"mmbestonbest#gmail.com"},"requestMetadata":{"callerIp":"47.30.174.168","callerSuppliedUserAgent":"FirebaseCLI/8.0.1,gzip(gfe),gzip(gfe)","requestAttributes":{"time":"2020-04-05T03:51:23.614Z","auth":{}},"destinationAttributes":{}},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","authorizationInfo":[{"resource":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","permission":"cloudfunctions.functions.update","granted":true,"resourceAttributes":{}}],"resourceName":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","request":{"updateMask":"sourceUploadUrl,name,labels,runtime,httpsTrigger","#type":"type.googleapis.com/google.cloud.functions.v1.UpdateFunctionRequest","function":{"sourceUploadUrl":"https://storage.googleapis.com/gcf-upload-us-central1-2535687d-781c-43d3-8bb1-6cdc1434531f/87426444-4523-4584-a501-e219ac62e36e.zip?GoogleAccessId=service-615941328944#gcf-admin-robot.iam.gserviceaccount.com&Expires=1586060478&Signature=g2AJztAxLbvci2q7MDms1K7%2B466Z2RM6ALQmeBdH%2By7AA3hMAkdKSI7B3FzY8g1m%2BBuMlO8fkCWBSXcgHauxsOni%2FNW1LD7MZ%2FSUSkZ4npE%2FyVNRy0aitEzVSo6GaPmV9415KoFADyXHAxNakuD8JPZ4wl7qn%2FdcmQ8cZRJ%2BX%2BZ7w2xRw6BmG%2Fbnnmy8DCZe%2F%2Fw%2BIBhM4bpSOO8Ne8nMDa7qAfMzMXHHU8PDuIuIqdOmdIG0xF0itGsw3bhvAc530xWcJY%2F%2B7u%2FUjaszVikTV9igU33nUsqA5%2FzuNLmXrR9B42gn1ncCiwjnx8rlrcETmKkMrD6%2FABM5nYEQ%2Fvy%2BRw%3D%3D","runtime":"nodejs8","name":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","httpsTrigger":{},"labels":{"deployment-tool":"cli-firebase","deployment-callable":"true"}}},"resourceLocation":{"currentLocations":["us-central1"]}}
9:21:56.574 AM
confirmPayment
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","status":{},"authenticationInfo":{"principalEmail":"mmbestonbest#gmail.com"},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","resourceName":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment"}
11:45:07.349 AM
confirmPayment
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","authenticationInfo":{"principalEmail":"mmbestonbest#gmail.com"},"requestMetadata":{"callerIp":"47.30.162.219","callerSuppliedUserAgent":"FirebaseCLI/8.0.1,gzip(gfe),gzip(gfe)","requestAttributes":{"time":"2020-04-05T06:15:07.712Z","auth":{}},"destinationAttributes":{}},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","authorizationInfo":[{"resource":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","permission":"cloudfunctions.functions.update","granted":true,"resourceAttributes":{}}],"resourceName":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","request":{"updateMask":"sourceUploadUrl,name,labels,runtime,httpsTrigger","#type":"type.googleapis.com/google.cloud.functions.v1.UpdateFunctionRequest","function":{"runtime":"nodejs8","name":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment","httpsTrigger":{},"labels":{"deployment-callable":"true","deployment-tool":"cli-firebase"},"sourceUploadUrl":"https://storage.googleapis.com/gcf-upload-us-central1-2535687d-781c-43d3-8bb1-6cdc1434531f/82b41c31-8b5c-4cd4-857c-301b4f554dd5.zip?GoogleAccessId=service-615941328944#gcf-admin-robot.iam.gserviceaccount.com&Expires=1586069101&Signature=FNLT8XrMwerp00RaqJXMPj6qk7Ztawx0NSAYJIWnWsMy0xdvB0bgqUrYx0dUYGx38r1c6xtyN7mSqFEXEN4IDOkDqWCRFDibiABDmTG9J60F2822bCeReGyYvmTJGVA%2BvBELdtvoiSBaVFHHYQfQdCKGKObboW2950zEeuq52pk30M3doDCUoXuGQUDSpQrZnlXLabH6JjvPDDj6VYcF42HnUmnesd43yErky6ZiW2qo6F4nGAj9hwEDAKFJHX%2FoW1HLDdMjQ2EI0t9%2FPRBi6fvtNjLqbAtE7xjQSwvDlyU1uMFAqwVC5RxKeTGM195E6RbKlSY6YsEzp4rAWltU%2Fw%3D%3D"}},"resourceLocation":{"currentLocations":["us-central1"]}}
11:45:32.142 AM
confirmPayment
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","status":{},"authenticationInfo":{"principalEmail":"mmbestonbest#gmail.com"},"serviceName":"cloudfunctions.googleapis.com","methodName":"google.cloud.functions.v1.CloudFunctionsService.UpdateFunction","resourceName":"projects/beingfit-6c699/locations/us-central1/functions/confirmPayment"}
Logs are subject to Cloud Logging's
I have a MongoDB/Webpack/NodeJS Express set up in my ReactJS + Redux project.
I am making API calls from action creators in redux, and reach the API server and get a successful status back, yet the data never gets saved and the database never gets created even checking with in terminal mongo -> dbs and it doesn't show practicedb database which I named it as.
What could be the issue? Am I missing something?
Any guidance or insight would be greatly appreciated. Thank you
This is my set up for API:
import axios from 'axios';
import { browserHistory } from 'react-router';
import cookie from 'react-cookie';
import { AUTH_USER, AUTH_ERROR } from './types';
const API_URL = 'http://localhost:3000/api';
export function errorHandler(dispatch, error, type) {
let errorMessage = (error.data.error) ? error.data.error : error.data;
// NOT AUTHENTICATED ERROR
if(error.status === 401) {
errorMessage = 'You are not authorized to do this.';
}
dispatch({
type: type,
payload: errorMessage
});
}
export function registerUser({ email }) {
return function(dispatch) {
axios.post(`${API_URL}/auth/register`, { email })
.then(response => {
console.log('THIS IS TESTING PURPOSE')
console.log(response)
dispatch({ type: AUTH_USER });
})
.catch((error) => {
errorHandler(dispatch, error.response, AUTH_ERROR)
});
}
}
And my API controller is set up as such:
"use strict";
const User = require('../models/user')
exports.register = function(req, res, next) {
const email = req.body.email;
console.log('ERROR 1')
if(!email) {
return res.status(422).send({ error: 'You must enter an email address.'})
console.log('ERROR 1')
}
User.findOne({ email: email }, function(err, existingUser) {
if(err) { return next(err); }
console.log('ERROR 2')
if(existingUser) {
return res.status(422).send({ error: 'That email address is already in use.'})
}
console.log('ERROR 3')
let user = new User({
email: email,
})
console.log('ERROR 4')
user.save(function(err, user) {
if(err) { return next(err); }
console.log('ERROR 5')
res.status(201).json({
user: user,
})
})
})
console.log('ERROR 6')
}
Configuration for the API:
module.exports = {
'database': 'mongodb://localhost/practicedb',
'port': process.env.PORT || 3000,
'secret': 'dogcat',
}
The project so far just has an input text field, where it accepts an email address. If the email has already been registered, the API should return the error That email address is already in use. and it does.
So I tried console logging to see what the problem is, and the first time I submit the POST request, it logs the following (the terminal showing API console logs):
And if I try to submit the same email again, it throws me the API error that the email is already in use with 422 error, yet the data do not get saved and database (practicedb) never get created:
Also, what is the OPTIONS request that shows up in terminal? I only made an attempt to POST. Lastly, is OPTIONS why the ERROR log in API server is not logging in chronological order?
EDIT
You're using the wrong Mongo shell command: db will only show you the current database (test), but if you want to see a list of all databases, you should use show dbs.
If you want to switch databases:
use practicedb
And, if you want to see the collections in the current database:
show collections
I am using a meteor method to retrieve values from a client side function. I am using stripe api, it is working fine
However when there is a error in the stripe.charges.create function the error is not passed back to the client, which results in the stripeCheckout method sending the user to the complete template. I assume there is a way to take the errors in the Stripe.charges.create err.type response from stripes servers or the Stripe.customers.create function on the server side pass them to the client and let the user know the specific error as well as not sending them to the complete template using a if statement based on errors or Status of success from the stripe server which is passed to the meteor.
It's that connection from the error response from stripes 'Stripe.charges.createfunction to the meteor server and then passing it back to the client through thestripeCheckout` method.
Ok Hope I can get this solved. And any tips to approach this token creation, customer creation and charge in better practice, I am open to any suggestions.
Thanks!
Client JS
Stripe.card.createToken({
number: $('.card-number').val(),
cvc: $('.card-cvc').val(),
exp_month: $('.card-expiry-month').val(),
exp_year: $('.card-expiry-year').val(),
address_line1: addressValue1,
address_line2 : addressValue2,
address_city: cityValue,
address_state: provinceState,
address_country: country,
address_zip: zip,
name: firstName + lastName
}, stripeResponseHandler);
function stripeResponseHandler(status, response) {
if (response.error) {
alert(response.error.message);
}else{
// response contains id and card, which contains additional card details
var token = response.id;
Meteor.call('stripeCheckout',token, function (error, result) {
Router.go("/complete");
});
}
}
Server JS
Meteor.methods({
stripeCheckout: function (token) {
Stripe.customers.create({
source: token
}, function(err, customer) {
id = customer.id;
if(err){
throw new Meteor.Error("create-failed", err.message);
}else{
throw new Meteor.Error("create-failed", err.message);
}
Stripe.charges.create({
amount: 1000,
currency: 'usd',
customer: id
}, function (err, res) {
if(err){
throw new Meteor.Error("create-failed", err.message);
}else{
throw new Meteor.Error("create-failed", err.message);
}
});
});
}
});
UPDATE:
I added my current error detecting, I throw a error in all instances and I get this response in my console.
Exception in delivering result of invoking 'stripeCheckout': TypeError: Cannot read property 'error' of undefined
at http://localhost:3000/client/stripeClient.js?0eb126fd5e018d3cac3f8ec1505f32b7fdc97604:197:22
at Meteor.bindEnvironment [as _callback] (http://localhost:3000/packages/meteor.js?81e2f06cff198adaa81b3bc09fc4f3728b7370ec:977:22)
at _.extend._maybeInvokeCallback (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:3858:12)
at _.extend.receiveResult (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:3878:10)
at _.extend._livedata_result (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:4931:9)
at onMessage (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:3723:12)
at http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:2717:11
at Array.forEach (native)
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
at _.extend._launchConnection.self.socket.onmessage (http://localhost:3000/packages/ddp.js?41b62dcceb3ce0de6ca79c6aed088cccde6a44d8:2716:11)
This is the Stripe POST /v1/customers response
{
error:{
message: "Your card was declined."
type: "card_error"
code: "card_declined"
}
}
Simply throw a Meteor.Error like this:
Meteor.methods({
stripeCheckout: function (token) {
Stripe.customers.create({
source: token
}, function(err, customer) {
id = customer.id;
Stripe.charges.create({
amount: 1000,
currency: 'usd',
customer: id
}, function (err, res) {
// first argument is error code, second is error details
throw new Meteor.Error("create-failed", err.message);
});
});
}
});
You will get the error you threw in the error argument of the method callback.
See the docs here: http://docs.meteor.com/#/full/meteor_error