Welcome to the Expi API documentation. All endpoints are accessed via the central query handler.
The API is built for quick integration: send JSON requests, receive JSON responses, and keep all payment workflows in one place. Use it to build custom checkout experiences, manage customers, issue invoices, and automate recurring billing with minimal overhead.
If you are new to the platform, start with Authentication, then explore the endpoint sections for the resources you need. Each section highlights core fields and common workflows.
https://your-domain.com/query
Every request must be authenticated. You can do this via Basic Auth or by including credentials in the JSON body. Pick one method and keep it consistent across your integration.
Use your merchant username as x_login and your secret key as x_tran_key. These are required for all endpoints that hit the query handler.
POST /query/login — Exchanges an application username/password for a Bearer token.GET /query/me — Returns the current authenticated user and merchant context (requires authentication).{
"username": "user@example.com",
"password": "your_password"
}
Authorization: Bearer <access_token>
Authorization: Basic <base64(username:secret_key)>
Base64 must be generated from the exact string username:secret_key (one colon, no extra spaces).
{
"x_login": "your_username",
"x_tran_key": "your_secret_key"
}
Streamline Transactions with Expitrans API
Our REST API allows developers to integrate online payment functionalities into their applications. By making API requests, you can process transactions, manage customers, handle subscriptions, and generate invoices programmatically.
The API uses JSON format for requests and responses, ensuring seamless communication between your application and our payment gateway. Authentication is required for secure access, and each request must include the necessary credentials.
Our REST API provides several key functionalities:
These endpoints allow businesses to automate payment workflows and enhance their integration capabilities. In the next sections, we’ll provide detailed instructions on how to use each API.
Create short-lived card tokens for use with the Charges API.
Authentication:
- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)
- or Authorization: Basic (merchant x_login / x_tran_key)
- or include x_login and x_tran_key in the JSON body
| Field | Type | Required | Description |
|---|---|---|---|
number | string | Yes | 16-digit card number. |
month | string | Yes | 2-digit month 01–12. |
year | string | Yes | 2-digit year YY. |
x_login | string | No | Merchant login (only if not using Authorization header). |
x_tran_key | string | No | Merchant tran key/secret (only if not using Authorization header). |
{
"number": "4242424242424242",
"month": "12",
"year": "30"
}
{
"result": "success",
"token": "tok_..."
}
429 with Retry-After.Charge operations backed by Transactions. A charge id corresponds to the Transaction presentation_id within the authenticated merchant scope.
Authentication:
- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)
- or Authorization: Basic (merchant x_login / x_tran_key)
- or include x_login and x_tran_key in the JSON body
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Conditional | Token from /tokens. Required unless charging with payment_method_id. |
payment_method_id | number | Conditional | Existing saved payment method id (CustomerDetails). Required unless charging with token. Aliases: x_payment_id, paymentmethodid. |
cvc | string | Conditional | Required for token-based charges. Provide at charge time (do not store). You can also pass billing.cvc. |
amount | number | Yes | Charge amount. |
transtype | string | No | Defaults to AUTH_CAPTURE. Use AUTH_ONLY for auth-then-capture flows. |
billing | object | No | Billing/contact fields (first_name, last_name, address, city, state, zip, country, phone, email, description). |
customer_id | number | No | Optional customer id. When charging with payment_method_id, if provided it must match the payment method’s customer. |
save_payment_method | boolean | No | If true, creates a customer/payment method (if needed) and charges it. Requires token-based charge (raw card data is needed). |
use_customer_profile | boolean | No | If true and customer_id is set, instructs the gateway to use the stored customer profile where supported. Auto-enabled for payment_method_id charges. |
x_login | string | No | Merchant login (only if not using Authorization header). |
x_tran_key | string | No | Merchant tran key/secret (only if not using Authorization header). |
{
"token": "tok_...",
"cvc": "123",
"amount": 12.34,
"transtype": "AUTH_CAPTURE",
"billing": {
"first_name": "Jane",
"last_name": "Smith",
"address": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "USA",
"email": "jane@example.com",
"phone": "5550123",
"description": "Online Purchase"
}
}
{
"payment_method_id": 12345,
"customer_id": 67890,
"amount": 12.34,
"transtype": "AUTH_CAPTURE"
}
{
"token": "tok_...",
"cvc": "123",
"amount": 12.34,
"save_payment_method": true,
"billing": {
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"company": "Acme Inc",
"address": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "USA",
"phone": "5550123"
}
}
{
"result": "success",
"charge": {
"id": 123456,
"transaction_id": 98765,
"amount": 12.34,
"currency": "USD",
"status": 1,
"status_text": "succeeded",
"type": 1,
"created": "...",
"description": "Online Purchase",
"notes": null,
"reference_id": 0,
"last4": "4242"
},
"customer_id": 67890,
"payment_method_id": 12345,
"transaction": {
"status": 1,
"status_text": "Success",
"reason_text": "...",
"transaction_id": "123456"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | No | Optional capture amount (omit for full capture where supported). |
x_login | string | No | Merchant login (only if not using Authorization header). |
x_tran_key | string | No | Merchant tran key/secret (only if not using Authorization header). |
{
"amount": 12.34
}
429 with Retry-After.description and notes only.amount and either token or payment_method_id.cvc (or billing.cvc). CVC is not stored in tokens.payment_method_id, customer_id is optional but (if provided) must match.save_payment_method requires a token-based charge.Transaction records are backed by the transactions table. A transaction uniqueID corresponds to the Transaction presentation_id within the authenticated merchant scope.
POST /query/transaction creates a transaction record only. It does not run a gateway charge.
Use /charges to actually process a payment.
Raw card data (PAN/CVC/exp/routing/account) is rejected.
status is always forced to Unprocessed on create and cannot be set via this endpoint.
customer_id.
On create, if customer_id is omitted, the API will create a customer record using either a provided customer object or the provided billing/shipping fields.
Authentication:
- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)
- or Authorization: Basic (merchant x_login / x_tran_key)
- or include x_login and x_tran_key in the JSON body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Transaction amount. |
description | string | No | Optional description. |
notes | string | No | Optional notes. |
transtype | string|number | No | Defaults to AuthCapture. Accepts string or numeric code. |
status | string|number | No | Not accepted on create. Always stored as Unprocessed. |
state | string|number | No | Defaults to Unknown. Accepts string or numeric code. |
source | string|number | No | Defaults to Endpoint. Accepts string or numeric code. |
transdate | string | No | Optional transaction timestamp (if omitted, DB/defaults apply). |
invoice_id | number | No | Optional link to an invoice (maps to invoicing_id). |
invoice | object | No | If provided and invoice_id is omitted, an invoice is created and linked. |
items / line_items | array | No | Optional line items. Stored on the linked invoice as invoice details. If no invoice context is supplied, an invoice will be created (requires customer_id or enough customer/billing data to create one). |
customer_id | number | No | Customer association. If omitted, a customer record is created from customer or billing/shipping. |
customer | object | No | Optional customer payload used to create a customer when customer_id is omitted. |
payment_information.method | number|string | No | Non-sensitive payment method indicator (ex: CC, echeck, or numeric code). |
payment_information.last4 | string | No | Non-sensitive last 4 digits (stored as provided digits only). |
billing | object | No | Optional billing/contact fields (first_name, last_name, address, city, state, zip, country, phone, email). |
shipping | object | No | Optional shipping/contact fields (first_name, last_name, address, city, state, zip, country, phone, email). |
{
"amount": 12.34,
"description": "Order #1001",
"notes": "Recorded from mobile tap-to-pay",
"transtype": "AuthCapture",
"state": "Settled",
"transdate": "2026-01-29 12:34:56",
"payment_information": {
"method": "CC",
"last4": "4242"
},
"billing": {
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"phone": "555-555-5555"
},
"items": [
{"title": "T-Shirt", "quantity": 1, "unit_price": 12.34}
]
}
{
"result": "success",
"transaction": {
"uniqueID": 123456,
"transaction_id": 98765,
"customer_id": 555,
"amount": 12.34,
"currency": "USD",
"created": "...",
"description": "Order #1001",
"notes": "Created by integration",
"billing": {
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"phone": "555-555-5555",
"address": null,
"address2": null,
"city": null,
"state": null,
"zip": null,
"country": null
},
"shipping": {
"first_name": null,
"last_name": null,
"email": null,
"phone": null,
"address": null,
"address2": null,
"city": null,
"state": null,
"zip": null,
"country": null
},
"payment_information": {
"method": 16,
"last4": "4242"
},
"invoice": {},
"invoicing_id": null,
"reference_id": null,
"status": "Unprocessed",
"state": "Unknown",
"transtype": "AuthCapture",
"source": "Endpoint"
}
}
Refund operations backed by Transactions. Refunds are processed as gateway CREDIT transactions against an existing charge (Transaction presentation_id) within the authenticated merchant scope.
Authentication:
- Authorization: Bearer <access_token> (recommended if you use the login/JWT flow)
- or Authorization: Basic (merchant x_login / x_tran_key)
- or include x_login and x_tran_key in the JSON body
| Field | Type | Required | Description |
|---|---|---|---|
charge_id | number | Yes | Original charge Transaction presentation_id. Alias: transaction_id. |
amount | number | Yes | Refund amount. Must be greater than 0 and not exceed the original charge amount. |
notes | string | No | Optional notes sent to the gateway. |
x_login | string | No | Merchant login (only if not using Authorization header). |
x_tran_key | string | No | Merchant tran key/secret (only if not using Authorization header). |
{
"charge_id": 123456,
"amount": 12.34,
"notes": "Customer requested refund"
}
{
"result": "success",
"refund": {
"id": 222222,
"transaction_id": 98765,
"amount": 12.34,
"currency": "USD",
"status": 1,
"status_text": "succeeded",
"type": 4,
"created": "...",
"description": null,
"notes": null,
"reference_id": 0,
"last4": "4242"
},
"original_charge": {
"id": 123456,
"transaction_id": 12345,
"amount": 12.34,
"currency": "USD",
"status": 1,
"status_text": "succeeded",
"type": 1,
"created": "...",
"description": "Online Purchase",
"notes": null,
"reference_id": 0,
"last4": "4242"
},
"transaction": {
"status": 1,
"status_text": "Success",
"reason_text": "...",
"transaction_id": "222222"
}
}
CREDIT transactions referencing the original charge id.429 with Retry-After.Manage customer profiles with a single endpoint. Create customers and store contact, billing, and custom fields for downstream billing workflows.
{
"result": "success",
"customer": {
"uniqueID": 1234,
"customer_information": {
"firstname": "Alex",
"lastname": "Rivera",
"address1": "123 Market Street",
"address2": "",
"city": "San Francisco",
"state": "CA",
"zip": "94105",
"country": "USA",
"phone1": "4155550134",
"phone2": "",
"email": "alex.rivera@example.com"
},
"billing_information": {
"firstname": "Alex",
"lastname": "Rivera",
"address1": "123 Market Street",
"address2": "",
"city": "San Francisco",
"state": "CA",
"zip": "94105",
"country": "USA",
"phone": "4155550134",
"email": "alex.rivera@example.com"
},
"custom": {
"custom1": "A-1001",
"custom2": "Gold",
"custom3": "West",
"custom4": "",
"custom5": "",
"custom6": "",
"custom7": "",
"custom8": "",
"custom9": "",
"custom10": ""
},
"defaultPaymentID": 2002,
"customer_payments": [
{
"paymentID": 2001,
"paymenttype": "Credit Card",
"lastfour": "4242"
},
{
"paymentID": 2002,
"paymenttype": "Checking",
"lastfour": "6789"
}
]
}
}
{
"x_login": "...",
"x_tran_key": "...",
"customer": {
"customer_information": {
"firstname": "Jane",
"lastname": "Smith",
"email": "jane@example.com",
"phone1": "555-0123",
"address1": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
"billing_information": {
"firstname": "Jane",
"lastname": "Smith",
"address1": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
"custom": {
"custom1": "VIP Client"
}
}
}
{
"x_login": "...",
"x_tran_key": "...",
"_method": "PUT",
"customer": {
"customer_information": {
"firstname": "Jane",
"lastname": "Smith",
"email": "jane@example.com",
"phone1": "555-0123"
},
"billing_information": {
"address1": "456 Elm St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
"custom": {
"custom1": "VIP Client"
},
"customer_payments": [
{
"paymentID": 2002
}
]
}
}
Create and manage recurring billing schedules through the central query handler.
Required: customer_id, payment_id, and product_id are required to create a recurring schedule.
| Field | Required | Notes |
|---|---|---|
customer_id | Yes | Customer for the schedule. |
payment_id | No | Stored payment method for the customer. If omitted, uses the customer's default payment method when available; otherwise returns a failed response. |
product_id | Yes | Creates the recurring item; amount is product price + surcharge. |
interval | No | Overrides product rule: 1=Day, 2=Week, 3=Month, 4=Year. |
interval_number | No | Overrides product rule: interval multiplier. |
run_until | No | 0=Until terminated, 1=Specific date, 2=Fixed count. |
run_limit | No | Required when run_until is 2. |
end_date | No | Required when run_until is 1 (YYYY-MM-DD). |
run_next | No | Next run date (YYYY-MM-DD); ignored if run_transaction is true. |
surcharge | No | Added to product price for total amount. |
status | No | 1=Active, 2=Completed, 4=Paused, 5=Terminated. |
run_transaction | No | When true, runs immediately and recalculates next run. |
{
"x_login": "...",
"x_tran_key": "...",
"recurring": {
"customer_id": 123,
"payment_id": 456,
"product_id": 111,
"run_transaction": true,
"status": 1,
"interval": 2,
"interval_number": 1,
"run_until": 2,
"run_limit": 12,
"end_date": null,
"run_next": "2024-12-01",
"surcharge": 0.00
}
}
{
"x_login": "...",
"x_tran_key": "...",
"recurring": {
"customer_id": 123,
"payment_id": 456,
"product_id": 111,
"interval": 2,
"interval_number": 1,
"run_until": 2,
"run_limit": 12,
"run_next": "2024-12-01",
"surcharge": 3.50,
"status": 1
}
}
| Field | Required | Description |
|---|---|---|
uniqueID | No | Optional when calling /query/recurring/{id}; otherwise required. |
status | No | 1=Active, 2=Completed, 4=Paused, 5=Terminated. |
interval | No | 1=Day, 2=Week, 3=Month, 4=Year. |
interval_number | No | Number of intervals between runs. |
run_until | No | 0=Until terminated, 1=Specific date, 2=Fixed count. |
run_limit | No | Required when run_until is 2 (count). |
end_date | No | Required when run_until is 1 (YYYY-MM-DD). |
run_next | No | Next run date (YYYY-MM-DD). |
surcharge | No | Surcharge amount added to product price. |
payment_id | No | Stored payment method ID. |
Note: Recurring line items cannot be updated via the update endpoint.
{
"x_login": "...",
"x_tran_key": "...",
"_method": "PUT",
"recurring": {
"status": 1,
"interval": 2,
"interval_number": 1,
"run_until": 2,
"run_limit": 12,
"run_next": "2024-12-08"
}
}
Create and manage invoices.
Returns a paginated list of invoices. Supports optional filters:
| Filter | Description |
|---|---|
customer_id | Limit to a specific customer |
status | Invoice status (e.g., Pending, Sent, Paid) |
due_before | Invoices due before date (YYYY-MM-DD) |
due_after | Invoices due after date (YYYY-MM-DD) |
Returns a single invoice by unique ID. If not found, returns 404.
Note: Provide customer_id to associate with an existing customer. If customer_id is omitted, include a customer object to create a new customer.
{
"x_login": "...",
"x_tran_key": "...",
"invoice": {
"invoice_number": "INV-2024-001",
"due_date": "2024-12-31",
"notes": "Thank you for your business",
"discount": 0,
"tax": 10.50,
"shipping": 5.00,
"amount": 635.50,
"customer_id": 123,
"items": [
{
"title": "Web Design",
"description": "Homepage design",
"quantity": 1,
"unit_price": 500.00
},
{
"title": "Hosting",
"quantity": 12,
"unit_price": 10.00
}
]
}
}
{
"x_login": "...",
"x_tran_key": "...",
"_method": "PUT",
"invoice": {
"uniqueID": 456,
"notes": "Updated notes",
"status": "Sent"
}
}
DELETE /query/invoice/456
Manage products and services.
Returns a list of products. If none exist, returns an empty list: { "products": [] } with status 200.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Product name. |
description | string | No | Product description. |
price | number | No | Product price. |
isBookable | boolean | No | Marks product as bookable. |
duration | integer | No | Duration in minutes (for bookable products). |
is_recurring | boolean | No | Enable recurring schedule; provide recurring_rule when true. |
recurring_rule |
object | Conditional |
Recurring schedule config; required when is_recurring is true.
Format: {"interval":"1","interval_number":"1","run_limit":"7"}.
interval: 1=Day, 2=Week, 3=Month, 4=Year. interval_number: how many intervals between charges (e.g., 2 with interval=Week means every 2 weeks). run_limit: number of times to run; omit or use 0 for unlimited. |
{
"x_login": "...",
"x_tran_key": "...",
"product": {
"name": "Premium Service",
"description": "One hour consultation",
"price": 99.99,
"isBookable": true,
"duration": 60,
"is_recurring": true,
"recurring_rule": {
"interval": "1",
"interval_number": "1",
"run_limit": "7"
}
}
}
| Field | Type | Required | Description |
|---|---|---|---|
uniqueID | integer | No | Optional when calling /query/product/{id}; otherwise required. |
name | string | No | Product name. |
description | string | No | Product description. |
price | number | No | Product price. |
isBookable | boolean | No | Marks product as bookable. |
duration | integer | No | Duration in minutes (for bookable products). |
is_recurring | boolean | No | Enable recurring schedule; provide recurring_rule when true. |
recurring_rule |
object | Conditional |
Recurring schedule config; required when is_recurring is true.
Format: {"interval":"1","interval_number":"1","run_limit":"7"}.
interval: 1=Day, 2=Week, 3=Month, 4=Year. interval_number: how many intervals between charges (e.g., 2 with interval=Week means every 2 weeks). run_limit: number of times to run; omit or use 0 for unlimited. |
Notes:
- Omit fields you do not want to change.
- When setting is_recurring to false, the recurring schedule is cleared.
{
"x_login": "...",
"x_tran_key": "...",
"_method": "PUT",
"product": {
"name": "Updated Service Name",
"price": 149.99,
"isBookable": true,
"duration": 60,
"is_recurring": false,
"recurring_rule": {
"interval": "1",
"interval_number": "1",
"run_limit": "7"
}
}
}
Manage discount coupons.
Returns a list of coupons. If none exist, returns an empty list: { "coupons": [] } with status 200.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Coupon name. |
description | string | No | Coupon description. |
code | string | No | Coupon code customers enter. |
percent_off | number | No | Percent discount (e.g., 10 for 10% off). |
duration_type | string | No | Discount duration (e.g., once). |
first_purchase_only | boolean | No | Only apply to the first purchase. |
max_redemptions | integer | No | Maximum number of redemptions allowed. |
enabled | boolean | No | Enable/disable coupon. |
{
"x_login": "...",
"x_tran_key": "...",
"coupon": {
"name": "New Customer Discount",
"description": "10% off first purchase",
"code": "WELCOME10",
"percent_off": 10,
"duration_type": "once",
"first_purchase_only": true,
"max_redemptions": 100,
"enabled": true
}
}
| Field | Type | Required | Description |
|---|---|---|---|
uniqueID | integer | No | Optional when calling /query/coupon/{id}; otherwise required. |
name | string | No | Coupon name. |
description | string | No | Coupon description. |
code | string | No | Coupon code customers enter. |
percent_off | number | No | Percent discount. |
duration_type | string | No | Discount duration. |
first_purchase_only | boolean | No | Only apply to the first purchase. |
max_redemptions | integer | No | Maximum number of redemptions allowed. |
enabled | boolean | No | Enable/disable coupon. |
{
"x_login": "...",
"x_tran_key": "...",
"_method": "PUT",
"coupon": {
"name": "Updated Coupon Name",
"percent_off": 15,
"enabled": true
}
}
DELETE /query/coupon/123
Issue and manage cards via the central query handler. Primary-account endpoints require merchant authentication; the cardholder list-cards endpoint uses cardholder credentials in the body.
Two request sections:
Optional filters: search, type (virtual|physical), status.
GET /query/expicard
Returns full details (including PAN/CVC) for authorized merchant/enhanced users. The response includes card.id (the requested card ID) and card.token (partner token).
GET /query/expicard?uniqueID=CARD-12345
Lightweight, cached card summary without sensitive details; falls back to full read if unavailable. Includes card.id (requested card ID) and card.token (partner token).
GET /query/expicard?subaction=summary&uniqueID=CARD-12345
Body fields: first_name, last_name, email, amount, address_line1, city, state, zip, type (virtual|physical), cardholder_type (team_member|vendor|contractor), optional external_id.
{
"action": "expicard",
"subaction": "create",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"password": "TempPassword123",
"amount": 200.00,
"address_line1": "123 Main St",
"city": "Austin",
"state": "TX",
"zip": "78701",
"type": "virtual",
"cardholder_type": "team_member",
"external_id": "CARD-EXT-001"
}
{
"action": "expicard",
"subaction": "fund",
"uniqueID": "CARD-67890",
"amount": 50.00
}
Optional filters supported: from, to, status.
GET /query/expicard?subaction=transactions&uniqueID=CARD-12345&from=2025-10-01&to=2025-10-31&status=approved
Creates a funding bank (bank account) for a specific subaccount.
Body fields: subaccountId, bankAccountNumber, bankRoutingNumber. Additional fields may be included per partner requirements.
Note: The query handler lowercases top-level JSON keys. To avoid casing issues, you can send snake_case keys (bank_account_number, bank_routing_number) or nest fields under a bank object.
{
"action": "expicard",
"subaction": "subaccount_bank_create",
"subaccountId": "SUB-123456",
"bank_account_number": "1234567890",
"bank_routing_number": "021000021"
}
Note: Sensitive card detail fields are only returned to authorized merchant/enhanced users; summaries are optimized for portal views.
These endpoints do not require merchant authentication. They use merchant API credentials for partner access internally, but require cardholder username and password in the request body.
Response: Returns full card details for the authenticated cardholder, including sensitive fields such as full card number (PAN), CVC, and expiration. Handle this response securely.
Authentication: You can provide the cardholder username/password either in the body or via HTTP Basic Auth (recommended). When using Basic Auth, the body credentials are optional.
Authorization: Basic <base64(cardholder_username:cardholder_password)>
{
"action": "expicard",
"role": "user",
"subaction": "user_cards",
"username": "cardholder@example.com",
"password": "cardholderPassword"
}
Note: User endpoints restrict access to cards linked to the authenticated cardholder; sensitive fields are not returned.