Payment Processor

Processes payments through CreditCard, PayPal, and Crypto types that satisfy a Processor interface. Uses type switches for type-specific fees and the Stringer interface for formatted receipts.

package main

import "fmt"

type Processor interface {
	Charge(amount float64) (string, error)
	Fee(amount float64) float64
}

type CreditCard struct {
	Number   string
	LastFour string
}

type PayPal struct {
	Email string
}

type Crypto struct {
	Wallet  string
	Network string
}

func (c CreditCard) Charge(amount float64) (string, error) {
	total := amount + c.Fee(amount)
	txID := fmt.Sprintf("CC-%s-%d", c.LastFour, int(total*100))
	return txID, nil
}

func (c CreditCard) Fee(amount float64) float64 {
	return amount * 0.029 // 2.9%
}

func (c CreditCard) String() string {
	return fmt.Sprintf("Credit Card ending in %s", c.LastFour)
}

func (p PayPal) Charge(amount float64) (string, error) {
	total := amount + p.Fee(amount)
	txID := fmt.Sprintf("PP-%d", int(total*100))
	return txID, nil
}

func (p PayPal) Fee(amount float64) float64 {
	return amount*0.034 + 0.30 // 3.4% + $0.30
}

func (p PayPal) String() string {
	return fmt.Sprintf("PayPal (%s)", p.Email)
}

func (cr Crypto) Charge(amount float64) (string, error) {
	if amount < 1.0 {
		return "", fmt.Errorf("minimum crypto payment is $1.00, got $%.2f", amount)
	}
	total := amount + cr.Fee(amount)
	txID := fmt.Sprintf("CRYPTO-%s-%d", cr.Network, int(total*100))
	return txID, nil
}

func (cr Crypto) Fee(amount float64) float64 {
	return 0.50 // flat network fee
}

func (cr Crypto) String() string {
	return fmt.Sprintf("Crypto [%s] %s...%s", cr.Network, cr.Wallet[:6], cr.Wallet[len(cr.Wallet)-4:])
}

func processPayment(p Processor, amount float64) {
	fee := p.Fee(amount)
	total := amount + fee

	// Type switch for extra info
	switch v := p.(type) {
	case CreditCard:
		fmt.Printf("  Method: %s\n", v)
	case PayPal:
		fmt.Printf("  Method: %s\n", v)
	case Crypto:
		fmt.Printf("  Method: %s\n", v)
	}

	txID, err := p.Charge(amount)
	if err != nil {
		fmt.Printf("  FAILED: %v\n\n", err)
		return
	}

	fmt.Printf("  Amount: $%.2f | Fee: $%.2f | Total: $%.2f\n", amount, fee, total)
	fmt.Printf("  Transaction: %s\n\n", txID)
}

func main() {
	processors := []Processor{
		CreditCard{Number: "4111111111111234", LastFour: "1234"},
		PayPal{Email: "[email protected]"},
		Crypto{Wallet: "0x7a3b9c2d1e4f5678abcd", Network: "ETH"},
	}

	amounts := []float64{49.99, 125.00, 0.50}

	for i, p := range processors {
		fmt.Printf("Payment #%d:\n", i+1)
		processPayment(p, amounts[i])
	}
}
▶ Open Go Playground

Copy the code above and paste to run

© 2026 ByteLearn.dev. Free courses for developers. · Privacy