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.
X-CSRF-Token header.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"
}
Retrieves a fresh CSRF token.
GET /api/user/customer/authToken
Response:
{
"success": true,
"code": 200,
"messages": [],
"errors": [],
"data": "D8DAB178E1C74E4382A802374D7C04B4",
"requestId": "OJSDHI-20251230135722"
}
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"
}
If a 401 status is returned:
/api/user/customer/authToken and retry the operation401, the session has expired - redirect user to loginLogs 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.
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.
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"
}
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"
}
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"
}
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 cardscompanyID (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"
}
Adding a new card is a multi-step process that uses the Kodaris Payments iframe to securely capture card details.
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 formcompanyID (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"
}
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>
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'
);
};
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
}
});
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"
}
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"
}
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"
}