> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.greenlane.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.greenlane.ai/_mcp/server.

# Capture

POST https://pos.fuel.greenlane.ai/gfp/capture
Content-Type: application/json

The capture request is the second step the merchant POS will call when the customer hangs up the pump and the fuel transaction is completed.

1. Ensure the `transaction_id` and `payment_code` pair match a previously authorized transaction.
    
2. The `transaction_time_ms` should be the epoch time in millis of when the customer completed the transaction.
    
3. The amounts (volume and retail costs) are within the bounds of the authorization response.
    
    1. If the volume or retail costs are outside of the authorization response amounts, the capture will be **declined**.









        
4. A transaction may only be captured once. Additional captures will error out (except in the case where the request body is identical).
    
    1. Duplicate requests for the same transations and capture amounts will return identical responses.









        

Since pumps are not precise instruments, we suggest that the volume and cost amounts are capped (i.e. via `min(auth_volume, actual_volume)`), and the pump hardware is configured to release less than the authorized amounts (e.g. 0.5G less).

**Using the Merchant Initiated Flag**

You may do a capture without an explicit authorization by using the `merchant_initiated`flag. This is useful in cases when there's an overfill, or as part of a refund + recapture flow. To ensure this works correctly, send the same `payment_code` as original transaction but a new `transaction_id`.

Reference: https://docs.greenlane.ai/greenlane-fuel-platform/capture

## Authentication

- `Authorization` header (bearer token, required)

## Request

### Body (application/json)

- `merchant_id` (string, required)
- `site_id` (string, required)
- `transaction_id` (string, required)
- `transaction_time_ms` (integer, required)
- `transaction_amt` (double, required)
- `merchant_initiated` (boolean, required)
- `fuel` (list of object, required)
  - `pump_number` (integer, required)
  - `product_code` (string, required)
  - `retail_price_per_unit` (double, required)
  - `cost_price_per_unit` (double, required)
  - `volume` (double, required)
  - `amount` (double, required)
  - `unit_of_measure` (string, required)
  - `taxes` (list of object, required)
    - `tax_code` (string, required)
    - `amount` (double, required)
- `payment_code` (string, required)

## Response

### 200

OK

- `merchant_id` (string, required)
- `transaction_id` (string, required)
- `authorized_amt` (double, required)
- `authorized_flag` (boolean, required)
- `authorization_code` (string, required)

## Examples

### Capture successful

**Request**

```json
undefined
```

**Response**

```json
{
  "merchant_id": "merchant-123",
  "transaction_id": "123abcd",
  "authorized_amt": 352.41,
  "authorized_flag": true,
  "authorization_code": "QWE4412VF"
}
```

**SDK Code**

```python Capture successful
import requests

url = "https://pos.fuel.greenlane.ai/gfp/capture"

headers = {"Authorization": "Bearer <token>"}

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

print(response.json())
```

```javascript Capture successful
const url = 'https://pos.fuel.greenlane.ai/gfp/capture';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

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

```go Capture successful
package main

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

func main() {

	url := "https://pos.fuel.greenlane.ai/gfp/capture"

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

	req.Header.Add("Authorization", "Bearer <token>")

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

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

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

}
```

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

url = URI("https://pos.fuel.greenlane.ai/gfp/capture")

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

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

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

```java Capture successful
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://pos.fuel.greenlane.ai/gfp/capture")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Capture successful
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://pos.fuel.greenlane.ai/gfp/capture', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp Capture successful
using RestSharp;

var client = new RestClient("https://pos.fuel.greenlane.ai/gfp/capture");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Capture successful
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://pos.fuel.greenlane.ai/gfp/capture")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

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()
```

### Capture declined

**Request**

```json
undefined
```

**Response**

```json
{
  "merchant_id": "merchant-123",
  "transaction_id": "123abcd",
  "authorized_amt": 1.1,
  "authorized_flag": false,
  "authorization_code": "string",
  "denied_reason": "Requested volume 88.124 exceeds limit 80 for fuel code DIESEL_ULSD."
}
```

**SDK Code**

```python Capture declined
import requests

url = "https://pos.fuel.greenlane.ai/gfp/capture"

headers = {"Authorization": "Bearer <token>"}

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

print(response.json())
```

```javascript Capture declined
const url = 'https://pos.fuel.greenlane.ai/gfp/capture';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

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

```go Capture declined
package main

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

func main() {

	url := "https://pos.fuel.greenlane.ai/gfp/capture"

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

	req.Header.Add("Authorization", "Bearer <token>")

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

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

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

}
```

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

url = URI("https://pos.fuel.greenlane.ai/gfp/capture")

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

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

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

```java Capture declined
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://pos.fuel.greenlane.ai/gfp/capture")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Capture declined
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://pos.fuel.greenlane.ai/gfp/capture', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp Capture declined
using RestSharp;

var client = new RestClient("https://pos.fuel.greenlane.ai/gfp/capture");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Capture declined
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://pos.fuel.greenlane.ai/gfp/capture")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

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()
```

### Capture_example

**Request**

```json
{
  "merchant_id": "merchant-id",
  "site_id": "441",
  "transaction_id": "123abcd",
  "transaction_time_ms": 1787636532000,
  "transaction_amt": 352.41,
  "merchant_initiated": false,
  "fuel": [
    {
      "pump_number": 1,
      "product_code": "DIESEL_ULSD",
      "retail_price_per_unit": 3.999,
      "cost_price_per_unit": 3.65,
      "volume": 88.124,
      "amount": 352.41,
      "unit_of_measure": "GALLON",
      "taxes": [
        {
          "tax_code": "FEDERAL",
          "amount": 15.42
        },
        {
          "tax_code": "STATE",
          "amount": 12.11
        }
      ]
    }
  ],
  "payment_code": "75123456"
}
```

**Response**

```json
{
  "merchant_id": "merchant-123",
  "transaction_id": "123abcd",
  "authorized_amt": 352.41,
  "authorized_flag": true,
  "authorization_code": "QWE4412VF"
}
```

**SDK Code**

```python Capture_example
import requests

url = "https://pos.fuel.greenlane.ai/gfp/capture"

payload = {
    "merchant_id": "merchant-id",
    "site_id": "441",
    "transaction_id": "123abcd",
    "transaction_time_ms": 1787636532000,
    "transaction_amt": 352.41,
    "merchant_initiated": False,
    "fuel": [
        {
            "pump_number": 1,
            "product_code": "DIESEL_ULSD",
            "retail_price_per_unit": 3.999,
            "cost_price_per_unit": 3.65,
            "volume": 88.124,
            "amount": 352.41,
            "unit_of_measure": "GALLON",
            "taxes": [
                {
                    "tax_code": "FEDERAL",
                    "amount": 15.42
                },
                {
                    "tax_code": "STATE",
                    "amount": 12.11
                }
            ]
        }
    ],
    "payment_code": "75123456"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript Capture_example
const url = 'https://pos.fuel.greenlane.ai/gfp/capture';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"merchant_id":"merchant-id","site_id":"441","transaction_id":"123abcd","transaction_time_ms":1787636532000,"transaction_amt":352.41,"merchant_initiated":false,"fuel":[{"pump_number":1,"product_code":"DIESEL_ULSD","retail_price_per_unit":3.999,"cost_price_per_unit":3.65,"volume":88.124,"amount":352.41,"unit_of_measure":"GALLON","taxes":[{"tax_code":"FEDERAL","amount":15.42},{"tax_code":"STATE","amount":12.11}]}],"payment_code":"75123456"}'
};

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

```go Capture_example
package main

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

func main() {

	url := "https://pos.fuel.greenlane.ai/gfp/capture"

	payload := strings.NewReader("{\n  \"merchant_id\": \"merchant-id\",\n  \"site_id\": \"441\",\n  \"transaction_id\": \"123abcd\",\n  \"transaction_time_ms\": 1787636532000,\n  \"transaction_amt\": 352.41,\n  \"merchant_initiated\": false,\n  \"fuel\": [\n    {\n      \"pump_number\": 1,\n      \"product_code\": \"DIESEL_ULSD\",\n      \"retail_price_per_unit\": 3.999,\n      \"cost_price_per_unit\": 3.65,\n      \"volume\": 88.124,\n      \"amount\": 352.41,\n      \"unit_of_measure\": \"GALLON\",\n      \"taxes\": [\n        {\n          \"tax_code\": \"FEDERAL\",\n          \"amount\": 15.42\n        },\n        {\n          \"tax_code\": \"STATE\",\n          \"amount\": 12.11\n        }\n      ]\n    }\n  ],\n  \"payment_code\": \"75123456\"\n}")

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

	req.Header.Add("Authorization", "Bearer <token>")
	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 Capture_example
require 'uri'
require 'net/http'

url = URI("https://pos.fuel.greenlane.ai/gfp/capture")

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

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"merchant_id\": \"merchant-id\",\n  \"site_id\": \"441\",\n  \"transaction_id\": \"123abcd\",\n  \"transaction_time_ms\": 1787636532000,\n  \"transaction_amt\": 352.41,\n  \"merchant_initiated\": false,\n  \"fuel\": [\n    {\n      \"pump_number\": 1,\n      \"product_code\": \"DIESEL_ULSD\",\n      \"retail_price_per_unit\": 3.999,\n      \"cost_price_per_unit\": 3.65,\n      \"volume\": 88.124,\n      \"amount\": 352.41,\n      \"unit_of_measure\": \"GALLON\",\n      \"taxes\": [\n        {\n          \"tax_code\": \"FEDERAL\",\n          \"amount\": 15.42\n        },\n        {\n          \"tax_code\": \"STATE\",\n          \"amount\": 12.11\n        }\n      ]\n    }\n  ],\n  \"payment_code\": \"75123456\"\n}"

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

```java Capture_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://pos.fuel.greenlane.ai/gfp/capture")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"merchant_id\": \"merchant-id\",\n  \"site_id\": \"441\",\n  \"transaction_id\": \"123abcd\",\n  \"transaction_time_ms\": 1787636532000,\n  \"transaction_amt\": 352.41,\n  \"merchant_initiated\": false,\n  \"fuel\": [\n    {\n      \"pump_number\": 1,\n      \"product_code\": \"DIESEL_ULSD\",\n      \"retail_price_per_unit\": 3.999,\n      \"cost_price_per_unit\": 3.65,\n      \"volume\": 88.124,\n      \"amount\": 352.41,\n      \"unit_of_measure\": \"GALLON\",\n      \"taxes\": [\n        {\n          \"tax_code\": \"FEDERAL\",\n          \"amount\": 15.42\n        },\n        {\n          \"tax_code\": \"STATE\",\n          \"amount\": 12.11\n        }\n      ]\n    }\n  ],\n  \"payment_code\": \"75123456\"\n}")
  .asString();
```

```php Capture_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://pos.fuel.greenlane.ai/gfp/capture', [
  'body' => '{
  "merchant_id": "merchant-id",
  "site_id": "441",
  "transaction_id": "123abcd",
  "transaction_time_ms": 1787636532000,
  "transaction_amt": 352.41,
  "merchant_initiated": false,
  "fuel": [
    {
      "pump_number": 1,
      "product_code": "DIESEL_ULSD",
      "retail_price_per_unit": 3.999,
      "cost_price_per_unit": 3.65,
      "volume": 88.124,
      "amount": 352.41,
      "unit_of_measure": "GALLON",
      "taxes": [
        {
          "tax_code": "FEDERAL",
          "amount": 15.42
        },
        {
          "tax_code": "STATE",
          "amount": 12.11
        }
      ]
    }
  ],
  "payment_code": "75123456"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp Capture_example
using RestSharp;

var client = new RestClient("https://pos.fuel.greenlane.ai/gfp/capture");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"merchant_id\": \"merchant-id\",\n  \"site_id\": \"441\",\n  \"transaction_id\": \"123abcd\",\n  \"transaction_time_ms\": 1787636532000,\n  \"transaction_amt\": 352.41,\n  \"merchant_initiated\": false,\n  \"fuel\": [\n    {\n      \"pump_number\": 1,\n      \"product_code\": \"DIESEL_ULSD\",\n      \"retail_price_per_unit\": 3.999,\n      \"cost_price_per_unit\": 3.65,\n      \"volume\": 88.124,\n      \"amount\": 352.41,\n      \"unit_of_measure\": \"GALLON\",\n      \"taxes\": [\n        {\n          \"tax_code\": \"FEDERAL\",\n          \"amount\": 15.42\n        },\n        {\n          \"tax_code\": \"STATE\",\n          \"amount\": 12.11\n        }\n      ]\n    }\n  ],\n  \"payment_code\": \"75123456\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Capture_example
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "merchant_id": "merchant-id",
  "site_id": "441",
  "transaction_id": "123abcd",
  "transaction_time_ms": 1787636532000,
  "transaction_amt": 352.41,
  "merchant_initiated": false,
  "fuel": [
    [
      "pump_number": 1,
      "product_code": "DIESEL_ULSD",
      "retail_price_per_unit": 3.999,
      "cost_price_per_unit": 3.65,
      "volume": 88.124,
      "amount": 352.41,
      "unit_of_measure": "GALLON",
      "taxes": [
        [
          "tax_code": "FEDERAL",
          "amount": 15.42
        ],
        [
          "tax_code": "STATE",
          "amount": 12.11
        ]
      ]
    ]
  ],
  "payment_code": "75123456"
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://pos.fuel.greenlane.ai/gfp/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()
```