Skip to main content
POST
/
v1
/
payments
/
{paymentId}
/
mark-paid
Mark payment as paid
curl --request POST \
  --url https://api-eu.flexportal.io/v1/payments/{paymentId}/mark-paid \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'Tenant-ID: <tenant-id>' \
  --data '
{
  "paymentReference": "<string>",
  "notes": "<string>"
}
'
{
  "success": true,
  "message": "<string>",
  "payment": {
    "paymentId": "<string>",
    "tenantId": "<string>",
    "customerId": "<string>",
    "subtotal": 1,
    "total": 1,
    "currency": "<string>",
    "paymentType": "individual",
    "billingPeriod": "<string>",
    "status": "pending",
    "idempotencyKey": "<string>",
    "dueDate": "<string>",
    "createdAt": "<string>",
    "updatedAt": "<string>",
    "taxAmount": 0,
    "taxRate": 0,
    "amount": 1,
    "rentalId": "<string>",
    "billingGroupId": "<string>",
    "provider": "stripe",
    "transactionId": "<string>",
    "providerResponse": {},
    "manuallyMarked": false,
    "paymentReference": "<string>",
    "markedBy": "<string>",
    "captureAttempts": 0,
    "lastCaptureError": {
      "code": "<string>",
      "message": "<string>",
      "declineCode": "<string>"
    },
    "lineItems": [
      {
        "rentalId": "<string>",
        "description": "<string>",
        "amount": 1,
        "taxAmount": 0
      }
    ],
    "lateFeeApplied": false,
    "lateFeeAmount": 1,
    "originalAmount": 1,
    "notes": "<string>",
    "paidAt": "<string>",
    "lastCaptureAttempt": "<string>",
    "nextRetryAt": "<string>"
  }
}

Overview

Manually mark a payment as paid. Use this when payment was collected outside of automated billing (e.g., bank transfer, check, cash) or to reconcile payments manually.
This endpoint is for manual reconciliation. Automated payments through integrated payment processors are marked paid automatically.

Common Use Cases

  • Bank Transfers: Customer paid via wire transfer
  • Checks: Payment received by check
  • Cash: In-person cash payment
  • External Systems: Payment collected through another system
  • Reconciliation: Fix discrepancies between systems

Request Fields

FieldRequiredDescription
paidAtNoWhen payment was received (default: now)
notesNoNotes about the payment
referenceNoExternal reference (bank ref, check number)

Example Request

{
  "paidAt": "2025-01-15T10:30:00Z",
  "reference": "WIRE-2025-001234",
  "notes": "Received via bank transfer"
}

What Happens

When you mark a payment as paid:
  1. Payment status changes to paid
  2. paidAt timestamp recorded
  3. Subscription cost recovery metrics updated
  4. Customer lifetime value updated

Example: Process Bank Transfer

async function recordBankTransfer(paymentId, bankReference, transferDate) {
  return await markPaymentPaid(paymentId, {
    paidAt: transferDate,
    reference: bankReference,
    notes: 'Manual reconciliation - bank transfer'
  });
}

// Usage
await recordBankTransfer('pay_abc123', 'TRF-2025-001234', '2025-01-15T10:30:00Z');

Example: Bulk Reconciliation

async function reconcilePayments(reconciliationData) {
  const results = { success: 0, errors: [] };

  for (const item of reconciliationData) {
    try {
      await markPaymentPaid(item.paymentId, {
        paidAt: item.paidDate,
        reference: item.bankReference
      });
      results.success++;
    } catch (error) {
      results.errors.push({
        paymentId: item.paymentId,
        error: error.message
      });
    }
  }

  return results;
}

Error Handling

Error CodeCauseSolution
NOT_FOUNDPayment doesn’t existVerify payment ID
ALREADY_PAIDPayment already marked as paidNo action needed
PAYMENT_CANCELLEDCannot mark cancelled payment as paidPayment is final

Authorizations

Authorization
string
header
required

API key obtained from FlexPortal dashboard

Headers

Tenant-ID
string
required

Your tenant identifier

Path Parameters

paymentId
string
required

The payment ID

Body

application/json
paymentReference
string
notes
string

Response

Payment marked as paid

success
enum<boolean>
required
Available options:
true,
false
message
string
required
payment
object
required