Payments API
Process payments, manage payouts, and handle settlement with AI-powered processor selection.
Overview
The Payments API provides:
- Payment Processing — Multiple payment methods
- AI Processor Selection — Contextual Multi-Armed Bandit optimization
- Daily Settlement — Automated payout settlement
- Dual Custody — TerraPay and Escrow.com integration
Base URL
https://api.huntrecht.com/api/v1/payments
Required Scopes
| Scope | Permission |
|---|---|
payments:read | View payments |
payments:write | Process payments |
Process Payment
POST /payments
Process a payment for an order or subscription.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
customer_id | string | Yes | Customer ID |
amount | number | Yes | Payment amount |
currency | string | Yes | Currency code (USD, EUR, etc.) |
payment_method | string | Yes | bank_transfer, card, link |
order_id | string | No | Associated order ID |
subscription_id | string | No | Associated subscription ID |
processor | string | No | Specific processor (auto-select if omitted) |
Example Request
payment = client.payments.create({
"customer_id": "cust_abc123",
"amount": 2050.00,
"currency": "USD",
"payment_method": "bank_transfer",
"order_id": "ord_xyz789"
})
Example Response
{
"id": "pay_abc123",
"customer_id": "cust_abc123",
"amount": 2050.00,
"currency": "USD",
"status": "pending",
"payment_method": "bank_transfer",
"processor": "circle",
"processor_reference": "pay_circle_123",
"order_id": "ord_xyz789",
"created_at": "2026-01-11T10:00:00Z",
"estimated_settlement": "2026-01-12T00:00:00Z"
}
AI Processor Selection
The system uses a Contextual Multi-Armed Bandit algorithm to select the optimal payment processor:
graph TD
A[Payment Request] --> B[Context Analysis]
B --> C{Feature Extraction}
C --> D[Amount]
C --> E[Customer History]
C --> F[Region]
C --> G[Time]
D --> H[ML Model]
E --> H
F --> H
G --> H
H --> I[Processor Scores]
I --> J[Selected Processor]
J --> K[Circle / Payoneer / Shopify]
Supported Processors
| Processor | Best For | Settlement Time |
|---|---|---|
| Circle | USDC, cross-border | Near-instant |
| Shopify Payments | Shopify orders | 2-3 business days |
| Payoneer | Cross-border B2B | 1-2 business days |
| TerraPay | Dual custody | 1 business day |
| Escrow.com | High-value transactions | 3-5 business days |
List Payments
GET /payments
Retrieve payments with filtering.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
customer_id | string | Filter by customer |
status | string | pending, completed, failed, refunded |
order_id | string | Filter by order |
start_date | string | Filter by created date |
end_date | string | Filter by created date |
page | integer | Page number |
limit | integer | Results per page |
payments = client.payments.list(
customer_id="cust_abc123",
status="completed",
page=1,
limit=20
)
Get Payment
GET /payments/{payment_id}
Retrieve payment details including processor information.
payment = client.payments.get("pay_abc123")
Response
{
"id": "pay_abc123",
"customer_id": "cust_abc123",
"amount": 2050.00,
"currency": "USD",
"status": "completed",
"payment_method": "bank_transfer",
"processor": "circle",
"processor_reference": "pay_circle_123",
"processor_status": "settled",
"order_id": "ord_xyz789",
"fees": 10.25,
"net_amount": 2039.75,
"settlement_id": "settle_abc123",
"completed_at": "2026-01-11T10:05:00Z",
"metadata": {
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0..."
}
}
Request Payout
POST /payments/payout
Request payout for available balance.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Payout amount |
currency | string | Yes | Currency code |
bank_account_id | string | Yes | Destination bank account |
processor | string | No | Preferred processor |
payout = client.payments.request_payout({
"amount": 10000.00,
"currency": "USD",
"bank_account_id": "bank_abc123",
"processor": "circle"
})
Payout Response
{
"id": "payout_xyz789",
"amount": 10000.00,
"currency": "USD",
"status": "pending",
"processor": "circle",
"bank_account_id": "bank_abc123",
"estimated_arrival": "2026-01-12T00:00:00Z",
"fees": 25.00,
"net_amount": 9975.00,
"created_at": "2026-01-11T10:00:00Z"
}
Refund Payment
POST /payments/{payment_id}/refund
Process a refund for a completed payment.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | No | Refund amount (full if omitted) |
reason | string | Yes | Refund reason |
refund = client.payments.refund(
payment_id="pay_abc123",
amount=1025.00,
reason="Partial order cancellation"
)
Payment Status Flow
stateDiagram-v2
[*] --> pending: Created
pending --> processing: Processor Selected
processing --> completed: Payment Successful
processing --> failed: Payment Failed
processing --> requires_action: 3DS Required
requires_action --> completed: Verification Passed
requires_action --> failed: Verification Failed
completed --> refunded: Refund Processed
completed --> [*]
failed --> [*]
Webhook Events
| Event | Description |
|---|---|
payment.created | Payment initiated |
payment.completed | Payment successful |
payment.failed | Payment failed |
payment.refunded | Refund processed |
payout.created | Payout initiated |
payout.completed | Payout completed |
payout.failed | Payout failed |
Error Codes
| Code | Description |
|---|---|
PAYMENT_NOT_FOUND | Payment ID not found |
INSUFFICIENT_FUNDS | Insufficient balance |
PROCESSOR_ERROR | Payment processor error |
INVALID_BANK_ACCOUNT | Bank account invalid |
DUPLICATE_PAYMENT | Duplicate payment detected |
Next Steps
- Settlement Guide
- Circle Integration
- AI Processor Selection