Capture Authorized Payment
Capture funds from a previously authorized payment intent.
Endpoint
GET /api/v2/intents/{intent_id}/capture
Authentication: Required (API Key)
Description
This endpoint allows you to capture funds from a payment that has been authorized but not yet captured. This is used when you create a payment intent with capture_mode: "prefer_delay" and the payment method supports delayed capture (e.g., credit cards).
Authorization vs Capture
In a two-step payment flow:
- Authorization - Reserves the funds on the customer's payment method without actually transferring them. The customer's available balance is reduced, but you haven't received the money yet.
- Capture - Transfers the authorized funds from the customer to your account.
This separation allows you to:
- Verify inventory availability before charging
- Confirm service delivery before payment
- Adjust the final amount (if supported by the PSP)
- Cancel the authorization if needed
When to Use
Use delayed capture when:
- You need to verify inventory before charging
- You want to confirm order details before finalizing payment
- You're shipping physical goods and want to charge at shipment time
- You need to perform fraud checks before capturing funds
Request
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer token with your API key |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
intent_id | string (UUID) | Yes | The ID of the authorized payment intent |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
merchant_id | string | No | Your merchant ID (optional, auto-detected from key) |
iauth | string | No | Intent authentication token (alternative to API key) |
Example Request
curl -X GET https://app.infinic.com/api/v2/intents/550e8400-e29b-41d4-a716-446655440000/capture \
-H "Authorization: Bearer YOUR_API_KEY"
curl -X GET "https://app.infinic.com/api/v2/intents/550e8400-e29b-41d4-a716-446655440000/capture?iauth=eyJ0eXAiOiJKV1QiLCJhbGc..."
const intentId = "550e8400-e29b-41d4-a716-446655440000";
const response = await fetch(
`https://app.infinic.com/api/v2/intents/${intentId}/capture`,
{
method: "GET",
headers: {
Authorization: `Bearer ${YOUR_API_KEY}`,
},
},
);
const data = await response.json();
console.log("Capture result:", data);
import requests
intent_id = '550e8400-e29b-41d4-a716-446655440000'
response = requests.get(
f'https://app.infinic.com/api/v2/intents/{intent_id}/capture',
headers={
'Authorization': f'Bearer {YOUR_API_KEY}'
}
)
data = response.json()
print('Capture result:', data)
Response
Success Response (200 OK)
The response contains details about the captured payment attempt.
{
"id": 12345,
"attempt_status": "success",
"method": "card",
"failure_reason": null,
"intent_id": "550e8400-e29b-41d4-a716-446655440000",
"intent_status": "success",
"action": null,
"redirect_url": null
}
| Field | Type | Description |
|---|---|---|
id | integer | Unique payment attempt identifier |
attempt_status | string | Status of the attempt (success, pending, failed) |
method | string | Payment method used (e.g., card) |
failure_reason | string / null | Reason for failure (null if successful) |
intent_id | string (UUID) | Associated payment intent ID |
intent_status | string | Status of the intent (success, pending, failed) |
action | object / null | Additional action required (usually null) |
redirect_url | string / null | Redirect URL (usually null) |
Error Responses
401 Unauthorized
{
"detail": "Invalid or missing API key"
}
Causes:
- Missing Authorization header
- Invalid API key
- Using sandbox key with production URL (or vice versa)
403 Forbidden
{
"detail": "Not authorized to capture this payment"
}
Causes:
- Intent belongs to different merchant
- Invalid
iauthtoken - Insufficient permissions
404 Not Found
{
"detail": "Payment intent not found"
}
Causes:
- Invalid intent_id
- Intent does not exist
- Intent has been deleted
422 Validation Error
{
"detail": "Payment intent is not in authorized status"
}
Causes:
- Intent is not in
authorizedstatus - Payment has already been captured
- Authorization has expired
- Payment was canceled
Other possible errors:
{
"detail": "Capture failed: Authorization expired"
}
{
"detail": "Capture not supported for this payment method"
}
Payment Flow
Complete Delayed Capture Flow
- Create Intent with
capture_mode: "prefer_delay"
{
"amount": 10000,
"currency": "ZAR",
"reference_id": "order_12345",
"purchaser_id": "customer_abc",
"return_url": "https://yoursite.com/payment/callback",
"allow_remember_credentials": false,
"capture_mode": "prefer_delay"
}
- Customer Completes Payment - Intent status becomes
authorized - Verify Order/Inventory - Your business logic
- Capture Payment - Call this endpoint
- Receive Success Webhook - Intent status becomes
success
Status Transitions
selection → pending → authorized → success
↓
canceled
Important Notes
Authorization Window
- Most payment providers hold authorizations for 7 days
- Some providers may have shorter or longer windows
- After expiration, authorizations are automatically canceled
- You cannot capture an expired authorization
Partial Captures
Currently, NjiaPay does not support partial captures. The full authorized amount will be captured.
Multiple Captures
You cannot capture the same authorization multiple times. Once captured, the payment is complete.
Payment Method Support
Not all payment methods support delayed capture:
- Supported: Credit cards, debit cards
- Not Supported: Bank transfers, mobile money, vouchers
If you use capture_mode: "prefer_delay" with an unsupported method, it will be captured immediately.
Webhook Notifications
After a successful capture, you'll receive a webhook notification:
{
"type": "StatusChange",
"created": "2024-09-01T00:00:00Z",
"content": {
"intent_id": "550e8400-e29b-41d4-a716-446655440000",
"reference_id": "order_12345",
"purchaser_id": "customer_abc",
"amount": 10000,
"currency": "ZAR",
"status": "success",
"partner": "adyen",
"method": "card",
"brand": "visa",
"event_ts": "2024-09-01T10:30:00Z"
}
}
Best Practices
1. Capture Promptly
Capture payments as soon as you're ready to fulfill the order. Don't wait until the last minute before expiration.
2. Handle Expiration
Set up monitoring to track authorized payments and capture them before they expire. Send reminders to your operations team.
3. Error Handling
Always handle capture errors gracefully:
- Retry transient failures
- Notify customers if capture fails
- Have a process for expired authorizations
4. Webhook Integration
Rely on webhook notifications for status updates rather than polling the API.
5. Testing
Test the full delayed capture flow in the sandbox environment:
- Create an authorized payment
- Capture it successfully
- Test expiration scenarios
- Test failed captures
Use Cases
- E-commerce - Authorize at checkout, capture at shipment
- Hotels - Authorize at booking, capture at check-in
- Rentals - Authorize at reservation, capture after service
- Custom Orders - Authorize upfront, capture when ready
- Fraud Prevention - Authorize first, review for fraud, then capture
Next Steps
After capturing a payment:
- Fulfill the order - Ship products or deliver services
- Update your system - Mark order as paid
- Notify customer - Send confirmation email