Back to Kodaris.com

APIs for Managing Credit Cards on the Customer Side - Technical Implementation Guide

Overview

This guide covers the implementation of a stored payment cards management interface. Users can view, add, edit, and delete their saved credit/debit cards through the Kodaris Payments Gateway.

Implementation Flow

  1. User logs in via the login endpoint
  2. Determine company context - if user has multiple companies, allow selection or use the currently selected company
  3. Display stored cards - fetch and display the user's saved payment methods
  4. Card operations - user can add new cards (via Kodaris Payments iframe), edit card details, or delete cards

Key Concepts

  • CSRF Token: Required for all mutating operations (POST, PUT, DELETE). Include in the X-CSRF-Token header.
  • Company ID: Payment methods are scoped to a company. Users with multiple companies need to select which company's cards to manage.
  • Kodaris Iframe: Card details are entered in a PCI-compliant iframe hosted by Kodaris. The iframe returns a nonce that is exchanged for a stored payment method details.

Authentication

Login

Authenticates the user and returns session tokens.

POST /api/user/customer/loginV2
Content-Type: application/json

Request:

{
  "userName": "user@example.com",
  "password": "password",
  "rememberMe": false
}

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": {
    "access_token": "KSS929858993A604425AF85BAA07B0AA02E84E44B017248671E49F591989CAEFE1E",
    "refresh_token": null,
    "csrf_token": "D8DAB178E1C74E4382A802374D7C04B4",
    "userSessionApiKey": "KSS929858993A604425AF85BAA07B0AA02E84E44B017248671E49F591989CAEFE1E",
    "customerAPIAccessToken": "KSS929858993A604425AF85BAA07B0AA02E84E44B017248671E49F591989CAEFE1E"
  },
  "requestId": "ZIICWG-20251230133542"
}

Get CSRF Token

Retrieves a fresh CSRF token.

GET /api/user/customer/authToken

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": "D8DAB178E1C74E4382A802374D7C04B4",
  "requestId": "OJSDHI-20251230135722"
}

Get Current User

Returns information about the currently logged-in user. Use this to check if a session is valid and to get user details.

GET /api/account/customer/myAccount

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": {
    "firstName": "",
    "lastName": "",
    "email1": "user@example.com",
    "userName": "user@example.com",
    "companyID": 594,
    "customerID": 1436,
    "customerRoles": [...],
    ...
  },
  "requestId": "MXYPBK-20251230203751"
}

Session Handling

If a 401 status is returned:

  1. Fetch a new CSRF token via /api/user/customer/authToken and retry the operation
  2. If still 401, the session has expired - redirect user to login

Logout

Logs out the current user and invalidates the session.

GET /api/account/customer/logout

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": null,
  "requestId": "H91F22-20251230203018"
}

Note: A 401 response from this endpoint should be ignored as it indicates the user is already logged out or the session has already expired.


Multi-Company Support

A single user login can have access to multiple companies. Payment methods are stored per-company, so the correct companyID must be used when calling payment method endpoints.

List Companies

Returns all companies the logged-in user has access to. Use this to populate a company selector dropdown.

GET /api/user/customer/listCompanies

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": [
    {
      "companyID": 506,
      "code": "124",
      "companyName": "Test 2",
      "backorder": false,
      "externalID": null,
      "externalCompanyCode": null,
      "purchaseOrderRequired": null,
      "city": "ATLANTA",
      "state": "GA",
      "approvalFlowTwoLevel": false,
      "warehouseCode": "ATL",
      "shiptoCode": "XXXX"
    },
    {
      "companyID": 594,
      "code": "123",
      "companyName": "Test Corporation",
      "backorder": false,
      "externalID": "1000_5000",
      "externalCompanyCode": "test123",
      "purchaseOrderRequired": false,
      "city": "DENVER",
      "state": "CO",
      "approvalFlowTwoLevel": false,
      "warehouseCode": "CO1",
      "shiptoCode": "W0000151"
    }
  ],
  "requestId": "YW4YHO-20251230193140"
}

Get Selected Company

Returns the user's currently selected company. Use this to determine which company's cards to display by default.

GET /api/user/customer/selectedCompany

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": {
    "companyID": 594,
    "code": "123",
    "companyName": "Test Corporation",
    "backorder": false,
    "externalID": "1000_5000",
    "externalCompanyCode": "test123",
    "purchaseOrderRequired": false,
    "city": "DENVER",
    "state": "CO",
    "approvalFlowTwoLevel": false,
    "warehouseCode": "CO1",
    "shiptoCode": "W0000151"
  },
  "requestId": "QCXL7J-20251230193048"
}

Update Selected Company

Changes the user's currently selected company. Call this when the user selects a different company from a dropdown.

PUT /api/user/customer/selectedCompany?selectedCompanyID={COMPANY_ID}
X-CSRF-Token: {CSRF_TOKEN}

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": {
    "companyID": 594,
    "code": "123",
    "companyName": "Test Corporation",
    "backorder": false,
    "externalID": "1000_5000",
    "externalCompanyCode": "test123",
    "purchaseOrderRequired": false,
    "city": "DENVER",
    "state": "CO",
    "approvalFlowTwoLevel": false,
    "warehouseCode": "CO1",
    "shiptoCode": "W0000151"
  },
  "requestId": "RBUSQK-20251230195230"
}

List Payment Methods

Retrieves stored cards. Call this on page load to display the user's saved payment methods.

GET /api/account/paymentProcessing/methods?paymentMethodType=cardAccount&companyID={COMPANY_ID}

Parameters:

  • paymentMethodType (required): Set to cardAccount for credit/debit cards
  • companyID (optional): The company ID to fetch cards for. If omitted, returns cards for the user's assigned company.

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": [
    {
      "paymentMethodUUID": "371f155a-43b4-40fc-bcef-e7be85b25cef",
      "companyID": 594,
      "type": "cardAccount",
      "description": "************0002",
      "shortDescription": "Visa",
      "created": "2025-07-18 00:38:08",
      "name": "Card Holder Name",
      "email": null,
      "address": "2011 Commerce Dr Suite",
      "zipCode": "30269",
      "state": "GA",
      "cardType": "CREDIT",
      "cardExpirationDate": "0828",
      "requiresCvvOnPayWithPaymentMethodUUID": false,
      "externalID": "10000001215723",
      "bankName": null
    }
  ],
  "requestId": "VS0BDX-20251230133844"
}

Add Payment Method

Adding a new card is a multi-step process that uses the Kodaris Payments iframe to securely capture card details.

Step 1: Get Card Form URL

Request a unique form URL from the server. This URL contains a one-time nonce and is used as the iframe source.

GET /api/account/paymentProcessing/card/company/formUrl?requestEmail=true&companyID={COMPANY_ID}

Parameters:

  • requestEmail (optional): Set to true to include an email field in the form
  • companyID (optional): The company ID to attach the payment method to. Use this when storing a card for a specific company.

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": "https://payments.kodaris.com/api/user/kodarispayments/cardForm?nonce=KPN7429F0E5D3894C4CB9B95A3854D432A5F8FDBC2FC50262FF67536D2AF37A3626",
  "requestId": "CHUGI6-20251230134203"
}

Step 2: Embed Kodaris Iframe

Display the Kodaris payment form in an iframe. The iframe handles all card input securely - card details never touch your server.

<iframe
  id="kodaris-payment-iframe"
  src="FORM_URL_FROM_STEP_1"
  width="100%"
  height="400">
</iframe>
<button id="submit-payment">Save Card</button>

Step 3: Submit Form via postMessage

The submit button lives outside the iframe. Use postMessage to trigger form submission within the iframe.

const iframe = document.getElementById('kodaris-payment-iframe');
const submitBtn = document.getElementById('submit-payment');

submitBtn.onclick = () => {
  iframe.contentWindow.postMessage(
    { type: 'kpSubmit' },
    'https://payments.kodaris.com'
  );
};

Step 4: Handle Iframe Response

Listen for the iframe's response. On success, you receive a nonce to exchange for the stored payment method.

window.addEventListener('message', async (ev) => {
  // Only trust messages from Kodaris
  if (ev.origin !== 'https://payments.kodaris.com') {
    return;
  }

  if (ev.data.type === 'kpSubmitSuccess') {
    const nonce = ev.data.nonce;
    // Send nonce to backend to save card
  } else if (ev.data.type === 'kpSubmitError') {
    // Handle validation or submission errors
  }
});

Step 5: Save Card with Nonce

Exchange the nonce for a stored payment method. This creates the card record and returns the saved card details.

POST /api/account/paymentProcessing/methods/byNonce?nonce={NONCE}&companyID={COMPANY_ID}
X-CSRF-Token: {CSRF_TOKEN}

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": {
    "paymentMethodUUID": "d72743c1-1310-43da-96db-0dde4f66f6a6",
    "companyID": 594,
    "type": "cardAccount",
    "description": "************4242",
    "shortDescription": "Visa",
    "created": "2025-12-30 13:55:06",
    "name": "test",
    "email": null,
    "address": "123",
    "zipCode": "12345",
    "state": "NY",
    "cardType": "CREDIT",
    "cardExpirationDate": "0928",
    "requiresCvvOnPayWithPaymentMethodUUID": false,
    "externalID": "10000001231243",
    "bankName": null
  },
  "requestId": "A4PD9O-20251230135506"
}

Edit Payment Method

Update editable fields on an existing stored card. The card number cannot be changed - to use a different card number, delete and add a new card.

Editable fields: name, address, zipCode, cardExpirationDate, cardType

PUT /api/account/paymentProcessing/methods/{PAYMENT_METHOD_UUID}?type=cardAccount&companyID={COMPANY_ID}
Content-Type: application/json
X-CSRF-Token: {CSRF_TOKEN}

Request:

{
  "name": "Test New name",
  "address": "2011 Commerce Dr",
  "zipCode": "30267",
  "cardExpirationDate": "0829",
  "cardType": "CREDIT"
}

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": {
    "paymentMethodUUID": "371f155a-43b4-40fc-bcef-e7be85b25cef",
    "companyID": 594,
    "type": "cardAccount",
    "description": "************0002",
    "shortDescription": "Visa",
    "created": "2025-07-18 00:38:08",
    "name": "Test New name",
    "email": null,
    "address": "2011 Commerce Dr",
    "zipCode": "30267",
    "state": null,
    "cardType": "CREDIT",
    "cardExpirationDate": "0829",
    "requiresCvvOnPayWithPaymentMethodUUID": false,
    "externalID": "10000001215723",
    "bankName": null
  },
  "requestId": "INY71K-20251230164855"
}

Delete Payment Method

Permanently removes a stored card. This action cannot be undone.

DELETE /api/account/paymentProcessing/methods/{PAYMENT_METHOD_UUID}?companyID={COMPANY_ID}
X-CSRF-Token: {CSRF_TOKEN}

Response:

{
  "success": true,
  "code": 200,
  "messages": [],
  "errors": [],
  "data": {
    "paymentMethodUUID": "cf467307-3767-4245-b76b-1b73b57e3306",
    "type": "bankAccount",
    "description": null,
    "shortDescription": null,
    "created": null,
    "name": null,
    "email": null,
    "address": null,
    "zipCode": null,
    "state": null,
    "cardType": null,
    "cardExpirationDate": null,
    "requiresCvvOnPayWithPaymentMethodUUID": false,
    "externalID": null,
    "bankName": null
  },
  "requestId": "D9ZKOB-20251230165035"
}
In this article