Virtual Terminal
Process card-not-present transactions via the RapidCents API · Sale, Auth Only, Force, Refund
Summary
The RapidCents Virtual Terminal allows merchants to process card-not-present (CNP) transactions through the API. It supports manual card entry and saved (card-on-file) payments.
All Virtual Terminal endpoints require API authentication (Bearer token) and a valid business ID in the URL path.
Transaction Types
Sale
Authorize and capture a payment in a single step. Funds are immediately settled.
Auth Only
Authorize a payment without capturing. Reserves funds on the cardholder's account for later capture.
Force (Capture)
Capture a previously authorized (Auth Only) transaction. Converts a pre-auth into an actual charge.
Refund / Return
Return funds to the cardholder. Can be processed with manual card entry or saved card.
Transaction Lifecycle
Sale = Authorize + Capture (one step)
Auth Only → Force = Authorize first, then Capture later (two steps)
Refund = Return funds to cardholder
Processing Flow
- Merchant sends a transaction request (Sale, Auth Only, or Refund) to the RapidCents Virtual Terminal API with card details or a saved card ID.
- RapidCents validates the request, resolves the customer, and prepares the transaction payload.
- RapidCents submits the transaction to Visa, Mastercard, Discover, Amex.
- The card network returns an authorization response (approved / declined).
- RapidCents records the transaction, updates the wallet/batch, and returns the result to the merchant.
- If approved and automatic invoicing is enabled, an invoice email is sent to the customer.
Authentication
All Virtual Terminal endpoints require:
| Requirement | Details |
|---|---|
| Authorization Header | Bearer <access_token> |
| Business ID | Included in the URL path: /api/{business_id}/vt/... |
| Content-Type | application/json |
Sale (Credit Sale)
A Sale transaction authorizes and captures payment in a single step. Funds are settled immediately.
Sale — Manual Card Entry
POST /api/{business_id}/vt/sale
{
"cardEntryMethod": "0",
"customerId": "customer-uuid",
"amount": 25.00,
"cardData": {
"nameOnCard": "John Doe",
"cardNumber": "4111111111111111",
"month": 12,
"year": 2028,
"cvv": "123",
"saveCard": true
},
"description": "Order #1234",
"customInvoiceNumber": "INV-001"
}
Sale — Saved Card (Card on File)
POST /api/{business_id}/vt/customer/{customer_id}/sale
{
"amount": 25.00,
"cardId": "stored-card-uuid"
}
Response (Sale)
{
"ok": true,
"message": "Transaction approved",
"transaction": {
"id": "txn-uuid",
"status": "Approved",
"auth_code": "123456",
"amount": 25.00,
"type": "Sale"
}
}
Auth Only (Pre-Authorization)
An Auth Only transaction reserves funds on the cardholder's account without capturing. Use the Force endpoint to capture later.
Pre-authorized transactions must be captured (forced) before the authorization expires (typically 5-7 days depending on card network).
Auth Only — Manual Card Entry
POST /api/{business_id}/vt/pre-auth
{
"cardEntryMethod": "0",
"customerId": "customer-uuid",
"amount": 100.00,
"cardData": {
"nameOnCard": "Jane Smith",
"cardNumber": "4111111111111111",
"month": 6,
"year": 2027,
"cvv": "456",
"saveCard": false
}
}
Auth Only — Saved Card (Card on File)
POST /api/{business_id}/vt/customer/{customer_id}/pre-auth
{
"amount": 100.00,
"cardId": "stored-card-uuid"
}
Response (Auth Only)
{
"ok": true,
"message": "Transaction approved",
"transaction": {
"id": "txn-uuid",
"status": "Approved",
"auth_code": "789012",
"amount": 100.00,
"type": "Auth Only"
}
}
Force (Capture Pre-Auth)
A Force (capture) converts a previously authorized Auth Only transaction into a completed charge. The funds are moved from hold to settlement.
The amount in the force request can be equal to or less than the original pre-auth amount. You cannot force an amount greater than the original authorization.
POST /api/{business_id}/transactions/{transaction_id}/force
{
"amount": 100.00
}
Response (Force)
{
"ok": true,
"message": "Transaction captured successfully",
"transaction": {
"id": "txn-uuid",
"status": "Approved",
"amount": 100.00,
"type": "Force"
}
}
Auth Only → Force Workflow
- Submit an Auth Only request to
/api/{business_id}/vt/pre-auth. Note the returnedtransaction.id. - When ready to capture, submit a Force request to
/api/{business_id}/transactions/{transaction_id}/forcewith the desired amount. - The transaction is captured and funds move to settlement.
Refund / Return
A Refund (return) sends funds back to the cardholder. Can be processed with manual card entry or a saved card.
The business must have sufficient balance to process a refund. If the refund amount exceeds the available balance, the request will be rejected.
Refund — Manual Card Entry
POST /api/{business_id}/vt/return
{
"cardEntryMethod": "0",
"customerId": "customer-uuid",
"amount": 15.00,
"cardData": {
"nameOnCard": "John Doe",
"cardNumber": "4111111111111111",
"month": 12,
"year": 2028,
"cvv": "123"
}
}
Refund — Saved Card (Card on File)
POST /api/{business_id}/vt/customer/{customer_id}/return
{
"amount": 15.00,
"cardId": "stored-card-uuid"
}
Response (Refund)
{
"ok": true,
"message": "Refund processed successfully",
"transaction": {
"id": "txn-uuid",
"status": "Approved",
"amount": 15.00,
"type": "Return"
}
}
All Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /{business_id}/vt/sale |
Sale — manual card entry |
| POST | /{business_id}/vt/customer/{customer_id}/sale |
Sale — saved card |
| POST | /{business_id}/vt/pre-auth |
Auth Only — manual card entry |
| POST | /{business_id}/vt/customer/{customer_id}/pre-auth |
Auth Only — saved card |
| POST | /{business_id}/transactions/{transaction_id}/force |
Force (capture pre-auth) |
| POST | /{business_id}/vt/return |
Refund — manual card entry |
| POST | /{business_id}/vt/customer/{customer_id}/return |
Refund — saved card |
Card Data Fields
Manual Entry (cardEntryMethod: "0")
| Field | Type | Required | Description |
|---|---|---|---|
cardData.cardNumber | string | Yes | Full card number (PAN) |
cardData.month | integer | Yes | Expiration month (1-12) |
cardData.year | integer | Yes | Expiration year (e.g., 2028) |
cardData.cvv | string | No | Card verification value |
cardData.nameOnCard | string | No | Cardholder name |
cardData.saveCard | boolean | No | Save card for future use |
Saved Card (cardEntryMethod: "1")
| Field | Type | Required | Description |
|---|---|---|---|
cardId | string (UUID) | Yes | ID of the stored card |
Common Fields
| Field | Type | Required | Description |
|---|---|---|---|
amount | numeric | Yes | Transaction amount |
customerId | string (UUID) | Yes | Customer ID (auto-set to guest if omitted) |
description | string | No | Transaction description |
customInvoiceNumber | string | No | Custom invoice reference |
Error Handling
{
"ok": false,
"message": "Transaction declined",
"errors": {
"amount": ["The amount field is required."]
}
}
| Scenario | HTTP Status | Description |
|---|---|---|
| Validation error | 422 | Missing or invalid fields |
| Unauthorized | 401 | Missing or invalid Bearer token |
| Insufficient balance (refund) | 422 | Business does not have enough balance to refund |
| Transaction declined | 200 | Processor declined the transaction (ok: false) |
Notifications
When a Sale transaction is approved and the business has automatic invoice emailing enabled, RapidCents automatically sends an invoice email to the customer.
Automatic invoice emails can be enabled/disabled in the business configuration settings under automatic_invoice_mail.