1 package linodego
2 3 import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "time"
8 9 "github.com/linode/linodego/internal/parseabletime"
10 )
11 12 // PaymentMethod represents a PaymentMethod object
13 type PaymentMethod struct {
14 // The unique ID of the Payment Method.
15 ID int `json:"id"`
16 17 // When the Payment Method was created.
18 Created *time.Time `json:"created"`
19 20 // Whether this Payment Method is the default method for automatically processing service charges.
21 IsDefault bool `json:"is_default"`
22 23 // The type of Payment Method.
24 Type string `json:"type"`
25 26 // The detailed data for the Payment Method, which can be of varying types.
27 Data any `json:"data"`
28 }
29 30 // PaymentMethodDataCreditCard represents a PaymentMethodDataCreditCard object
31 type PaymentMethodDataCreditCard struct {
32 // The type of credit card.
33 CardType string `json:"card_type"`
34 35 // The expiration month and year of the credit card.
36 Expiry string `json:"expiry"`
37 38 // The last four digits of the credit card number.
39 LastFour string `json:"last_four"`
40 }
41 42 // PaymentMethodDataGooglePay represents a PaymentMethodDataGooglePay object
43 type PaymentMethodDataGooglePay struct {
44 // The type of credit card.
45 CardType string `json:"card_type"`
46 47 // The expiration month and year of the credit card.
48 Expiry string `json:"expiry"`
49 50 // The last four digits of the credit card number.
51 LastFour string `json:"last_four"`
52 }
53 54 // PaymentMethodDataPaypal represents a PaymentMethodDataPaypal object
55 type PaymentMethodDataPaypal struct {
56 // The email address associated with your PayPal account.
57 Email string `json:"email"`
58 59 // PayPal Merchant ID associated with your PayPal account.
60 PaypalID string `json:"paypal_id"`
61 }
62 63 // PaymentMethodCreateOptions fields are those accepted by CreatePaymentMethod
64 type PaymentMethodCreateOptions struct {
65 // Whether this Payment Method is the default method for automatically processing service charges.
66 IsDefault bool `json:"is_default"`
67 68 // The type of Payment Method. Alternative payment methods including Google Pay and PayPal can be added using the Cloud Manager.
69 Type string `json:"type"`
70 71 // An object representing the credit card information you have on file with Linode to make Payments against your Account.
72 Data *PaymentMethodCreateOptionsData `json:"data"`
73 }
74 75 type PaymentMethodCreateOptionsData struct {
76 // Your credit card number. No spaces or hyphens (-) allowed.
77 CardNumber string `json:"card_number"`
78 79 // CVV (Card Verification Value) of the credit card, typically found on the back of the card.
80 CVV string `json:"cvv"`
81 82 // A value from 1-12 representing the expiration month of your credit card.
83 ExpiryMonth int `json:"expiry_month"`
84 85 // A four-digit integer representing the expiration year of your credit card.
86 ExpiryYear int `json:"expiry_year"`
87 }
88 89 // UnmarshalJSON implements the json.Unmarshaler interface
90 func (i *PaymentMethod) UnmarshalJSON(b []byte) error {
91 if len(b) == 0 || string(b) == "{}" || string(b) == "null" {
92 return nil
93 }
94 95 type Mask PaymentMethod
96 97 pm := &struct {
98 *Mask
99 100 Created *parseabletime.ParseableTime `json:"created"`
101 Data json.RawMessage `json:"data"`
102 }{
103 Mask: (*Mask)(i),
104 }
105 106 if err := json.Unmarshal(b, &pm); err != nil {
107 return err
108 }
109 110 // Process Data based on the Type field
111 switch i.Type {
112 case "credit_card":
113 var creditCardData PaymentMethodDataCreditCard
114 if err := json.Unmarshal(pm.Data, &creditCardData); err != nil {
115 return err
116 }
117 118 i.Data = creditCardData
119 case "google_pay":
120 var googlePayData PaymentMethodDataGooglePay
121 if err := json.Unmarshal(pm.Data, &googlePayData); err != nil {
122 return err
123 }
124 125 i.Data = googlePayData
126 case "paypal":
127 var paypalData PaymentMethodDataPaypal
128 if err := json.Unmarshal(pm.Data, &paypalData); err != nil {
129 return err
130 }
131 132 i.Data = paypalData
133 default:
134 return fmt.Errorf("unknown payment method type: %s", i.Type)
135 }
136 137 i.Created = (*time.Time)(pm.Created)
138 139 return nil
140 }
141 142 // ListPaymentMethods lists PaymentMethods
143 func (c *Client) ListPaymentMethods(ctx context.Context, opts *ListOptions) ([]PaymentMethod, error) {
144 return getPaginatedResults[PaymentMethod](ctx, c, "account/payment-methods", opts)
145 }
146 147 // GetPaymentMethod gets the payment method with the provided ID
148 func (c *Client) GetPaymentMethod(ctx context.Context, paymentMethodID int) (*PaymentMethod, error) {
149 e := formatAPIPath("account/payment-methods/%d", paymentMethodID)
150 return doGETRequest[PaymentMethod](ctx, c, e)
151 }
152 153 // DeletePaymentMethod deletes the payment method with the provided ID
154 func (c *Client) DeletePaymentMethod(ctx context.Context, paymentMethodID int) error {
155 e := formatAPIPath("account/payment-methods/%d", paymentMethodID)
156 return doDELETERequest(ctx, c, e)
157 }
158 159 // AddPaymentMethod adds the provided payment method to the account
160 func (c *Client) AddPaymentMethod(ctx context.Context, opts PaymentMethodCreateOptions) error {
161 return doPOSTRequestNoResponseBody(ctx, c, "account/payment-methods", opts)
162 }
163 164 // SetDefaultPaymentMethod sets the payment method with the provided ID as the default
165 func (c *Client) SetDefaultPaymentMethod(ctx context.Context, paymentMethodID int) error {
166 e := formatAPIPath("account/payment-methods/%d", paymentMethodID)
167 return doPOSTRequestNoRequestResponseBody(ctx, c, e)
168 }
169