I am learning web development and I am currently working on creating a lambda test application for stripe. The paymentMethod id from the front-end is not being detected by my lambda function when I run it locally by calling sam local start-api
. I am doing my development on VS Code.
I followed the instructions on this page to create and run my application. My directory structure looks like this:
hello_world/app.py
has my Lambda function.
The code for invoking the lambda end-point in script.js
looks like this:
var stripe = Stripe('pk_test_DIGITS');
var elements = stripe.elements();
form.addEventListener('submit', function(event) {
// We don't want to let default form submission happen here,
// which would refresh the page.
event.preventDefault();
stripe.createPaymentMethod({
type: 'card',
card: cardElement,
billing_details: {
// Include any additional collected billing details.
name: 'Jenny Rosen',
},
}).then(stripePaymentMethodHandler);
});
function stripePaymentMethodHandler(result) {
if (result.error) {
// Show error in payment form
} else {
// Otherwise send paymentMethod.id to your server (see Step 4)
fetch('http://127.0.0.1:3000/payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payment_method_id: result.paymentMethod.id,
})
}).then(function(result) {
// Handle server response (see Step 4)
result.json().then(function(json) {
handleServerResponse(json);
})
});
}
}
I ran the application on the browser by doing this:
When I click on Pay
from my browser I can see the response in the logs on my dashboard:
The following code is for my lambda function app.py
:
import json
import stripe
import requests
import logging
stripe.api_key= "sk_test_DIGITS"
def process_payment(event, context):
try:
print("START PRINTING")
print(event)
print("END PRINTING")
intent = stripe.PaymentIntent.create(
payment_method = 'event["body"]["payment_method_id"]',
amount = 1555,
currency = 'usd',
confirmation_method = 'automatic',
confirm = True,
payment_method_types=["card"]
)
return {
"statusCode": 200,
"body": json.dumps({
'clientSecret': intent['client_secret'],
# "location": ip.text.replace("\n", "")
}),
}
except Exception as e:
return {
"statusCode": 400,
"body": json.dumps({
"message": str(e),
# "location": ip.text.replace("\n", "")
}),
}
My template.yaml
is as follows:
Globals:
Function:
Timeout: 30
Resources:
StripePaymentProcessor:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.process_payment
Runtime: python3.6
Events:
Payment:
Type: Api
Properties:
Path: /payment
Method: post
Outputs:
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Payment function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/payment/"
HelloWorldFunction:
Description: "Payment Lambda Function ARN"
Value: !GetAtt StripePaymentProcessor.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Payment function"
Value: !GetAtt StripePaymentProcessorRole.Arn
While keeping the browser window open, I ran the sam build
command and it worked properly. After that I ran the sam local invoke
command and it produced the following output:
I do not understand why event
is empty. Should it not show the JSON data that got produced when I hit the pay button?
To do some trouble-shooting, I ran sam local start-api
, invoked the POST
method on Postman by pasting the JSON body from my Stripe logs:
What I did on Postman makes no sense to me and the snippet above raised another question for me. I do not understand why I see "message": "string indices must be integers"
as a response on Postman.
EDIT:
After following wcw's suggestion I edited my fetch code to look like this:
I did not not see any written matter on the console by changing my code in this way.
I am keeping the browser open via the command prompt and I ran sam local start-api
via the VS code console to keep http://127.0.0.1:3000/payment
open. When I clicked on the pay button, I got the following response:
So the image above seems to indicate that the lambda function is not detecting the paymentmethod body.