Skip to main content

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​

ScopePermission
payments:readView payments
payments:writeProcess payments

Process Payment​

POST /payments

Process a payment for an order or subscription.

Request Body​

FieldTypeRequiredDescription
customer_idstringYesCustomer ID
amountnumberYesPayment amount
currencystringYesCurrency code (USD, EUR, etc.)
payment_methodstringYesbank_transfer, card, link
order_idstringNoAssociated order ID
subscription_idstringNoAssociated subscription ID
processorstringNoSpecific 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​

ProcessorBest ForSettlement Time
CircleUSDC, cross-borderNear-instant
Shopify PaymentsShopify orders2-3 business days
PayoneerCross-border B2B1-2 business days
TerraPayDual custody1 business day
Escrow.comHigh-value transactions3-5 business days

List Payments​

GET /payments

Retrieve payments with filtering.

Query Parameters​

ParameterTypeDescription
customer_idstringFilter by customer
statusstringpending, completed, failed, refunded
order_idstringFilter by order
start_datestringFilter by created date
end_datestringFilter by created date
pageintegerPage number
limitintegerResults 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​

FieldTypeRequiredDescription
amountnumberYesPayout amount
currencystringYesCurrency code
bank_account_idstringYesDestination bank account
processorstringNoPreferred 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​

FieldTypeRequiredDescription
amountnumberNoRefund amount (full if omitted)
reasonstringYesRefund 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​

EventDescription
payment.createdPayment initiated
payment.completedPayment successful
payment.failedPayment failed
payment.refundedRefund processed
payout.createdPayout initiated
payout.completedPayout completed
payout.failedPayout failed

Error Codes​

CodeDescription
PAYMENT_NOT_FOUNDPayment ID not found
INSUFFICIENT_FUNDSInsufficient balance
PROCESSOR_ERRORPayment processor error
INVALID_BANK_ACCOUNTBank account invalid
DUPLICATE_PAYMENTDuplicate payment detected

Next Steps​