Procare Pay Integration Service

Complete API Documentation for Payment Processing

Delete Saved Payment Method

DELETE /v1/rest/merchants/{merchantId}/payors/{payorId}/savedPaymentMethods/{savedPaymentMethodId}

Description: Deletes (soft deletes) a single saved payment method from a payor's profile. The payment method is marked as deleted but remains in the system for transaction history and reporting purposes. This operation cannot be undone.

What is this endpoint used for?

This endpoint removes a specific payment method while keeping others active. Common scenarios include:

  • Remove Old Card: Customer's card was replaced and they no longer need the old expired card in their profile
  • Consolidate Payment Methods: Customer has too many saved cards and wants to remove unused ones
  • Security Concern: Customer suspects a card was compromised and wants it immediately removed
  • Account Closed: Bank account or credit card account was closed and should no longer be available
  • Switch Payment Types: Customer switching from ACH to credit card (or vice versa) and removing the old method
  • Compliance: Remove payment methods that haven't been used in a certain period per your retention policy
Important Notes:
  • Soft Delete: This is a soft delete operation. The payment method is marked as deleted (isDeleted: true) but remains in the database for audit and reporting purposes
  • Cannot Delete Last Method: You cannot delete a payor's only remaining payment method. The payor must have at least one active payment method
  • Default Payment Handling: If you delete the default payment method, another active payment method will be automatically promoted to default
  • No Undo: This operation cannot be undone. The payment method cannot be restored - you must create a new one if needed
Related Endpoints:

To delete ALL payment methods for a payor at once, use DELETE /merchants/{merchantId}/payors/{payorId}/savedPaymentMethods (without the savedPaymentMethodId). To delete the payor profile entirely including all payment methods, use DELETE /merchants/{merchantId}/payors/{payorId}.

Path Parameters

merchantId (required)
Type: string
Pattern: Must be an 11-digit number
Description: The unique 11-digit merchant identifier
Example: 12345678901
payorId (required)
Type: string
Description: The payor identifier
Example: 550e8400-e29b-41d4-a716-446655440000 (GUID format) or 123456789 (64-bit integer)
savedPaymentMethodId (required)
Type: string
Description: The unique identifier for the saved payment method to delete
Example: 7c9e6679-7425-40de-944b-e07fc1f90ae7 (GUID format) or 987654321 (64-bit integer)

Request Body

This endpoint does not require a request body. All necessary information is provided in the URL path parameters.

Response

Returns HTTP 200 (OK) with a SavedPaymentMethodResponse object containing the deleted payment method details:

Field Type Description
payorId string The payor identifier
savedPaymentMethodId string The identifier of the deleted payment method
maskedAccountNumber string Masked version of the account number (e.g., "************1234")
accountType string The card brand or account type (e.g., "VISA", "MC", "ECHK", "SAV")
isDefault boolean Will be false after deletion (if it was the default, another method was promoted)
isDeleted boolean Will be true, indicating the payment method is now deleted
sponsorKey string The sponsor key if one was associated with this payment method

Error Responses

Status Code Meaning Common Causes
400 Bad Request
  • Invalid parameter format (merchantId not 11 digits, invalid UUID format)
  • Cannot delete the last remaining payment method for this payor
  • Payment method is already deleted
404 Not Found
  • Merchant ID does not exist
  • Payor ID does not exist or was deleted
  • Saved payment method ID does not exist
  • Payment method does not belong to the specified payor
500 Internal Server Error Server-side error. Check error message for details and retry if appropriate

Code Examples

using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;

public class PaymentMethodClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;
    private readonly string _bearerToken;

    public PaymentMethodClient(string baseUrl, string bearerToken)
    {
        _baseUrl = baseUrl;
        _bearerToken = bearerToken;
        _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {bearerToken}");
    }

    // Delete a single saved payment method
    public async Task DeleteSavedPaymentMethodAsync(
        string merchantId,
        string payorId,
        string savedPaymentMethodId)
    {
        string endpoint = $"{_baseUrl}/v1/rest/merchants/{merchantId}/payors/{payorId}/savedPaymentMethods/{savedPaymentMethodId}";

        HttpResponseMessage response = await _httpClient.DeleteAsync(endpoint);

        if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            throw new Exception("Payment method not found. It may have already been deleted or does not exist.");
        }

        response.EnsureSuccessStatusCode();

        string json = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize(json);
    }

    // Helper: Get all active payment methods before deleting
    public async Task> GetActiveSavedPaymentMethodsAsync(
        string merchantId,
        string payorId)
    {
        string endpoint = $"{_baseUrl}/v1/rest/merchants/{merchantId}/payors/{payorId}/savedPaymentMethods";

        HttpResponseMessage response = await _httpClient.GetAsync(endpoint);
        response.EnsureSuccessStatusCode();

        string json = await response.Content.ReadAsStringAsync();
        List allMethods = JsonSerializer.Deserialize>(json);

        // Filter to only active (non-deleted) methods
        return allMethods.Where(m => !m.IsDeleted).ToList();
    }

    // Safe delete: Verify not the last payment method before deleting
    public async Task SafeDeleteSavedPaymentMethodAsync(
        string merchantId,
        string payorId,
        string savedPaymentMethodId)
    {
        // First, get all active payment methods
        List activeMethods = await GetActiveSavedPaymentMethodsAsync(merchantId, payorId);

        if (activeMethods.Count <= 1)
        {
            throw new InvalidOperationException(
                "Cannot delete the last remaining payment method. The payor must have at least one active payment method.");
        }

        // Safe to delete
        return await DeleteSavedPaymentMethodAsync(merchantId, payorId, savedPaymentMethodId);
    }

    // Delete and optionally set a new default
    public async Task DeleteAndSetNewDefaultAsync(
        string merchantId,
        string payorId,
        string savedPaymentMethodIdToDelete,
        string newDefaultPaymentMethodId)
    {
        // First, delete the old payment method
        SavedPaymentMethodResponse deleted = await DeleteSavedPaymentMethodAsync(
            merchantId, payorId, savedPaymentMethodIdToDelete);

        // If the deleted method was the default, set a new default
        if (deleted.IsDefault)
        {
            // Update the new default method
            var updateRequest = new { setAsDefaultPaymentMethod = true };
            string endpoint = $"{_baseUrl}/v1/rest/merchants/{merchantId}/payors/{payorId}/savedPaymentMethods/{newDefaultPaymentMethodId}";
            string json = JsonSerializer.Serialize(updateRequest);
            HttpContent content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

            HttpResponseMessage response = await _httpClient.PutAsync(endpoint, content);
            response.EnsureSuccessStatusCode();
        }

        return deleted;
    }
}

// Usage example
public class Program
{
    public static async Task Main()
    {
        string baseUrl = "https://api.example.com";
        string bearerToken = "your-oauth-token-here";
        string merchantId = "12345678901";
        string payorId = "550e8400-e29b-41d4-a716-446655440000";
        string paymentMethodToDelete = "7c9e6679-7425-40de-944b-e07fc1f90ae7";

        PaymentMethodClient client = new PaymentMethodClient(baseUrl, bearerToken);

        try
        {
            // Safe delete with validation
            SavedPaymentMethodResponse result = await client.SafeDeleteSavedPaymentMethodAsync(
                merchantId, payorId, paymentMethodToDelete);

            Console.WriteLine($"Payment method deleted: {result.MaskedAccountNumber}");
            Console.WriteLine($"Account type: {result.AccountType}");
            Console.WriteLine($"Is deleted: {result.IsDeleted}");
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine($"Cannot delete: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

public class SavedPaymentMethodResponse
{
    public string PayorId { get; set; }
    public string SavedPaymentMethodId { get; set; }
    public string MaskedAccountNumber { get; set; }
    public string AccountType { get; set; }
    public bool IsDefault { get; set; }
    public bool IsDeleted { get; set; }
    public string SponsorKey { get; set; }
}
    
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Imports System.Linq

Public Class PaymentMethodClient
    Private ReadOnly _httpClient As HttpClient
    Private ReadOnly _baseUrl As String
    Private ReadOnly _bearerToken As String

    Public Sub New(baseUrl As String, bearerToken As String)
        _baseUrl = baseUrl
        _bearerToken = bearerToken
        _httpClient = New HttpClient()
        _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {bearerToken}")
    End Sub

    ' Delete a single saved payment method
    Public Async Function DeleteSavedPaymentMethodAsync(
        merchantId As String,
        payorId As String,
        savedPaymentMethodId As String) As Task(Of SavedPaymentMethodResponse)

        Dim endpoint As String = $"{_baseUrl}/v1/rest/merchants/{merchantId}/payors/{payorId}/savedPaymentMethods/{savedPaymentMethodId}"

        Dim response As HttpResponseMessage = Await _httpClient.DeleteAsync(endpoint)

        If response.StatusCode = Net.HttpStatusCode.NotFound Then
            Throw New Exception("Payment method not found. It may have already been deleted or does not exist.")
        End If

        response.EnsureSuccessStatusCode()

        Dim json As String = Await response.Content.ReadAsStringAsync()
        Return JsonSerializer.Deserialize(Of SavedPaymentMethodResponse)(json)
    End Function

    ' Helper: Get all active payment methods before deleting
    Public Async Function GetActiveSavedPaymentMethodsAsync(
        merchantId As String,
        payorId As String) As Task(Of List(Of SavedPaymentMethodResponse))

        Dim endpoint As String = $"{_baseUrl}/v1/rest/merchants/{merchantId}/payors/{payorId}/savedPaymentMethods"

        Dim response As HttpResponseMessage = Await _httpClient.GetAsync(endpoint)
        response.EnsureSuccessStatusCode()

        Dim json As String = Await response.Content.ReadAsStringAsync()
        Dim allMethods As List(Of SavedPaymentMethodResponse) = JsonSerializer.Deserialize(Of List(Of SavedPaymentMethodResponse))(json)

        ' Filter to only active (non-deleted) methods
        Return allMethods.Where(Function(m) Not m.IsDeleted).ToList()
    End Function

    ' Safe delete: Verify not the last payment method before deleting
    Public Async Function SafeDeleteSavedPaymentMethodAsync(
        merchantId As String,
        payorId As String,
        savedPaymentMethodId As String) As Task(Of SavedPaymentMethodResponse)

        ' First, get all active payment methods
        Dim activeMethods As List(Of SavedPaymentMethodResponse) = Await GetActiveSavedPaymentMethodsAsync(merchantId, payorId)

        If activeMethods.Count <= 1 Then
            Throw New InvalidOperationException(
                "Cannot delete the last remaining payment method. The payor must have at least one active payment method.")
        End If

        ' Safe to delete
        Return Await DeleteSavedPaymentMethodAsync(merchantId, payorId, savedPaymentMethodId)
    End Function
End Class

' Usage example
Module Program
    Sub Main()
        MainAsync().Wait()
    End Sub

    Async Function MainAsync() As Task
        Dim baseUrl As String = "https://api.example.com"
        Dim bearerToken As String = "your-oauth-token-here"
        Dim merchantId As String = "12345678901"
        Dim payorId As String = "550e8400-e29b-41d4-a716-446655440000"
        Dim paymentMethodToDelete As String = "7c9e6679-7425-40de-944b-e07fc1f90ae7"

        Dim client As New PaymentMethodClient(baseUrl, bearerToken)

        Try
            ' Safe delete with validation
            Dim result As SavedPaymentMethodResponse = Await client.SafeDeleteSavedPaymentMethodAsync(
                merchantId, payorId, paymentMethodToDelete)

            Console.WriteLine($"Payment method deleted: {result.MaskedAccountNumber}")
            Console.WriteLine($"Account type: {result.AccountType}")
            Console.WriteLine($"Is deleted: {result.IsDeleted}")

        Catch ex As InvalidOperationException
            Console.WriteLine($"Cannot delete: {ex.Message}")
        Catch ex As Exception
            Console.WriteLine($"Error: {ex.Message}")
        End Try
    End Function
End Module

Public Class SavedPaymentMethodResponse
    Public Property PayorId As String
    Public Property SavedPaymentMethodId As String
    Public Property MaskedAccountNumber As String
    Public Property AccountType As String
    Public Property IsDefault As Boolean
    Public Property IsDeleted As Boolean
    Public Property SponsorKey As String
End Class
    
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;

public class PaymentMethodClient {
    private final HttpClient httpClient;
    private final String baseUrl;
    private final String bearerToken;
    private final ObjectMapper objectMapper;

    public PaymentMethodClient(String baseUrl, String bearerToken) {
        this.baseUrl = baseUrl;
        this.bearerToken = bearerToken;
        this.httpClient = HttpClient.newHttpClient();
        this.objectMapper = new ObjectMapper();
    }

    // Delete a single saved payment method
    public SavedPaymentMethodResponse deleteSavedPaymentMethod(
            String merchantId,
            String payorId,
            String savedPaymentMethodId) throws IOException, InterruptedException {

        String endpoint = String.format("%s/v1/rest/merchants/%s/payors/%s/savedPaymentMethods/%s",
                baseUrl, merchantId, payorId, savedPaymentMethodId);

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endpoint))
                .header("Authorization", "Bearer " + bearerToken)
                .DELETE()
                .build();

        HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() == 404) {
            throw new RuntimeException("Payment method not found. It may have already been deleted or does not exist.");
        }

        if (response.statusCode() != 200) {
            throw new RuntimeException("Failed to delete payment method: " + response.statusCode() +
                    " - " + response.body());
        }

        return objectMapper.readValue(response.body(), SavedPaymentMethodResponse.class);
    }

    // Helper: Get all active payment methods before deleting
    public List getActiveSavedPaymentMethods(
            String merchantId,
            String payorId) throws IOException, InterruptedException {

        String endpoint = String.format("%s/v1/rest/merchants/%s/payors/%s/savedPaymentMethods",
                baseUrl, merchantId, payorId);

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endpoint))
                .header("Authorization", "Bearer " + bearerToken)
                .GET()
                .build();

        HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 200) {
            throw new RuntimeException("Failed to get payment methods: " + response.statusCode());
        }

        List allMethods = objectMapper.readValue(
                response.body(),
                new TypeReference>() {}
        );

        // Filter to only active (non-deleted) methods
        return allMethods.stream()
                .filter(m -> !m.isDeleted())
                .collect(Collectors.toList());
    }

    // Safe delete: Verify not the last payment method before deleting
    public SavedPaymentMethodResponse safeDeleteSavedPaymentMethod(
            String merchantId,
            String payorId,
            String savedPaymentMethodId) throws IOException, InterruptedException {

        // First, get all active payment methods
        List activeMethods = getActiveSavedPaymentMethods(merchantId, payorId);

        if (activeMethods.size() <= 1) {
            throw new IllegalStateException(
                    "Cannot delete the last remaining payment method. The payor must have at least one active payment method.");
        }

        // Safe to delete
        return deleteSavedPaymentMethod(merchantId, payorId, savedPaymentMethodId);
    }

    // Usage example
    public static void main(String[] args) {
        try {
            String baseUrl = "https://api.example.com";
            String bearerToken = "your-oauth-token-here";
            String merchantId = "12345678901";
            String payorId = "550e8400-e29b-41d4-a716-446655440000";
            String paymentMethodToDelete = "7c9e6679-7425-40de-944b-e07fc1f90ae7";

            PaymentMethodClient client = new PaymentMethodClient(baseUrl, bearerToken);

            // Safe delete with validation
            SavedPaymentMethodResponse result = client.safeDeleteSavedPaymentMethod(
                    merchantId, payorId, paymentMethodToDelete);

            System.out.println("Payment method deleted: " + result.getMaskedAccountNumber());
            System.out.println("Account type: " + result.getAccountType());
            System.out.println("Is deleted: " + result.isDeleted());

        } catch (IllegalStateException ex) {
            System.out.println("Cannot delete: " + ex.getMessage());
        } catch (Exception ex) {
            System.out.println("Error: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}

// Response model
class SavedPaymentMethodResponse {
    @JsonProperty("payorId")
    private String payorId;

    @JsonProperty("savedPaymentMethodId")
    private String savedPaymentMethodId;

    @JsonProperty("maskedAccountNumber")
    private String maskedAccountNumber;

    @JsonProperty("accountType")
    private String accountType;

    @JsonProperty("isDefault")
    private boolean isDefault;

    @JsonProperty("isDeleted")
    private boolean isDeleted;

    @JsonProperty("sponsorKey")
    private String sponsorKey;

    public String getPayorId() { return payorId; }
    public String getSavedPaymentMethodId() { return savedPaymentMethodId; }
    public String getMaskedAccountNumber() { return maskedAccountNumber; }
    public String getAccountType() { return accountType; }
    public boolean isDefault() { return isDefault; }
    public boolean isDeleted() { return isDeleted; }
    public String getSponsorKey() { return sponsorKey; }
}
    
require 'net/http'
require 'json'

class PaymentMethodClient
  def initialize(base_url, bearer_token)
    @base_url = base_url
    @bearer_token = bearer_token
  end

  # Delete a single saved payment method
  def delete_saved_payment_method(merchant_id:, payor_id:, saved_payment_method_id:)
    uri = URI("#{@base_url}/v1/rest/merchants/#{merchant_id}/payors/#{payor_id}/savedPaymentMethods/#{saved_payment_method_id}")
    request = Net::HTTP::Delete.new(uri)
    request['Authorization'] = "Bearer #{@bearer_token}"

    response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
      http.request(request)
    end

    if response.code == '404'
      raise "Payment method not found. It may have already been deleted or does not exist."
    end

    raise "Failed to delete payment method: #{response.code} - #{response.body}" unless response.code == '200'

    JSON.parse(response.body)
  end

  # Helper: Get all active payment methods before deleting
  def get_active_saved_payment_methods(merchant_id:, payor_id:)
    uri = URI("#{@base_url}/v1/rest/merchants/#{merchant_id}/payors/#{payor_id}/savedPaymentMethods")
    request = Net::HTTP::Get.new(uri)
    request['Authorization'] = "Bearer #{@bearer_token}"

    response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
      http.request(request)
    end

    raise "Failed to get payment methods: #{response.code}" unless response.code == '200'

    all_methods = JSON.parse(response.body)

    # Filter to only active (non-deleted) methods
    all_methods.select { |m| !m['isDeleted'] }
  end

  # Safe delete: Verify not the last payment method before deleting
  def safe_delete_saved_payment_method(merchant_id:, payor_id:, saved_payment_method_id:)
    # First, get all active payment methods
    active_methods = get_active_saved_payment_methods(merchant_id: merchant_id, payor_id: payor_id)

    if active_methods.length <= 1
      raise ArgumentError, "Cannot delete the last remaining payment method. The payor must have at least one active payment method."
    end

    # Safe to delete
    delete_saved_payment_method(
      merchant_id: merchant_id,
      payor_id: payor_id,
      saved_payment_method_id: saved_payment_method_id
    )
  end
end

# Usage example
if __FILE__ == $0
  base_url = 'https://api.example.com'
  bearer_token = 'your-oauth-token-here'
  merchant_id = '12345678901'
  payor_id = '550e8400-e29b-41d4-a716-446655440000'
  payment_method_to_delete = '7c9e6679-7425-40de-944b-e07fc1f90ae7'

  client = PaymentMethodClient.new(base_url, bearer_token)

  begin
    # Safe delete with validation
    result = client.safe_delete_saved_payment_method(
      merchant_id: merchant_id,
      payor_id: payor_id,
      saved_payment_method_id: payment_method_to_delete
    )

    puts "Payment method deleted: #{result['maskedAccountNumber']}"
    puts "Account type: #{result['accountType']}"
    puts "Is deleted: #{result['isDeleted']}"

  rescue ArgumentError => e
    puts "Cannot delete: #{e.message}"
  rescue => e
    puts "Error: #{e.message}"
  end
end
    

Common Use Cases

1. Remove Expired Card After Adding Replacement

// Step 1: Add new card with updated expiration
SavedPaymentMethodResponse newCard = await client.AddCreditCardAsync(..., setAsDefault: true);

// Step 2: Delete the old expired card
SavedPaymentMethodResponse deletedCard = await client.DeleteSavedPaymentMethodAsync(
    merchantId: "12345678901",
    payorId: "550e8400-e29b-41d4-a716-446655440000",
    savedPaymentMethodId: oldCardId
);

Console.WriteLine($"Replaced {deletedCard.MaskedAccountNumber} with new card");
    

2. Clean Up Unused Payment Methods

// Get all active payment methods
List methods = await client.GetActiveSavedPaymentMethodsAsync(merchantId, payorId);

// Keep the default, remove all others
foreach (var method in methods.Where(m => !m.IsDefault))
{
    await client.DeleteSavedPaymentMethodAsync(merchantId, payorId, method.SavedPaymentMethodId);
    Console.WriteLine($"Removed: {method.MaskedAccountNumber}");
}
    

3. Switch from Credit Card to ACH

// Step 1: Add new ACH account and set as default
SavedPaymentMethodResponse achAccount = await client.AddBankAccountAsync(..., setAsDefault: true);

// Step 2: Remove all old credit cards
List creditCards = (await client.GetActiveSavedPaymentMethodsAsync(merchantId, payorId))
    .Where(m => m.AccountType == "VISA" || m.AccountType == "MC" || m.AccountType == "AMEX" || m.AccountType == "DISC")
    .ToList();

foreach (var card in creditCards)
{
    await client.DeleteSavedPaymentMethodAsync(merchantId, payorId, card.SavedPaymentMethodId);
}
    

Troubleshooting

Error: "Cannot delete the last remaining payment method" (400)

Solution: A payor must have at least one active payment method. Before deleting, either add a new payment method or delete the entire payor profile using DELETE /payors/{payorId} instead.

Error: "Saved payment method not found" (404)

Solution: The payment method may have already been deleted, or the ID is incorrect. Call GET /savedPaymentMethods to list all payment methods and verify the ID. Remember that deleted methods still appear in the list with isDeleted: true.

Payment method deleted but still showing in UI

Solution: This is expected behavior. Deleted payment methods are soft-deleted (marked with isDeleted: true) but remain in the system. Filter them out in your UI by checking the isDeleted flag. Example: activeMethods = allMethods.Where(m => !m.IsDeleted).

Deleted default payment method - which one becomes new default?

Solution: The API automatically promotes another active payment method to default. To control which one becomes default, explicitly set it before or after deletion using PUT /savedPaymentMethods/{id} with setAsDefaultPaymentMethod: true.

Best Practices

  • Validate before delete: Use the safe delete pattern shown in the examples to verify the payor has multiple active payment methods before attempting deletion
  • Add before remove: When replacing a payment method, add the new one first (and optionally set it as default), then delete the old one. This ensures continuous payment capability
  • Confirm with user: Since this operation cannot be undone, implement a confirmation step in your UI before calling this endpoint
  • Handle default promotion: If deleting the default payment method, either set a new default explicitly or inform the user which payment method was automatically promoted
  • Audit logging: Log all deletion operations in your system for audit trails and customer support purposes
  • Grace period: Consider implementing a "disable" flag in your UI before actually calling this API, giving users a grace period to change their mind
  • Transaction history: Inform users that past transactions will still show this payment method even after deletion (for reporting and reconciliation)

Security Considerations

Important Security Notes:
  • Authorization: Ensure the authenticated user has permission to delete payment methods for this payor. Implement proper access control in your application
  • Audit trail: The soft delete preserves payment method data for audit purposes. Deleted methods remain in the system for regulatory compliance and dispute resolution
  • No recovery: Once deleted, a payment method cannot be restored. Users must re-enter payment information to create a new payment method
  • Fraud detection: Monitor deletion patterns - excessive deletion and re-creation of payment methods may indicate testing stolen card numbers
  • PCI compliance: Even deleted payment methods maintain PCI compliance - actual account numbers remain encrypted and are never exposed