Implement Backend

Backend Implementation

Use the payment token obtained from your frontend to process the payment on your server by calling the NMI Payments API.

Server-Side Example

// Server-side code (Node.js/Express)
const express = require('express');
const axios = require('axios');
const router = express.Router();

router.post('/process-payment', async (req, res) => {
  try {
    const { paymentToken, amount } = req.body;
    
    // Call NMI's Direct Post API
    const response = await axios.post('https://secure.networkmerchants.com/api/transact.php', {
      security_key: '{user.privateApiKey}',
      payment_token: paymentToken,
      amount: amount,
      type: 'sale',
    });
    
    // Check for successful response (response code 1)
    if (response.data.response === '1') {
      return res.json({
        success: true,
        transactionId: response.data.transactionid
      });
    } else {
      return res.json({
        success: false,
        error: response.data.responsetext
      });
    }
  } catch (error) {
    console.error('Payment processing error:', error);
    return res.status(500).json({
      success: false,
      error: 'An error occurred while processing the payment'
    });
  }
});

module.exports = router;
# Server-side code (Python/Flask)
from flask import Flask, request, jsonify
import requests
import logging

app = Flask(__name__)

@app.route('/process-payment', methods=['POST'])
def process_payment():
    try:
        data = request.get_json()
        payment_token = data.get('paymentToken')
        amount = data.get('amount')
        
        # Call NMI's Direct Post API
        payload = {
            'security_key': '{user.privateApiKey}',
            'payment_token': payment_token,
            'amount': amount,
            'type': 'sale'
        }
        
        response = requests.post(
            'https://secure.networkmerchants.com/api/transact.php',
            data=payload
        )
        
        # Parse response (assuming it's in query string format)
        response_data = dict(x.split('=') for x in response.text.split('&'))
        
        # Check for successful response (response code 1)
        if response_data.get('response') == '1':
            return jsonify({
                'success': True,
                'transactionId': response_data.get('transactionid')
            })
        else:
            return jsonify({
                'success': False,
                'error': response_data.get('responsetext', 'Unknown error')
            })
            
    except Exception as error:
        logging.error(f'Payment processing error: {error}')
        return jsonify({
            'success': False,
            'error': 'An error occurred while processing the payment'
        }), 500

if __name__ == '__main__':
    app.run(debug=True)
// Server-side code (Java/Spring Boot)
package com.example.payments;

import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;

@RestController
@RequestMapping("/api")
public class PaymentController {
    
    @PostMapping("/process-payment")
    public ResponseEntity<Map<String, Object>> processPayment(@RequestBody PaymentRequest request) {
        try {
            // Prepare the request to NMI's API
            RestTemplate restTemplate = new RestTemplate();
            
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("security_key", "{user.privateApiKey}");
            params.add("payment_token", request.getPaymentToken());
            params.add("amount", request.getAmount().toString());
            params.add("type", "sale");
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            
            HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);
            
            // Call NMI's Direct Post API
            ResponseEntity<String> response = restTemplate.exchange(
                "https://secure.networkmerchants.com/api/transact.php",
                HttpMethod.POST,
                entity,
                String.class
            );
            
            // Parse response (query string format)
            Map<String, String> responseData = parseQueryString(response.getBody());
            
            Map<String, Object> result = new HashMap<>();
            
            // Check for successful response (response code 1)
            if ("1".equals(responseData.get("response"))) {
                result.put("success", true);
                result.put("transactionId", responseData.get("transactionid"));
            } else {
                result.put("success", false);
                result.put("error", responseData.getOrDefault("responsetext", "Unknown error"));
            }
            
            return ResponseEntity.ok(result);
            
        } catch (Exception error) {
            System.err.println("Payment processing error: " + error.getMessage());
            
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("success", false);
            errorResult.put("error", "An error occurred while processing the payment");
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResult);
        }
    }
    
    private Map<String, String> parseQueryString(String queryString) {
        Map<String, String> result = new HashMap<>();
        if (queryString != null) {
            Arrays.stream(queryString.split("&"))
                .forEach(param -> {
                    String[] pair = param.split("=", 2);
                    if (pair.length == 2) {
                        result.put(pair[0], pair[1]);
                    }
                });
        }
        return result;
    }
    
    public static class PaymentRequest {
        private String paymentToken;
        private Double amount;
        
        // Getters and setters
        public String getPaymentToken() { return paymentToken; }
        public void setPaymentToken(String paymentToken) { this.paymentToken = paymentToken; }
        public Double getAmount() { return amount; }
        public void setAmount(Double amount) { this.amount = amount; }
    }
}
// Server-side code (C#/.NET Core)
using Microsoft.AspNetCore.Mvc;
using System.Text;

[ApiController]
[Route("api/[controller]")]
public class PaymentController : ControllerBase
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<PaymentController> _logger;

    public PaymentController(HttpClient httpClient, ILogger<PaymentController> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
    }

    [HttpPost("process-payment")]
    public async Task<IActionResult> ProcessPayment([FromBody] PaymentRequest request)
    {
        try
        {
            // Prepare the request to NMI's API
            var parameters = new List<KeyValuePair<string, string>>
            {
                new("security_key", "{user.privateApiKey}"),
                new("payment_token", request.PaymentToken),
                new("amount", request.Amount.ToString()),
                new("type", "sale")
            };

            var content = new FormUrlEncodedContent(parameters);

            // Call NMI's Direct Post API
            var response = await _httpClient.PostAsync(
                "https://secure.networkmerchants.com/api/transact.php", 
                content
            );

            var responseString = await response.Content.ReadAsStringAsync();
            
            // Parse response (query string format)
            var responseData = ParseQueryString(responseString);

            // Check for successful response (response code 1)
            if (responseData.TryGetValue("response", out var responseCode) && responseCode == "1")
            {
                return Ok(new
                {
                    success = true,
                    transactionId = responseData.GetValueOrDefault("transactionid")
                });
            }
            else
            {
                return Ok(new
                {
                    success = false,
                    error = responseData.GetValueOrDefault("responsetext", "Unknown error")
                });
            }
        }
        catch (Exception error)
        {
            _logger.LogError(error, "Payment processing error");
            
            return StatusCode(500, new
            {
                success = false,
                error = "An error occurred while processing the payment"
            });
        }
    }

    private static Dictionary<string, string> ParseQueryString(string queryString)
    {
        var result = new Dictionary<string, string>();
        
        if (!string.IsNullOrEmpty(queryString))
        {
            var pairs = queryString.Split('&');
            foreach (var pair in pairs)
            {
                var parts = pair.Split('=', 2);
                if (parts.Length == 2)
                {
                    result[parts[0]] = parts[1];
                }
            }
        }
        
        return result;
    }

    public class PaymentRequest
    {
        public string PaymentToken { get; set; } = string.Empty;
        public decimal Amount { get; set; }
    }
}
<?php
// Server-side code (PHP)
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'error' => 'Method not allowed']);
    exit;
}

try {
    // Get JSON input
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input || !isset($input['paymentToken']) || !isset($input['amount'])) {
        http_response_code(400);
        echo json_encode(['success' => false, 'error' => 'Missing required fields']);
        exit;
    }
    
    $paymentToken = $input['paymentToken'];
    $amount = $input['amount'];
    
    // Prepare the request to NMI's API
    $postData = [
        'security_key' => '{user.privateApiKey}',
        'payment_token' => $paymentToken,
        'amount' => $amount,
        'type' => 'sale'
    ];
    
    // Call NMI's Direct Post API
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://secure.networkmerchants.com/api/transact.php');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($response === false) {
        throw new Exception('cURL error occurred');
    }
    
    // Parse response (query string format)
    parse_str($response, $responseData);
    
    // Check for successful response (response code 1)
    if (isset($responseData['response']) && $responseData['response'] === '1') {
        echo json_encode([
            'success' => true,
            'transactionId' => $responseData['transactionid'] ?? null
        ]);
    } else {
        echo json_encode([
            'success' => false,
            'error' => $responseData['responsetext'] ?? 'Unknown error'
        ]);
    }
    
} catch (Exception $error) {
    error_log('Payment processing error: ' . $error->getMessage());
    
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => 'An error occurred while processing the payment'
    ]);
}
?>
<?php
// Server-side code (PHP/Laravel)
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class PaymentController extends Controller
{
    public function processPayment(Request $request): JsonResponse
    {
        try {
            // Validate the request
            $validated = $request->validate([
                'paymentToken' => 'required|string',
                'amount' => 'required|numeric|min:0.01'
            ]);
            
            // Prepare the request to NMI's API
            $response = Http::asForm()->post('https://secure.networkmerchants.com/api/transact.php', [
                'security_key' => '{user.privateApiKey}',
                'payment_token' => $validated['paymentToken'],
                'amount' => $validated['amount'],
                'type' => 'sale'
            ]);
            
            // Parse response (query string format)
            $responseData = [];
            parse_str($response->body(), $responseData);
            
            // Check for successful response (response code 1)
            if (isset($responseData['response']) && $responseData['response'] === '1') {
                return response()->json([
                    'success' => true,
                    'transactionId' => $responseData['transactionid'] ?? null
                ]);
            } else {
                return response()->json([
                    'success' => false,
                    'error' => $responseData['responsetext'] ?? 'Unknown error'
                ]);
            }
            
        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'success' => false,
                'error' => 'Validation failed',
                'details' => $e->errors()
            ], 400);
            
        } catch (\Exception $e) {
            Log::error('Payment processing error: ' . $e->getMessage());
            
            return response()->json([
                'success' => false,
                'error' => 'An error occurred while processing the payment'
            ], 500);
        }
    }
}

API Key Configuration

Security Key

You can find your API security key at key management under 'Merchant keys'.

Unlike the tokenization key in the previous step, this key is private and should be kept secure on your server. It authenticates your merchant account and authorizes payment processing requests.

Your sandbox key has been included in the code sample on the right.

🚧

Security: Never expose your API security key in client-side code. Always keep it secure on your server. While we have included your test key in the code sample, you should not commit it to source control and instead inject it via an environment variable.