diff --git a/pkg/customer/customercard/card.go b/pkg/customer/customercard/card.go new file mode 100644 index 00000000..63cf9bf3 --- /dev/null +++ b/pkg/customer/customercard/card.go @@ -0,0 +1,166 @@ +package customercard + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/mercadopago/sdk-go/pkg/config" + "github.com/mercadopago/sdk-go/pkg/internal/httpclient" +) + +const ( + baseURL = "https://api.mercadopago.com/v1/customers/{customer_id}" + cardsURL = baseURL + "/cards" + cardsByIDURL = baseURL + cardsURL + "/{card_id}" +) + +// Client contains the methods to interact with the Payment Methods API. +type Client interface { + // Create a new customer card. + // It is a post request to the endpoint: https://api.mercadopago.com/v1/customer/{customer_id}/cards + // Reference: https://www.mercadopago.com/developers/en/reference/cards/_customers_customer_id_cards/post + Create(ctx context.Context, customerID string, request Request) (*Response, error) + + // Get a customer card by ID. + // It is a get request to the endpoint: https://api.mercadopago.com/v1/customer/{customer_id}/cards/{card_id} + // Reference: https://www.mercadopago.com/developers/en/reference/cards/_customers_customer_id_cards_id/get + Get(ctx context.Context, customerID, cardID string) (*Response, error) + + // Update a customer card by ID. + // It is a put request to the endpoint: https://api.mercadopago.com/v1/customer/{customer_id}/cards/{card_id} + // Reference: https://www.mercadopago.com/developers/en/reference/cards/_customers_customer_id_cards_id/put + Update(ctx context.Context, customerID, cardID string) (*Response, error) + + // Delete deletes a customer card by ID. + // It is a delete request to the endpoint: https://api.mercadopago.com/v1/customer/{customer_id}/cards/{card_id} + // Reference: https://www.mercadopago.com/developers/en/reference/cards/_customers_customer_id_cards_id/delete + Delete(ctx context.Context, customerID, cardID string) (*Response, error) + + // List all customers. + // It is a get request to the endpoint: https://api.mercadopago.com/v1/customer/{customer_id}/cards + // Reference: https://www.mercadopago.com/developers/en/reference/cards/_customers_customer_id_cards/get + List(ctx context.Context, customerID string) ([]Response, error) +} + +// client is the implementation of Client. +type client struct { + config *config.Config +} + +// NewClient returns a new Payment Methods API Client. +func NewClient(c *config.Config) Client { + return &client{ + config: c, + } +} + +func (c *client) Create(ctx context.Context, customerID string, request Request) (*Response, error) { + body, err := json.Marshal(&request) + if err != nil { + return nil, fmt.Errorf("error marshaling request body: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, cardsURL, strings.NewReader(string(body))) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + + res, err := httpclient.Send(ctx, c.config, req) + if err != nil { + return nil, err + } + + formatted := &Response{} + if err := json.Unmarshal(res, &formatted); err != nil { + return nil, fmt.Errorf("error unmarshaling response: %w", err) + } + + return formatted, nil +} + +func (c *client) Get(ctx context.Context, customerID, cardID string) (*Response, error) { + url := strings.Replace(cardsByIDURL, "{customer_id}", customerID, 1) + url = strings.Replace(cardsByIDURL, "{card_id}", cardID, 1) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + + res, err := httpclient.Send(ctx, c.config, req) + if err != nil { + return nil, err + } + + formatted := &Response{} + if err := json.Unmarshal(res, &formatted); err != nil { + return nil, fmt.Errorf("error unmarshaling response: %w", err) + } + + return formatted, nil +} + +func (c *client) Update(ctx context.Context, customerID, cardID string) (*Response, error) { + conv := strconv.Itoa(int(id)) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.Replace(getURL, "{id}", conv, 1), nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + + res, err := httpclient.Send(ctx, c.config, req) + if err != nil { + return nil, err + } + + formatted := &Response{} + if err := json.Unmarshal(res, &formatted); err != nil { + return nil, fmt.Errorf("error unmarshaling response: %w", err) + } + + return formatted, nil +} + +func (c *client) Delete(ctx context.Context, customerID, cardID string) (*Response, error) { + conv := strconv.Itoa(int(id)) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.Replace(getURL, "{id}", conv, 1), nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + + res, err := httpclient.Send(ctx, c.config, req) + if err != nil { + return nil, err + } + + formatted := &Response{} + if err := json.Unmarshal(res, &formatted); err != nil { + return nil, fmt.Errorf("error unmarshaling response: %w", err) + } + + return formatted, nil +} + +func (c *client) List(ctx context.Context, customerID string) ([]Response, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + + res, err := httpclient.Send(ctx, c.config, req) + if err != nil { + return nil, err + } + + var formatted []Response + if err := json.Unmarshal(res, &formatted); err != nil { + return nil, err + } + + return formatted, nil +} diff --git a/pkg/customer/customercard/request.go b/pkg/customer/customercard/request.go new file mode 100644 index 00000000..66740317 --- /dev/null +++ b/pkg/customer/customercard/request.go @@ -0,0 +1,5 @@ +package customercard + +type Request struct { + Token string `json:"token"` +} diff --git a/pkg/customer/customercard/response.go b/pkg/customer/customercard/response.go new file mode 100644 index 00000000..07d33bed --- /dev/null +++ b/pkg/customer/customercard/response.go @@ -0,0 +1,52 @@ +package customercard + +type Response struct { + ID string `json:"id"` + Name string `json:"name"` + PaymentTypeID string `json:"payment_type_id"` + Status string `json:"status"` + SecureThumbnail string `json:"secure_thumbnail"` + Thumbnail string `json:"thumbnail"` + DeferredCapture string `json:"deferred_capture"` + AdditionalInfoNeeded []string `json:"additional_info_needed"` + ProcessingModes []string `json:"processing_modes"` + AccreditationTime int64 `json:"accreditation_time"` + MinAllowedAmount float64 `json:"min_allowed_amount"` + MaxAllowedAmount float64 `json:"max_allowed_amount"` + + Settings []SettingsResponse `json:"settings"` + FinancialInstitutions []FinancialInstitutionResponse `json:"financial_institutions"` +} + +// SettingsResponse represents payment method settings. +type SettingsResponse struct { + Bin *SettingsBinResponse `json:"bin"` + CardNumber *SettingsCardNumberResponse `json:"card_number"` + SecurityCode *SettingsSecurityCodeResponse `json:"security_code"` +} + +// SettingsBinResponse represents BIN (Bank Identification Number) settings. +type SettingsBinResponse struct { + Pattern string `json:"pattern"` + ExclusionPattern string `json:"exclusion_pattern"` + InstallmentsPattern string `json:"installments_pattern"` +} + +// SettingsCardNumberResponse represents customer number settings. +type SettingsCardNumberResponse struct { + Length int `json:"length"` + Validation string `json:"validation"` +} + +// SettingsSecurityCodeResponse represents security code settings. +type SettingsSecurityCodeResponse struct { + Mode string `json:"mode"` + Length int `json:"length"` + CardLocation string `json:"card_location"` +} + +// FinancialInstitutionResponse represents financial institution settings. +type FinancialInstitutionResponse struct { + ID string `json:"id"` + Description string `json:"description"` +} diff --git a/pkg/paymentmethod/client.go b/pkg/paymentmethod/payment_method.go similarity index 100% rename from pkg/paymentmethod/client.go rename to pkg/paymentmethod/payment_method.go diff --git a/pkg/paymentmethod/response.go b/pkg/paymentmethod/response.go index 5cffb157..aeec6fac 100644 --- a/pkg/paymentmethod/response.go +++ b/pkg/paymentmethod/response.go @@ -32,7 +32,7 @@ type SettingsBinResponse struct { InstallmentsPattern string `json:"installments_pattern"` } -// SettingsCardNumberResponse represents card number settings. +// SettingsCardNumberResponse represents customer number settings. type SettingsCardNumberResponse struct { Length int `json:"length"` Validation string `json:"validation"`