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

# Process Payment

## [API Reference](/virtual-card-agent/process/create)

Once you've identified an invoice that supports card payment, you can process the payment by triggering a [processing job](/virtual-card-agent/process/create). This involves submitting the invoice document along with the virtual card details.

You can view the details of the Process jobs in the [admin dashboard](https://mercoa.com/dashboard/admin/payment-gateway-jobs).

### Request

POST [https://api.mercoa.com/payment-gateway/process](https://api.mercoa.com/payment-gateway/process)

**`Direct`**

```curl Direct
curl -X POST https://api.mercoa.com/payment-gateway/process \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{
  "type": "document",
  "cardDetails": {
    "type": "direct",
    "cardNumber": "4242424242424242",
    "country": "US",
    "cvv": "123",
    "expirationMonth": 10,
    "expirationYear": 2025,
    "firstName": "John",
    "lastName": "Doe",
    "postalCode": "12345",
    "achDetails": {
      "routingNumber": "123456789",
      "accountNumber": "987654321",
      "accountName": "John Doe"
    }
  },
  "document": "data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg=="
}'
```

**`Direct`**

```python Direct
import requests

url = "https://api.mercoa.com/payment-gateway/process"

payload = {
    "type": "document",
    "cardDetails": {
        "type": "direct",
        "cardNumber": "4242424242424242",
        "country": "US",
        "cvv": "123",
        "expirationMonth": 10,
        "expirationYear": 2025,
        "firstName": "John",
        "lastName": "Doe",
        "postalCode": "12345",
        "achDetails": {
            "routingNumber": "123456789",
            "accountNumber": "987654321",
            "accountName": "John Doe"
        }
    },
    "document": "data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg=="
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

**`Direct`**

```typescript Direct
import { MercoaClient } from "@mercoa/javascript";

const client = new MercoaClient({ token: "YOUR_TOKEN" });
await client.paymentGateway.process.create({
    type: "document",
    document: "data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg==",
    cardDetails: {
        type: "direct",
        firstName: "John",
        lastName: "Doe",
        cardNumber: "4242424242424242",
        expirationMonth: 10,
        expirationYear: 2025,
        cvv: "123",
        postalCode: "12345",
        country: "US",
        achDetails: {
            routingNumber: "123456789",
            accountNumber: "987654321",
            accountName: "John Doe"
        }
    }
});

```

**`Direct`**

```go Direct
package main

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

func main() {

	url := "https://api.mercoa.com/payment-gateway/process"

	payload := strings.NewReader("{\n  \"type\": \"document\",\n  \"cardDetails\": {\n    \"type\": \"direct\",\n    \"cardNumber\": \"4242424242424242\",\n    \"country\": \"US\",\n    \"cvv\": \"123\",\n    \"expirationMonth\": 10,\n    \"expirationYear\": 2025,\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"postalCode\": \"12345\",\n    \"achDetails\": {\n      \"routingNumber\": \"123456789\",\n      \"accountNumber\": \"987654321\",\n      \"accountName\": \"John Doe\"\n    }\n  },\n  \"document\": \"data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg==\"\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))

}
```

**`Direct`**

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

url = URI("https://api.mercoa.com/payment-gateway/process")

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  \"type\": \"document\",\n  \"cardDetails\": {\n    \"type\": \"direct\",\n    \"cardNumber\": \"4242424242424242\",\n    \"country\": \"US\",\n    \"cvv\": \"123\",\n    \"expirationMonth\": 10,\n    \"expirationYear\": 2025,\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"postalCode\": \"12345\",\n    \"achDetails\": {\n      \"routingNumber\": \"123456789\",\n      \"accountNumber\": \"987654321\",\n      \"accountName\": \"John Doe\"\n    }\n  },\n  \"document\": \"data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg==\"\n}"

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

**`Direct`**

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

HttpResponse<String> response = Unirest.post("https://api.mercoa.com/payment-gateway/process")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"type\": \"document\",\n  \"cardDetails\": {\n    \"type\": \"direct\",\n    \"cardNumber\": \"4242424242424242\",\n    \"country\": \"US\",\n    \"cvv\": \"123\",\n    \"expirationMonth\": 10,\n    \"expirationYear\": 2025,\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"postalCode\": \"12345\",\n    \"achDetails\": {\n      \"routingNumber\": \"123456789\",\n      \"accountNumber\": \"987654321\",\n      \"accountName\": \"John Doe\"\n    }\n  },\n  \"document\": \"data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg==\"\n}")
  .asString();
```

**`Direct`**

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.mercoa.com/payment-gateway/process', [
  'body' => '{
  "type": "document",
  "cardDetails": {
    "type": "direct",
    "cardNumber": "4242424242424242",
    "country": "US",
    "cvv": "123",
    "expirationMonth": 10,
    "expirationYear": 2025,
    "firstName": "John",
    "lastName": "Doe",
    "postalCode": "12345",
    "achDetails": {
      "routingNumber": "123456789",
      "accountNumber": "987654321",
      "accountName": "John Doe"
    }
  },
  "document": "data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg=="
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

**`Direct`**

```csharp Direct
using RestSharp;

var client = new RestClient("https://api.mercoa.com/payment-gateway/process");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"type\": \"document\",\n  \"cardDetails\": {\n    \"type\": \"direct\",\n    \"cardNumber\": \"4242424242424242\",\n    \"country\": \"US\",\n    \"cvv\": \"123\",\n    \"expirationMonth\": 10,\n    \"expirationYear\": 2025,\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"postalCode\": \"12345\",\n    \"achDetails\": {\n      \"routingNumber\": \"123456789\",\n      \"accountNumber\": \"987654321\",\n      \"accountName\": \"John Doe\"\n    }\n  },\n  \"document\": \"data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg==\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

**`Direct`**

```swift Direct
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "type": "document",
  "cardDetails": [
    "type": "direct",
    "cardNumber": "4242424242424242",
    "country": "US",
    "cvv": "123",
    "expirationMonth": 10,
    "expirationYear": 2025,
    "firstName": "John",
    "lastName": "Doe",
    "postalCode": "12345",
    "achDetails": [
      "routingNumber": "123456789",
      "accountNumber": "987654321",
      "accountName": "John Doe"
    ]
  ],
  "document": "data:application/pdf;base64,JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1BhZ2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAgL0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVudCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAvU3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21hbgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29udGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBUagogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAwMDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAgICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg=="
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/payment-gateway/process")! 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()
```

## Provide Card Details

To provide virtual card details to the Virtual Card Agent:

1. Generate the virtual card through your issuing partner.
2. Submit the card details to the Virtual Card Agent using one of the following methods.

### iFrame Card Details (Recommended)

The recommended approach is to provide an **iFrame link** containing the card details or use one of our [native integrations](/virtual-card-agent/process-card-payments/process-payment#native-integrations). The Virtual Card Agent will access this iFrame to retrieve the card data securely.

* The iFrame should display **only the card details** (card number, expiration date, CVV).
* All required authentication should be embedded within the iFrame URL as query parameters or session tokens.
* This method avoids direct transmission of sensitive card data and maintains PCI compliance.

**Note**: Ensure that the iFrame is lightweight, renders quickly, and does not include any additional content beyond the card details.

```json
{
  "type": "html",
  "html": "<html><body><h1>Invoice Details</h1><a href=\"https://www.payment-gateway.com/invoice/123123\">Pay Invoice</a></body></html>",
  "cardDetails": {
    "type": "iframe",
    "firstName": "John",
    "lastName": "Doe",
    "postalCode": "12345",
    "country": "US",
    "iframeUrl": "https://www.myvirtualcard.com/iframe/345345"
  }
}
```

### Native Integrations

Mercoa supports native integrations with the following issuing partners:

* [Stripe Issuing](/virtual-card-agent/process-card-payments/stripe-issuing)
* [Lithic](/virtual-card-agent/process-card-payments/lithic)
* [Marqeta](/virtual-card-agent/process-card-payments/marqeta)

We are actively working to expand support for additional issuing partners. To request integration with your preferred partner, contact us at [support@mercoa.com](mailto:support@mercoa.com).

### Direct Card Details

We strongly recommend using an iFrame link or native integration to provide card details. Avoid including card information directly in the request body to reduce exposure of sensitive data.

```json
{
  "type": "document",
  "document": "data:application/pdf;base64,...",
  "cardDetails": {
    "type": "direct",
    "firstName": "John",
    "lastName": "Doe",
    "cardNumber": "4242424242424242",
    "expirationMonth": 10,
    "expirationYear": 2025,
    "cvv": "123",
    "postalCode": "12345",
    "country": "US"
  }
}
```

**ACH Fallback**: To automatically avoid card processing fees, you can configure ACH fallback. See our [dedicated ACH Fallback documentation](/virtual-card-agent/ach-fallback) for complete details on setup and configuration.

## Job Pending State

While the payment job is in a pending state, the Virtual Card Agent performs the following steps:

* Navigates to the vendor’s payment portal
* Enters the provided card details
* Submits the payment
* Captures the payment receipt
* Returns a payment confirmation

### Successful Completion

When the payment is successfully processed, the job result will include:

* A **receipt URL** of the completed payment

### Failure Handling

If the agent is unable to complete the payment:

* **No funds are moved.**
* The job result will include a **descriptive error message** explaining the reason for the failure.

### Request

GET [https://api.mercoa.com/payment-gateway/process/\{jobId}](https://api.mercoa.com/payment-gateway/process/\{jobId})

**`Default`**

```curl Default
curl https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a \
     -H "Authorization: Bearer <token>"
```

**`Default`**

```python Default
import requests

url = "https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a"

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

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

print(response.json())
```

**`Default`**

```typescript Default
import { MercoaClient } from "@mercoa/javascript";

const client = new MercoaClient({ token: "YOUR_TOKEN" });
await client.paymentGateway.process.get("job_1a92b5f7-f522-435e-a953-fd649363730a");

```

**`Default`**

```go Default
package main

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

func main() {

	url := "https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a"

	req, _ := http.NewRequest("GET", 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))

}
```

**`Default`**

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

url = URI("https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a")

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

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

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

**`Default`**

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

HttpResponse<String> response = Unirest.get("https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a")
  .header("Authorization", "Bearer <token>")
  .asString();
```

**`Default`**

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

**`Default`**

```csharp Default
using RestSharp;

var client = new RestClient("https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

**`Default`**

```swift Default
import Foundation

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.mercoa.com/payment-gateway/process/job_1a92b5f7-f522-435e-a953-fd649363730a")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
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()
```

```json
{
  "jobStatus": "success",
  "jobId": "pgp_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
  "receiptUrl": "https://www.payment-gateway.com/receipt/123123",
  "attempts": [{
    "id": "pgpa_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
    "status": "COMPLETED",
    "amount": 150.75,
    "receiptUrl": "https://www.payment-gateway.com/receipt/123123",
    "createdAt": "2024-01-01T00:00:00Z"
  }],
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-01T00:00:00Z"
}
```

## Job Completed Webhook

### Success Response

```json
{
  "jobStatus": "success",
  "jobId": "pgp_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
  "receiptUrl": "https://www.payment-gateway.com/receipt/123123",
  "attempts": [{
    "id": "pgpa_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
    "status": "COMPLETED",
    "amount": 150.75,
    "receiptUrl": "https://www.payment-gateway.com/receipt/123123",
    "createdAt": "2024-01-01T00:00:00Z"
  }],
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-01T00:00:00Z"
}
```

### Failure Response

```json
{
  "jobStatus": "failed",
  "jobId": "pgp_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
  "errorType": "NO_VALID_PAYMENT_GATEWAY_FOUND",
  "errorMessage": "No valid payment gateway was found in the document or HTML",
  "attempts": [],
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-01T00:00:00Z"
}
```

### Response Fields

| Field          | Type   | Description                                                             |
| -------------- | ------ | ----------------------------------------------------------------------- |
| `jobStatus`    | string | Status of the job: `success`, `failed`, or `pending`.                   |
| `jobId`        | string | Unique identifier for the processing job.                               |
| `receiptUrl`   | string | URL of the payment receipt downloaded from the vendor portal.           |
| `attempts`     | array  | List of payment gateway attempts for this job.                          |
| `createdAt`    | string | The timestamp when the job was created.                                 |
| `updatedAt`    | string | The timestamp when the job was last updated.                            |
| `errorType`    | string | Error code, present only if the job failed.                             |
| `errorMessage` | string | Human-readable explanation of the failure, present only on job failure. |

## Webhooks

Mercoa sends webhook notifications when Virtual Card Agent processing jobs complete. You can configure these webhooks in the [Mercoa Developer Portal](https://mercoa.com/dashboard/developers).

### Processing Job Completed

When a Virtual Card Agent processing job completes (either successfully or with an error), a webhook with the event type `paymentGateway.process.completed` is sent to your configured webhook endpoint.

**Webhook Payload:**

```json
{
  "eventType": "paymentGateway.process.completed",
  "jobId": "pgp_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
  "data": {
    "jobStatus": "success",
    "jobId": "pgp_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
    "receiptUrl": "https://www.payment-gateway.com/receipt/123123",
    "attempts": [{
      "id": "pgpa_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
      "status": "COMPLETED",
      "amount": 150.75,
      "receiptUrl": "https://www.payment-gateway.com/receipt/123123",
      "createdAt": "2024-01-01T00:00:00Z"
    }],
    "createdAt": "2024-01-01T00:00:00Z",
    "updatedAt": "2024-01-01T00:00:00Z"
  }
}
```

### Error Handling

If a job fails, the webhook will include error information in the response:

```json
{
  "eventType": "paymentGateway.process.completed",
  "jobId": "pgp_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
  "data": {
    "jobStatus": "failed",
    "jobId": "pgp_8f86116b-3b4d-4ded-99ef-3bc929d8c33c",
    "errorType": "NO_VALID_PAYMENT_GATEWAY_FOUND",
    "errorMessage": "No valid payment gateway was found in the document or HTML",
    "createdAt": "2024-01-01T00:00:00Z",
    "updatedAt": "2024-01-01T00:00:00Z"
  }
}
```

For more information about webhooks, see our [Webhooks documentation](/api-reference/webhooks/payment-gateway-process-job-completed).