1package faker
2
3import (
4 "reflect"
5 "strconv"
6 "strings"
7
8 "github.com/go-faker/faker/v4/pkg/options"
9)
10
11const (
12 numberBytes = "0123456789"
13)
14
15// creditCard struct
16type creditCard struct {
17 ccType string
18 length int
19 prefixes []int
20}
21
22var creditCards = map[string]creditCard{
23 "visa": {"VISA", 16, []int{4539, 4556, 4916, 4532, 4929, 40240071, 4485, 4716, 4}},
24 "mastercard": {"MasterCard", 16, []int{51, 52, 53, 54, 55}},
25 "american express": {"American Express", 15, []int{34, 37}},
26 "discover": {"Discover", 16, []int{6011}},
27 "jcb": {"JCB", 16, []int{3528, 3538, 3548, 3558, 3568, 3578, 3588}},
28 "diners club": {"Diners Club", 14, []int{36, 38, 39}},
29}
30
31var cacheCreditCard string
32
33// GetPayment returns a new Render interface of Payment struct
34func GetPayment() Render {
35 pay := &Payment{}
36 return pay
37}
38
39// Render contains Whole Random Credit Card Generators with their types
40type Render interface {
41 CreditCardType(v reflect.Value) (interface{}, error)
42 CreditCardNumber(v reflect.Value) (interface{}, error)
43}
44
45// Payment struct
46type Payment struct{}
47
48func (p Payment) cctype() string {
49 n := len(creditCards)
50 if cacheCreditCard != "" {
51 return cacheCreditCard
52 }
53 var ccTypes []string
54
55 for _, cc := range creditCards {
56 ccTypes = append(ccTypes, cc.ccType)
57 }
58 cacheCreditCard = ccTypes[rand.Intn(n)]
59 return cacheCreditCard
60}
61
62// CreditCardType returns one of the following credit values:
63// VISA, MasterCard, American Express, Discover, JCB and Diners Club
64func (p Payment) CreditCardType(v reflect.Value) (interface{}, error) {
65 return p.cctype(), nil
66}
67
68// CCType get a credit card type randomly in string (VISA, MasterCard, etc)
69func CCType(opts ...options.OptionFunc) string {
70 return singleFakeData(CreditCardType, func() interface{} {
71 p := Payment{}
72 return p.cctype()
73 }, opts...).(string)
74}
75
76func (p Payment) ccnumber() string {
77 ccType := p.cctype()
78 cacheCreditCard = ccType
79 card := creditCards[strings.ToLower(ccType)]
80 prefix := strconv.Itoa(card.prefixes[rand.Intn(len(card.prefixes))])
81
82 num := prefix
83 digit := randomStringNumber(card.length - len(prefix))
84
85 num += digit
86 return num
87}
88
89// CreditCardNumber generated credit card number according to the card number rules
90func (p Payment) CreditCardNumber(v reflect.Value) (interface{}, error) {
91 return p.ccnumber(), nil
92}
93
94// CCNumber get a credit card number randomly in string (VISA, MasterCard, etc)
95func CCNumber(opts ...options.OptionFunc) string {
96 return singleFakeData(CreditCardNumber, func() interface{} {
97 p := Payment{}
98 return p.ccnumber()
99 }, opts...).(string)
100}