如何使用 AWS Lambda Node.js 服务器实施 Braintree 并生成带有承诺的客户端令牌?
How to implement Braintree with AWS Lambda Node.js server and generate a client token with a promise?
我正在尝试生成 Braintree 的 clientToken
,我应该从 Braintree 网关获取它,根据此处找到的文档,当我的 UI 触发时,我需要我的 lambda 连接到该网关: https://developers.braintreepayments.com/start/hello-server/node
我正在尝试在 Lambda 函数中实现此功能,我需要将其导出以供我的无服务器应用程序的其余部分使用。此外,我正在尝试根据需要使用 ES6 import
语句来导入 Braintree 功能。虽然,即使我使用 require
语句,我也会得到同样的错误。
这是我的 Lambda 函数:
import * as dynamoDbLib from "./libs/dynamodb-lib";
import { success, failure } from "./libs/response-lib";
import braintree from "braintree";
export async function main(event, context) {
/*
All secrets are declared in the serverless template for the specific function
and stored in AWS SecretsManger
*/
// create a Braintree gateway
let gateway = braintree.connect({
environment: braintree.Environment.Sandbox, // either Sandbox or Production
merchantId: process.env.merchantId, // these come from the Lambda's environmental variables
publicKey: process.env.publicKey,
privateKey: process.env.privateKey
});
/*************************************************
* Braintree related functions based on documentation at
* https://developers.braintreepayments.com/start/hello-server/node
*/
/////////////////////////////////////
// get a client token from Braintree and send it to the client
/////////////////////////////////////
const getClientToken = (options = {}) => {
console.log("getting client token: ", gateway); // console.logs will show up in AWS Cloudwatch
let customerId = options && options.hasOwnProperty("customerID")
? options.customerID
: null;
// THIS IS THE ONLY THING THAT PRINTS TO CONSOLE!!!
console.log("This is customerID: ", customerId);
// NONE OF THIS WORKS!!!???
gateway.clientToken.generate({})
.then((res) => {
console.log("maybe result: ", res); // <---- None of these print!?!?
console.log("Maybe success/fail: ", res.success);
console.log("maybe token: ", res.clientToken);
// Code here
})
.catch (err => {
console.log("ERROR CAUGHT: ", err);
failure({
status: false,
error: "did it trigger 2: " + err
});
}
);
};
// try to execute API calls
try {
switch (event.pathParameters.txnMethod) {
case "get-client-token":
// call getClientToken with the parsed version of optional body if present, otherwise call it with nothing
getClientToken(
event.hasOwnProperty("body")
? JSON.parse(event.body)
: null
);
break;
default:
failure({
status: false,
error: "invalid query string"
});
break;
}
} catch (error) {
failure({
status: false,
error: "Did it trigger 1: " + error
});
}
}
只有第一个 console
语句实际打印任何东西,之后从 gateway.clientToken.generate({})
开始一切都失败,最重要的是它失败时没有抛出任何错误....
当我输出console.log("getting client token: ", gateway);
我得到这样的数据结构:
getting client token: BraintreeGateway {
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment:
Environment {
server: 'api.sandbox.braintreegateway.com',
port: '443',
authUrl: 'https://auth.sandbox.venmo.com',
ssl: true,
graphQLServer: 'payments.sandbox.braintree-api.com',
graphQLPort: '443' } },
graphQLClient: GraphQLClient { _service: GraphQL { config: [Config] } },
http:
Http {
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
addOn:
AddOnGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
address:
AddressGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
clientToken:
ClientTokenGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
creditCard:
CreditCardGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
creditCardVerification:
...........
所以我试着把这个:gateway.clientToken.generate({})
改成这个:
gateway.BraintreeGateway.clientToken.generate({})
希望 `generate() 方法与该结构关联,以下是我在测试时收到的错误:
TypeError: Cannot read property 'clientToken' of undefined"
我假设那里什么都没有。
如何使用 ES6 导入语句在我的无服务器 lambda 函数中生成 Braintree 令牌?
我意识到,由于这些 lambda 是异步函数,而且由于我们必须等待 Braintree 返回的响应,因此我们必须声明嵌套 async/await
语句的正确组合。
下面的代码是我使用正确的承诺链实现来正确处理 async
过程的最终实现:
import * as dynamoDbLib from "./libs/dynamodb-lib";
import { success, failure } from "./libs/response-lib";
import braintree from "braintree";
export async function main(event, context) {
/*
All secrets are declared in the serverless template for the specific function
and stored in AWS SecretsManger
*/
// create a Braintree gateway
let gateway = braintree.connect({
environment: braintree.Environment.Sandbox, // either Sandbox or Production
merchantId: process.env.merchantId, // these come from the Lambda's environmental variables
publicKey: process.env.publicKey,
privateKey: process.env.privateKey
});
/*************************************************
* Braintree related functions based on documentation at
* https://developers.braintreepayments.com/start/hello-server/node
*/
/////////////////////////////////////
// get a client token from Braintree and send it to the client
/////////////////////////////////////
const getClientToken = async (options = {}) => {
console.log("Getting client token...");
//console.log("hasOwnProps: ", options.hasOwnProperty("customerID") );
let customerId = options && options.hasOwnProperty("customerID")
? options.customerID
: null;
console.log("This is customerID: ", customerId);
return await gateway.clientToken.generate({});
};
/////////////////////////////////////
// purchase an item using Braintree's transaction method
/////////////////////////////////////
const purchaseItem = async (purchaseInformation) => {
/* console.log(
"purchaseInformation: ",
util.inspect(purchaseInformation, { showHidden: false, depth: null })
); */
return await gateway.transaction.sale(
{
amount: purchaseInformation.amount,
paymentMethodNonce: purchaseInformation.nonce,
options: {
submitForSettlement: true
}
}
);
};
/*************************************************
* Enter here
*/
// view the event that was received
console.log("event: ", event);
let result;
// try to execute API calls
try {
switch (event.pathParameters.txnMethod) {
case "get-client-token":
// call getClientToken with the parsed version of optional body if present, otherwise call it with nothing
await getClientToken(
event.hasOwnProperty("body")
? JSON.parse(event.body)
: null)
.then((res) => {
//console.log("maybe result: ", res);
//console.log("Maybe success/fail: ", typeof(res.success));
//console.log("maybe token: ", res.clientToken);
// Code here
if(res.success.toString() === "true"){
//console.log("SUCCESS token: ", res.clientToken);
return context.succeed(success({
status: true,
clientToken: res.clientToken
}));
} else {
return failure({
status: false,
error: "Braintree ClientToken Failure."
});
}
})
.catch (err => {
console.log("ERROR CAUGHT: ", err);
return failure({
status: false,
error: "did it trigger 2: " + err
});
});
break;
case "purchase-item":
console.log("purchasing item");
const data = JSON.parse(event.body);
await purchaseItem(data)
.then((res) => {
// Code here
if(res.success === true){
console.log("~~~~~~~~~~~");
console.log("This is RES: ", res);
console.log("This is ERR>RES: ", res.ErrorResponse);
return context.succeed(success({
status: true,
TxnAuth: res
}));
} else if (res.success === false) {
console.log("#################");
console.log(res.result);
return failure({
status: false,
error: "Error validating payment server information"
});
} else {
return failure({
status: false,
error: "Braintree Server Failure."
});
}
})
.catch (err => {
console.log("ERROR CAUGHT: ", err);
console.log("*********");
return failure({
status: false,
error: "did it trigger 3pmt: " + err
});
});
break;
default:
return failure({
status: false,
error: "invalid query string"
});
break;
}
} catch (error) {
return failure({
status: false,
error: "API Call to Braintree Failed: " + error
});
}
}
我正在尝试生成 Braintree 的 clientToken
,我应该从 Braintree 网关获取它,根据此处找到的文档,当我的 UI 触发时,我需要我的 lambda 连接到该网关: https://developers.braintreepayments.com/start/hello-server/node
我正在尝试在 Lambda 函数中实现此功能,我需要将其导出以供我的无服务器应用程序的其余部分使用。此外,我正在尝试根据需要使用 ES6 import
语句来导入 Braintree 功能。虽然,即使我使用 require
语句,我也会得到同样的错误。
这是我的 Lambda 函数:
import * as dynamoDbLib from "./libs/dynamodb-lib";
import { success, failure } from "./libs/response-lib";
import braintree from "braintree";
export async function main(event, context) {
/*
All secrets are declared in the serverless template for the specific function
and stored in AWS SecretsManger
*/
// create a Braintree gateway
let gateway = braintree.connect({
environment: braintree.Environment.Sandbox, // either Sandbox or Production
merchantId: process.env.merchantId, // these come from the Lambda's environmental variables
publicKey: process.env.publicKey,
privateKey: process.env.privateKey
});
/*************************************************
* Braintree related functions based on documentation at
* https://developers.braintreepayments.com/start/hello-server/node
*/
/////////////////////////////////////
// get a client token from Braintree and send it to the client
/////////////////////////////////////
const getClientToken = (options = {}) => {
console.log("getting client token: ", gateway); // console.logs will show up in AWS Cloudwatch
let customerId = options && options.hasOwnProperty("customerID")
? options.customerID
: null;
// THIS IS THE ONLY THING THAT PRINTS TO CONSOLE!!!
console.log("This is customerID: ", customerId);
// NONE OF THIS WORKS!!!???
gateway.clientToken.generate({})
.then((res) => {
console.log("maybe result: ", res); // <---- None of these print!?!?
console.log("Maybe success/fail: ", res.success);
console.log("maybe token: ", res.clientToken);
// Code here
})
.catch (err => {
console.log("ERROR CAUGHT: ", err);
failure({
status: false,
error: "did it trigger 2: " + err
});
}
);
};
// try to execute API calls
try {
switch (event.pathParameters.txnMethod) {
case "get-client-token":
// call getClientToken with the parsed version of optional body if present, otherwise call it with nothing
getClientToken(
event.hasOwnProperty("body")
? JSON.parse(event.body)
: null
);
break;
default:
failure({
status: false,
error: "invalid query string"
});
break;
}
} catch (error) {
failure({
status: false,
error: "Did it trigger 1: " + error
});
}
}
只有第一个 console
语句实际打印任何东西,之后从 gateway.clientToken.generate({})
开始一切都失败,最重要的是它失败时没有抛出任何错误....
当我输出console.log("getting client token: ", gateway);
我得到这样的数据结构:
getting client token: BraintreeGateway {
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment:
Environment {
server: 'api.sandbox.braintreegateway.com',
port: '443',
authUrl: 'https://auth.sandbox.venmo.com',
ssl: true,
graphQLServer: 'payments.sandbox.braintree-api.com',
graphQLPort: '443' } },
graphQLClient: GraphQLClient { _service: GraphQL { config: [Config] } },
http:
Http {
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
addOn:
AddOnGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
address:
AddressGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
clientToken:
ClientTokenGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
creditCard:
CreditCardGateway {
gateway: [Circular],
config:
Config {
timeout: 60000,
apiVersion: '5',
graphQLApiVersion: '2018-09-10',
publicKey: 'sbxkeys',
privateKey: 'sbxkeys',
merchantId: 'sbxkeys',
environment: [Environment] } },
creditCardVerification:
...........
所以我试着把这个:gateway.clientToken.generate({})
改成这个:
gateway.BraintreeGateway.clientToken.generate({})
希望 `generate() 方法与该结构关联,以下是我在测试时收到的错误:
TypeError: Cannot read property 'clientToken' of undefined"
我假设那里什么都没有。
如何使用 ES6 导入语句在我的无服务器 lambda 函数中生成 Braintree 令牌?
我意识到,由于这些 lambda 是异步函数,而且由于我们必须等待 Braintree 返回的响应,因此我们必须声明嵌套 async/await
语句的正确组合。
下面的代码是我使用正确的承诺链实现来正确处理 async
过程的最终实现:
import * as dynamoDbLib from "./libs/dynamodb-lib";
import { success, failure } from "./libs/response-lib";
import braintree from "braintree";
export async function main(event, context) {
/*
All secrets are declared in the serverless template for the specific function
and stored in AWS SecretsManger
*/
// create a Braintree gateway
let gateway = braintree.connect({
environment: braintree.Environment.Sandbox, // either Sandbox or Production
merchantId: process.env.merchantId, // these come from the Lambda's environmental variables
publicKey: process.env.publicKey,
privateKey: process.env.privateKey
});
/*************************************************
* Braintree related functions based on documentation at
* https://developers.braintreepayments.com/start/hello-server/node
*/
/////////////////////////////////////
// get a client token from Braintree and send it to the client
/////////////////////////////////////
const getClientToken = async (options = {}) => {
console.log("Getting client token...");
//console.log("hasOwnProps: ", options.hasOwnProperty("customerID") );
let customerId = options && options.hasOwnProperty("customerID")
? options.customerID
: null;
console.log("This is customerID: ", customerId);
return await gateway.clientToken.generate({});
};
/////////////////////////////////////
// purchase an item using Braintree's transaction method
/////////////////////////////////////
const purchaseItem = async (purchaseInformation) => {
/* console.log(
"purchaseInformation: ",
util.inspect(purchaseInformation, { showHidden: false, depth: null })
); */
return await gateway.transaction.sale(
{
amount: purchaseInformation.amount,
paymentMethodNonce: purchaseInformation.nonce,
options: {
submitForSettlement: true
}
}
);
};
/*************************************************
* Enter here
*/
// view the event that was received
console.log("event: ", event);
let result;
// try to execute API calls
try {
switch (event.pathParameters.txnMethod) {
case "get-client-token":
// call getClientToken with the parsed version of optional body if present, otherwise call it with nothing
await getClientToken(
event.hasOwnProperty("body")
? JSON.parse(event.body)
: null)
.then((res) => {
//console.log("maybe result: ", res);
//console.log("Maybe success/fail: ", typeof(res.success));
//console.log("maybe token: ", res.clientToken);
// Code here
if(res.success.toString() === "true"){
//console.log("SUCCESS token: ", res.clientToken);
return context.succeed(success({
status: true,
clientToken: res.clientToken
}));
} else {
return failure({
status: false,
error: "Braintree ClientToken Failure."
});
}
})
.catch (err => {
console.log("ERROR CAUGHT: ", err);
return failure({
status: false,
error: "did it trigger 2: " + err
});
});
break;
case "purchase-item":
console.log("purchasing item");
const data = JSON.parse(event.body);
await purchaseItem(data)
.then((res) => {
// Code here
if(res.success === true){
console.log("~~~~~~~~~~~");
console.log("This is RES: ", res);
console.log("This is ERR>RES: ", res.ErrorResponse);
return context.succeed(success({
status: true,
TxnAuth: res
}));
} else if (res.success === false) {
console.log("#################");
console.log(res.result);
return failure({
status: false,
error: "Error validating payment server information"
});
} else {
return failure({
status: false,
error: "Braintree Server Failure."
});
}
})
.catch (err => {
console.log("ERROR CAUGHT: ", err);
console.log("*********");
return failure({
status: false,
error: "did it trigger 3pmt: " + err
});
});
break;
default:
return failure({
status: false,
error: "invalid query string"
});
break;
}
} catch (error) {
return failure({
status: false,
error: "API Call to Braintree Failed: " + error
});
}
}