From 07ee2bf4ad3ccf8c907f847c395ad6d12ab59593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Mon, 18 Sep 2023 22:47:34 +0300 Subject: [PATCH] feat: init --- .github/workflows/ci.yml | 88 +++++ .golangci.yml | 152 ++++++++ .version | 1 + CODE_OF_CONDUCT.md | 132 +++++++ LICENSE | 201 +++++++++++ Makefile | 26 ++ README.md | 7 + api_keys.go | 261 ++++++++++++++ authorization.go | 147 ++++++++ checkouts.go | 685 ++++++++++++++++++++++++++++++++++++ client.go | 105 ++++++ customers.go | 519 +++++++++++++++++++++++++++ error.go | 52 +++ example/go.mod | 11 + example/go.sum | 2 + example/simple/main.go | 22 ++ go.mod | 3 + merchant.go | 586 +++++++++++++++++++++++++++++++ models.go | 177 ++++++++++ payouts.go | 96 +++++ receipts.go | 163 +++++++++ subaccounts.go | 207 +++++++++++ transactions.go | 736 +++++++++++++++++++++++++++++++++++++++ 23 files changed, 4379 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .golangci.yml create mode 100644 .version create mode 100644 CODE_OF_CONDUCT.md create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100755 api_keys.go create mode 100755 authorization.go create mode 100755 checkouts.go create mode 100755 client.go create mode 100755 customers.go create mode 100644 error.go create mode 100644 example/go.mod create mode 100644 example/go.sum create mode 100644 example/simple/main.go create mode 100644 go.mod create mode 100755 merchant.go create mode 100755 models.go create mode 100755 payouts.go create mode 100755 receipts.go create mode 100755 subaccounts.go create mode 100755 transactions.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..77f4125 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,88 @@ +name: CI + +on: + workflow_dispatch: {} + push: + branches: + - main + tags: + - v[0-9]+.[0-9]+.[0-9]+* + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe + with: + go-version-file: 'go.mod' + + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: v1.54 + + test: + name: Test + runs-on: ubuntu-latest + strategy: + matrix: + go: + - "1.19" + - "1.18" + - "1.17" + steps: + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe + with: + go-version: ${{ matrix.go }} + - name: Test + run: make test + + vulncheck: + name: Vulnerabilities check + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe + with: + go-version: ${{ matrix.go }} + - name: Scan for Vulnerabilities in Code + uses: Templum/govulncheck-action@6bb063b41d78c53c2fc7f5589828e30ad7c697ee + + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe + with: + go-version: ${{ matrix.go }} + - name: Initialize CodeQL + uses: github/codeql-action/init@1245696032ecf7d39f87d54daa406e22ddf769a8 + with: + languages: go + queries: +security-extended,security-and-quality + ram: 4096 + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@1245696032ecf7d39f87d54daa406e22ddf769a8 + with: + category: '/language:go' + diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..921f8f0 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,152 @@ +run: + timeout: 3m + skip-dirs-use-default: true + +issues: + max-per-linter: 0 + max-same-issues: 0 + exclude-rules: + - path: _test\.go + linters: + - bodyclose + - dupl + - errcheck + - errorlint + - funlen + - goconst + - gocyclo + - goerr113 + - gosec + - lll + - noctx + - prealloc + - unparam + +output: + uniq-by-line: true + sort-results: true + +linters: + disable-all: true + enable: + - asciicheck + - bodyclose + - depguard + - durationcheck + - errcheck + - errorlint + - exhaustive + - exportloopref + - gocritic + - gofmt + - goimports + - gomoddirectives + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - makezero + - megacheck + - misspell + - nakedret + - nakedret + - nilerr + - noctx + - nolintlint + - prealloc + - revive + - rowserrcheck + - sqlclosecheck + - staticcheck + # Disabled until we have proper camel-casing with initialisms + # See: https://golangci-lint.run/usage/linters/#stylecheck + # - stylecheck + - typecheck + - unconvert + - unparam + - unused + - vet + - vetshadow + - wastedassign + - whitespace + +linters-settings: + depguard: + rules: + main: + deny: + - pkg: github.com/pkg/errors + desc: Use "errors" from std lib instead. + errorlint: + errorf: true + asserts: false + comparison: true + errcheck: + check-type-assertions: true + check-blank: false + exhaustive: + default-signifies-exhaustive: true + gci: + sections: + - standard + - default + - prefix(github.com/sumup/portier) + - dot + skip-generated: false + gocritic: + disabled-checks: + - sloppyReassign + - whyNoLint + enabled-tags: + - diagnostic + - style + - performance + settings: + hugeParam: + sizeThreshold: 512 + gofmt: + simplify: true + goimports: + local-prefixes: github.com/sumup/portier + golint: + min-confidence: 0.8 + gomoddirectives: + replace-local: true + replace-allow-list: + - github.com/sumup/portier-migrate + - github.com/sqlc-dev/sqlc + gosimple: + checks: ["all"] + govet: + check-shadowing: true + enable-all: true + disable: + - fieldalignment + nakedret: + max-func-lines: 10 + misspell: + locale: US + prealloc: + simple: true + range-loops: true + for-loops: false + revive: + rules: + - name: blank-imports + disabled: true + nolintlint: + allow-unused: false + allow-leading-space: false + allow-no-explanation: [noctx] + require-explanation: true + require-specific: true + staticcheck: + checks: ['all'] + unparam: + check-exported: false + unused: + check-exported: false + whitespace: + multi-if: false + multi-func: false diff --git a/.version b/.version new file mode 100644 index 0000000..8a9ecc2 --- /dev/null +++ b/.version @@ -0,0 +1 @@ +0.0.1 \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f6bdbc9 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement listed on the +[project's `README`](https://github.com/sumup-oss/circuit-ui#maintainers). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][mozilla coc]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][faq]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[mozilla coc]: https://github.com/mozilla/diversity +[faq]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f9bd2d0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2019 SumUp Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4e63384 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +# Make this makefile self-documented with target `help` +.PHONY: help +.DEFAULT_GOAL := help +help: ## Show help + @grep -Eh '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: fmt +fmt: ## Format go files + goimports -w . + +.PHONY: lint +lint: ## Lint go files + golangci-lint run -v + +.PHONY: test +test: ## Run tests + go test -v -failfast -race -timeout 10m ./... + +.PHONY: download +download: + @echo Download go.mod dependencies + @go mod download + +.PHONE: vulncheck +vulncheck: ## Check for Vulnerabilities (make sure you have the tools install: `make install-tools`) + govulncheck ./... diff --git a/README.md b/README.md new file mode 100644 index 0000000..bd6a6e2 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# sumup.go + +[![Go Reference](https://pkg.go.dev/badge/github.com/sumup/sumup.go.svg)](https://pkg.go.dev/github.com/sumup/sumup.go) + +_**IMPORTANT:** This SDK is under heavy development and will have constant breaking changes._ + +The Golang SDK for SumUp [API](https://developer.sumup.com). diff --git a/api_keys.go b/api_keys.go new file mode 100755 index 0000000..800e6ec --- /dev/null +++ b/api_keys.go @@ -0,0 +1,261 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +// Apikey is the type definition for a Apikey. +type Apikey struct { + CreatedAt time.Time `json:"created_at"` + // Unique identifier of the API Key. + Id string `json:"id"` + // User-assigned name of the API Key. + Name string `json:"name"` + // The plaintext value of the API key. This field is returned only in the response to API key creation and is never again available in the plaintext form. + Plaintext *string `json:"plaintext,omitempty"` + // Last 8 characters of the API key. + Preview string `json:"preview"` + Scopes Oauth2Scopes `json:"scopes"` + Type ApikeyType `json:"type"` + UpdatedAt time.Time `json:"updated_at"` +} + +type ApikeyType string + +const ( + ApikeyTypePublic ApikeyType = "public" + ApikeyTypeSecret ApikeyType = "secret" +) + +// ApikeysList is the type definition for a ApikeysList. +type ApikeysList struct { + Items []Apikey `json:"items"` + TotalCount int `json:"total_count"` +} + +// Oauth2Scopes is the type definition for a Oauth2Scopes. +type Oauth2Scopes []string + +// ListApikeysParams are query parameters for ListApikeys +type ListApikeysParams struct { + Limit *int `json:"limit,omitempty"` + Offset *int `json:"offset,omitempty"` +} + +// CreateAPIKey request body. +type CreateApikeyBody struct { + Name string `json:"name"` + Scopes []string `json:"scopes"` +} + +// UpdateAPIKey request body. +type UpdateApikeyBody struct { + // New name for the API key. + Name string `json:"name"` + Scopes []string `json:"scopes"` +} + +type ApiKeysService service + +// ListApikeys: List API keys +// Returns paginated list of API keys. +// + +func (s *ApiKeysService) ListApikeys(ctx context.Context, offset int, limit int, merchantCode string, params ListApikeysParams) (*ApikeysList, error) { + path := fmt.Sprintf("/v0.1/merchants/%v/api-keys", merchantCode) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v ApikeysList + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// CreateApikey: Create an API key +// Creates a new API key for the user. +func (s *ApiKeysService) CreateApikey(ctx context.Context, merchantCode string, body CreateApikeyBody) (*Apikey, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/merchants/%v/api-keys", merchantCode) + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Apikey + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// RevokeApikey: Revoke an API key +// Revokes an API key. +func (s *ApiKeysService) RevokeApikey(ctx context.Context, merchantCode string, keyId string) error { + path := fmt.Sprintf("/v0.1/merchants/%v/api-keys/%v", merchantCode, keyId) + + req, err := s.client.NewRequest(ctx, http.MethodDelete, path, http.NoBody) + if err != nil { + return fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return fmt.Errorf("read error response: %s", err.Error()) + } + + return &apiErr + } + + return nil +} + +// GetApikey: Retrieve an API Key +// Gets an API key. +// + +func (s *ApiKeysService) GetApikey(ctx context.Context, merchantCode string, keyId string) (*Apikey, error) { + path := fmt.Sprintf("/v0.1/merchants/%v/api-keys/%v", merchantCode, keyId) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Apikey + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// UpdateApikey: Update an API key +// Updates an API key. +func (s *ApiKeysService) UpdateApikey(ctx context.Context, merchantCode string, keyId string, body UpdateApikeyBody) error { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/merchants/%v/api-keys/%v", merchantCode, keyId) + + req, err := s.client.NewRequest(ctx, http.MethodPut, path, buf) + if err != nil { + return fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return fmt.Errorf("read error response: %s", err.Error()) + } + + return &apiErr + } + + return nil +} diff --git a/authorization.go b/authorization.go new file mode 100755 index 0000000..6b2bf37 --- /dev/null +++ b/authorization.go @@ -0,0 +1,147 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" +) + +// CreateToken request body. +type CreateTokenBody struct { + // The client ID of your application that was generated when you [registered it](https://developer.sumup.com/docs/register-app). + ClientId string `json:"client_id"` + // The client secret of your application that was generated when you [registered it](https://developer.sumup.com/docs/register-app). + ClientSecret string `json:"client_secret"` + // The authorization code that you received from requesting an authorization code. + Code string `json:"code"` + // The grant type used for obtaining an access token. + GrantType CreateTokenBodyGrantType `json:"grant_type"` + // A **required** parameter when generating a refresh token. + RefreshToken *string `json:"refresh_token,omitempty"` +} + +// The grant type used for obtaining an access token. +type CreateTokenBodyGrantType string + +const ( + CreateTokenBodyGrantTypeAuthorizationCode CreateTokenBodyGrantType = "authorization_code" + CreateTokenBodyGrantTypeRefreshToken CreateTokenBodyGrantType = "refresh_token" +) + +// CreateTokenResponse is the type definition for a CreateTokenResponse. +type CreateTokenResponse struct { + // The access token that you need to use in your requests to the SumUp API. + AccessToken *string `json:"access_token,omitempty"` + // The validity of the access token in seconds. + ExpiresIn *int `json:"expires_in,omitempty"` + // The refresh token provided in the request call + RefreshToken *string `json:"refresh_token,omitempty"` + // List of authorization scopes granted to your access token. + Scope *string `json:"scope,omitempty"` + // The type of the token. The value is always `Bearer`. + TokenType *string `json:"token_type,omitempty"` +} + +// AuthorizeParams are query parameters for Authorize +type AuthorizeParams struct { + ClientId *string `json:"client_id,omitempty"` + RedirectUri *string `json:"redirect_uri,omitempty"` + ResponseType *string `json:"response_type,omitempty"` + Scope *string `json:"scope,omitempty"` + State *string `json:"state,omitempty"` +} + +// AuthorizeResponse is the type definition for a AuthorizeResponse. +type AuthorizeResponse struct { +} + +type AuthorizationService service + +// Authorize: Request authorization from users +// Request authorization from users and grant your application access to resources associated with the user's account. +// + +func (s *AuthorizationService) Authorize(ctx context.Context, responseType string, clientId string, redirectUri string, scope string, state string, params AuthorizeParams) (*AuthorizeResponse, error) { + path := fmt.Sprintf("/authorize") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v AuthorizeResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// CreateToken: Generate a token +// Generate a token or a refresh token +func (s *AuthorizationService) CreateToken(ctx context.Context, body CreateTokenBody) (*CreateTokenResponse, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/token") + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v CreateTokenResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} diff --git a/checkouts.go b/checkouts.go new file mode 100755 index 0000000..121acfc --- /dev/null +++ b/checkouts.go @@ -0,0 +1,685 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +// Checkout is Details of the payment checkout. +type Checkout struct { + // Amount of the payment. + Amount *float64 `json:"amount,omitempty"` + // Unique ID of the payment checkout specified by the client application when creating the checkout resource. + CheckoutReference *string `json:"checkout_reference,omitempty"` + // Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. + Currency *Currency `json:"currency,omitempty"` + // Unique identification of a customer. If specified, the checkout session and payment instrument are associated with the referrenced customer. + CustomerId *string `json:"customer_id,omitempty"` + // Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + Date *time.Time `json:"date,omitempty"` + // Short description of the checkout visible in the SumUp dashboard. The description can contribute to reporting, allowing easier identification of a checkout. + Description *string `json:"description,omitempty"` + // Unique ID of the checkout resource. + Id *string `json:"id,omitempty"` + // Created mandate + Mandate *MandateResponse `json:"mandate,omitempty"` + // Unique identifying code of the merchant profile. + MerchantCode *string `json:"merchant_code,omitempty"` + // Email address of the registered user (merchant) to whom the payment is made. + PayToEmail *string `json:"pay_to_email,omitempty"` + // URL to which the SumUp platform sends the processing status of the payment checkout. + ReturnUrl *string `json:"return_url,omitempty"` + // Current status of the checkout. + Status *CheckoutStatus `json:"status,omitempty"` + // List of transactions related to the payment. + Transactions *[]string `json:"transactions,omitempty"` + // Date and time of the checkout expiration before which the client application needs to send a processing request. If no value is present, the checkout does not have an expiration time. + ValidUntil *time.Time `json:"valid_until,omitempty"` +} + +// Current status of the checkout. +type CheckoutStatus string + +const ( + CheckoutStatusFailed CheckoutStatus = "FAILED" + CheckoutStatusPaid CheckoutStatus = "PAID" + CheckoutStatusPending CheckoutStatus = "PENDING" +) + +// Current status of the checkout. +type CheckoutSuccessStatus string + +const ( + CheckoutSuccessStatusFailed CheckoutSuccessStatus = "FAILED" + CheckoutSuccessStatusPaid CheckoutSuccessStatus = "PAID" + CheckoutSuccessStatusPending CheckoutSuccessStatus = "PENDING" +) + +// CheckoutSuccessPaymentInstrument description +type CheckoutSuccessPaymentInstrument struct { + // Token value + Token *string `json:"token,omitempty"` +} + +// CheckoutSuccess is the type definition for a CheckoutSuccess. +type CheckoutSuccess struct { + // Amount of the payment. + Amount *float64 `json:"amount,omitempty"` + // Unique ID of the payment checkout specified by the client application when creating the checkout resource. + CheckoutReference *string `json:"checkout_reference,omitempty"` + // Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. + Currency *Currency `json:"currency,omitempty"` + // Unique identification of a customer. If specified, the checkout session and payment instrument are associated with the referrenced customer. + CustomerId *string `json:"customer_id,omitempty"` + // Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + Date *time.Time `json:"date,omitempty"` + // Short description of the checkout visible in the SumUp dashboard. The description can contribute to reporting, allowing easier identification of a checkout. + Description *string `json:"description,omitempty"` + // Unique ID of the checkout resource. + Id *string `json:"id,omitempty"` + // Created mandate + Mandate *MandateResponse `json:"mandate,omitempty"` + // Unique identifying code of the merchant profile. + MerchantCode *string `json:"merchant_code,omitempty"` + // Name of the merchant + MerchantName *string `json:"merchant_name,omitempty"` + // Email address of the registered user (merchant) to whom the payment is made. + PayToEmail *string `json:"pay_to_email,omitempty"` + // Object containing token information for the specified payment instrument + PaymentInstrument *CheckoutSuccessPaymentInstrument `json:"payment_instrument,omitempty"` + // Refers to a url where the end user is redirected once the payment processing completes. + RedirectUrl *string `json:"redirect_url,omitempty"` + // URL to which the SumUp platform sends the processing status of the payment checkout. + ReturnUrl *string `json:"return_url,omitempty"` + // Current status of the checkout. + Status *CheckoutSuccessStatus `json:"status,omitempty"` + // Transaction code of the successful transaction with which the payment for the checkout is completed. + TransactionCode *string `json:"transaction_code,omitempty"` + // Transaction ID of the successful transaction with which the payment for the checkout is completed. + TransactionId *string `json:"transaction_id,omitempty"` + // List of transactions related to the payment. + Transactions *[]string `json:"transactions,omitempty"` + // Date and time of the checkout expiration before which the client application needs to send a processing request. If no value is present, the checkout does not have an expiration time. + ValidUntil *time.Time `json:"valid_until,omitempty"` +} + +// Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. +type Currency string + +const ( + CurrencyBgn Currency = "BGN" + CurrencyBrl Currency = "BRL" + CurrencyChf Currency = "CHF" + CurrencyClp Currency = "CLP" + CurrencyCzk Currency = "CZK" + CurrencyDkk Currency = "DKK" + CurrencyEur Currency = "EUR" + CurrencyGbp Currency = "GBP" + CurrencyHrk Currency = "HRK" + CurrencyHuf Currency = "HUF" + CurrencyNok Currency = "NOK" + CurrencyPln Currency = "PLN" + CurrencyRon Currency = "RON" + CurrencySek Currency = "SEK" + CurrencyUsd Currency = "USD" +) + +// DetailsError is Error message structure. +type DetailsError struct { + // Details of the error. + Details *string `json:"details,omitempty"` + FailedConstraints *[]string `json:"failed_constraints,omitempty"` + // The status code. + Status *float64 `json:"status,omitempty"` + // Short title of the error. + Title *string `json:"title,omitempty"` +} + +// CreateCheckout request body. +type CreateCheckoutBody struct { + // Amount of the payment. + Amount float64 `json:"amount"` + // Unique ID of the payment checkout specified by the client application when creating the checkout resource. + CheckoutReference string `json:"checkout_reference"` + // Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. + Currency CreateCheckoutBodyCurrency `json:"currency"` + // Unique identification of a customer. If specified, the checkout session and payment instrument are associated with the referrenced customer. + CustomerId *string `json:"customer_id,omitempty"` + // Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + Date *time.Time `json:"date,omitempty"` + // Short description of the checkout visible in the SumUp dashboard. The description can contribute to reporting, allowing easier identification of a checkout. + Description *string `json:"description,omitempty"` + // Unique ID of the checkout resource. + Id *string `json:"id,omitempty"` + // Unique identifying code of the merchant profile. + MerchantCode string `json:"merchant_code"` + // Email address of the registered user (merchant) to whom the payment is made. It is highly recommended to use `merchant_code` instead of `pay_to_email`. + PayToEmail *string `json:"pay_to_email,omitempty"` + // Alternative payment method name + PaymentType *string `json:"payment_type,omitempty"` + // Object containing personal details about the payer, typical for __Boleto__ checkouts + PersonalDetails *CreateCheckoutBodyPersonalDetails `json:"personal_details,omitempty"` + // __Required for 3DS checkouts.__ Refers to a url where the end user is redirected once the payment processing completes. + RedirectUrl *string `json:"redirect_url,omitempty"` + // URL to which the SumUp platform sends the processing status of the payment checkout. + ReturnUrl *string `json:"return_url,omitempty"` + // Currrent status of the checkout. + Status *CreateCheckoutBodyStatus `json:"status,omitempty"` + // List of transactions related to the payment. + Transactions *[]string `json:"transactions,omitempty"` + // Date and time of the checkout expiration before which the client application needs to send a processing request. If no value is present, the checkout does not have an expiration time. + ValidUntil *time.Time `json:"valid_until,omitempty"` +} + +// CreateCheckoutBodyPersonalDetails description +type CreateCheckoutBodyPersonalDetails struct { + // Payer's address information + Address *CreateCheckoutBodyPersonalDetailsAddress `json:"address,omitempty"` + // Payer's email address + Email *string `json:"email,omitempty"` + // Payer's first name + FirstName *string `json:"first_name,omitempty"` + // Payer's last name + LastName *string `json:"last_name,omitempty"` + // Payer's tax identification number (CPF) + TaxId *string `json:"tax_id,omitempty"` +} + +// CreateCheckoutBodyPersonalDetailsAddress description +type CreateCheckoutBodyPersonalDetailsAddress struct { + // Payer's city + City *string `json:"city,omitempty"` + // Payer's country + Country *string `json:"country,omitempty"` + // Field for address details + Line1 *string `json:"line_1,omitempty"` + // Payer's postal code. Must be eight digits long, however an optional dash could be applied after the 5th digit ([more information about the format available here](https://en.wikipedia.org/wiki/List_of_postal_codes_in_Brazil)). Both options are accepted as correct. + PostalCode *string `json:"postal_code,omitempty"` + // Payer's state code + State *CreateCheckoutBodyPersonalDetailsAddressState `json:"state,omitempty"` +} + +// Payer's state code +type CreateCheckoutBodyPersonalDetailsAddressState string + +const ( + CreateCheckoutBodyPersonalDetailsAddressStateAc CreateCheckoutBodyPersonalDetailsAddressState = "AC" + CreateCheckoutBodyPersonalDetailsAddressStateAl CreateCheckoutBodyPersonalDetailsAddressState = "AL" + CreateCheckoutBodyPersonalDetailsAddressStateAm CreateCheckoutBodyPersonalDetailsAddressState = "AM" + CreateCheckoutBodyPersonalDetailsAddressStateAp CreateCheckoutBodyPersonalDetailsAddressState = "AP" + CreateCheckoutBodyPersonalDetailsAddressStateBa CreateCheckoutBodyPersonalDetailsAddressState = "BA" + CreateCheckoutBodyPersonalDetailsAddressStateCe CreateCheckoutBodyPersonalDetailsAddressState = "CE" + CreateCheckoutBodyPersonalDetailsAddressStateDf CreateCheckoutBodyPersonalDetailsAddressState = "DF" + CreateCheckoutBodyPersonalDetailsAddressStateEs CreateCheckoutBodyPersonalDetailsAddressState = "ES" + CreateCheckoutBodyPersonalDetailsAddressStateGo CreateCheckoutBodyPersonalDetailsAddressState = "GO" + CreateCheckoutBodyPersonalDetailsAddressStateMa CreateCheckoutBodyPersonalDetailsAddressState = "MA" + CreateCheckoutBodyPersonalDetailsAddressStateMg CreateCheckoutBodyPersonalDetailsAddressState = "MG" + CreateCheckoutBodyPersonalDetailsAddressStateMs CreateCheckoutBodyPersonalDetailsAddressState = "MS" + CreateCheckoutBodyPersonalDetailsAddressStateMt CreateCheckoutBodyPersonalDetailsAddressState = "MT" + CreateCheckoutBodyPersonalDetailsAddressStatePa CreateCheckoutBodyPersonalDetailsAddressState = "PA" + CreateCheckoutBodyPersonalDetailsAddressStatePb CreateCheckoutBodyPersonalDetailsAddressState = "PB" + CreateCheckoutBodyPersonalDetailsAddressStatePe CreateCheckoutBodyPersonalDetailsAddressState = "PE" + CreateCheckoutBodyPersonalDetailsAddressStatePi CreateCheckoutBodyPersonalDetailsAddressState = "PI" + CreateCheckoutBodyPersonalDetailsAddressStatePr CreateCheckoutBodyPersonalDetailsAddressState = "PR" + CreateCheckoutBodyPersonalDetailsAddressStateRj CreateCheckoutBodyPersonalDetailsAddressState = "RJ" + CreateCheckoutBodyPersonalDetailsAddressStateRn CreateCheckoutBodyPersonalDetailsAddressState = "RN" + CreateCheckoutBodyPersonalDetailsAddressStateRo CreateCheckoutBodyPersonalDetailsAddressState = "RO" + CreateCheckoutBodyPersonalDetailsAddressStateRr CreateCheckoutBodyPersonalDetailsAddressState = "RR" + CreateCheckoutBodyPersonalDetailsAddressStateRs CreateCheckoutBodyPersonalDetailsAddressState = "RS" + CreateCheckoutBodyPersonalDetailsAddressStateSc CreateCheckoutBodyPersonalDetailsAddressState = "SC" + CreateCheckoutBodyPersonalDetailsAddressStateSe CreateCheckoutBodyPersonalDetailsAddressState = "SE" + CreateCheckoutBodyPersonalDetailsAddressStateSp CreateCheckoutBodyPersonalDetailsAddressState = "SP" + CreateCheckoutBodyPersonalDetailsAddressStateTo CreateCheckoutBodyPersonalDetailsAddressState = "TO" +) + +// Currrent status of the checkout. +type CreateCheckoutBodyStatus string + +const ( + CreateCheckoutBodyStatusFailed CreateCheckoutBodyStatus = "FAILED" + CreateCheckoutBodyStatusPaid CreateCheckoutBodyStatus = "PAID" + CreateCheckoutBodyStatusPending CreateCheckoutBodyStatus = "PENDING" +) + +// Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. +type CreateCheckoutBodyCurrency string + +const ( + CreateCheckoutBodyCurrencyBgn CreateCheckoutBodyCurrency = "BGN" + CreateCheckoutBodyCurrencyBrl CreateCheckoutBodyCurrency = "BRL" + CreateCheckoutBodyCurrencyChf CreateCheckoutBodyCurrency = "CHF" + CreateCheckoutBodyCurrencyClp CreateCheckoutBodyCurrency = "CLP" + CreateCheckoutBodyCurrencyCzk CreateCheckoutBodyCurrency = "CZK" + CreateCheckoutBodyCurrencyDkk CreateCheckoutBodyCurrency = "DKK" + CreateCheckoutBodyCurrencyEur CreateCheckoutBodyCurrency = "EUR" + CreateCheckoutBodyCurrencyGbp CreateCheckoutBodyCurrency = "GBP" + CreateCheckoutBodyCurrencyHrk CreateCheckoutBodyCurrency = "HRK" + CreateCheckoutBodyCurrencyHuf CreateCheckoutBodyCurrency = "HUF" + CreateCheckoutBodyCurrencyNok CreateCheckoutBodyCurrency = "NOK" + CreateCheckoutBodyCurrencyPln CreateCheckoutBodyCurrency = "PLN" + CreateCheckoutBodyCurrencyRon CreateCheckoutBodyCurrency = "RON" + CreateCheckoutBodyCurrencySek CreateCheckoutBodyCurrency = "SEK" + CreateCheckoutBodyCurrencyUsd CreateCheckoutBodyCurrency = "USD" +) + +// ListCheckoutsParams are query parameters for ListCheckouts +type ListCheckoutsParams struct { + CheckoutReference *string `json:"checkout_reference,omitempty"` +} + +// ListCheckoutsResponse is the type definition for a ListCheckoutsResponse. +type ListCheckoutsResponse []CheckoutSuccess + +// DeactivateCheckoutResponse is Details of the deleted checkout. +type DeactivateCheckoutResponse struct { + // Amount of the payment. + Amount *float64 `json:"amount,omitempty"` + // Unique ID of the payment checkout specified by the client application when creating the checkout resource. + CheckoutReference *string `json:"checkout_reference,omitempty"` + // Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. + Currency *Currency `json:"currency,omitempty"` + // Date and time of the creation of the payment checkout. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + Date *time.Time `json:"date,omitempty"` + // Short description of the checkout visible in the SumUp dashboard. The description can contribute to reporting, allowing easier identification of a checkout. + Description *string `json:"description,omitempty"` + // Unique ID of the checkout resource. + Id *string `json:"id,omitempty"` + // Unique identifying code of the merchant profile. + MerchantCode *string `json:"merchant_code,omitempty"` + // Merchant name + MerchantName *string `json:"merchant_name,omitempty"` + // Email address of the registered user (merchant) to whom the payment is made. It is highly recommended to use `merchant_code` instead of `pay_to_email`. + PayToEmail *string `json:"pay_to_email,omitempty"` + // Purpose of the checkout creation initially + Purpose *DeactivateCheckoutResponsePurpose `json:"purpose,omitempty"` + // Current status of the checkout. + Status *DeactivateCheckoutResponseStatus `json:"status,omitempty"` + // List of transactions related to the payment. + Transactions *[]string `json:"transactions,omitempty"` + // Date and time of the checkout expiration before which the client application needs to send a processing request. If no value is present, the checkout does not have an expiration time. + ValidUntil *time.Time `json:"valid_until,omitempty"` +} + +// Purpose of the checkout creation initially +type DeactivateCheckoutResponsePurpose string + +const ( + DeactivateCheckoutResponsePurposeCheckout DeactivateCheckoutResponsePurpose = "CHECKOUT" + DeactivateCheckoutResponsePurposeSetupRecurringPayment DeactivateCheckoutResponsePurpose = "SETUP_RECURRING_PAYMENT" +) + +// Current status of the checkout. +type DeactivateCheckoutResponseStatus string + +const ( + DeactivateCheckoutResponseStatusExpired DeactivateCheckoutResponseStatus = "EXPIRED" +) + +// ProcessCheckout request body. +type ProcessCheckoutBody struct { + // __Required when payment type is `card`.__ Details of the payment card. + Card *ProcessCheckoutBodyCard `json:"card,omitempty"` + // __Required when `token` is provided.__ Unique ID of the customer. + CustomerId *string `json:"customer_id,omitempty"` + // Number of installments for deferred payments. Available only to merchant users in Brazil. + Installments *int `json:"installments,omitempty"` + // Mandate is passed when a card is to be tokenised + Mandate *ProcessCheckoutBodyMandate `json:"mandate,omitempty"` + PaymentType ProcessCheckoutBodyPaymentType `json:"payment_type"` + // __Required when using a tokenized card to process a checkout.__ Unique token identifying the saved payment card for a customer. + Token *string `json:"token,omitempty"` +} + +// ProcessCheckoutBodyCard description +type ProcessCheckoutBodyCard struct { + // Three or four-digit card verification value (security code) of the payment card. + Cvv string `json:"cvv"` + // Month from the expiration time of the payment card. Accepted format is `MM`. + ExpiryMonth ProcessCheckoutBodyCardExpiryMonth `json:"expiry_month"` + // Year from the expiration time of the payment card. Accepted formats are `YY` and `YYYY`. + ExpiryYear string `json:"expiry_year"` + // Last 4 digits of the payment card number. + Last4Digits string `json:"last_4_digits"` + // Name of the cardholder as it appears on the payment card. + Name string `json:"name"` + // Number of the payment card (without spaces). + Number string `json:"number"` + // Issuing card network of the payment card. + Type ProcessCheckoutBodyCardType `json:"type"` + // Required five-digit ZIP code. Applicable only to merchant users in the USA. + ZipCode *string `json:"zip_code,omitempty"` +} + +// Issuing card network of the payment card. +type ProcessCheckoutBodyCardType string + +const ( + ProcessCheckoutBodyCardTypeAmex ProcessCheckoutBodyCardType = "AMEX" + ProcessCheckoutBodyCardTypeCup ProcessCheckoutBodyCardType = "CUP" + ProcessCheckoutBodyCardTypeDiners ProcessCheckoutBodyCardType = "DINERS" + ProcessCheckoutBodyCardTypeDiscover ProcessCheckoutBodyCardType = "DISCOVER" + ProcessCheckoutBodyCardTypeElo ProcessCheckoutBodyCardType = "ELO" + ProcessCheckoutBodyCardTypeElv ProcessCheckoutBodyCardType = "ELV" + ProcessCheckoutBodyCardTypeHipercard ProcessCheckoutBodyCardType = "HIPERCARD" + ProcessCheckoutBodyCardTypeJcb ProcessCheckoutBodyCardType = "JCB" + ProcessCheckoutBodyCardTypeMaestro ProcessCheckoutBodyCardType = "MAESTRO" + ProcessCheckoutBodyCardTypeMastercard ProcessCheckoutBodyCardType = "MASTERCARD" + ProcessCheckoutBodyCardTypeUnknown ProcessCheckoutBodyCardType = "UNKNOWN" + ProcessCheckoutBodyCardTypeVisa ProcessCheckoutBodyCardType = "VISA" + ProcessCheckoutBodyCardTypeVisaElectron ProcessCheckoutBodyCardType = "VISA_ELECTRON" + ProcessCheckoutBodyCardTypeVisaVpay ProcessCheckoutBodyCardType = "VISA_VPAY" +) + +// Month from the expiration time of the payment card. Accepted format is `MM`. +type ProcessCheckoutBodyCardExpiryMonth string + +const ( + ProcessCheckoutBodyCardExpiryMonth01 ProcessCheckoutBodyCardExpiryMonth = "01" + ProcessCheckoutBodyCardExpiryMonth02 ProcessCheckoutBodyCardExpiryMonth = "02" + ProcessCheckoutBodyCardExpiryMonth03 ProcessCheckoutBodyCardExpiryMonth = "03" + ProcessCheckoutBodyCardExpiryMonth04 ProcessCheckoutBodyCardExpiryMonth = "04" + ProcessCheckoutBodyCardExpiryMonth05 ProcessCheckoutBodyCardExpiryMonth = "05" + ProcessCheckoutBodyCardExpiryMonth06 ProcessCheckoutBodyCardExpiryMonth = "06" + ProcessCheckoutBodyCardExpiryMonth07 ProcessCheckoutBodyCardExpiryMonth = "07" + ProcessCheckoutBodyCardExpiryMonth08 ProcessCheckoutBodyCardExpiryMonth = "08" + ProcessCheckoutBodyCardExpiryMonth09 ProcessCheckoutBodyCardExpiryMonth = "09" + ProcessCheckoutBodyCardExpiryMonth10 ProcessCheckoutBodyCardExpiryMonth = "10" + ProcessCheckoutBodyCardExpiryMonth11 ProcessCheckoutBodyCardExpiryMonth = "11" + ProcessCheckoutBodyCardExpiryMonth12 ProcessCheckoutBodyCardExpiryMonth = "12" +) + +// ProcessCheckoutBodyMandate description +type ProcessCheckoutBodyMandate struct { + // Indicates the mandate type + Type ProcessCheckoutBodyMandateType `json:"type"` + // Operating system and web client used by the end user + UserAgent string `json:"user_agent"` + // IP address of the end user. Supports IPv4 and IPv6 + UserIp *string `json:"user_ip,omitempty"` +} + +// Indicates the mandate type +type ProcessCheckoutBodyMandateType string + +const ( + ProcessCheckoutBodyMandateTypeRecurrent ProcessCheckoutBodyMandateType = "recurrent" +) + +type ProcessCheckoutBodyPaymentType string + +const ( + ProcessCheckoutBodyPaymentTypeBancontact ProcessCheckoutBodyPaymentType = "bancontact" + ProcessCheckoutBodyPaymentTypeBoleto ProcessCheckoutBodyPaymentType = "boleto" + ProcessCheckoutBodyPaymentTypeCard ProcessCheckoutBodyPaymentType = "card" + ProcessCheckoutBodyPaymentTypeIdeal ProcessCheckoutBodyPaymentType = "ideal" + ProcessCheckoutBodyPaymentTypeSofort ProcessCheckoutBodyPaymentType = "sofort" +) + +// GetPaymentMethodsParams are query parameters for GetPaymentMethods +type GetPaymentMethodsParams struct { + Amount *float64 `json:"amount,omitempty"` + Currency *string `json:"currency,omitempty"` +} + +// GetPaymentMethodsResponse is the type definition for a GetPaymentMethodsResponse. +type GetPaymentMethodsResponse struct { + AvailablePaymentMethods *[]string `json:"available_payment_methods,omitempty"` +} + +type CheckoutsService service + +// ListCheckouts: List checkouts +// Lists created checkout resources according to the applied `checkout_reference`. + +func (s *CheckoutsService) ListCheckouts(ctx context.Context, checkoutReference string, params ListCheckoutsParams) (*ListCheckoutsResponse, error) { + path := fmt.Sprintf("/v0.1/checkouts") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v ListCheckoutsResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// CreateCheckout: Create a checkout +// Creates a new payment checkout resource. The unique `checkout_reference` created by this request, is used for further manipulation of the checkout. +// +// For 3DS checkouts, add the `redirect_url` parameter to your request body schema. +// +// Follow by processing a checkout to charge the provided payment instrument. +func (s *CheckoutsService) CreateCheckout(ctx context.Context, body CreateCheckoutBody) (*Checkout, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/checkouts") + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Checkout + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// DeactivateCheckout: Deactivate a checkout +// Deactivates an identified checkout resource. If the checkout has already been processed it can not be deactivated. + +func (s *CheckoutsService) DeactivateCheckout(ctx context.Context, id string) (*DeactivateCheckoutResponse, error) { + path := fmt.Sprintf("/v0.1/checkouts/%v", id) + + req, err := s.client.NewRequest(ctx, http.MethodDelete, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v DeactivateCheckoutResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetCheckouts: Retrieve a checkout +// Retrieves an identified checkout resource. Use this request after processing a checkout to confirm its status and inform the end user respectively. + +func (s *CheckoutsService) GetCheckouts(ctx context.Context, id string) (*CheckoutSuccess, error) { + path := fmt.Sprintf("/v0.1/checkouts/%v", id) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v CheckoutSuccess + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// ProcessCheckout: Process a checkout +// Processing a checkout will attempt to charge the provided payment instrument for the amount of the specified checkout resource initiated in the `Create a checkout` endpoint. +// +// Follow this request with `Retrieve a checkout` to confirm its status. +func (s *CheckoutsService) ProcessCheckout(ctx context.Context, id string, body ProcessCheckoutBody) (*CheckoutSuccess, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/checkouts/%v", id) + + req, err := s.client.NewRequest(ctx, http.MethodPut, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v CheckoutSuccess + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetPaymentMethods: Get available payment methods +// Get payment methods available for the given merchant to use with a checkout. + +func (s *CheckoutsService) GetPaymentMethods(ctx context.Context, merchantCode string, amount float64, currency string, params GetPaymentMethodsParams) (*GetPaymentMethodsResponse, error) { + path := fmt.Sprintf("/v0.1/merchants/%v/payment-methods", merchantCode) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v GetPaymentMethodsResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} diff --git a/client.go b/client.go new file mode 100755 index 0000000..9b0af46 --- /dev/null +++ b/client.go @@ -0,0 +1,105 @@ +package sumup + +import ( + "context" + _ "embed" + "fmt" + "io" + "net/http" + "strings" +) + +//go:embed .version +var version string + +const ( + // APIUrl is the URL of our API. Currently, SumUp doesn't provide any + // other environment or APIs thus APIUrl is used as the default URL + // for the client. + APIUrl = "https://api.sumup.com" +) + +type service struct { + client *Client +} + +type Client struct { + // service is the shared service struct re-used for all services. + svc service + + // client is the HTTP client used to communicate with the API. + client *http.Client + // url is the url of the API the requests will be sent to. + url string + // userAgent is the user-agent header that will be sent with + // every request. + userAgent string + // key is the API key or access token used for authorization. + key string + + Subaccounts *SubaccountsService + Transactions *TransactionsService + ApiKeys *ApiKeysService + Payouts *PayoutsService + Checkouts *CheckoutsService + Customers *CustomersService + Merchant *MerchantService + Authorization *AuthorizationService + Receipts *ReceiptsService +} + +// NewClient creates new SumUp API client authorized using the API [key]. +func NewClient(key string) *Client { + c := &Client{ + client: http.DefaultClient, + userAgent: fmt.Sprintf("sumup.go/%s", version), + key: key, + url: APIUrl, + } + c.populate() + return c +} + +func (c *Client) populate() { + c.svc.client = c + c.Subaccounts = (*SubaccountsService)(&c.svc) + c.Transactions = (*TransactionsService)(&c.svc) + c.ApiKeys = (*ApiKeysService)(&c.svc) + c.Payouts = (*PayoutsService)(&c.svc) + c.Checkouts = (*CheckoutsService)(&c.svc) + c.Customers = (*CustomersService)(&c.svc) + c.Merchant = (*MerchantService)(&c.svc) + c.Authorization = (*AuthorizationService)(&c.svc) + c.Receipts = (*ReceiptsService)(&c.svc) + +} + +func (c *Client) NewRequest( + ctx context.Context, + method, path string, + body io.Reader, +) (*http.Request, error) { + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + req, err := http.NewRequestWithContext( + ctx, + http.MethodGet, + c.url+path, + http.NoBody, + ) + if err != nil { + return nil, fmt.Errorf("build request: %s", err.Error()) + } + + req.Header.Add("Authorization", "Bearer "+c.key) + req.Header.Add("Content-Type", "application/json") + req.Header.Add("SumUp-Version", version) + req.Header.Add("User-Agent", c.userAgent) + + return req, nil +} + +func (c *Client) Do(req *http.Request) (*http.Response, error) { + return c.client.Do(req) +} diff --git a/customers.go b/customers.go new file mode 100755 index 0000000..c35a2bc --- /dev/null +++ b/customers.go @@ -0,0 +1,519 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +// Customer is the type definition for a Customer. +type Customer struct { + // Unique ID of the customer. + CustomerId string `json:"customer_id"` + // Personal details for the customer. + PersonalDetails *CustomerPersonalDetails `json:"personal_details,omitempty"` +} + +// CustomerPersonalDetails description +type CustomerPersonalDetails struct { + // Account's personal address information. + Address *CustomerPersonalDetailsAddress `json:"address,omitempty"` + // Date of birth of the customer. + Birthdate *time.Time `json:"birthdate,omitempty"` + // Email address of the customer. + Email *string `json:"email,omitempty"` + // First name of the customer. + FirstName *string `json:"first_name,omitempty"` + // Last name of the customer. + LastName *string `json:"last_name,omitempty"` + // Phone number of the customer. + Phone *string `json:"phone,omitempty"` +} + +// CustomerPersonalDetailsAddress description +type CustomerPersonalDetailsAddress struct { + // City name from the address. + City *string `json:"city,omitempty"` + // Two letter country code formatted according to [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). + Country string `json:"country"` + // First line of the address with details of the street name and number. + Line1 *string `json:"line1,omitempty"` + // Second line of the address with details of the building, unit, apartment, and floor numbers. + Line2 *string `json:"line2,omitempty"` + // Postal code from the address. + PostalCode *string `json:"postal_code,omitempty"` + // State name or abbreviation from the address. + State *string `json:"state,omitempty"` +} + +// PaymentInstrumentResponse is Payment Instrument Response +type PaymentInstrumentResponse struct { + // Indicates whether the payment instrument is active and can be used for payments. To deactivate it, send a `DELETE` request to the resource endpoint. + Active *bool `json:"active,omitempty"` + // Details of the payment card. + Card *PaymentInstrumentResponseCard `json:"card,omitempty"` + // Creation date of payment instrument. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + CreatedAt *time.Time `json:"created_at,omitempty"` + // Created mandate + Mandate *MandateResponse `json:"mandate,omitempty"` + // Unique token identifying the saved payment card for a customer. + Token *string `json:"token,omitempty"` + // Type of the payment instrument. + Type *PaymentInstrumentResponseType `json:"type,omitempty"` +} + +// Type of the payment instrument. +type PaymentInstrumentResponseType string + +const ( + PaymentInstrumentResponseTypeCard PaymentInstrumentResponseType = "card" +) + +// PaymentInstrumentResponseCard description +type PaymentInstrumentResponseCard struct { + // Last 4 digits of the payment card number. + Last4Digits *string `json:"last_4_digits,omitempty"` + // Issuing card network of the payment card. + Type *PaymentInstrumentResponseCardType `json:"type,omitempty"` +} + +// Issuing card network of the payment card. +type PaymentInstrumentResponseCardType string + +const ( + PaymentInstrumentResponseCardTypeAmex PaymentInstrumentResponseCardType = "AMEX" + PaymentInstrumentResponseCardTypeCup PaymentInstrumentResponseCardType = "CUP" + PaymentInstrumentResponseCardTypeDiners PaymentInstrumentResponseCardType = "DINERS" + PaymentInstrumentResponseCardTypeDiscover PaymentInstrumentResponseCardType = "DISCOVER" + PaymentInstrumentResponseCardTypeElo PaymentInstrumentResponseCardType = "ELO" + PaymentInstrumentResponseCardTypeElv PaymentInstrumentResponseCardType = "ELV" + PaymentInstrumentResponseCardTypeHipercard PaymentInstrumentResponseCardType = "HIPERCARD" + PaymentInstrumentResponseCardTypeJcb PaymentInstrumentResponseCardType = "JCB" + PaymentInstrumentResponseCardTypeMaestro PaymentInstrumentResponseCardType = "MAESTRO" + PaymentInstrumentResponseCardTypeMastercard PaymentInstrumentResponseCardType = "MASTERCARD" + PaymentInstrumentResponseCardTypeUnknown PaymentInstrumentResponseCardType = "UNKNOWN" + PaymentInstrumentResponseCardTypeVisa PaymentInstrumentResponseCardType = "VISA" + PaymentInstrumentResponseCardTypeVisaElectron PaymentInstrumentResponseCardType = "VISA_ELECTRON" + PaymentInstrumentResponseCardTypeVisaVpay PaymentInstrumentResponseCardType = "VISA_VPAY" +) + +// ListPaymentInstrumentsResponse is the type definition for a ListPaymentInstrumentsResponse. +type ListPaymentInstrumentsResponse []PaymentInstrumentResponse + +// CreatePaymentInstrument request body. +type CreatePaymentInstrumentBody struct { + // Indicates whether the payment instrument is active and can be used for payments. To deactivate it, send a `DELETE` request to the resource endpoint. + Active bool `json:"active"` + // __Required when payment type is `card`.__ Details of the payment card. + Card CreatePaymentInstrumentBodyCard `json:"card"` + // Unique token identifying the saved payment card for a customer. + Token string `json:"token"` + // Type of the payment instrument. + Type CreatePaymentInstrumentBodyType `json:"type"` +} + +// CreatePaymentInstrumentBodyCard description +type CreatePaymentInstrumentBodyCard struct { + // Three or four-digit card verification value (security code) of the payment card. + Cvv string `json:"cvv"` + // Month from the expiration time of the payment card. Accepted format is `MM`. + ExpiryMonth CreatePaymentInstrumentBodyCardExpiryMonth `json:"expiry_month"` + // Year from the expiration time of the payment card. Accepted formats are `YY` and `YYYY`. + ExpiryYear string `json:"expiry_year"` + // Last 4 digits of the payment card number. + Last4Digits string `json:"last_4_digits"` + // Name of the cardholder as it appears on the payment card. + Name string `json:"name"` + // Number of the payment card (without spaces). + Number string `json:"number"` + // Issuing card network of the payment card. + Type CreatePaymentInstrumentBodyCardType `json:"type"` + // Required five-digit ZIP code. Applicable only to merchant users in the USA. + ZipCode *string `json:"zip_code,omitempty"` +} + +// Month from the expiration time of the payment card. Accepted format is `MM`. +type CreatePaymentInstrumentBodyCardExpiryMonth string + +const ( + CreatePaymentInstrumentBodyCardExpiryMonth01 CreatePaymentInstrumentBodyCardExpiryMonth = "01" + CreatePaymentInstrumentBodyCardExpiryMonth02 CreatePaymentInstrumentBodyCardExpiryMonth = "02" + CreatePaymentInstrumentBodyCardExpiryMonth03 CreatePaymentInstrumentBodyCardExpiryMonth = "03" + CreatePaymentInstrumentBodyCardExpiryMonth04 CreatePaymentInstrumentBodyCardExpiryMonth = "04" + CreatePaymentInstrumentBodyCardExpiryMonth05 CreatePaymentInstrumentBodyCardExpiryMonth = "05" + CreatePaymentInstrumentBodyCardExpiryMonth06 CreatePaymentInstrumentBodyCardExpiryMonth = "06" + CreatePaymentInstrumentBodyCardExpiryMonth07 CreatePaymentInstrumentBodyCardExpiryMonth = "07" + CreatePaymentInstrumentBodyCardExpiryMonth08 CreatePaymentInstrumentBodyCardExpiryMonth = "08" + CreatePaymentInstrumentBodyCardExpiryMonth09 CreatePaymentInstrumentBodyCardExpiryMonth = "09" + CreatePaymentInstrumentBodyCardExpiryMonth10 CreatePaymentInstrumentBodyCardExpiryMonth = "10" + CreatePaymentInstrumentBodyCardExpiryMonth11 CreatePaymentInstrumentBodyCardExpiryMonth = "11" + CreatePaymentInstrumentBodyCardExpiryMonth12 CreatePaymentInstrumentBodyCardExpiryMonth = "12" +) + +// Issuing card network of the payment card. +type CreatePaymentInstrumentBodyCardType string + +const ( + CreatePaymentInstrumentBodyCardTypeAmex CreatePaymentInstrumentBodyCardType = "AMEX" + CreatePaymentInstrumentBodyCardTypeCup CreatePaymentInstrumentBodyCardType = "CUP" + CreatePaymentInstrumentBodyCardTypeDiners CreatePaymentInstrumentBodyCardType = "DINERS" + CreatePaymentInstrumentBodyCardTypeDiscover CreatePaymentInstrumentBodyCardType = "DISCOVER" + CreatePaymentInstrumentBodyCardTypeElo CreatePaymentInstrumentBodyCardType = "ELO" + CreatePaymentInstrumentBodyCardTypeElv CreatePaymentInstrumentBodyCardType = "ELV" + CreatePaymentInstrumentBodyCardTypeHipercard CreatePaymentInstrumentBodyCardType = "HIPERCARD" + CreatePaymentInstrumentBodyCardTypeJcb CreatePaymentInstrumentBodyCardType = "JCB" + CreatePaymentInstrumentBodyCardTypeMaestro CreatePaymentInstrumentBodyCardType = "MAESTRO" + CreatePaymentInstrumentBodyCardTypeMastercard CreatePaymentInstrumentBodyCardType = "MASTERCARD" + CreatePaymentInstrumentBodyCardTypeUnknown CreatePaymentInstrumentBodyCardType = "UNKNOWN" + CreatePaymentInstrumentBodyCardTypeVisa CreatePaymentInstrumentBodyCardType = "VISA" + CreatePaymentInstrumentBodyCardTypeVisaElectron CreatePaymentInstrumentBodyCardType = "VISA_ELECTRON" + CreatePaymentInstrumentBodyCardTypeVisaVpay CreatePaymentInstrumentBodyCardType = "VISA_VPAY" +) + +// Type of the payment instrument. +type CreatePaymentInstrumentBodyType string + +const ( + CreatePaymentInstrumentBodyTypeCard CreatePaymentInstrumentBodyType = "card" +) + +// CreateCustomer request body. +type CreateCustomerBody struct { + // Unique ID of the customer. + CustomerId string `json:"customer_id"` + // Personal details for the customer. + PersonalDetails *CreateCustomerBodyPersonalDetails `json:"personal_details,omitempty"` +} + +// CreateCustomerBodyPersonalDetails description +type CreateCustomerBodyPersonalDetails struct { + // Account's personal address information. + Address *CreateCustomerBodyPersonalDetailsAddress `json:"address,omitempty"` + // Date of birth of the customer. + Birthdate *time.Time `json:"birthdate,omitempty"` + // Email address of the customer. + Email *string `json:"email,omitempty"` + // First name of the customer. + FirstName *string `json:"first_name,omitempty"` + // Last name of the customer. + LastName *string `json:"last_name,omitempty"` + // Phone number of the customer. + Phone *string `json:"phone,omitempty"` +} + +// CreateCustomerBodyPersonalDetailsAddress description +type CreateCustomerBodyPersonalDetailsAddress struct { + // City name from the address. + City *string `json:"city,omitempty"` + // Two letter country code formatted according to [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). + Country string `json:"country"` + // First line of the address with details of the street name and number. + Line1 *string `json:"line1,omitempty"` + // Second line of the address with details of the building, unit, apartment, and floor numbers. + Line2 *string `json:"line2,omitempty"` + // Postal code from the address. + PostalCode *string `json:"postal_code,omitempty"` + // State name or abbreviation from the address. + State *string `json:"state,omitempty"` +} + +// UpdateCustomer request body. +type UpdateCustomerBody struct { + // Personal details for the customer. + PersonalDetails *UpdateCustomerBodyPersonalDetails `json:"personal_details,omitempty"` +} + +// UpdateCustomerBodyPersonalDetails description +type UpdateCustomerBodyPersonalDetails struct { + // Account's personal address information. + Address *UpdateCustomerBodyPersonalDetailsAddress `json:"address,omitempty"` + // Date of birth of the customer. + Birthdate *time.Time `json:"birthdate,omitempty"` + // Email address of the customer. + Email *string `json:"email,omitempty"` + // First name of the customer. + FirstName *string `json:"first_name,omitempty"` + // Last name of the customer. + LastName *string `json:"last_name,omitempty"` + // Phone number of the customer. + Phone *string `json:"phone,omitempty"` +} + +// UpdateCustomerBodyPersonalDetailsAddress description +type UpdateCustomerBodyPersonalDetailsAddress struct { + // City name from the address. + City *string `json:"city,omitempty"` + // Two letter country code formatted according to [ISO3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). + Country string `json:"country"` + // First line of the address with details of the street name and number. + Line1 *string `json:"line1,omitempty"` + // Second line of the address with details of the building, unit, apartment, and floor numbers. + Line2 *string `json:"line2,omitempty"` + // Postal code from the address. + PostalCode *string `json:"postal_code,omitempty"` + // State name or abbreviation from the address. + State *string `json:"state,omitempty"` +} + +// DeactivatePaymentInstrumentResponse is the type definition for a DeactivatePaymentInstrumentResponse. +type DeactivatePaymentInstrumentResponse struct { +} + +type CustomersService service + +// CreateCustomer: Create a customer +// Creates a new saved customer resource which you can later manipulate and save payment instruments to. +func (s *CustomersService) CreateCustomer(ctx context.Context, body CreateCustomerBody) (*Customer, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/customers") + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Customer + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetCustomer: Retrieve a customer +// Retrieves an identified saved customer resource through the unique `customer_id` parameter, generated upon customer creation. + +func (s *CustomersService) GetCustomer(ctx context.Context, customerId string) (*Customer, error) { + path := fmt.Sprintf("/v0.1/customers/%v", customerId) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Customer + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// UpdateCustomer: Update a customer +// Updates an identified saved customer resource's personal details. +// +// The request only overwrites the parameters included in the request, all other parameters will remain with their initially assigned values. +func (s *CustomersService) UpdateCustomer(ctx context.Context, customerId string, body UpdateCustomerBody) (*Customer, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/customers/%v", customerId) + + req, err := s.client.NewRequest(ctx, http.MethodPut, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Customer + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// ListPaymentInstruments: List payment instruments +// Lists all payment instrument resources that are saved for an identified customer. + +func (s *CustomersService) ListPaymentInstruments(ctx context.Context, customerId string) (*ListPaymentInstrumentsResponse, error) { + path := fmt.Sprintf("/v0.1/customers/%v/payment-instruments", customerId) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v ListPaymentInstrumentsResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// CreatePaymentInstrument: Create a payment instrument +// Creates and activates a new payment instrument resource by saving a payment card for an identified customer. Implement to improve customer experience by skipping the step of entering payment instrument details. +// +// The token created via this endpoint **can not** be used for recurring payments by merchants operating within the EU. For more information visit our [recurring payments guide](https://developer.sumup.com/docs/recurring-payments/). +func (s *CustomersService) CreatePaymentInstrument(ctx context.Context, customerId string, body CreatePaymentInstrumentBody) (*PaymentInstrumentResponse, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/customers/%v/payment-instruments", customerId) + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v PaymentInstrumentResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// DeactivatePaymentInstrument: Deactivate a payment instrument +// Deactivates an identified card payment instrument resource for a customer. + +func (s *CustomersService) DeactivatePaymentInstrument(ctx context.Context, customerId string, token string) (*DeactivatePaymentInstrumentResponse, error) { + path := fmt.Sprintf("/v0.1/customers/%v/payment-instruments/%v", customerId, token) + + req, err := s.client.NewRequest(ctx, http.MethodDelete, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v DeactivatePaymentInstrumentResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} diff --git a/error.go b/error.go new file mode 100644 index 0000000..0965ab2 --- /dev/null +++ b/error.go @@ -0,0 +1,52 @@ +package sumup + +import "fmt" + +// APIError is custom error type for SumUp API that combinas *all* of our +// current error types into one underlying struct. +type APIError struct { + // Platform code for the error. + ErrorCode *string `json:"error_code,omitempty"` + // Short description of the error. + Message *string `json:"message,omitempty"` + // Parameter name (with relative location) to which the error applies. Parameters from embedded resources are displayed using dot notation. For example, `card.name` refers to the `name` parameter embedded in the `card` object. + Param *string `json:"param,omitempty"` + // Short description of the error. + ErrorMessage *string `json:"error_message,omitempty"` + // HTTP status code for the error. + StatusCode *string `json:"status_code,omitempty"` + // Details of the error. + Details *string `json:"details,omitempty"` + FailedConstraints *[]string `json:"failed_constraints,omitempty"` + // The status code. + Status *float64 `json:"status,omitempty"` + // Short title of the error. + Title *string `json:"title,omitempty"` +} + +// Error returns the error message. +func (e *APIError) Error() string { + var code string + if e.ErrorCode != nil { + code = *e.ErrorCode + } + if e.StatusCode != nil && code == "" { + code = *e.StatusCode + } + if e.Title != nil && code == "" { + code = *e.Title + } + + var message string + if e.Message != nil { + message = *e.Message + } + if e.ErrorMessage != nil && message == "" { + message = *e.ErrorMessage + } + if e.Details != nil && message == "" { + message = *e.Details + } + + return fmt.Sprintf("%s: %s", code, message) +} diff --git a/example/go.mod b/example/go.mod new file mode 100644 index 0000000..94b510d --- /dev/null +++ b/example/go.mod @@ -0,0 +1,11 @@ +module github.com/sumup/sumup.go/example + +go 1.21.1 + +require ( + github.com/sumup/sumup.go v0.0.0-20230919081147-7283f347e1b5 + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 +) + +// Use version at HEAD, not the latest published. +replace github.com/sumup/sumup.go => ../ diff --git a/example/go.sum b/example/go.sum new file mode 100644 index 0000000..fa6da3f --- /dev/null +++ b/example/go.sum @@ -0,0 +1,2 @@ +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= diff --git a/example/simple/main.go b/example/simple/main.go new file mode 100644 index 0000000..f5e5aef --- /dev/null +++ b/example/simple/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "context" + "os" + + "golang.org/x/exp/slog" + + "github.com/sumup/sumup.go" +) + +func main() { + client := sumup.NewClient(os.Getenv("SUMUP_KEY")) + + account, err := client.Merchant.GetAccount(context.Background(), nil, sumup.GetAccountParams{}) + if err != nil { + slog.Error("get merchant account", slog.String("error", err.Error())) + return + } + + slog.Info("merchant account", slog.String("merchant_code", *account.MerchantProfile.MerchantCode)) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e43fb1d --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/sumup/sumup.go + +go 1.21.1 diff --git a/merchant.go b/merchant.go new file mode 100755 index 0000000..5e195f2 --- /dev/null +++ b/merchant.go @@ -0,0 +1,586 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "context" + "encoding/json" + "fmt" + "net/http" +) + +// Account is Account information. +type Account struct { + // The role of the user. + Type *AccountType `json:"type,omitempty"` + // Type of the account. + Username *string `json:"username,omitempty"` +} + +// The role of the user. +type AccountType string + +const ( + AccountTypeNormal AccountType = "normal" + AccountTypeOperator AccountType = "operator" +) + +// AddressWithDetails is Details of the registered address. +type AddressWithDetails struct { + // Address line 1 + AddressLine1 *string `json:"address_line1,omitempty"` + // Address line 2 + AddressLine2 *string `json:"address_line2,omitempty"` + // City + City *string `json:"city,omitempty"` + // undefined + Company *string `json:"company,omitempty"` + // Country ISO 3166-1 code + Country *string `json:"country,omitempty"` + // Country Details + CountryDetails *CountryDetails `json:"country_details,omitempty"` + // undefined + FirstName *string `json:"first_name,omitempty"` + // Landline number + Landline *string `json:"landline,omitempty"` + // undefined + LastName *string `json:"last_name,omitempty"` + // Postal code + PostCode *string `json:"post_code,omitempty"` + // Region code + RegionCode *string `json:"region_code,omitempty"` + // Country region id + RegionId *float64 `json:"region_id,omitempty"` + // Region name + RegionName *string `json:"region_name,omitempty"` + // undefined + StateId *string `json:"state_id,omitempty"` + // TimeOffset Details + TimeoffsetDetails *TimeoffsetDetails `json:"timeoffset_details,omitempty"` +} + +// AppSettings is Mobile app settings +type AppSettings struct { + // Advanced mode. + AdvancedMode *string `json:"advanced_mode,omitempty"` + // Barcode scanner. + BarcodeScanner *string `json:"barcode_scanner,omitempty"` + // Cash payment. + CashPayment *string `json:"cash_payment,omitempty"` + // Checkout preference + CheckoutPreference *string `json:"checkout_preference,omitempty"` + // Expected max transaction amount. + ExpectedMaxTransactionAmount *float64 `json:"expected_max_transaction_amount,omitempty"` + // Include vat. + IncludeVat *bool `json:"include_vat,omitempty"` + // Manual entry. + ManualEntry *string `json:"manual_entry,omitempty"` + // Manual entry tutorial. + ManualEntryTutorial *bool `json:"manual_entry_tutorial,omitempty"` + // Mobile payment. + MobilePayment *string `json:"mobile_payment,omitempty"` + // Mobile payment tutorial. + MobilePaymentTutorial *bool `json:"mobile_payment_tutorial,omitempty"` + // Reader payment. + ReaderPayment *string `json:"reader_payment,omitempty"` + // Referral. + Referral *string `json:"referral,omitempty"` + // Tax enabled. + TaxEnabled *bool `json:"tax_enabled,omitempty"` + // Terminal mode tutorial. + TerminalModeTutorial *bool `json:"terminal_mode_tutorial,omitempty"` + // Tip rates. + TipRates *[]string `json:"tip_rates,omitempty"` + // Tipping. + Tipping *string `json:"tipping,omitempty"` +} + +// BankAccount is the type definition for a BankAccount. +type BankAccount struct { + // Account category - business or personal + AccountCategory *string `json:"account_category,omitempty"` + AccountHolderName *string `json:"account_holder_name,omitempty"` + // Account number + AccountNumber *string `json:"account_number,omitempty"` + // Type of the account + AccountType *string `json:"account_type,omitempty"` + // Bank code + BankCode *string `json:"bank_code,omitempty"` + // Bank name + BankName *string `json:"bank_name,omitempty"` + // Branch code + BranchCode *string `json:"branch_code,omitempty"` + // Creation date of the bank account + CreatedAt *string `json:"created_at,omitempty"` + // IBAN + Iban *string `json:"iban,omitempty"` + // The primary bank account is the one used for settlements + Primary *bool `json:"primary,omitempty"` + // Status in the verification process + Status *string `json:"status,omitempty"` + // SWIFT code + Swift *string `json:"swift,omitempty"` +} + +// BusinessOwnersItem is Account's business address information +type BusinessOwnersItem struct { + // Date of birth + DateOfBirth *string `json:"date_of_birth,omitempty"` + // BO's first name + FirstName *string `json:"first_name,omitempty"` + // BO's Landline + Landline *string `json:"landline,omitempty"` + // BO's last name of the user + LastName *string `json:"last_name,omitempty"` + // Mobile phone number + MobilePhone *string `json:"mobile_phone,omitempty"` + // Ownership percentage + Ownership *float64 `json:"ownership,omitempty"` +} + +// BusinessOwners is Account's business address information +type BusinessOwners []BusinessOwnersItem + +// CountryDetails is Country Details +type CountryDetails struct { + // Currency ISO 4217 code + Currency *string `json:"currency,omitempty"` + // Country EN name + EnName *string `json:"en_name,omitempty"` + // Country ISO code + IsoCode *string `json:"iso_code,omitempty"` + // Country native name + NativeName *string `json:"native_name,omitempty"` +} + +// DoingBusinessAs is Doing Business As information +type DoingBusinessAs struct { + Address *interface{} `json:"address,omitempty"` + // Doing business as name + BusinessName *string `json:"business_name,omitempty"` + // Doing business as company registration number + CompanyRegistrationNumber *string `json:"company_registration_number,omitempty"` + // Doing business as email + Email *string `json:"email,omitempty"` + // Doing business as vat id + VatId *string `json:"vat_id,omitempty"` + // Doing business as website + Website *string `json:"website,omitempty"` +} + +// LegalType is Id of the legal type of the merchant profile +type LegalType struct { + // Legal type short description + Description *string `json:"description,omitempty"` + // Legal type description + FullDescription *string `json:"full_description,omitempty"` + // Unique id + Id *float64 `json:"id,omitempty"` + // Sole trader legal type if true + SoleTrader *bool `json:"sole_trader,omitempty"` +} + +// MerchantAccount is Details of user account. +type MerchantAccount struct { + // Account information. + Account *Account `json:"account,omitempty"` + // Mobile app settings + AppSettings *AppSettings `json:"app_settings,omitempty"` + // Merchant comes from payleven BR migration + IsMigratedPaylevenBr *bool `json:"is_migrated_payleven_br,omitempty"` + // Account's merchant profile + MerchantProfile *MerchantProfile `json:"merchant_profile,omitempty"` + Operators *Operators `json:"operators,omitempty"` + // User permissions + Permissions *Permissions `json:"permissions,omitempty"` + // Account's personal profile. + PersonalProfile *PersonalProfile `json:"personal_profile,omitempty"` +} + +// MerchantProfile is Account's merchant profile +type MerchantProfile struct { + // Details of the registered address. + Address *AddressWithDetails `json:"address,omitempty"` + BankAccounts *[]BankAccount `json:"bank_accounts,omitempty"` + // Account's business address information + BusinessOwners *BusinessOwners `json:"business_owners,omitempty"` + // Company name + CompanyName *string `json:"company_name,omitempty"` + // Company registration number + CompanyRegistrationNumber *string `json:"company_registration_number,omitempty"` + // Merchant country isocode (for internal usage only) + Country *string `json:"country,omitempty"` + // Doing Business As information + DoingBusinessAs *DoingBusinessAs `json:"doing_business_as,omitempty"` + // True if the merchant is extdev + Extdev *bool `json:"extdev,omitempty"` + // Id of the legal type of the merchant profile + LegalType *LegalType `json:"legal_type,omitempty"` + // Merchant locale (for internal usage only) + Locale *string `json:"locale,omitempty"` + // Merchant category code + MerchantCategoryCode *string `json:"merchant_category_code,omitempty"` + // Unique identifying code of the merchant profile + MerchantCode *string `json:"merchant_code,omitempty"` + // Mobile phone number + MobilePhone *string `json:"mobile_phone,omitempty"` + // Nature and purpose of the business + NatureAndPurpose *string `json:"nature_and_purpose,omitempty"` + // True if the payout zone of this merchant is migrated + PayoutZoneMigrated *bool `json:"payout_zone_migrated,omitempty"` + // Permanent certificate access code (Portugal) + PermanentCertificateAccessCode *string `json:"permanent_certificate_access_code,omitempty"` + // Merchant settings (like \"payout_type\", \"payout_period\") + Settings *MerchantSettings `json:"settings,omitempty"` + // Vat ID + VatId *string `json:"vat_id,omitempty"` + // Merchant VAT rates + VatRates *VatRates `json:"vat_rates,omitempty"` + // Website + Website *string `json:"website,omitempty"` +} + +// MerchantSettings is Merchant settings (like \"payout_type\", \"payout_period\") +type MerchantSettings struct { + // Adyen company + AdyenCompany *string `json:"adyen_company,omitempty"` + // Adyen merchant code + AdyenMerchantCode *string `json:"adyen_merchant_code,omitempty"` + // Adyen password + AdyenPassword *string `json:"adyen_password,omitempty"` + // Adyen username + AdyenUser *string `json:"adyen_user,omitempty"` + // Whether merchant will receive daily payout emails + DailyPayoutEmail *bool `json:"daily_payout_email,omitempty"` + // Whether merchant has gross settlement enabled + GrossSettlement *bool `json:"gross_settlement,omitempty"` + // Whether merchant will receive monthly payout emails + MonthlyPayoutEmail *bool `json:"monthly_payout_email,omitempty"` + // Whether merchant can make MOTO payments + MotoPayment *MerchantSettingsMotoPayment `json:"moto_payment,omitempty"` + // Payout Instrument + PayoutInstrument *string `json:"payout_instrument,omitempty"` + // Whether merchant will receive payouts on demand + PayoutOnDemand *bool `json:"payout_on_demand,omitempty"` + // Whether merchant can edit payouts on demand + PayoutOnDemandAvailable *bool `json:"payout_on_demand_available,omitempty"` + // Payout frequency + PayoutPeriod *string `json:"payout_period,omitempty"` + // Payout type + PayoutType *string `json:"payout_type,omitempty"` + // Whether to show printers in mobile app + PrintersEnabled *bool `json:"printers_enabled,omitempty"` + // Stone merchant code + StoneMerchantCode *string `json:"stone_merchant_code,omitempty"` + // Whether to show tax in receipts (saved per transaction) + TaxEnabled *bool `json:"tax_enabled,omitempty"` +} + +// Whether merchant can make MOTO payments +type MerchantSettingsMotoPayment string + +const ( + MerchantSettingsMotoPaymentEnforced MerchantSettingsMotoPayment = "ENFORCED" + MerchantSettingsMotoPaymentOff MerchantSettingsMotoPayment = "OFF" + MerchantSettingsMotoPaymentOn MerchantSettingsMotoPayment = "ON" + MerchantSettingsMotoPaymentUnavailable MerchantSettingsMotoPayment = "UNAVAILABLE" +) + +// OperatorsItem is the type definition for a OperatorsItem. +type OperatorsItem struct { + // Username of the operator + Username *string `json:"username,omitempty"` +} + +// Operators is the type definition for a Operators. +type Operators []OperatorsItem + +// PersonalProfile is Account's personal profile. +type PersonalProfile struct { + // Details of the registered address. + Address *AddressWithDetails `json:"address,omitempty"` + Complete *bool `json:"complete,omitempty"` + // Date of birth + DateOfBirth *string `json:"date_of_birth,omitempty"` + // First name of the user + FirstName *string `json:"first_name,omitempty"` + // Last name of the user + LastName *string `json:"last_name,omitempty"` + // Mobile phone number + MobilePhone *string `json:"mobile_phone,omitempty"` +} + +// TimeoffsetDetails is TimeOffset Details +type TimeoffsetDetails struct { + // Daylight Saving Time + Dst *bool `json:"dst,omitempty"` + // UTC offset + Offset *float64 `json:"offset,omitempty"` + // Postal code + PostCode *string `json:"post_code,omitempty"` +} + +// VatRates is Merchant VAT rates +type VatRates struct { + // Country ISO code + Country *string `json:"country,omitempty"` + // Description + Description *string `json:"description,omitempty"` + // Internal ID + Id *float64 `json:"id,omitempty"` + // Ordering + Ordering *float64 `json:"ordering,omitempty"` + // Rate + Rate *float64 `json:"rate,omitempty"` +} + +// ListBankAccountsParams are query parameters for ListBankAccounts +type ListBankAccountsParams struct { + Primary *bool `json:"primary,omitempty"` +} + +// ListBankAccountsResponse is the type definition for a ListBankAccountsResponse. +type ListBankAccountsResponse []BankAccount + +// GetAccountParams are query parameters for GetAccount +type GetAccountParams struct { + Include *[]string `json:"include[],omitempty"` +} + +type MerchantService service + +// GetAccount: Retrieve an account +// Returns user account information. + +func (s *MerchantService) GetAccount(ctx context.Context, include []string, params GetAccountParams) (*MerchantAccount, error) { + path := fmt.Sprintf("/v0.1/me") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v MerchantAccount + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetMerchantProfile: Retrieve a merchant profile +// Retrieves merchant profile data. + +func (s *MerchantService) GetMerchantProfile(ctx context.Context) (*MerchantProfile, error) { + path := fmt.Sprintf("/v0.1/me/merchant-profile") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v MerchantProfile + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// ListBankAccounts: List bank accounts +// Retrives bank accounts of the merchant. + +func (s *MerchantService) ListBankAccounts(ctx context.Context, primary bool, params ListBankAccountsParams) (*ListBankAccountsResponse, error) { + path := fmt.Sprintf("/v0.1/me/merchant-profile/bank-accounts") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v ListBankAccountsResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetDoingBusinessAs: Retrieve DBA +// Retrieves Doing Business As profile. + +func (s *MerchantService) GetDoingBusinessAs(ctx context.Context) (*DoingBusinessAs, error) { + path := fmt.Sprintf("/v0.1/me/merchant-profile/doing-business-as") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v DoingBusinessAs + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetSettings: List settings +// Retrieves merchant settings. + +func (s *MerchantService) GetSettings(ctx context.Context) (*MerchantSettings, error) { + path := fmt.Sprintf("/v0.1/me/merchant-profile/settings") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v MerchantSettings + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetPersonalProfile: Retrieve a personal profile +// Retrieves personal profile data. + +func (s *MerchantService) GetPersonalProfile(ctx context.Context) (*PersonalProfile, error) { + path := fmt.Sprintf("/v0.1/me/personal-profile") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v PersonalProfile + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} diff --git a/models.go b/models.go new file mode 100755 index 0000000..37d913c --- /dev/null +++ b/models.go @@ -0,0 +1,177 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "time" +) + +// AmountEvent is Amount of the event. +type AmountEvent float64 + +// Error is Error message structure. +type Error struct { + // Platform code for the error. + ErrorCode *string `json:"error_code,omitempty"` + // Short description of the error. + Message *string `json:"message,omitempty"` +} + +// ErrorExtended is the type definition for a ErrorExtended. +type ErrorExtended struct { + // Platform code for the error. + ErrorCode *string `json:"error_code,omitempty"` + // Short description of the error. + Message *string `json:"message,omitempty"` + // Parameter name (with relative location) to which the error applies. Parameters from embedded resources are displayed using dot notation. For example, `card.name` refers to the `name` parameter embedded in the `card` object. + Param *string `json:"param,omitempty"` +} + +// ErrorForbidden is Error message for forbidden requests. +type ErrorForbidden struct { + // Platform code for the error. + ErrorCode *string `json:"error_code,omitempty"` + // Short description of the error. + ErrorMessage *string `json:"error_message,omitempty"` + // HTTP status code for the error. + StatusCode *string `json:"status_code,omitempty"` +} + +// EventId is Unique ID of the transaction event. +type EventId int64 + +// Status of the transaction event. +type EventStatus string + +const ( + EventStatusFailed EventStatus = "FAILED" + EventStatusPaidOut EventStatus = "PAID_OUT" + EventStatusPending EventStatus = "PENDING" + EventStatusRefunded EventStatus = "REFUNDED" + EventStatusScheduled EventStatus = "SCHEDULED" + EventStatusSuccessful EventStatus = "SUCCESSFUL" +) + +// Type of the transaction event. +type EventType string + +const ( + EventTypeChargeBack EventType = "CHARGE_BACK" + EventTypePayout EventType = "PAYOUT" + EventTypePayoutDeduction EventType = "PAYOUT_DEDUCTION" + EventTypeRefund EventType = "REFUND" +) + +// MandateResponse is Created mandate +type MandateResponse struct { + // Merchant code which has the mandate + MerchantCode *string `json:"merchant_code,omitempty"` + // Mandate status + Status *string `json:"status,omitempty"` + // Indicates the mandate type + Type *string `json:"type,omitempty"` +} + +// Permissions is User permissions +type Permissions struct { + // Create MOTO payments + CreateMotoPayments *bool `json:"create_moto_payments,omitempty"` + // Create referral + CreateReferral *bool `json:"create_referral,omitempty"` + // Can view full merchant transaction history + FullTransactionHistoryView *bool `json:"full_transaction_history_view,omitempty"` + // Refund transactions + RefundTransactions *bool `json:"refund_transactions,omitempty"` +} + +// TimestampEvent is Date and time of the transaction event. +type TimestampEvent string + +// TransactionId is Unique ID of the transaction. +type TransactionId string + +// TransactionMixinBase is Details of the transaction. +type TransactionMixinBase struct { + // Total amount of the transaction. + Amount *float64 `json:"amount,omitempty"` + // Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. + Currency *TransactionMixinBaseCurrency `json:"currency,omitempty"` + // Unique ID of the transaction. + Id *string `json:"id,omitempty"` + // Current number of the installment for deferred payments. + InstallmentsCount *int `json:"installments_count,omitempty"` + // Payment type used for the transaction. + PaymentType *TransactionMixinBasePaymentType `json:"payment_type,omitempty"` + // Current status of the transaction. + Status *TransactionMixinBaseStatus `json:"status,omitempty"` + // Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + Timestamp *time.Time `json:"timestamp,omitempty"` + // Transaction code returned by the acquirer/processing entity after processing the transaction. + TransactionCode *string `json:"transaction_code,omitempty"` +} + +// Payment type used for the transaction. +type TransactionMixinBasePaymentType string + +const ( + TransactionMixinBasePaymentTypeBoleto TransactionMixinBasePaymentType = "BOLETO" + TransactionMixinBasePaymentTypeEcom TransactionMixinBasePaymentType = "ECOM" + TransactionMixinBasePaymentTypeRecurring TransactionMixinBasePaymentType = "RECURRING" +) + +// Current status of the transaction. +type TransactionMixinBaseStatus string + +const ( + TransactionMixinBaseStatusCancelled TransactionMixinBaseStatus = "CANCELLED" + TransactionMixinBaseStatusFailed TransactionMixinBaseStatus = "FAILED" + TransactionMixinBaseStatusPending TransactionMixinBaseStatus = "PENDING" + TransactionMixinBaseStatusSuccessful TransactionMixinBaseStatus = "SUCCESSFUL" +) + +// Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. +type TransactionMixinBaseCurrency string + +const ( + TransactionMixinBaseCurrencyBgn TransactionMixinBaseCurrency = "BGN" + TransactionMixinBaseCurrencyBrl TransactionMixinBaseCurrency = "BRL" + TransactionMixinBaseCurrencyChf TransactionMixinBaseCurrency = "CHF" + TransactionMixinBaseCurrencyClp TransactionMixinBaseCurrency = "CLP" + TransactionMixinBaseCurrencyCzk TransactionMixinBaseCurrency = "CZK" + TransactionMixinBaseCurrencyDkk TransactionMixinBaseCurrency = "DKK" + TransactionMixinBaseCurrencyEur TransactionMixinBaseCurrency = "EUR" + TransactionMixinBaseCurrencyGbp TransactionMixinBaseCurrency = "GBP" + TransactionMixinBaseCurrencyHrk TransactionMixinBaseCurrency = "HRK" + TransactionMixinBaseCurrencyHuf TransactionMixinBaseCurrency = "HUF" + TransactionMixinBaseCurrencyNok TransactionMixinBaseCurrency = "NOK" + TransactionMixinBaseCurrencyPln TransactionMixinBaseCurrency = "PLN" + TransactionMixinBaseCurrencyRon TransactionMixinBaseCurrency = "RON" + TransactionMixinBaseCurrencySek TransactionMixinBaseCurrency = "SEK" + TransactionMixinBaseCurrencyUsd TransactionMixinBaseCurrency = "USD" +) + +// TransactionMixinCheckout is the type definition for a TransactionMixinCheckout. +type TransactionMixinCheckout struct { + // Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments. + AuthCode *string `json:"auth_code,omitempty"` + // Entry mode of the payment details. + EntryMode *TransactionMixinCheckoutEntryMode `json:"entry_mode,omitempty"` + // Internal unique ID of the transaction on the SumUp platform. + InternalId *int `json:"internal_id,omitempty"` + // Unique code of the registered merchant to whom the payment is made. + MerchantCode *string `json:"merchant_code,omitempty"` + // Amount of the tip (out of the total transaction amount). + TipAmount *float64 `json:"tip_amount,omitempty"` + // Amount of the applicable VAT (out of the total transaction amount). + VatAmount *float64 `json:"vat_amount,omitempty"` +} + +// Entry mode of the payment details. +type TransactionMixinCheckoutEntryMode string + +const ( + TransactionMixinCheckoutEntryModeBoleto TransactionMixinCheckoutEntryMode = "BOLETO" + TransactionMixinCheckoutEntryModeCustomerEntry TransactionMixinCheckoutEntryMode = "CUSTOMER_ENTRY" +) diff --git a/payouts.go b/payouts.go new file mode 100755 index 0000000..4839523 --- /dev/null +++ b/payouts.go @@ -0,0 +1,96 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +// FinancialPayoutsItem is the type definition for a FinancialPayoutsItem. +type FinancialPayoutsItem struct { + Amount *float64 `json:"amount,omitempty"` + Currency *string `json:"currency,omitempty"` + Date *time.Time `json:"date,omitempty"` + Fee *float64 `json:"fee,omitempty"` + Id *int `json:"id,omitempty"` + Reference *string `json:"reference,omitempty"` + Status *FinancialPayoutsItemStatus `json:"status,omitempty"` + TransactionCode *string `json:"transaction_code,omitempty"` + Type *FinancialPayoutsItemType `json:"type,omitempty"` +} + +type FinancialPayoutsItemStatus string + +const ( + FinancialPayoutsItemStatusFailed FinancialPayoutsItemStatus = "FAILED" + FinancialPayoutsItemStatusSuccessful FinancialPayoutsItemStatus = "SUCCESSFUL" +) + +type FinancialPayoutsItemType string + +const ( + FinancialPayoutsItemTypeBalanceDeduction FinancialPayoutsItemType = "BALANCE_DEDUCTION" + FinancialPayoutsItemTypeChargeBackDeduction FinancialPayoutsItemType = "CHARGE_BACK_DEDUCTION" + FinancialPayoutsItemTypeDdReturnDeduction FinancialPayoutsItemType = "DD_RETURN_DEDUCTION" + FinancialPayoutsItemTypePayout FinancialPayoutsItemType = "PAYOUT" + FinancialPayoutsItemTypeRefundDeduction FinancialPayoutsItemType = "REFUND_DEDUCTION" +) + +// FinancialPayouts is the type definition for a FinancialPayouts. +type FinancialPayouts []FinancialPayoutsItem + +// ListPayoutsParams are query parameters for ListPayouts +type ListPayoutsParams struct { + EndDate time.Time `json:"end_date"` + Format *string `json:"format,omitempty"` + Limit *int `json:"limit,omitempty"` + Order *string `json:"order,omitempty"` + StartDate time.Time `json:"start_date"` +} + +type PayoutsService service + +// ListPayouts: List payouts +// Lists ordered payouts for the merchant account. + +func (s *PayoutsService) ListPayouts(ctx context.Context, startDate time.Time, endDate time.Time, format string, limit int, order string, params ListPayoutsParams) (*FinancialPayouts, error) { + path := fmt.Sprintf("/v0.1/me/financials/payouts") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v FinancialPayouts + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} diff --git a/receipts.go b/receipts.go new file mode 100755 index 0000000..c19a93c --- /dev/null +++ b/receipts.go @@ -0,0 +1,163 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +// Receipt is the type definition for a Receipt. +type Receipt struct { + AcquirerData *ReceiptAcquirerData `json:"acquirer_data,omitempty"` + EmvData *interface{} `json:"emv_data,omitempty"` + // Receipt merchant data + MerchantData *ReceiptMerchantData `json:"merchant_data,omitempty"` + // Transaction information. + TransactionData *ReceiptTransaction `json:"transaction_data,omitempty"` +} + +// ReceiptAcquirerData description +type ReceiptAcquirerData struct { + AuthorizationCode *string `json:"authorization_code,omitempty"` + LocalTime *string `json:"local_time,omitempty"` + ReturnCode *string `json:"return_code,omitempty"` + Tid *string `json:"tid,omitempty"` +} + +// ReceiptCard is the type definition for a ReceiptCard. +type ReceiptCard struct { + // Card last 4 digits. + Last4Digits *string `json:"last_4_digits,omitempty"` + // Card Scheme. + Type *string `json:"type,omitempty"` +} + +// ReceiptEvent is the type definition for a ReceiptEvent. +type ReceiptEvent struct { + // Amount of the event. + Amount *AmountEvent `json:"amount,omitempty"` + // Unique ID of the transaction event. + Id *EventId `json:"id,omitempty"` + ReceiptNo *string `json:"receipt_no,omitempty"` + // Status of the transaction event. + Status *EventStatus `json:"status,omitempty"` + // Date and time of the transaction event. + Timestamp *TimestampEvent `json:"timestamp,omitempty"` + // Unique ID of the transaction. + TransactionId *TransactionId `json:"transaction_id,omitempty"` + // Type of the transaction event. + Type *EventType `json:"type,omitempty"` +} + +// ReceiptMerchantData is Receipt merchant data +type ReceiptMerchantData struct { + Locale *string `json:"locale,omitempty"` + MerchantProfile *ReceiptMerchantDataMerchantProfile `json:"merchant_profile,omitempty"` +} + +// ReceiptMerchantDataMerchantProfile description +type ReceiptMerchantDataMerchantProfile struct { + Address *ReceiptMerchantDataMerchantProfileAddress `json:"address,omitempty"` + BusinessName *string `json:"business_name,omitempty"` + Email *string `json:"email,omitempty"` + MerchantCode *string `json:"merchant_code,omitempty"` +} + +// ReceiptMerchantDataMerchantProfileAddress description +type ReceiptMerchantDataMerchantProfileAddress struct { + AddressLine1 *string `json:"address_line1,omitempty"` + City *string `json:"city,omitempty"` + Country *string `json:"country,omitempty"` + CountryEnName *string `json:"country_en_name,omitempty"` + CountryNativeName *string `json:"country_native_name,omitempty"` + Landline *string `json:"landline,omitempty"` + PostCode *string `json:"post_code,omitempty"` +} + +// ReceiptTransaction is Transaction information. +type ReceiptTransaction struct { + // Transaction amount. + Amount *string `json:"amount,omitempty"` + Card *ReceiptCard `json:"card,omitempty"` + // Transaction currency. + Currency *string `json:"currency,omitempty"` + // Transaction entry mode. + EntryMode *string `json:"entry_mode,omitempty"` + // Events + Events *[]ReceiptEvent `json:"events,omitempty"` + // Number of installments. + InstallmentsCount *int `json:"installments_count,omitempty"` + // Transaction type. + PaymentType *string `json:"payment_type,omitempty"` + // Products + Products *[]string `json:"products,omitempty"` + // Receipt number + ReceiptNo *string `json:"receipt_no,omitempty"` + // Transaction processing status. + Status *string `json:"status,omitempty"` + // Time created at. + Timestamp *time.Time `json:"timestamp,omitempty"` + // Tip amount (included in transaction amount). + TipAmount *string `json:"tip_amount,omitempty"` + // Transaction code. + TransactionCode *string `json:"transaction_code,omitempty"` + // Transaction VAT amount. + VatAmount *string `json:"vat_amount,omitempty"` + // Vat rates. + VatRates *[]string `json:"vat_rates,omitempty"` + // Cardholder verification method. + VerificationMethod *string `json:"verification_method,omitempty"` +} + +// GetReceiptParams are query parameters for GetReceipt +type GetReceiptParams struct { + Mid string `json:"mid"` + TxEventId *int `json:"tx_event_id,omitempty"` +} + +type ReceiptsService service + +// GetReceipt: Retrieve receipt details +// Retrieves receipt specific data for a transaction. + +func (s *ReceiptsService) GetReceipt(ctx context.Context, id string, mid string, txEventId int, params GetReceiptParams) (*Receipt, error) { + path := fmt.Sprintf("/v1.1/receipts/%v", id) + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Receipt + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} diff --git a/subaccounts.go b/subaccounts.go new file mode 100755 index 0000000..7ce9a45 --- /dev/null +++ b/subaccounts.go @@ -0,0 +1,207 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" +) + +// Subaccount is the type definition for a Subaccount. +type Subaccount struct { + // Creation date of the operator + CreatedAt *string `json:"created_at,omitempty"` + Disabled *bool `json:"disabled,omitempty"` + // Id of the operator + Id *float64 `json:"id,omitempty"` + // User permissions + Permissions *Permissions `json:"permissions,omitempty"` + // Username of the operator + Username *string `json:"username,omitempty"` +} + +// ListSubAccountsResponse is the type definition for a ListSubAccountsResponse. +type ListSubAccountsResponse []Subaccount + +// CreateSubAccount request body. +type CreateSubAccountBody struct { + // Password + Password *string `json:"password,omitempty"` + // Username of the new account. Must be a valid email address + Username *string `json:"username,omitempty"` +} + +// UpdateSubAccount request body. +type UpdateSubAccountBody struct { + // Password + Password *string `json:"password,omitempty"` + // Username of the new account. Must be a valid email address + Username *string `json:"username,omitempty"` +} + +type SubaccountsService service + +// ListSubAccounts: List subaccounts + +func (s *SubaccountsService) ListSubAccounts(ctx context.Context) (*ListSubAccountsResponse, error) { + path := fmt.Sprintf("/v0.1/me/accounts") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v ListSubAccountsResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// CreateSubAccount: Create a subaccount +func (s *SubaccountsService) CreateSubAccount(ctx context.Context, body CreateSubAccountBody) (*Subaccount, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/me/accounts") + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Subaccount + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// DeactivateSubAccount: Deactivate a subaccount + +func (s *SubaccountsService) DeactivateSubAccount(ctx context.Context, operatorCode string) (*Subaccount, error) { + path := fmt.Sprintf("/v0.1/me/accounts/%v", operatorCode) + + req, err := s.client.NewRequest(ctx, http.MethodDelete, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Subaccount + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// UpdateSubAccount: Update a subaccount +func (s *SubaccountsService) UpdateSubAccount(ctx context.Context, operatorCode string, body UpdateSubAccountBody) (*Subaccount, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/me/accounts/%v", operatorCode) + + req, err := s.client.NewRequest(ctx, http.MethodPut, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v Subaccount + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} diff --git a/transactions.go b/transactions.go new file mode 100755 index 0000000..727d3c8 --- /dev/null +++ b/transactions.go @@ -0,0 +1,736 @@ +// Code generated by `gocodegen`. DO NOT EDIT. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. +package sumup + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +// CardResponse is Details of the payment card. +type CardResponse struct { + // Three-digit card verification value (security code) of the payment card. + Cvv *string `json:"cvv,omitempty"` + // Month from the expiration time of the payment card. Accepted format is `MM`. + ExpiryMonth *CardResponseExpiryMonth `json:"expiry_month,omitempty"` + // Year from the expiration time of the payment card. Accepted formats are `YY` and `YYYY`. + ExpiryYear *string `json:"expiry_year,omitempty"` + // Last 4 digits of the payment card number. + Last4Digits *string `json:"last_4_digits,omitempty"` + // Name of the cardholder as it appears on the payment card. + Name *string `json:"name,omitempty"` + // Number of the payment card (without spaces). + Number *string `json:"number,omitempty"` + // Issuing card network of the payment card. + Type *CardResponseType `json:"type,omitempty"` + // Required five-digit ZIP code. Applicable only to merchant users in the USA. + ZipCode *string `json:"zip_code,omitempty"` +} + +// Issuing card network of the payment card. +type CardResponseType string + +const ( + CardResponseTypeAmex CardResponseType = "AMEX" + CardResponseTypeCup CardResponseType = "CUP" + CardResponseTypeDiners CardResponseType = "DINERS" + CardResponseTypeDiscover CardResponseType = "DISCOVER" + CardResponseTypeElo CardResponseType = "ELO" + CardResponseTypeElv CardResponseType = "ELV" + CardResponseTypeHipercard CardResponseType = "HIPERCARD" + CardResponseTypeJcb CardResponseType = "JCB" + CardResponseTypeMaestro CardResponseType = "MAESTRO" + CardResponseTypeMastercard CardResponseType = "MASTERCARD" + CardResponseTypeUnknown CardResponseType = "UNKNOWN" + CardResponseTypeVisa CardResponseType = "VISA" + CardResponseTypeVisaElectron CardResponseType = "VISA_ELECTRON" + CardResponseTypeVisaVpay CardResponseType = "VISA_VPAY" +) + +// Month from the expiration time of the payment card. Accepted format is `MM`. +type CardResponseExpiryMonth string + +const ( + CardResponseExpiryMonth01 CardResponseExpiryMonth = "01" + CardResponseExpiryMonth02 CardResponseExpiryMonth = "02" + CardResponseExpiryMonth03 CardResponseExpiryMonth = "03" + CardResponseExpiryMonth04 CardResponseExpiryMonth = "04" + CardResponseExpiryMonth05 CardResponseExpiryMonth = "05" + CardResponseExpiryMonth06 CardResponseExpiryMonth = "06" + CardResponseExpiryMonth07 CardResponseExpiryMonth = "07" + CardResponseExpiryMonth08 CardResponseExpiryMonth = "08" + CardResponseExpiryMonth09 CardResponseExpiryMonth = "09" + CardResponseExpiryMonth10 CardResponseExpiryMonth = "10" + CardResponseExpiryMonth11 CardResponseExpiryMonth = "11" + CardResponseExpiryMonth12 CardResponseExpiryMonth = "12" +) + +// Event is the type definition for a Event. +type Event struct { + // Amount of the event. + Amount *AmountEvent `json:"amount,omitempty"` + // Amount deducted for the event. + DeductedAmount *float64 `json:"deducted_amount,omitempty"` + // Amount of the fee deducted for the event. + DeductedFeeAmount *float64 `json:"deducted_fee_amount,omitempty"` + // Amount of the fee related to the event. + FeeAmount *float64 `json:"fee_amount,omitempty"` + // Unique ID of the transaction event. + Id *EventId `json:"id,omitempty"` + // Consecutive number of the installment. + InstallmentNumber *int `json:"installment_number,omitempty"` + // Status of the transaction event. + Status *EventStatus `json:"status,omitempty"` + // Date and time of the transaction event. + Timestamp *TimestampEvent `json:"timestamp,omitempty"` + // Unique ID of the transaction. + TransactionId *TransactionId `json:"transaction_id,omitempty"` + // Type of the transaction event. + Type *EventType `json:"type,omitempty"` +} + +// FinancialTransactionsItem is the type definition for a FinancialTransactionsItem. +type FinancialTransactionsItem struct { + Amount *float64 `json:"amount,omitempty"` + Currency *string `json:"currency,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + Id *string `json:"id,omitempty"` + Timestamp *string `json:"timestamp,omitempty"` + TransactionCode *string `json:"transaction_code,omitempty"` + Type *FinancialTransactionsItemType `json:"type,omitempty"` +} + +type FinancialTransactionsItemType string + +const ( + FinancialTransactionsItemTypeChargeBack FinancialTransactionsItemType = "CHARGE_BACK" + FinancialTransactionsItemTypeDdReturn FinancialTransactionsItemType = "DD_RETURN" + FinancialTransactionsItemTypeDdReturnReversal FinancialTransactionsItemType = "DD_RETURN_REVERSAL" + FinancialTransactionsItemTypeRefund FinancialTransactionsItemType = "REFUND" + FinancialTransactionsItemTypeSale FinancialTransactionsItemType = "SALE" +) + +// FinancialTransactions is the type definition for a FinancialTransactions. +type FinancialTransactions []FinancialTransactionsItem + +// HorizontalAccuracy is Indication of the precision of the geographical position received from the payment terminal. +type HorizontalAccuracy float64 + +// Lat is Latitude value from the coordinates of the payment location (as received from the payment terminal reader). +type Lat float64 + +// Link is Details of a link to a related resource. +type Link struct { + // URL for accessing the related resource. + Href *string `json:"href,omitempty"` + // Specifies the relation to the current resource. + Rel *string `json:"rel,omitempty"` + // Specifies the media type of the related resource. + Type *string `json:"type,omitempty"` +} + +// LinkRefund is the type definition for a LinkRefund. +type LinkRefund struct { + // URL for accessing the related resource. + Href *string `json:"href,omitempty"` + // Maximum allowed amount for the refund. + MaxAmount *float64 `json:"max_amount,omitempty"` + // Minimum allowed amount for the refund. + MinAmount *float64 `json:"min_amount,omitempty"` + // Specifies the relation to the current resource. + Rel *string `json:"rel,omitempty"` + // Specifies the media type of the related resource. + Type *string `json:"type,omitempty"` +} + +// Lon is Longitude value from the coordinates of the payment location (as received from the payment terminal reader). +type Lon float64 + +// Product is Details of the product for which the payment is made. +type Product struct { + // Name of the product from the merchant's catalog. + Name *string `json:"name,omitempty"` + // Price of the product without VAT. + Price *float64 `json:"price,omitempty"` + // Price of a single product item with VAT. + PriceWithVat *float64 `json:"price_with_vat,omitempty"` + // Number of product items for the purchase. + Quantity *float64 `json:"quantity,omitempty"` + // Amount of the VAT for a single product item (calculated as the product of `price` and `vat_rate`, i.e. `single_vat_amount = price * vat_rate`). + SingleVatAmount *float64 `json:"single_vat_amount,omitempty"` + // Total price of the product items without VAT (calculated as the product of `price` and `quantity`, i.e. `total_price = price * quantity`). + TotalPrice *float64 `json:"total_price,omitempty"` + // Total price of the product items including VAT (calculated as the product of `price_with_vat` and `quantity`, i.e. `total_with_vat = price_with_vat * quantity`). + TotalWithVat *float64 `json:"total_with_vat,omitempty"` + // Total VAT amount for the purchase (calculated as the product of `single_vat_amount` and `quantity`, i.e. `vat_amount = single_vat_amount * quantity`). + VatAmount *float64 `json:"vat_amount,omitempty"` + // VAT rate applicable to the product. + VatRate *float64 `json:"vat_rate,omitempty"` +} + +// TransactionEvent is Details of a transaction event. +type TransactionEvent struct { + // Amount of the event. + Amount *AmountEvent `json:"amount,omitempty"` + // Date when the transaction event occurred. + Date *time.Time `json:"date,omitempty"` + // Date when the transaction event is due to occur. + DueDate *time.Time `json:"due_date,omitempty"` + // Type of the transaction event. + EventType *EventType `json:"event_type,omitempty"` + // Unique ID of the transaction event. + Id *EventId `json:"id,omitempty"` + // Consequtive number of the installment that is paid. Applicable only payout events, i.e. `event_type = PAYOUT`. + InstallmentNumber *int `json:"installment_number,omitempty"` + // Status of the transaction event. + Status *EventStatus `json:"status,omitempty"` + // Date and time of the transaction event. + Timestamp *TimestampEvent `json:"timestamp,omitempty"` +} + +// Payment type used for the transaction. +type TransactionFullPaymentType string + +const ( + TransactionFullPaymentTypeBoleto TransactionFullPaymentType = "BOLETO" + TransactionFullPaymentTypeEcom TransactionFullPaymentType = "ECOM" + TransactionFullPaymentTypeRecurring TransactionFullPaymentType = "RECURRING" +) + +// Current status of the transaction. +type TransactionFullStatus string + +const ( + TransactionFullStatusCancelled TransactionFullStatus = "CANCELLED" + TransactionFullStatusFailed TransactionFullStatus = "FAILED" + TransactionFullStatusPending TransactionFullStatus = "PENDING" + TransactionFullStatusSuccessful TransactionFullStatus = "SUCCESSFUL" +) + +// Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. +type TransactionFullCurrency string + +const ( + TransactionFullCurrencyBgn TransactionFullCurrency = "BGN" + TransactionFullCurrencyBrl TransactionFullCurrency = "BRL" + TransactionFullCurrencyChf TransactionFullCurrency = "CHF" + TransactionFullCurrencyClp TransactionFullCurrency = "CLP" + TransactionFullCurrencyCzk TransactionFullCurrency = "CZK" + TransactionFullCurrencyDkk TransactionFullCurrency = "DKK" + TransactionFullCurrencyEur TransactionFullCurrency = "EUR" + TransactionFullCurrencyGbp TransactionFullCurrency = "GBP" + TransactionFullCurrencyHrk TransactionFullCurrency = "HRK" + TransactionFullCurrencyHuf TransactionFullCurrency = "HUF" + TransactionFullCurrencyNok TransactionFullCurrency = "NOK" + TransactionFullCurrencyPln TransactionFullCurrency = "PLN" + TransactionFullCurrencyRon TransactionFullCurrency = "RON" + TransactionFullCurrencySek TransactionFullCurrency = "SEK" + TransactionFullCurrencyUsd TransactionFullCurrency = "USD" +) + +// Entry mode of the payment details. +type TransactionFullEntryMode string + +const ( + TransactionFullEntryModeBoleto TransactionFullEntryMode = "BOLETO" + TransactionFullEntryModeCustomerEntry TransactionFullEntryMode = "CUSTOMER_ENTRY" +) + +// Payout plan of the registered user at the time when the transaction was made. +type TransactionFullPayoutPlan string + +const ( + TransactionFullPayoutPlanAcceleratedInstallment TransactionFullPayoutPlan = "ACCELERATED_INSTALLMENT" + TransactionFullPayoutPlanSinglePayment TransactionFullPayoutPlan = "SINGLE_PAYMENT" + TransactionFullPayoutPlanTrueInstallment TransactionFullPayoutPlan = "TRUE_INSTALLMENT" +) + +// Verification method used for the transaction. +type TransactionFullVerificationMethod string + +const ( + TransactionFullVerificationMethodConfirmationCodeVerified TransactionFullVerificationMethod = "confirmation code verified" + TransactionFullVerificationMethodNone TransactionFullVerificationMethod = "none" + TransactionFullVerificationMethodOfflinePin TransactionFullVerificationMethod = "offline pin" + TransactionFullVerificationMethodOfflinePinSignature TransactionFullVerificationMethod = "offline pin + signature" + TransactionFullVerificationMethodOnlinePin TransactionFullVerificationMethod = "online pin" + TransactionFullVerificationMethodSignature TransactionFullVerificationMethod = "signature" +) + +// Simple name of the payment type. +type TransactionFullSimplePaymentType string + +const ( + TransactionFullSimplePaymentTypeCash TransactionFullSimplePaymentType = "CASH" + TransactionFullSimplePaymentTypeCcCustomerEntered TransactionFullSimplePaymentType = "CC_CUSTOMER_ENTERED" + TransactionFullSimplePaymentTypeCcSignature TransactionFullSimplePaymentType = "CC_SIGNATURE" + TransactionFullSimplePaymentTypeElv TransactionFullSimplePaymentType = "ELV" + TransactionFullSimplePaymentTypeEmv TransactionFullSimplePaymentType = "EMV" + TransactionFullSimplePaymentTypeManualEntry TransactionFullSimplePaymentType = "MANUAL_ENTRY" + TransactionFullSimplePaymentTypeMoto TransactionFullSimplePaymentType = "MOTO" +) + +// TransactionFullLocation description +type TransactionFullLocation struct { + // Indication of the precision of the geographical position received from the payment terminal. + HorizontalAccuracy *HorizontalAccuracy `json:"horizontal_accuracy,omitempty"` + // Latitude value from the coordinates of the payment location (as received from the payment terminal reader). + Lat *Lat `json:"lat,omitempty"` + // Longitude value from the coordinates of the payment location (as received from the payment terminal reader). + Lon *Lon `json:"lon,omitempty"` +} + +// Payout type for the transaction. +type TransactionFullPayoutType string + +const ( + TransactionFullPayoutTypeBalance TransactionFullPayoutType = "BALANCE" + TransactionFullPayoutTypeBankAccount TransactionFullPayoutType = "BANK_ACCOUNT" + TransactionFullPayoutTypePrepaidCard TransactionFullPayoutType = "PREPAID_CARD" +) + +// Status generated from the processing status and the latest transaction state. +type TransactionFullSimpleStatus string + +const ( + TransactionFullSimpleStatusCancelled TransactionFullSimpleStatus = "CANCELLED" + TransactionFullSimpleStatusCancelFailed TransactionFullSimpleStatus = "CANCEL_FAILED" + TransactionFullSimpleStatusChargeback TransactionFullSimpleStatus = "CHARGEBACK" + TransactionFullSimpleStatusFailed TransactionFullSimpleStatus = "FAILED" + TransactionFullSimpleStatusNonCollection TransactionFullSimpleStatus = "NON_COLLECTION" + TransactionFullSimpleStatusPaidOut TransactionFullSimpleStatus = "PAID_OUT" + TransactionFullSimpleStatusRefunded TransactionFullSimpleStatus = "REFUNDED" + TransactionFullSimpleStatusRefundFailed TransactionFullSimpleStatus = "REFUND_FAILED" + TransactionFullSimpleStatusSuccessful TransactionFullSimpleStatus = "SUCCESSFUL" +) + +// TransactionFull is the type definition for a TransactionFull. +type TransactionFull struct { + // Total amount of the transaction. + Amount *float64 `json:"amount,omitempty"` + // Authorization code for the transaction sent by the payment card issuer or bank. Applicable only to card payments. + AuthCode *string `json:"auth_code,omitempty"` + // Details of the payment card. + Card *CardResponse `json:"card,omitempty"` + // Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. + Currency *TransactionFullCurrency `json:"currency,omitempty"` + // Entry mode of the payment details. + EntryMode *TransactionFullEntryMode `json:"entry_mode,omitempty"` + // List of events related to the transaction. + Events *[]Event `json:"events,omitempty"` + // Indication of the precision of the geographical position received from the payment terminal. + HorizontalAccuracy *HorizontalAccuracy `json:"horizontal_accuracy,omitempty"` + // Unique ID of the transaction. + Id *string `json:"id,omitempty"` + // Current number of the installment for deferred payments. + InstallmentsCount *int `json:"installments_count,omitempty"` + // Internal unique ID of the transaction on the SumUp platform. + InternalId *int `json:"internal_id,omitempty"` + // Latitude value from the coordinates of the payment location (as received from the payment terminal reader). + Lat *Lat `json:"lat,omitempty"` + // List of hyperlinks for accessing related resources. + Links *[]string `json:"links,omitempty"` + // Local date and time of the creation of the transaction. + LocalTime *time.Time `json:"local_time,omitempty"` + // Details of the payment location as received from the payment terminal. + Location *TransactionFullLocation `json:"location,omitempty"` + // Longitude value from the coordinates of the payment location (as received from the payment terminal reader). + Lon *Lon `json:"lon,omitempty"` + // Unique code of the registered merchant to whom the payment is made. + MerchantCode *string `json:"merchant_code,omitempty"` + // Payment type used for the transaction. + PaymentType *TransactionFullPaymentType `json:"payment_type,omitempty"` + // Payout plan of the registered user at the time when the transaction was made. + PayoutPlan *TransactionFullPayoutPlan `json:"payout_plan,omitempty"` + // Payout type for the transaction. + PayoutType *TransactionFullPayoutType `json:"payout_type,omitempty"` + // Number of payouts that are made to the registered user specified in the `user` property. + PayoutsReceived *int `json:"payouts_received,omitempty"` + // Total number of payouts to the registered user specified in the `user` property. + PayoutsTotal *int `json:"payouts_total,omitempty"` + // Short description of the payment. The value is taken from the `description` property of the related checkout resource. + ProductSummary *string `json:"product_summary,omitempty"` + // List of products from the merchant's catalog for which the transaction serves as a payment. + Products *[]Product `json:"products,omitempty"` + // Simple name of the payment type. + SimplePaymentType *TransactionFullSimplePaymentType `json:"simple_payment_type,omitempty"` + // Status generated from the processing status and the latest transaction state. + SimpleStatus *TransactionFullSimpleStatus `json:"simple_status,omitempty"` + // Current status of the transaction. + Status *TransactionFullStatus `json:"status,omitempty"` + // Indicates whether tax deduction is enabled for the transaction. + TaxEnabled *bool `json:"tax_enabled,omitempty"` + // Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + Timestamp *time.Time `json:"timestamp,omitempty"` + // Amount of the tip (out of the total transaction amount). + TipAmount *float64 `json:"tip_amount,omitempty"` + // Transaction code returned by the acquirer/processing entity after processing the transaction. + TransactionCode *string `json:"transaction_code,omitempty"` + // List of transaction events related to the transaction. + TransactionEvents *[]TransactionEvent `json:"transaction_events,omitempty"` + // Email address of the registered user (merchant) to whom the payment is made. + Username *string `json:"username,omitempty"` + // Amount of the applicable VAT (out of the total transaction amount). + VatAmount *float64 `json:"vat_amount,omitempty"` + // List of VAT rates applicable to the transaction. + VatRates *[]string `json:"vat_rates,omitempty"` + // Verification method used for the transaction. + VerificationMethod *TransactionFullVerificationMethod `json:"verification_method,omitempty"` +} + +// Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. +type TransactionHistoryCurrency string + +const ( + TransactionHistoryCurrencyBgn TransactionHistoryCurrency = "BGN" + TransactionHistoryCurrencyBrl TransactionHistoryCurrency = "BRL" + TransactionHistoryCurrencyChf TransactionHistoryCurrency = "CHF" + TransactionHistoryCurrencyClp TransactionHistoryCurrency = "CLP" + TransactionHistoryCurrencyCzk TransactionHistoryCurrency = "CZK" + TransactionHistoryCurrencyDkk TransactionHistoryCurrency = "DKK" + TransactionHistoryCurrencyEur TransactionHistoryCurrency = "EUR" + TransactionHistoryCurrencyGbp TransactionHistoryCurrency = "GBP" + TransactionHistoryCurrencyHrk TransactionHistoryCurrency = "HRK" + TransactionHistoryCurrencyHuf TransactionHistoryCurrency = "HUF" + TransactionHistoryCurrencyNok TransactionHistoryCurrency = "NOK" + TransactionHistoryCurrencyPln TransactionHistoryCurrency = "PLN" + TransactionHistoryCurrencyRon TransactionHistoryCurrency = "RON" + TransactionHistoryCurrencySek TransactionHistoryCurrency = "SEK" + TransactionHistoryCurrencyUsd TransactionHistoryCurrency = "USD" +) + +// Payment type used for the transaction. +type TransactionHistoryPaymentType string + +const ( + TransactionHistoryPaymentTypeBoleto TransactionHistoryPaymentType = "BOLETO" + TransactionHistoryPaymentTypeEcom TransactionHistoryPaymentType = "ECOM" + TransactionHistoryPaymentTypeRecurring TransactionHistoryPaymentType = "RECURRING" +) + +// Current status of the transaction. +type TransactionHistoryStatus string + +const ( + TransactionHistoryStatusCancelled TransactionHistoryStatus = "CANCELLED" + TransactionHistoryStatusFailed TransactionHistoryStatus = "FAILED" + TransactionHistoryStatusPending TransactionHistoryStatus = "PENDING" + TransactionHistoryStatusSuccessful TransactionHistoryStatus = "SUCCESSFUL" +) + +// Payout plan of the registered user at the time when the transaction was made. +type TransactionHistoryPayoutPlan string + +const ( + TransactionHistoryPayoutPlanAcceleratedInstallment TransactionHistoryPayoutPlan = "ACCELERATED_INSTALLMENT" + TransactionHistoryPayoutPlanSinglePayment TransactionHistoryPayoutPlan = "SINGLE_PAYMENT" + TransactionHistoryPayoutPlanTrueInstallment TransactionHistoryPayoutPlan = "TRUE_INSTALLMENT" +) + +// Issuing card network of the payment card used for the transaction. +type TransactionHistoryCardType string + +const ( + TransactionHistoryCardTypeAmex TransactionHistoryCardType = "AMEX" + TransactionHistoryCardTypeCup TransactionHistoryCardType = "CUP" + TransactionHistoryCardTypeDiners TransactionHistoryCardType = "DINERS" + TransactionHistoryCardTypeDiscover TransactionHistoryCardType = "DISCOVER" + TransactionHistoryCardTypeElo TransactionHistoryCardType = "ELO" + TransactionHistoryCardTypeElv TransactionHistoryCardType = "ELV" + TransactionHistoryCardTypeHipercard TransactionHistoryCardType = "HIPERCARD" + TransactionHistoryCardTypeJcb TransactionHistoryCardType = "JCB" + TransactionHistoryCardTypeMaestro TransactionHistoryCardType = "MAESTRO" + TransactionHistoryCardTypeMastercard TransactionHistoryCardType = "MASTERCARD" + TransactionHistoryCardTypeUnknown TransactionHistoryCardType = "UNKNOWN" + TransactionHistoryCardTypeVisa TransactionHistoryCardType = "VISA" + TransactionHistoryCardTypeVisaElectron TransactionHistoryCardType = "VISA_ELECTRON" + TransactionHistoryCardTypeVisaVpay TransactionHistoryCardType = "VISA_VPAY" +) + +// Type of the transaction for the registered user specified in the `user` property. +type TransactionHistoryType string + +const ( + TransactionHistoryTypeChargeBack TransactionHistoryType = "CHARGE_BACK" + TransactionHistoryTypePayment TransactionHistoryType = "PAYMENT" + TransactionHistoryTypeRefund TransactionHistoryType = "REFUND" +) + +// TransactionHistory is the type definition for a TransactionHistory. +type TransactionHistory struct { + // Total amount of the transaction. + Amount *float64 `json:"amount,omitempty"` + // Issuing card network of the payment card used for the transaction. + CardType *TransactionHistoryCardType `json:"card_type,omitempty"` + // Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above. + Currency *TransactionHistoryCurrency `json:"currency,omitempty"` + // Unique ID of the transaction. + Id *string `json:"id,omitempty"` + // Current number of the installment for deferred payments. + InstallmentsCount *int `json:"installments_count,omitempty"` + // Payment type used for the transaction. + PaymentType *TransactionHistoryPaymentType `json:"payment_type,omitempty"` + // Payout plan of the registered user at the time when the transaction was made. + PayoutPlan *TransactionHistoryPayoutPlan `json:"payout_plan,omitempty"` + // Number of payouts that are made to the registered user specified in the `user` property. + PayoutsReceived *int `json:"payouts_received,omitempty"` + // Total number of payouts to the registered user specified in the `user` property. + PayoutsTotal *int `json:"payouts_total,omitempty"` + // Short description of the payment. The value is taken from the `description` property of the related checkout resource. + ProductSummary *string `json:"product_summary,omitempty"` + // Current status of the transaction. + Status *TransactionHistoryStatus `json:"status,omitempty"` + // Date and time of the creation of the transaction. Response format expressed according to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) code. + Timestamp *time.Time `json:"timestamp,omitempty"` + // Transaction code returned by the acquirer/processing entity after processing the transaction. + TransactionCode *string `json:"transaction_code,omitempty"` + // Unique ID of the transaction. + TransactionId *TransactionId `json:"transaction_id,omitempty"` + // Type of the transaction for the registered user specified in the `user` property. + Type *TransactionHistoryType `json:"type,omitempty"` + // Email address of the registered user (merchant) to whom the payment is made. + User *string `json:"user,omitempty"` +} + +// TransactionMixinHistory is the type definition for a TransactionMixinHistory. +type TransactionMixinHistory struct { + // Payout plan of the registered user at the time when the transaction was made. + PayoutPlan *TransactionMixinHistoryPayoutPlan `json:"payout_plan,omitempty"` + // Number of payouts that are made to the registered user specified in the `user` property. + PayoutsReceived *int `json:"payouts_received,omitempty"` + // Total number of payouts to the registered user specified in the `user` property. + PayoutsTotal *int `json:"payouts_total,omitempty"` + // Short description of the payment. The value is taken from the `description` property of the related checkout resource. + ProductSummary *string `json:"product_summary,omitempty"` +} + +// Payout plan of the registered user at the time when the transaction was made. +type TransactionMixinHistoryPayoutPlan string + +const ( + TransactionMixinHistoryPayoutPlanAcceleratedInstallment TransactionMixinHistoryPayoutPlan = "ACCELERATED_INSTALLMENT" + TransactionMixinHistoryPayoutPlanSinglePayment TransactionMixinHistoryPayoutPlan = "SINGLE_PAYMENT" + TransactionMixinHistoryPayoutPlanTrueInstallment TransactionMixinHistoryPayoutPlan = "TRUE_INSTALLMENT" +) + +// ListTransactionsParams are query parameters for ListTransactions +type ListTransactionsParams struct { + ChangesSince *time.Time `json:"changes_since,omitempty"` + Limit *int `json:"limit,omitempty"` + NewestRef *string `json:"newest_ref,omitempty"` + NewestTime *time.Time `json:"newest_time,omitempty"` + OldestRef *string `json:"oldest_ref,omitempty"` + OldestTime *time.Time `json:"oldest_time,omitempty"` + Order *string `json:"order,omitempty"` + PaymentTypes *[]string `json:"payment_types,omitempty"` + Statuses *[]string `json:"statuses,omitempty"` + TransactionCode *string `json:"transaction_code,omitempty"` + Types *[]string `json:"types,omitempty"` + Users *[]string `json:"users,omitempty"` +} + +// ListTransactionsResponse is the type definition for a ListTransactionsResponse. +type ListTransactionsResponse struct { + Items *[]TransactionHistory `json:"items,omitempty"` + Links *[]Link `json:"links,omitempty"` +} + +// GetTransactionParams are query parameters for GetTransaction +type GetTransactionParams struct { + Id *string `json:"id,omitempty"` + InternalId *string `json:"internal_id,omitempty"` + TransactionCode *string `json:"transaction_code,omitempty"` +} + +// RefundTransaction request body. +type RefundTransactionBody struct { + // Amount to be refunded. Eligible amount can't exceed the amount of the transaction and varies based on country and currency. If you do not specify a value, the system performs a full refund of the transaction. + Amount *float64 `json:"amount,omitempty"` +} + +// RefundTransactionResponse is the type definition for a RefundTransactionResponse. +type RefundTransactionResponse struct { +} + +// ListFinancialTransactionsParams are query parameters for ListFinancialTransactions +type ListFinancialTransactionsParams struct { + EndDate time.Time `json:"end_date"` + Format *string `json:"format,omitempty"` + Limit *int `json:"limit,omitempty"` + Order *string `json:"order,omitempty"` + StartDate time.Time `json:"start_date"` +} + +type TransactionsService service + +// ListFinancialTransactions: List financial transactions +// Lists a less detailed history of all transactions associated with the merchant account. + +func (s *TransactionsService) ListFinancialTransactions(ctx context.Context, startDate time.Time, endDate time.Time, format string, limit int, order string, params ListFinancialTransactionsParams) (*FinancialTransactions, error) { + path := fmt.Sprintf("/v0.1/me/financials/transactions") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v FinancialTransactions + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// Refund: Refund a transaction +// Refunds an identified transaction either in full or partially. +func (s *TransactionsService) Refund(ctx context.Context, txnId string, body RefundTransactionBody) (*RefundTransactionResponse, error) { + buf := new(bytes.Buffer) + if err := json.NewEncoder(buf).Encode(body); err != nil { + return nil, fmt.Errorf("encoding json body request failed: %v", err) + } + + path := fmt.Sprintf("/v0.1/me/refund/%v", txnId) + + req, err := s.client.NewRequest(ctx, http.MethodPost, path, buf) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v RefundTransactionResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// GetTransaction: Retrieve a transaction +// Retrieves the full details of an identified transaction. The transaction resource is identified by a query parameter and *one* of following parameters is required: +// * `id` +// * `internal_id` +// * `transaction_code` +// * `foreign_transaction_id` +// * `client_transaction_id` +// + +func (s *TransactionsService) GetTransaction(ctx context.Context, id string, internalId string, transactionCode string, params GetTransactionParams) (*TransactionFull, error) { + path := fmt.Sprintf("/v0.1/me/transactions") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v TransactionFull + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +} + +// ListTransactions: List transactions +// Lists detailed history of all transactions associated with the merchant account. + +func (s *TransactionsService) ListTransactions(ctx context.Context, transactionCode string, order string, limit int, users []string, statuses []string, paymentTypes []string, types []string, changesSince time.Time, newestTime time.Time, newestRef string, oldestTime time.Time, oldestRef string, params ListTransactionsParams) (*ListTransactionsResponse, error) { + path := fmt.Sprintf("/v0.1/me/transactions/history") + + req, err := s.client.NewRequest(ctx, http.MethodGet, path, http.NoBody) + if err != nil { + return nil, fmt.Errorf("error building request: %v", err) + } + + resp, err := s.client.Do(req) + if err != nil { + return nil, fmt.Errorf("error sending request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("invalid response: %d - %s", resp.StatusCode, http.StatusText(resp.StatusCode)) + } + + dec := json.NewDecoder(resp.Body) + if resp.StatusCode >= 400 { + var apiErr APIError + if err := dec.Decode(&apiErr); err != nil { + return nil, fmt.Errorf("read error response: %s", err.Error()) + } + + return nil, &apiErr + } + + var v ListTransactionsResponse + if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { + return nil, fmt.Errorf("decode response: %s", err.Error()) + } + + return &v, nil +}