# Capture Payment

POST https://global-api-sandbox.afterpay.com/v2/payments/{orderId}/capture
Content-Type: application/json

This endpoint captures a full or partial payment. Any amounts successfully captured are settled from Cash App Afterpay to the merchant's nominated bank account on the following day. Records of all payments captured against an order are returned in the events list as events of type, "CAPTURED".

**Note:** Authorization expires after 13 days and then the transaction is automatically voided. Voided transactions are frozen and cannot be captured, reopened or changed in any way. In this case your only option is to use the v2/checkouts endpoint to create a new order.

This operation is idempotent based on the `requestId` (if provided), which allows the safe retry of multiple requests. This safe retry guarantees the payment operation only occurs once.

**Connection Timeouts**
| Timeout | Time (Seconds) |
|---------|----------------|
| Open    | 10             |
| Read    | 70             |


Reference: https://developers.cash.app/cash-app-afterpay/api-reference/reference/payments/capture-payment

## OpenAPI Specification

```yaml
openapi: 3.1.1
info:
  title: Capture Payment
  version: endpoint_.capture-payment
paths:
  /v2/payments/{orderId}/capture:
    post:
      operationId: capture-payment
      summary: Capture Payment
      description: >
        This endpoint captures a full or partial payment. Any amounts
        successfully captured are settled from Cash App Afterpay to the
        merchant's nominated bank account on the following day. Records of all
        payments captured against an order are returned in the events list as
        events of type, "CAPTURED".


        **Note:** Authorization expires after 13 days and then the transaction
        is automatically voided. Voided transactions are frozen and cannot be
        captured, reopened or changed in any way. In this case your only option
        is to use the v2/checkouts endpoint to create a new order.


        This operation is idempotent based on the `requestId` (if provided),
        which allows the safe retry of multiple requests. This safe retry
        guarantees the payment operation only occurs once.


        **Connection Timeouts**

        | Timeout | Time (Seconds) |

        |---------|----------------|

        | Open    | 10             |

        | Read    | 70             |
      tags:
        - []
      parameters:
        - name: orderId
          in: path
          description: >-
            The unique ID of the Cash App Afterpay Order, returned as the `id`
            property of the Auth response.
          required: true
          schema:
            type: string
        - name: Authorization
          in: header
          description: Basic authentication of the form `Basic <username:password>`.
          required: true
          schema:
            type: string
        - name: User-Agent
          in: header
          required: true
          schema:
            type: string
        - name: Accept
          in: header
          required: false
          schema:
            type: string
            default: application/json
      responses:
        '201':
          description: >-
            If successful, returns an updated copy of the Payment object, with
            the newly captured payment appended to the `events` array as a
            Payment Event object with a `type` of "CAPTURED".
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
        '404':
          description: >-
            No numeric `orderId` was provided, or an invalid string was
            provided. Error code `not_found`.
          content: {}
        '410':
          description: >-
            Payment has already been fully captured for this order, or partially
            captured with the remainder voided. Error code `payment_captured`.
          content: {}
        '412':
          description: >
            | errorCode | Description |

            | --- | --- |

            | error | A numeric `orderId` was provided, but did not match any
            valid order. |

            | invalid_state | The order was declined by Cash App Afterpay; no
            payment can be captured for this order. |

            | payment_voided | The auth for this order has already been
            completely voided. |

            | payment_expired | The auth for this order has expired; no further
            payment can be captured. |
          content: {}
        '422':
          description: >
            | errorCode | Description |

            | --- | --- |

            | invalid_object | The `amount` was missing or invalid, or the
            `paymentEventMerchantReference` exceeded 128 characters. |

            | invalid_amount | The `amount` was less than the minimum capture
            amount, or more than the `openToCaptureAmount`. |
          content: {}
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CapturePayment'
components:
  schemas:
    MoneyCurrency:
      type: string
      enum:
        - value: AUD
        - value: NZD
        - value: USD
        - value: CAD
        - value: GBP
    Money:
      type: object
      properties:
        amount:
          type: string
          description: >-
            The amount as a string representation of a decimal number, rounded
            to 2 decimal places.
        currency:
          $ref: '#/components/schemas/MoneyCurrency'
      required:
        - amount
        - currency
    CapturePayment:
      type: object
      properties:
        requestId:
          type: string
          format: uuid
          description: A unique request ID, required for idempotent retries.
        merchantReference:
          type: string
          description: >-
            The reference/order ID that this payment corresponds to in the
            merchant's system. 


            Note: Providing a new value updates any value previously set in the
            Create Checkout request.
        amount:
          $ref: '#/components/schemas/Money'
        paymentEventMerchantReference:
          type: string
          description: >
            A unique reference for the individual payment capture event. If
            provided, the value appears in the daily settlement file as "Payment
            Event ID"
    PaymentStatus:
      type: string
      enum:
        - value: APPROVED
        - value: DECLINED
    PaymentPaymentState:
      type: string
      enum:
        - value: AUTH_APPROVED
        - value: AUTH_DECLINED
        - value: PARTIALLY_CAPTURED
        - value: CAPTURED
        - value: CAPTURE_DECLINED
        - value: VOIDED
    Refund:
      type: object
      properties:
        requestId:
          type: string
          description: Unique ID required for safe retries. Max length 64 (varchar).
        amount:
          $ref: '#/components/schemas/Money'
        merchantReference:
          type: string
          description: >-
            The merchant’s internal refund id/reference. This must be included
            along with the `requestId` to utilise idempotency. Max length 85
            (varchar).
        refundMerchantReference:
          type: string
          description: >-
            A unique reference for the individual refund event. Max length 128
            (varchar).
        refundId:
          type: string
          description: The unique, permanent, Cash App Afterpay-generated Refund ID.
        refundedAt:
          type: string
    Consumer:
      type: object
      properties:
        email:
          type: string
          format: email
        givenNames:
          type: string
          description: The consumer's first name
        surname:
          type: string
          description: The consumer's last name
        phoneNumber:
          type: string
      required:
        - email
    ContactCountryCode:
      type: string
      enum:
        - value: AU
        - value: NZ
        - value: US
        - value: CA
        - value: GB
    Contact:
      type: object
      properties:
        name:
          type: string
        line1:
          type: string
          description: First line of the address
        line2:
          type: string
          description: 'Second line of the address '
        area1:
          type: string
          description: |-
            - AU: Suburb
            - NZ: Town or City
            - UK: Postal Town
            - US: City
            - Canada: City
        area2:
          type: string
          description: |-
            - NZ: suburb
            - UK: village or local area.
        region:
          type: string
          description: |-
            - AU: State 
            - NZ: Region
            - UK: County
            - US: State
            - CA: Province or Territory
        postcode:
          type: string
        countryCode:
          $ref: '#/components/schemas/ContactCountryCode'
        phoneNumber:
          type: string
          description: >-
            The phone number, in [E.123](https://en.wikipedia.org/wiki/E.123)
            format.
      required:
        - name
        - line1
        - area1
        - region
        - postcode
        - countryCode
    ShippingCourierPriority:
      type: string
      enum:
        - value: STANDARD
        - value: EXPRESS
    Shipping-Courier:
      type: object
      properties:
        shippedAt:
          type: string
          format: date-time
        name:
          type: string
        tracking:
          type: string
        priority:
          $ref: '#/components/schemas/ShippingCourierPriority'
    Item:
      type: object
      properties:
        name:
          type: string
        sku:
          type: string
        pageUrl:
          type: string
        imageUrl:
          type: string
        quantity:
          type: integer
        price:
          $ref: '#/components/schemas/Money'
        categories:
          type: array
          items:
            type: array
            items:
              type: string
        estimatedShipmentDate:
          type: string
          format: date
        preorder:
          type: boolean
          default: false
      required:
        - name
        - quantity
        - price
    Discount:
      type: object
      properties:
        displayName:
          type: string
        amount:
          $ref: '#/components/schemas/Money'
    Order-Details:
      type: object
      properties:
        consumer:
          $ref: '#/components/schemas/Consumer'
        billing:
          $ref: '#/components/schemas/Contact'
        courier:
          $ref: '#/components/schemas/Shipping-Courier'
        items:
          type: array
          items:
            $ref: '#/components/schemas/Item'
        discounts:
          type: array
          items:
            $ref: '#/components/schemas/Discount'
        taxAmount:
          $ref: '#/components/schemas/Money'
        shippingAmount:
          $ref: '#/components/schemas/Money'
    PaymentEventType:
      type: string
      enum:
        - value: AUTH_APPROVED
        - value: AUTH_DECLINED
        - value: CAPTURED
        - value: CAPTURE_DECLINED
        - value: VOIDED
        - value: EXPIRED
    Payment-Event:
      type: object
      properties:
        id:
          type: string
        created:
          type: string
        expires:
          type: string
        type:
          $ref: '#/components/schemas/PaymentEventType'
        amount:
          $ref: '#/components/schemas/Money'
        paymentEventMerchantReference:
          type: string
    Payment:
      type: object
      properties:
        id:
          type: string
          description: The unique, permanent, Cash App Afterpay generated Order ID.
        token:
          type: string
          description: The token obtained from the checkout call
        status:
          $ref: '#/components/schemas/PaymentStatus'
          description: represents the status of the order
        created:
          type: string
          description: ' is the UTC timestamp of when the payment was completed.'
        originalAmount:
          $ref: '#/components/schemas/Money'
        openToCaptureAmount:
          $ref: '#/components/schemas/Money'
        paymentState:
          $ref: '#/components/schemas/PaymentPaymentState'
          description: is the current state for capturing payments
        merchantReference:
          type: string
          description: >-
            is the merchant's order id/reference that the payment corresponds
            to.
        refunds:
          type: array
          items:
            $ref: '#/components/schemas/Refund'
        orderDetails:
          $ref: '#/components/schemas/Order-Details'
        events:
          type: array
          items:
            $ref: '#/components/schemas/Payment-Event'

```

## SDK Code Examples

```python
import requests

url = "https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture"

payload = {}
headers = {
    "User-Agent": "User-Agent",
    "Authorization": "Basic <username>:<password>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture';
const options = {
  method: 'POST',
  headers: {
    'User-Agent': 'User-Agent',
    Authorization: 'Basic <username>:<password>',
    'Content-Type': 'application/json'
  },
  body: '{}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("User-Agent", "User-Agent")
	req.Header.Add("Authorization", "Basic <username>:<password>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["User-Agent"] = 'User-Agent'
request["Authorization"] = 'Basic <username>:<password>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java
HttpResponse<String> response = Unirest.post("https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture")
  .header("User-Agent", "User-Agent")
  .header("Authorization", "Basic <username>:<password>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php
<?php

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Basic <username>:<password>',
    'Content-Type' => 'application/json',
    'User-Agent' => 'User-Agent',
  ],
]);

echo $response->getBody();
```

```csharp
var client = new RestClient("https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture");
var request = new RestRequest(Method.POST);
request.AddHeader("User-Agent", "User-Agent");
request.AddHeader("Authorization", "Basic <username>:<password>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "User-Agent": "User-Agent",
  "Authorization": "Basic <username>:<password>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://global-api-sandbox.afterpay.com/v2/payments/orderId/capture")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```