Repository: VictorAvelar/mollie-api-go
Pull request #330 (2024-03-03 19:27:00)

check captures resource against api reference.
<!--- Provide a general summary of your changes in the Title above -->

# Description

Ensures that the `captures` resource delivers API parity.

## Motivation and context

Ensures the library has full API parity.

## How has this been tested?

Please describe in detail how you tested your changes.

Include details of your testing environment, and the tests you ran to
see how your change affects other areas of the code, etc.

- [x] Unit tests added / updated
- [x] The tests run on docker (using `make test`)
- [x] The required `test data` has been added / updated

If you are running the tests locally, please specify:

- OS: macos
- Go version 1.22

## Types of changes

What types of changes does your code introduce? Put an `x` in all the boxes that apply:

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] This change requires a documentation update

## Checklist

Go over all the following points, and put an `x` in all the boxes that apply.

Please, please, please, don't send your pull request until all of the boxes are ticked. Once your pull request is created, it will trigger a build on our continuous integration server to make sure your [tests and code style pass](https://help.github.com/articles/about-required-status-checks/).

- [x] I have read the **[CONTRIBUTING](CONTRIBUTING.md)** document.
- [x] My pull request addresses exactly one patch/feature.
- [x] I have created a branch for this patch/feature.
- [x] Each individual commit in the pull request is meaningful.
- [x] If my change requires a change to the documentation, I have updated it accordingly.

<!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->



Patch:
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index f642588..a0a3d88 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -35,11 +35,15 @@ jobs:
     permissions:
       contents: read
       pull-requests: read
+      checks: write
     steps:
       - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+        with:
+          fetch-depth: '0'
       - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
         with:
           go-version: 1.22.X
       - uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804
         with:
           version: latest
+          install-mode: binary
diff --git a/docs/README.md b/docs/README.md
index 729dab6..81da279 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -54,11 +54,15 @@ REST also implies a nice and clean structure for URLs or endpoints. This means y
   - [func \(be \*BaseError\) Error\(\) string](<#BaseError.Error>)
 - [type BusinessCategory](<#BusinessCategory>)
 - [type Capture](<#Capture>)
+- [type CaptureAccessTokenFields](<#CaptureAccessTokenFields>)
 - [type CaptureLinks](<#CaptureLinks>)
 - [type CaptureMode](<#CaptureMode>)
+- [type CaptureOptions](<#CaptureOptions>)
+- [type CaptureStatus](<#CaptureStatus>)
 - [type CapturesList](<#CapturesList>)
 - [type CapturesService](<#CapturesService>)
-  - [func \(cs \*CapturesService\) Get\(ctx context.Context, payment, capture string\) \(res \*Response, c \*Capture, err error\)](<#CapturesService.Get>)
+  - [func \(cs \*CapturesService\) Create\(ctx context.Context, payment string, capture CreateCapture\) \(res \*Response, c \*Capture, err error\)](<#CapturesService.Create>)
+  - [func \(cs \*CapturesService\) Get\(ctx context.Context, payment, capture string, options \*CaptureOptions\) \(res \*Response, c \*Capture, err error\)](<#CapturesService.Get>)
   - [func \(cs \*CapturesService\) List\(ctx context.Context, payment string\) \(res \*Response, cl \*CapturesList, err error\)](<#CapturesService.List>)
 - [type CardLabel](<#CardLabel>)
 - [type CategoryCode](<#CategoryCode>)
@@ -99,6 +103,7 @@ REST also implies a nice and clean structure for URLs or endpoints. This means y
 - [type ContextValue](<#ContextValue>)
 - [type ContextValues](<#ContextValues>)
   - [func \(cv \*ContextValues\) UnmarshalJSON\(data \[\]byte\) error](<#ContextValues.UnmarshalJSON>)
+- [type CreateCapture](<#CreateCapture>)
 - [type CreateMollieConnectPaymentFields](<#CreateMollieConnectPaymentFields>)
 - [type CreatePayment](<#CreatePayment>)
 - [type CreatePaymentAccessTokenFields](<#CreatePaymentAccessTokenFields>)
@@ -987,27 +992,41 @@ const (
 ```
 
 <a name="Capture"></a>
-## type [Capture](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L33-L44>)
+## type [Capture](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L44-L58>)
 
 Capture describes a single capture. Captures are used for payments that have the authorize\-then\-capture flow.
 
 ```go
 type Capture struct {
-    Resource         string       `json:"resource,omitempty"`
-    ID               string       `json:"id,omitempty"`
-    Mode             Mode         `json:"mode,omitempty"`
-    Amount           *Amount      `json:"amount,omitempty"`
-    SettlementAmount *Amount      `json:"settlementAmount,omitempty"`
-    PaymentID        string       `json:"paymentId,omitempty"`
-    ShipmentID       string       `json:"shipmentId,omitempty"`
-    SettlementID     string       `json:"settlementId,omitempty"`
-    CreatedAt        *time.Time   `json:"createdAt,omitempty"`
-    Links            CaptureLinks `json:"_links,omitempty"`
+    Resource         string        `json:"resource,omitempty"`
+    ID               string        `json:"id,omitempty"`
+    Mode             Mode          `json:"mode,omitempty"`
+    Amount           *Amount       `json:"amount,omitempty"`
+    Status           CaptureStatus `json:"status,omitempty"`
+    SettlementAmount *Amount       `json:"settlementAmount,omitempty"`
+    PaymentID        string        `json:"paymentId,omitempty"`
+    ShipmentID       string        `json:"shipmentId,omitempty"`
+    SettlementID     string        `json:"settlementId,omitempty"`
+    CreatedAt        *time.Time    `json:"createdAt,omitempty"`
+    Metadata         any           `json:"metadata,omitempty"`
+    Links            CaptureLinks  `json:"_links,omitempty"`
+    AccessTokenPaymentFields
+}
+```
+
+<a name="CaptureAccessTokenFields"></a>
+## type [CaptureAccessTokenFields](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L38-L40>)
+
+CaptureAccessTokenFields describes the payload for creating a capture with an access token.
+
+```go
+type CaptureAccessTokenFields struct {
+    Testmode bool `json:"testmode,omitempty"`
 }
 ```
 
 <a name="CaptureLinks"></a>
-## type [CaptureLinks](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L23-L29>)
+## type [CaptureLinks](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L61-L67>)
 
 CaptureLinks contains relevant links for a capture object.
 
@@ -1039,8 +1058,40 @@ const (
 )
 ```
 
+<a name="CaptureOptions"></a>
+## type [CaptureOptions](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L72-L74>)
+
+CaptureOptions describes the query params available to use when retrieving captures.
+
+See: https://docs.mollie.com/reference/v2/captures-api/get-capture#embedding-of-related-resources
+
+```go
+type CaptureOptions struct {
+    Embed []EmbedValue `url:"embed,omitempty"`
+}
+```
+
+<a name="CaptureStatus"></a>
+## type [CaptureStatus](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L20>)
+
+CaptureStatus describes the status of a capture.
+
+```go
+type CaptureStatus string
+```
+
+<a name="CaptureStatusPending"></a>CaptureStatus possible values.
+
+```go
+const (
+    CaptureStatusPending   CaptureStatus = "pending"
+    CaptureStatusSucceeded CaptureStatus = "succeeded"
+    CaptureStatusFailed    CaptureStatus = "failed"
+)
+```
+
 <a name="CapturesList"></a>
-## type [CapturesList](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L47-L53>)
+## type [CapturesList](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L77-L83>)
 
 CapturesList describes a list of captures.
 
@@ -1055,7 +1106,7 @@ type CapturesList struct {
 ```
 
 <a name="CapturesService"></a>
-## type [CapturesService](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L20>)
+## type [CapturesService](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L86>)
 
 CapturesService operates over captures resource.
 
@@ -1063,11 +1114,22 @@ CapturesService operates over captures resource.
 type CapturesService service
 ```
 
+<a name="CapturesService.Create"></a>
+### func \(\*CapturesService\) [Create](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L114-L118>)
+
+```go
+func (cs *CapturesService) Create(ctx context.Context, payment string, capture CreateCapture) (res *Response, c *Capture, err error)
+```
+
+Create creates a new capture for a payment.
+
+See: https://docs.mollie.com/reference/v2/captures-api/create-capture
+
 <a name="CapturesService.Get"></a>
-### func \(\*CapturesService\) [Get](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L59>)
+### func \(\*CapturesService\) [Get](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L92-L96>)
 
 ```go
-func (cs *CapturesService) Get(ctx context.Context, payment, capture string) (res *Response, c *Capture, err error)
+func (cs *CapturesService) Get(ctx context.Context, payment, capture string, options *CaptureOptions) (res *Response, c *Capture, err error)
 ```
 
 Get retrieves a single capture by its ID. Note the original payment’s ID is needed as well.
@@ -1075,7 +1137,7 @@ Get retrieves a single capture by its ID. Note the original payment’s ID is ne
 See: https://docs.mollie.com/reference/v2/captures-api/get-capture
 
 <a name="CapturesService.List"></a>
-### func \(\*CapturesService\) [List](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L77>)
+### func \(\*CapturesService\) [List](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L140>)
 
 ```go
 func (cs *CapturesService) List(ctx context.Context, payment string) (res *Response, cl *CapturesList, err error)
@@ -1722,6 +1784,20 @@ UnmarshalJSON implements the json.Unmarshaler interface on ContextValues.
 
 See: https://github.com/VictorAvelar/mollie-api-go/issues/251
 
+<a name="CreateCapture"></a>
+## type [CreateCapture](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/captures.go#L30-L35>)
+
+CreateCapture describes the payload for creating a capture.
+
+```go
+type CreateCapture struct {
+    Description string  `json:"description,omitempty"`
+    Metadata    any     `json:"metadata,omitempty"`
+    Amount      *Amount `json:"amount,omitempty"`
+    CaptureAccessTokenFields
+}
+```
+
 <a name="CreateMollieConnectPaymentFields"></a>
 ## type [CreateMollieConnectPaymentFields](<https://github.com/VictorAvelar/mollie-api-go/blob/master/mollie/payments.go#L134-L137>)
 
diff --git a/mollie/captures.go b/mollie/captures.go
index ea690e5..50936be 100644
--- a/mollie/captures.go
+++ b/mollie/captures.go
@@ -16,8 +16,46 @@ const (
 	ManualCapture    CaptureMode = "manual"
 )
 
-// CapturesService operates over captures resource.
-type CapturesService service
+// CaptureStatus describes the status of a capture.
+type CaptureStatus string
+
+// CaptureStatus possible values.
+const (
+	CaptureStatusPending   CaptureStatus = "pending"
+	CaptureStatusSucceeded CaptureStatus = "succeeded"
+	CaptureStatusFailed    CaptureStatus = "failed"
+)
+
+// CreateCapture describes the payload for creating a capture.
+type CreateCapture struct {
+	Description string  `json:"description,omitempty"`
+	Metadata    any     `json:"metadata,omitempty"`
+	Amount      *Amount `json:"amount,omitempty"`
+	CaptureAccessTokenFields
+}
+
+// CaptureAccessTokenFields describes the payload for creating a capture with an access token.
+type CaptureAccessTokenFields struct {
+	Testmode bool `json:"testmode,omitempty"`
+}
+
+// Capture describes a single capture.
+// Captures are used for payments that have the authorize-then-capture flow.
+type Capture struct {
+	Resource         string        `json:"resource,omitempty"`
+	ID               string        `json:"id,omitempty"`
+	Mode             Mode          `json:"mode,omitempty"`
+	Amount           *Amount       `json:"amount,omitempty"`
+	Status           CaptureStatus `json:"status,omitempty"`
+	SettlementAmount *Amount       `json:"settlementAmount,omitempty"`
+	PaymentID        string        `json:"paymentId,omitempty"`
+	ShipmentID       string        `json:"shipmentId,omitempty"`
+	SettlementID     string        `json:"settlementId,omitempty"`
+	CreatedAt        *time.Time    `json:"createdAt,omitempty"`
+	Metadata         any           `json:"metadata,omitempty"`
+	Links            CaptureLinks  `json:"_links,omitempty"`
+	AccessTokenPaymentFields
+}
 
 // CaptureLinks contains relevant links for a capture object.
 type CaptureLinks struct {
@@ -28,19 +66,11 @@ type CaptureLinks struct {
 	Documentation *URL `json:"documentation,omitempty"`
 }
 
-// Capture describes a single capture.
-// Captures are used for payments that have the authorize-then-capture flow.
-type Capture struct {
-	Resource         string       `json:"resource,omitempty"`
-	ID               string       `json:"id,omitempty"`
-	Mode             Mode         `json:"mode,omitempty"`
-	Amount           *Amount      `json:"amount,omitempty"`
-	SettlementAmount *Amount      `json:"settlementAmount,omitempty"`
-	PaymentID        string       `json:"paymentId,omitempty"`
-	ShipmentID       string       `json:"shipmentId,omitempty"`
-	SettlementID     string       `json:"settlementId,omitempty"`
-	CreatedAt        *time.Time   `json:"createdAt,omitempty"`
-	Links            CaptureLinks `json:"_links,omitempty"`
+// CaptureOptions describes the query params available to use when retrieving captures.
+//
+// See: https://docs.mollie.com/reference/v2/captures-api/get-capture#embedding-of-related-resources
+type CaptureOptions struct {
+	Embed []EmbedValue `url:"embed,omitempty"`
 }
 
 // CapturesList describes a list of captures.
@@ -52,14 +82,47 @@ type CapturesList struct {
 	Links PaginationLinks `json:"_links,omitempty"`
 }
 
+// CapturesService operates over captures resource.
+type CapturesService service
+
 // Get retrieves a single capture by its ID.
 // Note the original payment’s ID is needed as well.
 //
 // See: https://docs.mollie.com/reference/v2/captures-api/get-capture
-func (cs *CapturesService) Get(ctx context.Context, payment, capture string) (res *Response, c *Capture, err error) {
+func (cs *CapturesService) Get(ctx context.Context, payment, capture string, options *CaptureOptions) (
+	res *Response,
+	c *Capture,
+	err error,
+) {
 	u := fmt.Sprintf("v2/payments/%s/captures/%s", payment, capture)
 
-	res, err = cs.client.get(ctx, u, nil)
+	res, err = cs.client.get(ctx, u, options)
+	if err != nil {
+		return
+	}
+
+	if err = json.Unmarshal(res.content, &c); err != nil {
+		return
+	}
+
+	return
+}
+
+// Create creates a new capture for a payment.
+//
+// See: https://docs.mollie.com/reference/v2/captures-api/create-capture
+func (cs *CapturesService) Create(ctx context.Context, payment string, capture CreateCapture) (
+	res *Response,
+	c *Capture,
+	err error,
+) {
+	u := fmt.Sprintf("v2/payments/%s/captures", payment)
+
+	if cs.client.HasAccessToken() && cs.client.config.testing {
+		capture.Testmode = true
+	}
+
+	res, err = cs.client.post(ctx, u, capture, nil)
 	if err != nil {
 		return
 	}
@@ -74,10 +137,14 @@ func (cs *CapturesService) Get(ctx context.Context, payment, capture string) (re
 // List retrieves all captures for a certain payment.
 //
 // See: https://docs.mollie.com/reference/v2/captures-api/list-captures
-func (cs *CapturesService) List(ctx context.Context, payment string) (res *Response, cl *CapturesList, err error) {
+func (cs *CapturesService) List(ctx context.Context, payment string, options *CaptureOptions) (
+	res *Response,
+	cl *CapturesList,
+	err error,
+) {
 	u := fmt.Sprintf("v2/payments/%s/captures", payment)
 
-	res, err = cs.client.get(ctx, u, nil)
+	res, err = cs.client.get(ctx, u, options)
 	if err != nil {
 		return
 	}


Test patch:
diff --git a/mollie/captures_test.go b/mollie/captures_test.go
index 4c0a939..b2617e1 100644
--- a/mollie/captures_test.go
+++ b/mollie/captures_test.go
@@ -18,6 +18,7 @@ func TestCapturesService_Get(t *testing.T) {
 		ctx     context.Context
 		payment string
 		capture string
+		options *CaptureOptions
 	}
 
 	cases := []struct {
@@ -34,6 +35,7 @@ func TestCapturesService_Get(t *testing.T) {
 				context.Background(),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				nil,
 			},
 			false,
 			nil,
@@ -48,12 +50,37 @@ func TestCapturesService_Get(t *testing.T) {
 			},
 			noPre,
 		},
+		{
+			"get captures works expands query params correctly",
+			args{
+				context.Background(),
+				"tr_WDqYK6vllg",
+				"cpt_4qqhO89gsT",
+				&CaptureOptions{
+					Embed: []EmbedValue{EmbedPayment},
+				},
+			},
+			false,
+			nil,
+			func(w http.ResponseWriter, r *http.Request) {
+				testHeader(t, r, AuthHeader, "Bearer token_X12b31ggg23")
+				testMethod(t, r, "GET")
+				testQuery(t, r, "embed=payments")
+				if _, ok := r.Header[AuthHeader]; !ok {
+					w.WriteHeader(http.StatusUnauthorized)
+				}
+
+				_, _ = w.Write([]byte(testdata.GetCaptureResponse))
+			},
+			noPre,
+		},
 		{
 			"get captures returns an http error from the server",
 			args{
 				context.Background(),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				nil,
 			},
 			true,
 			fmt.Errorf("500 Internal Server Error: An internal server error occurred while processing your request."),
@@ -66,6 +93,7 @@ func TestCapturesService_Get(t *testing.T) {
 				context.Background(),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				nil,
 			},
 			true,
 			errBadBaseURL,
@@ -78,6 +106,7 @@ func TestCapturesService_Get(t *testing.T) {
 				context.Background(),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				nil,
 			},
 			true,
 			fmt.Errorf("invalid character 'h' looking for beginning of object key string"),
@@ -102,7 +131,7 @@ func TestCapturesService_Get(t *testing.T) {
 				c.handler,
 			)
 
-			res, capture, err := tClient.Captures.Get(c.args.ctx, c.args.payment, c.args.capture)
+			res, capture, err := tClient.Captures.Get(c.args.ctx, c.args.payment, c.args.capture, c.args.options)
 			if c.wantErr {
 				assert.NotNil(t, err)
 				assert.EqualError(t, err, c.err.Error())
@@ -116,6 +145,152 @@ func TestCapturesService_Get(t *testing.T) {
 	}
 }
 
+func TestCapturesService_Create(t *testing.T) {
+	setEnv()
+	defer unsetEnv()
+
+	type args struct {
+		ctx     context.Context
+		payment string
+		capture CreateCapture
+		options *CaptureOptions
+	}
+
+	cases := []struct {
+		name    string
+		args    args
+		wantErr bool
+		err     error
+		handler http.HandlerFunc
+		pre     func()
+	}{
+		{
+			"create captures works as expected",
+			args{
+				context.Background(),
+				"tr_WDqYK6vllg",
+				CreateCapture{
+					Amount: &Amount{
+						Value:    "20.00",
+						Currency: "EUR",
+					},
+					Description: "Order #12345",
+				},
+				nil,
+			},
+			false,
+			nil,
+			func(w http.ResponseWriter, r *http.Request) {
+				testHeader(t, r, AuthHeader, "Bearer token_X12b31ggg23")
+				testMethod(t, r, "POST")
+				if _, ok := r.Header[AuthHeader]; !ok {
+					w.WriteHeader(http.StatusUnauthorized)
+				}
+
+				_, _ = w.Write([]byte(testdata.CreateCaptureResponse))
+			},
+			noPre,
+		},
+		{
+			"create captures works as with access token expected",
+			args{
+				context.Background(),
+				"tr_WDqYK6vllg",
+				CreateCapture{
+					Amount: &Amount{
+						Value:    "20.00",
+						Currency: "EUR",
+					},
+					Description: "Order #12345",
+				},
+				nil,
+			},
+			false,
+			nil,
+			func(w http.ResponseWriter, r *http.Request) {
+				testHeader(t, r, AuthHeader, "Bearer access_token_test")
+				testMethod(t, r, "POST")
+				if _, ok := r.Header[AuthHeader]; !ok {
+					w.WriteHeader(http.StatusUnauthorized)
+				}
+
+				_, _ = w.Write([]byte(testdata.CreateCaptureWithAccessTokenResponse))
+			},
+			setAccessToken,
+		},
+		{
+			"create captures returns an http error from the server",
+			args{
+				context.Background(),
+				"tr_WDqYK6vllg",
+				CreateCapture{},
+				nil,
+			},
+			true,
+			fmt.Errorf("500 Internal Server Error: An internal server error occurred while processing your request."),
+			errorHandler,
+			noPre,
+		},
+		{
+			"create captures returns an error when creating the request",
+			args{
+				context.Background(),
+				"tr_WDqYK6vllg",
+				CreateCapture{},
+				nil,
+			},
+			true,
+			errBadBaseURL,
+			errorHandler,
+			crashSrv,
+		},
+		{
+			"create captures returns an error when trying to parse the json response",
+			args{
+				context.Background(),
+				"tr_WDqYK6vllg",
+				CreateCapture{},
+				nil,
+			},
+			true,
+			fmt.Errorf("invalid character 'h' looking for beginning of object key string"),
+			encodingHandler,
+			noPre,
+		},
+	}
+
+	for _, c := range cases {
+		setup()
+		defer teardown()
+
+		t.Run(c.name, func(t *testing.T) {
+			c.pre()
+
+			tMux.HandleFunc(
+				fmt.Sprintf(
+					"/v2/payments/%s/captures",
+					c.args.payment,
+				),
+				c.handler,
+			)
+
+			res, capture, err := tClient.Captures.Create(c.args.ctx, c.args.payment, c.args.capture)
+			if c.wantErr {
+				assert.NotNil(t, err)
+				assert.EqualError(t, err, c.err.Error())
+				if tClient.HasAccessToken() {
+					assert.True(t, capture.Testmode)
+				}
+			} else {
+				assert.Nil(t, err)
+				assert.IsType(t, &Capture{}, capture)
+				assert.EqualValues(t, c.args.ctx, res.Request.Context())
+				assert.IsType(t, &http.Response{}, res.Response)
+			}
+		})
+	}
+}
+
 func TestCapturesService_List(t *testing.T) {
 	setEnv()
 	defer unsetEnv()
@@ -124,6 +299,7 @@ func TestCapturesService_List(t *testing.T) {
 		ctx     context.Context
 		payment string
 		capture string
+		options *CaptureOptions
 	}
 
 	type key string
@@ -142,12 +318,17 @@ func TestCapturesService_List(t *testing.T) {
 				context.Background(),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				&CaptureOptions{
+					Embed: []EmbedValue{EmbedPayment},
+				},
 			},
 			false,
 			nil,
 			func(w http.ResponseWriter, r *http.Request) {
 				testHeader(t, r, AuthHeader, "Bearer token_X12b31ggg23")
 				testMethod(t, r, "GET")
+				testQuery(t, r, "embed=payments")
+
 				if _, ok := r.Header[AuthHeader]; !ok {
 					w.WriteHeader(http.StatusUnauthorized)
 				}
@@ -162,6 +343,7 @@ func TestCapturesService_List(t *testing.T) {
 				context.WithValue(context.Background(), key("test"), "test-value"),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				&CaptureOptions{},
 			},
 			true,
 			fmt.Errorf("500 Internal Server Error: An internal server error occurred while processing your request."),
@@ -174,6 +356,7 @@ func TestCapturesService_List(t *testing.T) {
 				context.Background(),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				&CaptureOptions{},
 			},
 			true,
 			errBadBaseURL,
@@ -186,6 +369,7 @@ func TestCapturesService_List(t *testing.T) {
 				context.Background(),
 				"tr_WDqYK6vllg",
 				"cpt_4qqhO89gsT",
+				&CaptureOptions{},
 			},
 			true,
 			fmt.Errorf("invalid character 'h' looking for beginning of object key string"),
@@ -209,7 +393,7 @@ func TestCapturesService_List(t *testing.T) {
 				c.handler,
 			)
 
-			res, list, err := tClient.Captures.List(c.args.ctx, c.args.payment)
+			res, list, err := tClient.Captures.List(c.args.ctx, c.args.payment, c.args.options)
 			if c.wantErr {
 				assert.NotNil(t, err)
 				assert.EqualError(t, err, c.err.Error())
diff --git a/testdata/captures.go b/testdata/captures.go
index 616a605..d28e789 100644
--- a/testdata/captures.go
+++ b/testdata/captures.go
@@ -100,3 +100,60 @@ const GetCaptureResponse = `{
         }
     }
 }`
+
+// CreateCaptureResponse example.
+const CreateCaptureResponse = `{
+    "resource": "capture",
+    "id": "cpt_mNepDkEtco6ah3QNPUGYH",
+    "mode": "live",
+    "amount": {
+        "value": "35.95",
+        "currency": "EUR"
+    },
+    "paymentId": "tr_WDqYK6vllg",
+    "createdAt": "2018-08-02T09:29:56+00:00",
+    "description": "Capture for cart #12345",
+    "_links": {
+        "self": {
+            "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg/captures/cpt_mNepDkEtco6ah3QNPUGYH",
+            "type": "application/hal+json"
+        },
+        "payment": {
+            "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg",
+            "type": "application/hal+json"
+        },
+        "documentation": {
+            "href": "https://docs.mollie.com/reference/v2/captures-api/create-capture",
+            "type": "text/html"
+        }
+    }
+}`
+
+// CreateCaptureWithAccessTokenResponse example.
+const CreateCaptureWithAccessTokenResponse = `{
+    "resource": "capture",
+    "id": "cpt_mNepDkEtco6ah3QNPUGYH",
+    "mode": "live",
+    "amount": {
+        "value": "35.95",
+        "currency": "EUR"
+    },
+    "paymentId": "tr_WDqYK6vllg",
+    "createdAt": "2018-08-02T09:29:56+00:00",
+    "description": "Capture for cart #12345",
+    "testmode": true,
+    "_links": {
+        "self": {
+            "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg/captures/cpt_mNepDkEtco6ah3QNPUGYH",
+            "type": "application/hal+json"
+        },
+        "payment": {
+            "href": "https://api.mollie.com/v2/payments/tr_WDqYK6vllg",
+            "type": "application/hal+json"
+        },
+        "documentation": {
+            "href": "https://docs.mollie.com/reference/v2/captures-api/create-capture",
+            "type": "text/html"
+        }
+    }
+}`