Skip to content

Latest commit

 

History

History
72 lines (45 loc) · 5.57 KB

File metadata and controls

72 lines (45 loc) · 5.57 KB

Payment service integrates with Stripe and provides a REST API for pre-authorization, collection and refund operations.

Implementation

Payment Infrastructure Architecture

Payment is comprised of a Serverless Application Repository App named API Lambda Stripe Charge and Python Lambda functions.

SAR Lambda Stripe Charge

The SAR App provides a public regional API Gateway endpoint coupled with Lambda functions that integrates with Stripe.

Configuration

Lambda Stripe Charge requires a Stripe Secret key to be stored in Parameter Store. We read the environment variable STRIPE_SECRET_KEY set in Amplify Console, and as part of the custom workflow we store the value in a parameter named /{env}/service/payment/stripe/secretKey.

API currently provides the following resources:

Resource Method Description
/charge POST Pre-authorize payment by invoking CreateStripeCharge Lambda function. It expects a simple JSON blob with amount, currency, stripeToken, description, email as keys - See Stripe specification for values and response.
/capture POST Capture pre-authorized payment by invoking CaptureStripeCharge Lambda function. It expects chargeId with the previously captured payment token - See Stripe specification for response values.
/refund POST Refund existing payment by invoking CreateRefund Lambda function. It expects chargeId with the previously captured payment token - See Stripe specification for response values.

Collect and Refund functions

Both functions call our Lambda Stripe Charge API as part of the Booking business workflow to collect previous pre-authorizations and refund should a booking isn't successful. PAYMENT_API_URL environment variable defined SAR App API URL.

Custom metrics currently emitted to CloudWatch:

Metric Description Dimensions
ColdStart Number of cold start executions function_name, service
InvalidPaymentRequest Number of payment transactions that didn't include pre-authorization/authorization charge token for collection service
InvalidRefundRequest Number of payment transactions that didn't include pre-authorization/authorization charge token for refund service
SuccessfulPayment Number of payments successfully collected from confirmed bookings service
FailedPayment Number of payments that failed to be collected from confirmed bookings e.g. payment already collected from charge token service

Parameter store

{env} being a git branch from where deployment originates (e.g. twitch):

Parameter Description
/{env}/service/payment/function/collect Collect-function ARN
/{env}/service/payment/function/refund Refund-function ARN
/{env}/service/payment/stripe/secretKey Stripe Secret Key, created and managed by Amplify Console Custom workflow

Integrations

Front-end

Stripe Elements provides card UI and Stripe JS implements card tokenization and validation. Once card is tokenized and validated, the front-end posts the tokenized information to the SAR App API on /charge. If successful, it makes a call to Booking API to starts processing booking details.

Payment front-end integration

Booking

Process Booking state machine invokes Collect and Refund function as part of their execution steps. As of now, Step Functions doesn't support HTTP calls hence we need Lambda functions to call our SAR App API.

Booking state machine

Decisions log

Almost as a tech debt record, this help us understand why certain patterns were implemented over others.

Decision Description Timeframe
Abstract Stripe implementation Most customers already have a payment provider and we wanted to replicate that with minimum effort. API Gateway provides a contract for payment operations regardless of the payment provider, and Lambda functions provide additional operations visibility. During Twitch season (Apr-Aug '19)
Drop Logging Stack AWS Lambda Powertools Metrics utilize the new Amazon CloudWatch Embedded Metrics Format (EMF) making our custom implementation unnecessary. This also has the benefit of not requiring any additional stack. July 22nd 2020
Introduce Lambda Layers Dependencies are now deployed separately as a Lambda Layer given it's shared with Booking too. This makes new changes to be deployed in seconds from ~1.5m. July 24th 2020