Using for Transactions
Process one-time sales for recurring customers using vault tokens with your merchant API key
Process one-time sales using vault tokens instead of raw payment data. This approach is ideal for serving returning customers without collecting payment information again.
Vault tokens eliminate the need to handle sensitive payment data for repeat transactions.
Server-side Example
The following is an example code snippet. Full parameter support can be seen in our docs under the "Credit Card - Sale" request.
// Process sale using vault token
const axios = require('axios');
router.post('/vault-sale', async (req, res) => {
try {
const { customerVaultId, amount } = req.body;
// Call NMI's v5 Payments API with customer vault ID
const response = await axios.post('https://secure.nmi.com/api/v5/payments/sale', {
amount: parseFloat(amount),
payment_details: {
customer_vault_id: customerVaultId
}
}, {
headers: {
'Content-Type': 'application/json',
'Authorization': '{user.privateApiKey}'
}
});
if (response.data.response === '1') {
return res.json({
success: true,
transactionId: response.data.id,
authCode: response.data.auth_code,
responseText: response.data.response_text
});
} else {
return res.json({
success: false,
error: response.data.response_text
});
}
} catch (error) {
console.error('Error processing vault sale:', error);
return res.status(500).json({
success: false,
error: 'An error occurred while processing vault sale'
});
}
});# Process sale using vault token
import requests
def process_vault_sale(vault_id, amount):
try:
# vault_id should be the customer vault ID returned when adding a vault entry
headers = {
'Content-Type': 'application/json',
'Authorization': '{user.privateApiKey}'
}
payload = {
'amount': float(amount),
'payment_details': {
'customer_vault_id': vault_id
}
}
response = requests.post(
'https://secure.nmi.com/api/v5/payments/sale',
json=payload,
headers=headers
)
response_data = response.json()
if response_data.get('response') == '1':
print('Vault sale processed successfully')
return {
'transactionId': response_data.get('id'),
'authCode': response_data.get('auth_code'),
'responseText': response_data.get('response_text')
}
else:
raise Exception(response_data.get('response_text', 'Failed to process vault sale'))
except Exception as error:
print(f'Error processing vault sale: {error}')
raise error// Process sale using vault token
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
import java.util.HashMap;
@PostMapping("/vault-sale")
public ResponseEntity<Map<String, Object>> processVaultSale(@RequestBody VaultSaleRequest request) {
try {
RestTemplate restTemplate = new RestTemplate();
// vault_id should be the customer vault ID returned when adding a vault entry
Map<String, Object> paymentDetails = new HashMap<>();
paymentDetails.put("customer_vault_id", request.getCustomerVaultId());
Map<String, Object> payload = new HashMap<>();
payload.put("amount", request.getAmount());
payload.put("payment_details", paymentDetails);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "{user.privateApiKey}");
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(payload, headers);
// Call NMI's v5 Payments API
ResponseEntity<Map> response = restTemplate.exchange(
"https://secure.nmi.com/api/v5/payments/sale",
HttpMethod.POST,
entity,
Map.class
);
Map<String, Object> responseData = response.getBody();
Map<String, Object> result = new HashMap<>();
if ("1".equals(responseData.get("response"))) {
result.put("success", true);
result.put("transactionId", responseData.get("id"));
result.put("authCode", responseData.get("auth_code"));
result.put("responseText", responseData.get("response_text"));
} else {
result.put("success", false);
result.put("error", responseData.getOrDefault("response_text", "Failed to process vault sale"));
}
return ResponseEntity.ok(result);
} catch (Exception error) {
System.err.println("Error processing vault sale: " + error.getMessage());
Map<String, Object> errorResult = new HashMap<>();
errorResult.put("success", false);
errorResult.put("error", "An error occurred while processing vault sale");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResult);
}
}// Process sale using vault token
using System.Text;
using System.Text.Json;
[HttpPost("vault-sale")]
public async Task<IActionResult> ProcessVaultSale([FromBody] VaultSaleRequest request)
{
try
{
// customerVaultId should be the ID returned when adding a vault entry
var payload = new
{
amount = request.Amount,
payment_details = new
{
customer_vault_id = request.CustomerVaultId
}
};
var jsonContent = new StringContent(
JsonSerializer.Serialize(payload),
Encoding.UTF8,
"application/json"
);
_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Add("Authorization", "{user.privateApiKey}");
var response = await _httpClient.PostAsync(
"https://secure.nmi.com/api/v5/payments/sale",
jsonContent
);
var responseContent = await response.Content.ReadAsStringAsync();
var responseData = JsonSerializer.Deserialize<Dictionary<string, object>>(responseContent);
if (responseData.TryGetValue("response", out var responseCode) && responseCode?.ToString() == "1")
{
return Ok(new
{
success = true,
transactionId = responseData.GetValueOrDefault("id")?.ToString(),
authCode = responseData.GetValueOrDefault("auth_code")?.ToString(),
responseText = responseData.GetValueOrDefault("response_text")?.ToString()
});
}
else
{
return BadRequest(new
{
success = false,
error = responseData.GetValueOrDefault("response_text")?.ToString() ?? "Failed to process vault sale"
});
}
}
catch (Exception ex)
{
return StatusCode(500, new
{
success = false,
error = "An error occurred while processing vault sale"
});
}
}<?php
// Process sale using vault token
function processVaultSale($vaultId, $amount) {
try {
// $vaultId should be the customer vault ID returned when adding a vault entry
$payload = [
'amount' => (float) $amount,
'payment_details' => [
'customer_vault_id' => $vaultId
]
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://secure.nmi.com/api/v5/payments/sale');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: {user.privateApiKey}'
]);
$response = curl_exec($ch);
curl_close($ch);
if ($response === false) {
throw new Exception('cURL error occurred');
}
// Parse the JSON response
$responseData = json_decode($response, true);
if ($responseData['response'] === '1') {
return [
'success' => true,
'transactionId' => $responseData['id'],
'authCode' => $responseData['auth_code'],
'responseText' => $responseData['response_text']
];
} else {
return [
'success' => false,
'error' => $responseData['response_text'] ?? 'Failed to process vault sale'
];
}
} catch (Exception $error) {
error_log('Error processing vault sale: ' . $error->getMessage());
return [
'success' => false,
'error' => 'An error occurred while processing vault sale'
];
}
}
// Example usage
function handleVaultSale() {
$result = processVaultSale('cust_12345', '10.00');
if ($result['success']) {
echo 'Vault sale processed successfully' . PHP_EOL;
echo 'Transaction ID: ' . $result['transactionId'] . PHP_EOL;
echo 'Auth Code: ' . $result['authCode'] . PHP_EOL;
echo 'Response: ' . $result['responseText'] . PHP_EOL;
} else {
echo 'Error: ' . $result['error'] . PHP_EOL;
}
}
// REST API endpoint example
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['REQUEST_URI'] === '/vault-sale') {
header('Content-Type: application/json');
$input = json_decode(file_get_contents('php://input'), true);
if (!$input || !isset($input['customerVaultId']) || !isset($input['amount'])) {
http_response_code(400);
echo json_encode(['success' => false, 'error' => 'Invalid JSON input or missing required fields']);
exit;
}
$result = processVaultSale($input['customerVaultId'], $input['amount']);
if ($result['success']) {
http_response_code(200);
} else {
http_response_code(500);
}
echo json_encode($result);
}
?><?php
// app/Http/Controllers/TransactionController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use App\Services\TransactionService;
class TransactionController extends Controller
{
public function __construct(
private TransactionService $transactionService
) {}
/**
* Process sale using vault token
*/
public function processVaultSale(Request $request): JsonResponse
{
$request->validate([
'customerVaultId' => 'required|string',
'amount' => 'required|numeric|min:0.01'
]);
try {
$result = $this->transactionService->processVaultSale(
$request->customerVaultId,
$request->amount
);
if ($result['success']) {
return response()->json([
'success' => true,
'transactionId' => $result['transactionId'],
'authCode' => $result['authCode'],
'responseText' => $result['responseText']
]);
} else {
return response()->json([
'success' => false,
'error' => $result['error']
], 400);
}
} catch (\Exception $e) {
Log::error('Error processing vault sale: ' . $e->getMessage());
return response()->json([
'success' => false,
'error' => 'An error occurred while processing vault sale'
], 500);
}
}
}
// app/Services/TransactionService.php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class TransactionService
{
public function processVaultSale(string $vaultId, float $amount): array
{
try {
// $vaultId should be the customer vault ID returned when adding a vault entry
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => '{user.privateApiKey}'
])->post('https://secure.nmi.com/api/v5/payments/sale', [
'amount' => $amount,
'payment_details' => [
'customer_vault_id' => $vaultId
]
]);
$responseData = $response->json();
if ($responseData['response'] === '1') {
return [
'success' => true,
'transactionId' => $responseData['id'],
'authCode' => $responseData['auth_code'],
'responseText' => $responseData['response_text']
];
} else {
return [
'success' => false,
'error' => $responseData['response_text'] ?? 'Failed to process vault sale'
];
}
} catch (\Exception $e) {
Log::error('Error processing vault sale: ' . $e->getMessage());
return [
'success' => false,
'error' => 'An error occurred while processing vault sale'
];
}
}
}Updated 3 months ago
