payment

package
v1.0.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 30, 2025 License: Apache-2.0 Imports: 1 Imported by: 0

README

Payment Platform Examples

This directory contains comprehensive examples of using DynamORM for a payment processing platform like Pay Theory. These examples demonstrate best practices for building high-performance, scalable payment systems on AWS DynamoDB.

Overview

The payment platform examples include:

  • Domain Models: Payment, Transaction, Customer, Merchant, and supporting entities
  • Lambda Handlers: Serverless functions for payment processing, reconciliation, and queries
  • Utilities: Idempotency middleware, audit tracking, and cost estimation
  • Tests: Integration tests and performance benchmarks

Features Demonstrated

1. Idempotent Payment Processing
  • Prevents duplicate payments using idempotency keys
  • Caches responses for repeated requests
  • TTL-based cleanup for old records
2. Multi-Tenant Architecture
  • Merchant-scoped data access
  • GSI-based efficient queries
  • Rate limiting per merchant
3. Audit Trail & Compliance
  • Complete audit logging for all operations
  • PCI-compliant data handling
  • Compliance report generation
4. High-Performance Operations
  • Optimized for Lambda cold starts
  • Connection pooling
  • Batch operations support
5. Cost Optimization
  • DynamoDB cost estimation
  • Usage-based recommendations
  • On-demand vs provisioned analysis

Project Structure

payment/
├── models.go           # Domain models with DynamORM tags
├── lambda/
│   ├── process/       # Payment processing handler
│   ├── reconcile/     # Batch reconciliation handler
│   └── query/         # Query API handler
├── utils/
│   ├── idempotency.go # Idempotency middleware
│   ├── audit.go       # Audit trail tracking
│   └── cost.go        # Cost estimation utilities
├── tests/
│   ├── integration_test.go # End-to-end tests
│   ├── benchmarks_test.go  # Performance benchmarks
│   └── load_test.go       # Load testing scenarios
└── README.md

Getting Started

Prerequisites
  • Go 1.21+
  • AWS SDK for Go v2
  • Local DynamoDB for testing (optional)
Installation
# Install dependencies
go get github.com/example/dynamorm
go get github.com/aws/aws-lambda-go
go get github.com/aws/aws-sdk-go-v2

# Run tests
cd examples/payment/tests
go test -v

# Run benchmarks
go test -bench=. -benchmem

Lambda Handlers

Payment Processing Handler

Processes payments with idempotency protection:

// Deploy with SAM/Serverless Framework
// Runtime: provided.al2023
// Handler: bootstrap
// Memory: 512MB
// Timeout: 30s

// Environment Variables:
// - DYNAMODB_REGION: us-east-1
// - DYNAMODB_ENDPOINT: (optional, for local testing)
Reconciliation Handler

Processes settlement files from S3:

// Triggered by S3 events
// Processes CSV files in batches
// Updates payment statuses
// Creates settlement records
Query API Handler

RESTful API for payment queries:

GET /payments              # List payments with pagination
GET /payments/{id}         # Get payment details
GET /payments/summary      # Get aggregate statistics
GET /payments/export       # Export payments to CSV

Performance Benchmarks

Based on tests with local DynamoDB:

Operation Performance Target
Payment Creation 20,000/sec < 50ms
Idempotency Check 50,000/sec < 10ms
Batch (25 items) 800 batches/sec < 5s
Query (100 items) 1,000/sec < 200ms
Running Benchmarks
# Run all benchmarks
go test -bench=. -benchmem -benchtime=10s

# Run specific benchmark
go test -bench=BenchmarkPaymentCreate -benchmem

# Generate CPU profile
go test -bench=BenchmarkHighVolume -cpuprofile=cpu.prof

# Analyze profile
go tool pprof cpu.prof

Cost Estimation

The cost estimator helps predict DynamoDB costs:

estimator := utils.NewCostEstimator()

// Estimate for 1M monthly transactions
breakdown := estimator.EstimatePaymentPlatformCosts(
    1_000_000,  // monthly transactions
    5.2,        // average queries per transaction
    90,         // retention days
)

fmt.Println(utils.FormatCostReport(breakdown, nil))

Example output:

Monthly Cost Breakdown:
----------------------
Read Operations:    $1.30
Write Operations:   $3.75
Storage:            $22.50
GSI:                $1.04
Streams:            $0.20
Backup:             $11.25
----------------------
Total Monthly:      $40.04
Total Yearly:       $480.48

Best Practices

1. Model Design
  • Use composite keys for efficient queries
  • Leverage GSIs for access patterns
  • Enable versioning for optimistic locking
2. Error Handling
  • Implement exponential backoff
  • Use circuit breakers for external services
  • Log all errors with context
3. Security
  • Encrypt sensitive data (PCI compliance)
  • Use IAM roles for Lambda functions
  • Implement API authentication (JWT)
4. Monitoring
  • Track payment success rates
  • Monitor idempotency cache hit rates
  • Alert on anomalies
5. Testing
  • Use local DynamoDB for development
  • Mock external services
  • Test error scenarios

Integration with Pay Theory

To integrate these examples with Pay Theory's infrastructure:

  1. Update Import Paths: Replace github.com/example/dynamorm with your actual module path

  2. Configure AWS Resources:

    # serverless.yml or SAM template
    Resources:
      PaymentsTable:
        Type: AWS::DynamoDB::Table
        Properties:
          BillingMode: PAY_PER_REQUEST
          StreamSpecification:
            StreamViewType: NEW_AND_OLD_IMAGES
          GlobalSecondaryIndexes:
            - IndexName: gsi-merchant
            - IndexName: gsi-idempotency
            - IndexName: gsi-customer
    
  3. Set Up CI/CD:

    # GitHub Actions example
    - name: Run Tests
      run: go test ./examples/payment/tests -v
    
    - name: Run Benchmarks
      run: go test ./examples/payment/tests -bench=. -benchmem
    
  4. Deploy Lambda Functions:

    # Build for Lambda
    GOOS=linux GOARCH=amd64 go build -o bootstrap lambda/process/handler.go
    zip function.zip bootstrap
    

Troubleshooting

Common Issues
  1. High Latency

    • Check GSI selection
    • Verify connection pooling
    • Monitor cold starts
  2. Throttling

    • Switch to on-demand billing
    • Implement retry logic
    • Check hot partitions
  3. Cost Overruns

    • Review access patterns
    • Implement TTL for old data
    • Optimize GSI projections

Contributing

To add new examples:

  1. Follow existing patterns
  2. Include comprehensive tests
  3. Document performance characteristics
  4. Update this README

License

These examples are provided as-is for demonstration purposes.

Documentation

Index

Constants

View Source
const (
	PaymentStatusPending    = "pending"
	PaymentStatusProcessing = "processing"
	PaymentStatusSucceeded  = "succeeded"
	PaymentStatusFailed     = "failed"
	PaymentStatusCanceled   = "canceled"
)

PaymentStatus constants

View Source
const (
	TransactionTypeCapture = "capture"
	TransactionTypeRefund  = "refund"
	TransactionTypeVoid    = "void"
)

TransactionType constants

View Source
const (
	WebhookStatusPending   = "pending"
	WebhookStatusDelivered = "delivered"
	WebhookStatusFailed    = "failed"
	WebhookStatusExpired   = "expired"
)

WebhookStatus constants

Variables

This section is empty.

Functions

This section is empty.

Types

type AuditEntry

type AuditEntry struct {
	Timestamp time.Time      `json:"timestamp"`
	Action    string         `json:"action"`
	UserID    string         `json:"user_id,omitempty"`
	IPAddress string         `json:"ip_address,omitempty"`
	Changes   map[string]any `json:"changes,omitempty"`
	Reason    string         `json:"reason,omitempty"`
}

AuditEntry represents an entry in the audit trail

type Customer

type Customer struct {
	ID             string            `dynamorm:"pk" json:"id"`
	MerchantID     string            `dynamorm:"index:gsi-merchant,pk" json:"merchant_id"`
	Email          string            `dynamorm:"index:gsi-email,pk,encrypted" json:"email"`
	Name           string            `dynamorm:"encrypted" json:"name"`
	Phone          string            `dynamorm:"encrypted" json:"phone,omitempty"`
	PaymentMethods []PaymentMethod   `dynamorm:"json,encrypted:pci" json:"payment_methods"`
	DefaultMethod  string            `json:"default_method,omitempty"`
	Metadata       map[string]string `dynamorm:"json" json:"metadata,omitempty"`
	CreatedAt      time.Time         `dynamorm:"created_at" json:"created_at"`
	UpdatedAt      time.Time         `dynamorm:"updated_at" json:"updated_at"`
	Version        int               `dynamorm:"version" json:"version"`
}

Customer represents a customer with PCI-compliant payment methods

type IdempotencyRecord

type IdempotencyRecord struct {
	Key         string    `dynamorm:"pk" json:"key"`
	MerchantID  string    `dynamorm:"index:gsi-merchant,pk" json:"merchant_id"`
	RequestHash string    `json:"request_hash"`
	Response    string    `dynamorm:"json" json:"response"`
	StatusCode  int       `json:"status_code"`
	CreatedAt   time.Time `dynamorm:"created_at" json:"created_at"`
	ExpiresAt   time.Time `dynamorm:"ttl" json:"expires_at"`
}

IdempotencyRecord tracks idempotent requests

type Merchant

type Merchant struct {
	ID              string         `dynamorm:"pk" json:"id"`
	Name            string         `json:"name"`
	Email           string         `dynamorm:"index:gsi-email,pk" json:"email"`
	Status          string         `json:"status"`
	ProcessorConfig map[string]any `dynamorm:"json,encrypted" json:"-"`
	WebhookURL      string         `json:"webhook_url,omitempty"`
	WebhookSecret   string         `dynamorm:"encrypted" json:"-"`
	Features        []string       `dynamorm:"set" json:"features"`
	RateLimits      RateLimits     `dynamorm:"json" json:"rate_limits"`
	CreatedAt       time.Time      `dynamorm:"created_at" json:"created_at"`
	UpdatedAt       time.Time      `dynamorm:"updated_at" json:"updated_at"`
	Version         int            `dynamorm:"version" json:"version"`
}

Merchant represents a merchant account

type Payment

type Payment struct {
	ID             string            `dynamorm:"pk" json:"id"`
	IdempotencyKey string            `dynamorm:"index:gsi-idempotency" json:"idempotency_key"`
	MerchantID     string            `dynamorm:"index:gsi-merchant,pk" json:"merchant_id"`
	Amount         int64             `json:"amount"` // Always in cents
	Currency       string            `json:"currency"`
	Status         string            `dynamorm:"index:gsi-merchant,sk,prefix:status" json:"status"`
	PaymentMethod  string            `json:"payment_method"`
	CustomerID     string            `dynamorm:"index:gsi-customer" json:"customer_id,omitempty"`
	Description    string            `json:"description,omitempty"`
	Metadata       map[string]string `dynamorm:"json" json:"metadata,omitempty"`
	CreatedAt      time.Time         `dynamorm:"created_at" json:"created_at"`
	UpdatedAt      time.Time         `dynamorm:"updated_at" json:"updated_at"`
	Version        int               `dynamorm:"version" json:"version"`
}

Payment represents a payment transaction with idempotency support

type PaymentMethod

type PaymentMethod struct {
	ID          string    `json:"id"`
	Type        string    `json:"type"` // card, bank_account
	Last4       string    `json:"last4"`
	Brand       string    `json:"brand,omitempty"` // For cards
	ExpiryMonth int       `json:"expiry_month,omitempty"`
	ExpiryYear  int       `json:"expiry_year,omitempty"`
	BankName    string    `json:"bank_name,omitempty"` // For bank accounts
	AccountType string    `json:"account_type,omitempty"`
	Token       string    `json:"-"` // Never expose in JSON
	IsDefault   bool      `json:"is_default"`
	CreatedAt   time.Time `json:"created_at"`
}

PaymentMethod represents a customer's payment method

type RateLimits

type RateLimits struct {
	PaymentsPerMinute int   `json:"payments_per_minute"`
	PaymentsPerDay    int   `json:"payments_per_day"`
	MaxPaymentAmount  int64 `json:"max_payment_amount"`
}

RateLimits defines rate limiting configuration

type Settlement

type Settlement struct {
	ID               string             `dynamorm:"pk" json:"id"`
	MerchantID       string             `dynamorm:"index:gsi-merchant,pk" json:"merchant_id"`
	Date             string             `dynamorm:"index:gsi-merchant,sk" json:"date"` // YYYY-MM-DD
	TotalAmount      int64              `json:"total_amount"`
	TransactionCount int                `json:"transaction_count"`
	Status           string             `json:"status"`
	BatchID          string             `json:"batch_id"`
	ProcessedAt      time.Time          `json:"processed_at,omitempty"`
	Transactions     []SettlementDetail `dynamorm:"json" json:"transactions"`
	CreatedAt        time.Time          `dynamorm:"created_at" json:"created_at"`
	UpdatedAt        time.Time          `dynamorm:"updated_at" json:"updated_at"`
}

Settlement represents a batch settlement

type SettlementDetail

type SettlementDetail struct {
	PaymentID     string `json:"payment_id"`
	TransactionID string `json:"transaction_id"`
	Amount        int64  `json:"amount"`
	Fee           int64  `json:"fee"`
	NetAmount     int64  `json:"net_amount"`
}

SettlementDetail represents a transaction in a settlement

type Transaction

type Transaction struct {
	ID           string       `dynamorm:"pk" json:"id"`
	PaymentID    string       `dynamorm:"index:gsi-payment" json:"payment_id"`
	Type         string       `json:"type"` // capture, refund, void
	Amount       int64        `json:"amount"`
	Status       string       `json:"status"`
	ProcessedAt  time.Time    `json:"processed_at"`
	ProcessorID  string       `json:"processor_id,omitempty"`
	ResponseCode string       `json:"response_code,omitempty"`
	ResponseText string       `json:"response_text,omitempty"`
	AuditTrail   []AuditEntry `dynamorm:"json" json:"audit_trail"`
	CreatedAt    time.Time    `dynamorm:"created_at" json:"created_at"`
	UpdatedAt    time.Time    `dynamorm:"updated_at" json:"updated_at"`
	Version      int          `dynamorm:"version" json:"version"`
}

Transaction represents a transaction on a payment (capture, refund, void)

type Webhook

type Webhook struct {
	ID           string         `dynamorm:"pk" json:"id"`
	MerchantID   string         `dynamorm:"index:gsi-merchant,pk" json:"merchant_id"`
	EventType    string         `dynamorm:"index:gsi-merchant,sk,prefix:event" json:"event_type"`
	PaymentID    string         `json:"payment_id,omitempty"`
	URL          string         `json:"url"`
	Payload      map[string]any `dynamorm:"json" json:"payload"`
	Attempts     int            `json:"attempts"`
	LastAttempt  time.Time      `json:"last_attempt,omitempty"`
	NextRetry    time.Time      `dynamorm:"index:gsi-retry" json:"next_retry,omitempty"`
	Status       string         `json:"status"`
	ResponseCode int            `json:"response_code,omitempty"`
	ResponseBody string         `json:"response_body,omitempty"`
	CreatedAt    time.Time      `dynamorm:"created_at" json:"created_at"`
	ExpiresAt    time.Time      `dynamorm:"ttl" json:"expires_at"`
}

Webhook represents a webhook delivery attempt

Directories

Path Synopsis
lambda
process command
query command
reconcile command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL