# 

## Prerequisites

* A valid API key — see [Obtain API credentials](/docs/how-tos/setup/obtain-credentials)
* An authorized transaction from a `card_auth` request (the two-step flow)


## When to use partial captures

* **Split shipments**: An order with multiple items ships in separate packages. Capture the amount for each shipment as it leaves.
* **Adjusted totals**: The final order amount is less than the initial authorization (item unavailable, price adjustment).
* **Hotel / rental**: The estimated hold exceeds the actual charge.


## Step 1: Authorize the full estimated amount

```shell
curl -X POST \
  https://api.dev.paradisegateway.net/v1/transactions \
  -H "Content-Type: application/json" \
  -H "APIKEY: YOUR-API-KEY" \
  -d '{
    "type": "auth",
    "amount": 50000,
    "payment_method": {
      "type": "card",
      "pan": "5500000000005678",
      "expiry":
        "month": "07",
        "year": "2029"
      },
      "cardholder_name": "Nyota Uhura",
      "cvv": "789",
      "address_line1": "42 Subspace Ln",
      "zip": "30301"
    },
    "metadata": {},
    "recurring": false,
    "purchase_description": "Starfleet uniform"
  }'
```

Response returns `transaction_state: authorized` with `amount: 50000`. Save the `id`.

## Step 2: Capture a partial amount

Send `POST /v1/transactions/{id}/capture` with an `amount` less than the authorized total.

curl
```shell
curl -X POST \
  https://api.dev.paradisegateway.net/v1/transactions/TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0/capture \
  -H "Content-Type: application/json" \
  -H "APIKEY: YOUR-API-KEY" \
  -d '{
    "type": "capture",
    "amount": 30000,
    "tip": 0
  }'
```

Python
```python
import requests

transaction_id = "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0"
resp = requests.post(
    f"https://api.dev.paradisegateway.net/v1/transactions/{transaction_id}/capture",
    headers={"Content-Type": "application/json", "APIKEY": "YOUR-API-KEY"},
    json={"type": "capture", "amount": 30000, "tip": 0},
)
print(resp.json())
```

JavaScript
```javascript
const transactionId = "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0";
const resp = await fetch(
  `https://api.dev.paradisegateway.net/v1/transactions/${transactionId}/capture`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "APIKEY": "YOUR-API-KEY",
    },
    body: JSON.stringify({
      type: "capture",
      amount: 30000,
      tip: 0,
    }),
  }
);
console.log(await resp.json());
```

C#
```csharp
var transactionId = "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0";
var payload = new { type = "capture", amount = 30000, tip = 0 };
var resp = await client.PostAsJsonAsync(
    $"https://api.dev.paradisegateway.net/v1/transactions/{transactionId}/capture",
    payload);
Console.WriteLine(await resp.Content.ReadAsStringAsync());
```

Java
```java
String transactionId = "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0";
String body = """
    {"type": "capture", "amount": 30000, "tip": 0}
    """;
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(
        "https://api.dev.paradisegateway.net/v1/transactions/"
        + transactionId + "/capture"))
    .header("Content-Type", "application/json")
    .header("APIKEY", "YOUR-API-KEY")
    .POST(HttpRequest.BodyPublishers.ofString(body)).build();
HttpResponse<String> resp = client.send(request,
    HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
```

Go
```go
transactionID := "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0"
payload := strings.NewReader(`{"type": "capture", "amount": 30000, "tip": 0}`)
req, _ := http.NewRequest("POST",
    "https://api.dev.paradisegateway.net/v1/transactions/"+transactionID+"/capture",
    payload)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("APIKEY", "YOUR-API-KEY")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
```

PHP
```php
$id = "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0";
$ch = curl_init(
    "https://api.dev.paradisegateway.net/v1/transactions/$id/capture");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["Content-Type: application/json", "APIKEY: YOUR-API-KEY"],
    CURLOPT_POSTFIELDS => json_encode([
        "type" => "capture", "amount" => 30000, "tip" => 0,
    ]),
]);
echo curl_exec($ch); curl_close($ch);
```

Ruby
```ruby
id = "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0"
uri = URI(
  "https://api.dev.paradisegateway.net/v1/transactions/#{id}/capture")
req = Net::HTTP::Post.new(uri, {
  "Content-Type" => "application/json", "APIKEY" => "YOUR-API-KEY",
})
req.body = { type: "capture", amount: 30000, tip: 0 }.to_json
resp = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts resp.body
```

## Step 3: Verify the capture

The response confirms the captured amount. The remaining 200.00 USD hold (500.00 authorized − 300.00 captured) is released back to the person.

```json
{
  "id": "TRANSACTION-02KNUHURA8YWP4LT9G3X5V7Z0",
  "type": "capture",
  "transaction_state": "completed",
  "response_status": "Approved",
  "response_code": "00",
  "amount": 30000,
  "tip": 0,
  "correlation_id": "f6a7b8c9-d0e1-2345-f012-3456789abcde"
}
```

## How partial captures work

```mermaid
---
config:
  theme: 'neutral'
---
flowchart TD
    A["Authorization: 500.00 USD"] --> B{Full or partial?}
    B -->|Full| C["Capture 500.00 USD"]
    B -->|Partial| D["Capture 300.00 USD"]
    D --> E["200.00 USD hold released"]
    C --> F[Settled in next batch]
    D --> F
```

| Scenario | Authorized | Captured | Released to person |
|  --- | --- | --- | --- |
| Full capture | 500.00 | 500.00 | 0.00 |
| Partial capture | 500.00 | 300.00 | 200.00 |
| Zero capture (cancel) | 500.00 | 0.00 | 500.00 |


## Rules and constraints

| Rule | Details |
|  --- | --- |
| Capture amount must be ≤ authorized amount | You cannot capture more than was authorized |
| Single capture per authorization | Each authorization can be captured once (for multiple captures, use multiple authorizations) |
| Timing | Must capture before the authorization expires (7–30 days, varies by issuer) |
| Tip at capture | You can include a `tip` in the capture request; the total (amount + tip) must not exceed the authorized amount |


Split shipments
For orders that ship in multiple packages, authorize the full order amount up front, then create separate authorizations for each shipment and capture individually. This is more reliable than attempting multiple partial captures against a single authorization.

## Next steps

* [Authorize and capture separately](/docs/how-tos/process-payments/authorize-capture-separately) — the full two-step flow
* [Add a tip or surcharge](/docs/how-tos/process-payments/add-tip) — adjust the amount before capture
* [About cancels and refunds](/docs/concepts/transactions/cancels-and-refunds) — what to do if you do not need to capture