0

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:

enter image description here

hello_world/app.py has my Lambda function.

The code for invoking the lambda end-point in script.jslooks 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: enter image description here

When I click on Pay from my browser I can see the response in the logs on my dashboard:

enter image description here

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:

enter image description here

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:

enter image description here

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:

enter image description here

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:

enter image description here

So the image above seems to indicate that the lambda function is not detecting the paymentmethod body.

a_sid
  • 577
  • 10
  • 28
  • 1
    The `string indices must be integers` most likely due to `payment_method = 'event["body"]["payment_method_id"]',` wher event["body"] is not a JSON but a JSON string. You might need to parse it to use it as an object? Also for stripe.js code, can you debug or print out the `result.paymentMethod` in console to see if is contains the payment method result? – wsw Aug 11 '20 at 06:31
  • @wsw I followed your suggestion to display messages on the console but I did not see anything. Additionally, when I clicked on the pay button after running `sam local start-api`, I got the `403` error which I have also shown in my question. – a_sid Aug 11 '20 at 19:10
  • @wsw Seems to be an issue with CORS. Irrespective of that, I do not understand why my messages are not appearing on the console. PS. I have very little experience with JS. – a_sid Aug 11 '20 at 19:56
  • [This](https://stackoverflow.com/a/20085477/6525712) answer was very useful for me for debugging issues with JSON. – a_sid Aug 11 '20 at 22:43
  • This problem is now solved. It was occurring because CORS was not enabled. – a_sid Aug 11 '20 at 23:23
  • awesome, thanks for sharing @a_sid – wsw Aug 12 '20 at 03:12

0 Answers0