Skip to content

Instantly share code, notes, and snippets.

@danrossi
Created May 4, 2021 12:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danrossi/35d605d8a8c3dbf0b8c6e4a46fedeb4b to your computer and use it in GitHub Desktop.
Save danrossi/35d605d8a8c3dbf0b8c6e4a46fedeb4b to your computer and use it in GitHub Desktop.
Stripe Checkout Webhook Lambda Function
# Stripe Checkout Webhook Lambda Function
# Updates customer with missing name and address
# Sends custom SES email with product, price and any metadata field required
# Possible to send custom post payment invoice
# @author Daniel Rossi
import stripe
import boto3
import json
import os
from botocore.exceptions import ClientError
AWS_REGION = os.environ['AWS_REGION']
ses = boto3.client('ses', region_name=AWS_REGION)
SENDER = os.environ['SENDER']
RECIPIENT = os.environ['RECIPIENT']
def send_checkout_mail(templateData, name, email):
reply_to = "{0} <{1}>".format(name,email)
return ses.send_templated_email(
Source = SENDER,
Destination={
'ToAddresses': [
RECIPIENT,
]
},
ReplyToAddresses=[reply_to],
Template="CheckoutNotify",
TemplateData=json.dumps(templateData)
)
def send_customer_mail(templateData, name, email):
to = "{0} <{1}>".format(name,email)
return ses.send_templated_email(
Source = SENDER,
Destination={
'ToAddresses': [
to,
]
},
Template="ProcessingNotify",
TemplateData=json.dumps(templateData)
)
def send_mail(name, email, product, price_option, domains):
templateData = {
"product": product,
"price_option": price_option,
"domains": domains
}
send_checkout_mail(templateData, name, email)
send_customer_mail(templateData, name, email)
def lambda_handler(event, context):
requestHeaders = event.get("headers")
signature = requestHeaders['stripe-signature']
try:
body = event.get("body")
if (isinstance(body, str)):
payload = json.loads(body)
else:
payload = body
if ("livemode" in payload and payload.get("livemode")):
stripe.api_key = os.environ['STRIPE_SECRET_KEY']
publish_key = os.environ['STRIPE_PUBLISHABLE_KEY']
endpoint_secret = os.environ['STRIPE_ENDPOINT_SECRET']
stripe.api_key = os.environ['STRIPE_SECRET_KEY']
else:
stripe.api_key = os.environ['STRIPE_TEST_SECRET_KEY']
publish_key = os.environ['STRIPE_TEST_PUBLISHABLE_KEY']
endpoint_secret = os.environ['STRIPE_TEST_ENDPOINT_SECRET']
stripe.api_key = os.environ['STRIPE_TEST_SECRET_KEY']
try:
webhook_event = stripe.Webhook.construct_event(
payload=event.get("body"),
sig_header=signature,
secret=endpoint_secret
)
except ValueError as e:
print(e)
return {
'statusCode': 400,
'body': json.dumps({
'statusCode': 400,
'message': e.user_message
})
}
except stripe.error.SignatureVerificationError as e:
print(e)
return {
'statusCode': 400,
'body': json.dumps({
'statusCode': 400,
'message': e.user_message
})
}
event_dict = webhook_event.to_dict()
session = event_dict['data']['object']
if (event_dict["type"] == 'checkout.session.completed'):
#get name and address from payment intent
payment_intent = stripe.PaymentIntent.retrieve(session.payment_intent)
billing_details = payment_intent.charges.data[0].billing_details
#update customer with name and address
#TODO: Somehow send custom post paid invoice with produce and price. Somehow stop duplicated customers being added
customer = stripe.Customer.retrieve(session.customer)
if customer.name is None:
#print("Update customer")
stripe.Customer.modify(session.customer,
name=billing_details.name,
address=billing_details.address.to_dict()
)
#print("Payment Status")
#print(session.payment_status)
#get line items from session
items = stripe.checkout.Session.list_line_items(session.id, limit=1)
#only have one line item
item = items.data[0]
#get the product name not available in line items
product = stripe.Product.retrieve(item.price.product)
send_mail(billing_details.name, billing_details.email, product.name, item.description, session.metadata.domains)
except json.JSONDecodeError as e:
return {
'statusCode': 400,
'body': json.dumps({
'statusCode': 400,
'message': e
})
}
else:
return {
'statusCode': 200,
'body': json.dumps({
'statusCode': 200,
'message': "Webhook Success"
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment