Process Transaction Sale
Description: Processes a new payment transaction (sale). This endpoint charges a credit card or ACH account immediately. You can use either a saved payment method (by providing the payor and payment method IDs) or provide new payment information.
This is how you charge a customer for a purchase. Think of it like swiping a credit card or processing a check payment:
- E-commerce: Customer checks out and pays online
- Recurring billing: Charge a saved payment method automatically
- Phone orders: Process credit card over the phone
- Invoicing: Charge a customer's saved payment method for an invoice
Path Parameters
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
| amount | object | Required | The transaction amount (contains dollars and/or cents) |
| payorId | string | Optional* | The payor ID (use with savedPaymentMethodId for saved payment methods) |
| savedPaymentMethodId | string | Optional* | The saved payment method ID (use with payorId) |
| encryptedAccountNumber | string | Optional* | Encrypted account number (credit card or bank account) - required if not using saved payment method |
| cardExpiry | string | Optional | Card expiration in MMyy, MMyyyy, or yyyyMMdd format (required for credit cards) |
| abaRoutingNumber | string | Optional | Bank routing number (required for ACH) |
| encryptedCvv2 | string | Optional | Encrypted CVV2/security code (recommended for credit cards) |
| accountHolderName | string | Required | Name on the account |
| address | string | Optional | Billing street address |
| city | string | Optional | Billing city |
| postal | string | Optional | Billing ZIP/postal code |
| region | string | Optional | State/province (required for ACH) |
| phone | string | Optional | Account holder phone number |
| string | Optional | Account holder email address | |
| orderid | string | Optional | Your system's order number (for tracking) |
| locationid | integer | Optional | Location/school ID |
| bankAccountType | string | Optional | Account type: Checking, Saving, CreditCard, or Null |
| transtype | string | Optional | Transaction type: Ecomm (default), Moto, or Retail |
| transinit | string | Optional | Transaction initiator: Consumer (default) or Merchant |
| recurring | boolean | Optional | Indicates recurring/installment payment (default: false) |
| allowPartialApproval | boolean | Optional | Allow partial authorization (default: true) |
| savePaymentMethod | boolean | Optional | Save payment method for future use (default: false) |
| customAttributes | object | Optional | Custom key-value pairs for tracking |
You must provide payment information in ONE of these ways:
- Option 1: Saved payment method: Provide both
payorIdandsavedPaymentMethodId - Option 2: New payment method: Provide
encryptedAccountNumber(pluscardExpiryfor cards orabaRoutingNumberfor ACH)
Authentication
This endpoint requires bearer token authentication using the Authorization header.
Code Examples
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using Newtonsoft.Json;
public class TransactionRequest
{
[JsonProperty("amount")]
public AmountRequest Amount { get; set; }
[JsonProperty("payorId")]
public string PayorId { get; set; }
[JsonProperty("savedPaymentMethodId")]
public string SavedPaymentMethodId { get; set; }
[JsonProperty("encryptedAccountNumber")]
public string EncryptedAccountNumber { get; set; }
[JsonProperty("cardExpiry")]
public string CardExpiry { get; set; }
[JsonProperty("encryptedCvv2")]
public string EncryptedCvv2 { get; set; }
[JsonProperty("accountHolderName")]
public string AccountHolderName { get; set; }
[JsonProperty("address")]
public string Address { get; set; }
[JsonProperty("city")]
public string City { get; set; }
[JsonProperty("postal")]
public string Postal { get; set; }
[JsonProperty("region")]
public string Region { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("orderid")]
public string OrderId { get; set; }
[JsonProperty("locationid")]
public int? LocationId { get; set; }
[JsonProperty("transtype")]
public string TransType { get; set; }
[JsonProperty("recurring")]
public bool Recurring { get; set; }
[JsonProperty("savePaymentMethod")]
public bool SavePaymentMethod { get; set; }
[JsonProperty("customAttributes")]
public Dictionary<string, string> CustomAttributes { get; set; }
}
public class AmountRequest
{
[JsonProperty("dollars")]
public decimal? Dollars { get; set; }
[JsonProperty("cents")]
public decimal? Cents { get; set; }
}
public class TransactionClient
{
private readonly HttpClient _httpClient;
private readonly string _baseUrl = "https://your-api-domain.com";
private readonly string _bearerToken;
public TransactionClient(string bearerToken)
{
_bearerToken = bearerToken;
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri(_baseUrl);
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", _bearerToken);
_httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<string> ProcessTransactionAsync(
string merchantId,
TransactionRequest request)
{
try
{
string endpoint = $"/v1/rest/merchants/{merchantId}/transactions";
string jsonContent = JsonConvert.SerializeObject(
request,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
var content = new StringContent(
jsonContent,
Encoding.UTF8,
"application/json");
HttpResponseMessage response = await _httpClient.PostAsync(endpoint, content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request error: {e.Message}");
throw;
}
}
}
// Example 1: Process transaction with saved payment method
var client = new TransactionClient("your-bearer-token-here");
var request = new TransactionRequest
{
Amount = new AmountRequest { Dollars = 150.00m },
PayorId = "5513027774438108364",
SavedPaymentMethodId = "5513027774438108365",
AccountHolderName = "John Doe",
OrderId = "ORD-2026-12345",
LocationId = 5,
TransType = "Ecomm",
Recurring = false,
CustomAttributes = new Dictionary<string, string>
{
{ "invoiceNumber", "INV-001" },
{ "department", "Sales" }
}
};
string result = await client.ProcessTransactionAsync("12345678901", request);
Console.WriteLine(result);
Imports System
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Threading.Tasks
Imports System.Collections.Generic
Imports Newtonsoft.Json
Public Class TransactionRequest
<JsonProperty("amount")>
Public Property Amount As AmountRequest
<JsonProperty("payorId")>
Public Property PayorId As String
<JsonProperty("savedPaymentMethodId")>
Public Property SavedPaymentMethodId As String
<JsonProperty("accountHolderName")>
Public Property AccountHolderName As String
<JsonProperty("orderid")>
Public Property OrderId As String
<JsonProperty("locationid")>
Public Property LocationId As Integer?
<JsonProperty("transtype")>
Public Property TransType As String
<JsonProperty("recurring")>
Public Property Recurring As Boolean
<JsonProperty("customAttributes")>
Public Property CustomAttributes As Dictionary(Of String, String)
End Class
Public Class AmountRequest
<JsonProperty("dollars")>
Public Property Dollars As Decimal?
<JsonProperty("cents")>
Public Property Cents As Decimal?
End Class
Public Class TransactionClient
Private ReadOnly _httpClient As HttpClient
Private ReadOnly _baseUrl As String = "https://your-api-domain.com"
Private ReadOnly _bearerToken As String
Public Sub New(bearerToken As String)
_bearerToken = bearerToken
_httpClient = New HttpClient()
_httpClient.BaseAddress = New Uri(_baseUrl)
_httpClient.DefaultRequestHeaders.Authorization =
New AuthenticationHeaderValue("Bearer", _bearerToken)
_httpClient.DefaultRequestHeaders.Accept.Add(
New MediaTypeWithQualityHeaderValue("application/json"))
End Sub
Public Async Function ProcessTransactionAsync(
merchantId As String,
request As TransactionRequest) As Task(Of String)
Try
Dim endpoint As String = $"/v1/rest/merchants/{merchantId}/transactions"
Dim jsonContent As String = JsonConvert.SerializeObject(
request,
New JsonSerializerSettings With {
.NullValueHandling = NullValueHandling.Ignore
})
Dim content As New StringContent(
jsonContent,
Encoding.UTF8,
"application/json")
Dim response As HttpResponseMessage = Await _httpClient.PostAsync(endpoint, content)
response.EnsureSuccessStatusCode()
Return Await response.Content.ReadAsStringAsync()
Catch e As HttpRequestException
Console.WriteLine($"Request error: {e.Message}")
Throw
End Try
End Function
End Class
' Example: Process transaction with saved payment method
Dim client As New TransactionClient("your-bearer-token-here")
Dim request As New TransactionRequest With {
.Amount = New AmountRequest With {.Dollars = 150D},
.PayorId = "5513027774438108364",
.SavedPaymentMethodId = "5513027774438108365",
.AccountHolderName = "John Doe",
.OrderId = "ORD-2026-12345",
.LocationId = 5,
.TransType = "Ecomm",
.Recurring = False
}
Dim result As String = Await client.ProcessTransactionAsync("12345678901", request)
Console.WriteLine(result)
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;
import java.util.HashMap;
import java.util.Map;
class TransactionRequest {
private AmountRequest amount;
private String payorId;
private String savedPaymentMethodId;
private String accountHolderName;
private String orderid;
private Integer locationid;
private String transtype;
private Boolean recurring;
private Map<String, String> customAttributes;
// Getters and setters...
}
class AmountRequest {
private Double dollars;
private Double cents;
public AmountRequest(Double dollars) {
this.dollars = dollars;
}
// Getters and setters...
}
public class TransactionClient {
private final String baseUrl;
private final String bearerToken;
private final HttpClient httpClient;
private final Gson gson;
public TransactionClient(String baseUrl, String bearerToken) {
this.baseUrl = baseUrl;
this.bearerToken = bearerToken;
this.httpClient = HttpClient.newHttpClient();
this.gson = new Gson();
}
public String processTransaction(String merchantId, TransactionRequest request)
throws IOException, InterruptedException {
String endpoint = baseUrl + "/v1/rest/merchants/" + merchantId + "/transactions";
String jsonBody = gson.toJson(request);
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(endpoint))
.header("Authorization", "Bearer " + bearerToken)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse<String> response = httpClient.send(
httpRequest,
HttpResponse.BodyHandlers.ofString()
);
if (response.statusCode() != 200) {
throw new IOException("HTTP Error: " + response.statusCode());
}
return response.body();
}
}
// Example: Process transaction with saved payment method
TransactionClient client = new TransactionClient(
"https://your-api-domain.com",
"your-bearer-token-here"
);
TransactionRequest request = new TransactionRequest();
request.setAmount(new AmountRequest(150.00));
request.setPayorId("5513027774438108364");
request.setSavedPaymentMethodId("5513027774438108365");
request.setAccountHolderName("John Doe");
request.setOrderid("ORD-2026-12345");
request.setLocationid(5);
request.setTranstype("Ecomm");
request.setRecurring(false);
String result = client.processTransaction("12345678901", request);
System.out.println(result);
require 'net/http'
require 'uri'
require 'json'
class TransactionClient
def initialize(base_url, bearer_token)
@base_url = base_url
@bearer_token = bearer_token
end
def process_transaction(merchant_id, request_data)
endpoint = "#{@base_url}/v1/rest/merchants/#{merchant_id}/transactions"
uri = URI.parse(endpoint)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request['Authorization'] = "Bearer #{@bearer_token}"
request['Content-Type'] = 'application/json'
request['Accept'] = 'application/json'
request.body = request_data.to_json
response = http.request(request)
if response.code.to_i != 200
raise "HTTP Error: #{response.code} - #{response.body}"
end
response.body
end
end
# Example: Process transaction with saved payment method
client = TransactionClient.new(
'https://your-api-domain.com',
'your-bearer-token-here'
)
request_data = {
amount: {
dollars: 150.00
},
payorId: '5513027774438108364',
savedPaymentMethodId: '5513027774438108365',
accountHolderName: 'John Doe',
orderid: 'ORD-2026-12345',
locationid: 5,
transtype: 'Ecomm',
recurring: false,
customAttributes: {
invoiceNumber: 'INV-001',
department: 'Sales'
}
}
result = client.process_transaction('12345678901', request_data)
puts result
Example Request Bodies
Example 1: Charge Saved Payment Method
{
"amount": {
"dollars": 150.00
},
"payorId": "5513027774438108364",
"savedPaymentMethodId": "5513027774438108365",
"accountHolderName": "John Doe",
"orderid": "ORD-2026-12345",
"locationid": 5,
"transtype": "Ecomm",
"recurring": false
}
Example 2: One-Time Credit Card Payment (New Card)
{
"amount": {
"dollars": 75.50
},
"encryptedAccountNumber": "encrypted-card-number-here",
"cardExpiry": "1227",
"encryptedCvv2": "encrypted-cvv-here",
"accountHolderName": "Jane Smith",
"address": "123 Main St",
"city": "Springfield",
"postal": "62701",
"region": "IL",
"email": "jane@example.com",
"orderid": "ORD-2026-12346",
"transtype": "Ecomm",
"savePaymentMethod": false
}
Example 3: ACH Payment
{
"amount": {
"dollars": 250.00
},
"encryptedAccountNumber": "encrypted-account-number-here",
"abaRoutingNumber": "123456789",
"bankAccountType": "Checking",
"accountHolderName": "Bob Johnson",
"address": "456 Oak Ave",
"city": "Chicago",
"postal": "60601",
"region": "IL",
"phone": "555-1234",
"email": "bob@example.com",
"orderid": "ORD-2026-12347",
"transtype": "Ecomm",
"savePaymentMethod": true
}
Example 4: Recurring Payment
{
"amount": {
"dollars": 49.99
},
"payorId": "5513027774438108364",
"savedPaymentMethodId": "5513027774438108365",
"accountHolderName": "John Doe",
"orderid": "SUBSCRIPTION-2026-001",
"recurring": true,
"transinit": "Merchant",
"customAttributes": {
"subscriptionId": "SUB-12345",
"billingPeriod": "monthly"
}
}
Response Format
Success Response (HTTP 200)
{
"responseStatus": "TransactionApproved",
"responseMessage": "Approved",
"responseCode": "000",
"responseReason": null,
"responseResult": "success",
"legacyResponseCode": "A",
"correlationId": "abc123-def456-ghi789",
"transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"retref": 123456789,
"merchid": "12345678901",
"locationid": 5,
"transactionAmount": "150.00",
"authAmount": "150.00",
"accttype": "VISA",
"maskedAccountNumber": "************1234",
"lastfour": "1234",
"cardExpiry": "1227",
"payorId": "5513027774438108364",
"savedPaymentMethodId": "5513027774438108365",
"accountHolderName": "John Doe",
"orderid": "ORD-2026-12345",
"requestDate": "2026-04-02T10:30:00Z",
"authDate": "2026-04-02T10:30:03Z",
"settlementStatus": "Authorized",
"transtype": "Ecomm",
"transinit": "Consumer",
"recurring": false,
"customAttributes": {
"invoiceNumber": "INV-001",
"department": "Sales"
}
}
Declined Response (HTTP 200 with declined status)
{
"responseStatus": "TransactionDeclined",
"responseMessage": "Insufficient Funds",
"responseCode": "051",
"responseReason": "The transaction was declined due to insufficient funds",
"responseResult": "failure",
"legacyResponseCode": "D",
"correlationId": "xyz789-abc123-def456",
"transactionId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"retref": 123456790,
"merchid": "12345678901",
"transactionAmount": "150.00",
"authAmount": "0.00",
"accttype": "VISA",
"maskedAccountNumber": "************1234",
"lastfour": "1234",
"requestDate": "2026-04-02T10:31:00Z",
"settlementStatus": "Declined"
}
HTTP Status Codes
| Status Code | Description |
|---|---|
| 201 | Success - Transaction processed (check responseStatus for approved/declined) |
| 400 | Bad Request - Validation error (missing required fields, invalid format) |
| 401 | Unauthorized - Invalid or expired bearer token |
| 500 | Internal Server Error - Server error processing transaction |
responseStatus field. A value of "TransactionApproved" indicates success, while "TransactionDeclined" indicates the payment was declined by the bank.
Understanding Response Status Values
| Response Status | Meaning | Action Required |
|---|---|---|
| TransactionApproved | Transaction successful | Complete order, send confirmation |
| TransactionDeclined | Payment declined by bank | Ask customer to use different payment method |
| TransactionValidationError | Invalid request data | Fix validation issues and retry |
| Error | System error occurred | Check correlationId and contact support |
Best Practices
1. Always Check responseStatus
if (response.ResponseStatus == "TransactionApproved")
{
// Success - complete the order
CompleteOrder(orderId);
}
else if (response.ResponseStatus == "TransactionDeclined")
{
// Declined - show user-friendly message
ShowMessage("Payment declined. Please try a different payment method.");
}
2. Store Transaction IDs
Always store both transactionId and retref in your database.
You'll need these for refunds, voids, and customer service inquiries.
3. Use Order IDs for Tracking
Always provide an orderid that links the transaction to your order in your system.
This makes reconciliation and customer service much easier.
4. Handle Partial Approvals
If allowPartialApproval is true and the authAmount is less than
transactionAmount, the card was only approved for a partial amount.
5. Encrypt Sensitive Data
Card numbers and CVV must be encrypted using the public keys from the /keys endpoints
before sending to the API. Never send plain text card numbers.
6. Save Payment Methods When Appropriate
Set savePaymentMethod: true for recurring customers to enable one-click checkout
and automatic billing in the future.
Common Use Cases
1. E-commerce Checkout
Customer enters credit card at checkout and completes purchase
2. Recurring Subscription Billing
Automatically charge saved payment method on billing date
3. Invoice Payment
Customer pays invoice using saved payment method
4. Phone Order (MOTO)
Customer service rep processes credit card over phone
5. Auto-Pay for Services
Automatically charge customer's saved ACH account monthly
Troubleshooting
- Verify
amountobject contains either dollars or cents - Check that
accountHolderNameis provided - Ensure
cardExpiryis in correct format (MMyy, MMyyyy, or yyyyMMdd) - For ACH, verify
regionandabaRoutingNumberare provided - Check that either (payorId + savedPaymentMethodId) OR encryptedAccountNumber is provided
- Check
responseCodefor specific decline reason - Common reasons: insufficient funds, expired card, incorrect CVV, card reported lost/stolen
- Ask customer to contact their bank or try different payment method
- Do not retry declined transactions repeatedly - this may trigger fraud alerts
- Store
transactionIdimmediately after successful response - Implement idempotency - check if transaction already exists before processing
- Use webhook notifications to handle async settlement updates
- Have a reconciliation process to match transactions to orders
Security Considerations
- PCI Compliance: Never store plain text card numbers in your system
- Encryption: Always encrypt card numbers and CVV before sending to API
- HTTPS Only: Always use HTTPS for all API requests
- Tokenization: Use saved payment methods (tokens) instead of storing raw card data
- CVV: Never store CVV/CVV2 codes - they should only be used for the initial transaction
- Logging: Never log full card numbers - use masked numbers only
- Rate Limiting: Implement rate limiting to prevent abuse
Additional Notes
- Credit card transactions are authorized immediately and typically settle within 1-2 business days
- ACH transactions take 3-5 business days to settle and can be reversed within 60 days
- Set
transtypeto "Moto" for phone/mail orders to indicate card-not-present transaction - Set
recurring: truefor subscription payments to get better approval rates - The
correlationIdis essential for troubleshooting - always log it - Declined transactions still create a transaction record for tracking purposes
- Partial approvals are more common with gift cards and prepaid cards