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])
}
}