Troubleshooting payments
What goes wrong on the ledger endpoints, and the fix for each.
Read the response body first. A failed request has code: false and the message in error. A 202 on POST /payments or POST /adjustments means NexHealth accepted the request, so some problems only show up later, when the write into the health record system fails.
The request fails
You don't have access to perform this action. on /charges, /payments, /adjustments, /claims, /fee_schedules, /insurance_plans or a balance endpoint
- Cause: Financial data is not turned on for your production key. Sandbox locations have it on by default.
- Fix: Email [email protected]. The ledger backfill takes up to a day after it is turned on.
Payment Type with id 1 not found in location 456 on POST /payments
- Cause: The payment type does not exist at that location, or is not active there.
- Fix: Use an
idfromGET /payment_typescalled with the samelocation_id.
Adjustment Type with id 1 not found in location 456 on POST /adjustments
- Cause: The adjustment type does not exist at that location.
- Fix: Use an
idfromGET /adjustment_typescalled with the samelocation_id.
Patient with ID 123 not found in location 456 on POST /payments
- Cause: The patient belongs to another location on the same server.
GET /patientsreturns patients from every location on that server unless you say otherwise. - Fix: Send
location_strict=trueonGET /patients. Checklocation_idsonGET /patients/{id}before you post.
Something went wrong. Please try again or contact our support team. on POST /payments
- Cause: The patient is not in the health record system yet. Their
foreign_idisnullandforeign_id_typeisnex. A patient created through the API is written into the health record system with their first appointment. - Fix: Book an appointment for the patient first, then post the payment.
A debit adjustment fails on POST /adjustments
- Cause: A positive adjustment has to be linked to a charge or a provider. The request had neither
charge_splitsnorprovider_splits. - Fix: Send
charge_splitswith the charge IDs the debit applies to, orprovider_splitswith the provider IDs.
A list call fails with no filter on GET /charges, GET /payments, GET /adjustments or GET /guarantor_balances
- Cause: These endpoints need at least one filter. Charges take
patient_id,provider_id,procedure_id,guarantor_idorupdated_since. Guarantor balances takeguarantor_idorupdated_since. - Fix: Add a filter. For a full load, use
updated_sincewith a date before the practice went live.
The request succeeds, but the ledger is wrong
POST /payments returns 202 but the payment never appears
- Cause: The payment type is inactive or belongs to another location, the
transaction_idwas already used, or writes are paused becausewrite_statusonGET /sync_statusisred. The health record system does not accept two payments with the same transaction ID. - Fix: Subscribe to
payment_insertionto get acompleteorfailedresult for every payment. Use apayment_type_idfromGET /payment_typesfor that location and a newtransaction_idon every call. Then checkGET /paymentswithtransaction_idto see what landed.
A payment came back as an adjustment
- Cause: You posted a refund as a positive payment to Dentrix, Dentrix Enterprise or Eaglesoft. Those systems record refunds as adjustments, so NexHealth converted it. The response said an adjustment was created.
- Fix: Nothing. This is how refunds work on those systems. Open Dental records a refund as a positive payment.
A payment was recorded as a refund
- Cause: The
amountwas positive. A payment that lowers the balance is negative. - Fix: Send negative amounts for payments and for the values in
charge_splitsandprovider_splits. Post a correcting payment for the one that went in as a refund.
One payment became several records
- Cause: The payment was split across providers. The health record system stores one payment per provider.
- Fix: Nothing. All of them carry your
transaction_id. FilterGET /paymentsby it to see the set.
charge_id is null on every payment
- Cause: The location runs on Dentrix, which cannot link a payment to a charge.
- Fix: Use
provider_splitson Dentrix and match payments to charges in your own records.
The balance does not match what the office sees
- Cause: Balances are per guarantor, not per patient, so a family's balance sits on the responsible party. NexHealth reads the ledger on a cycle, so a payment the office just entered appears after the next read. Deleted charges and payments are left out unless you ask for them.
- Fix: Read
GET /guarantor_balanceswith the patient'sguarantor_id. Check the time of the last read onGET /sync_status. Sendinclude_deleted=truewhen you keep your own copy of the ledger.
Charges are missing right after financial data was turned on
- Cause: The ledger backfill takes up to a day and is still running.
- Fix: Wait for the backfill. If charges are still missing after a day, email [email protected] with the
subdomainandlocation_id.
Still stuck
Email [email protected] with the request, the full response body, the subdomain, the location_id, the transaction_id and the time of the call in UTC. Every message the API returns is in the Errors reference.
Updated about 1 hour ago