Implementing HIPAA-Safe Request-for-Payment Workflows

Patient responsibility is the slowest-collecting line in most practices' AR, and the reason is structural rather than behavioral. The instrument you use to ask for it — a printed statement, or an SMS containing a link to a login page — imposes work on the patient before any money can move, and it strips the claim reference off the payment on the way back. Digital request-for-payment (RfP) removes both problems, but only if you get three things right: the amount you ask for, what travels in the message, and how the patient proves who they are.

This piece covers those three in order. Every EDI segment, dollar figure, and identifier below is a synthetic illustration constructed for this article and contains no patient data.

Where the statement-and-portal loop leaks

A paper statement is a 30-day round trip with a call attached. The patient receives a claim-level total with no line detail, cannot tell what it is for, and phones the practice — where someone opens the remittance and reads the lines aloud. Then a check arrives with a stub that may or may not be returned, and posting guesses at the match.

The portal was supposed to fix this. Mostly it moved the friction: the patient now has to remember a password for a site they visit twice a year, complete a reset flow, and land in an interface built for chart review rather than for paying one balance. Every step is a drop-off point, and the drop-offs concentrate in exactly the population you most want to reach — patients with a small balance who would pay it immediately if paying took fifteen seconds.

SMS payment links partially solve the friction and create a new problem. A text message containing a dollar amount and a URL is formally indistinguishable from a smishing attempt. Patients who have been correctly trained to distrust that pattern will not click, and the ones who do click are being trained to do something you would rather they stop doing.

What a request for payment actually is

An RfP is a message, not a link. Your bank sends a payable request over a real-time rail to the patient's bank. The patient sees it inside the banking app they already use and already trust, approves or declines it there, and on approval their bank originates a credit transfer to the practice. You never hold card credentials, never store an account number, and never authenticate the patient yourself.

Three mechanics matter operationally:

  • It is credit-push. Nothing is pulled from an account you stored. On The Clearing House's RTP network, credit transfers are final at settlement; funds come back only through a request for return, not a unilateral reversal — so there is no chargeback window to reserve against [verify current terms against the TCH RTP Rulebook].
  • Structured remittance rides with the money. The rails are ISO 20022; RTP's request-for-payment is carried on pain.013, with the response on pain.014 [verify message identifiers against current network specs]. Reference data travels with the payment, so the credit that lands can be matched to the claim and the line that generated it without a human reading anything.
  • Coverage is partial and will stay partial for a while. The patient's bank must participate and must expose RfP to retail customers. FedNow offers its own request-for-payment capability with a different participation profile [verify against current FedNow Service documentation and your institution's supported message set]. Design for fallback from day one.

A concrete settlement path for an approved request, assuming both institutions are on-network:

code
T+0s       Practice's bank sends pain.013 (amount, reference token, expiry)
T+~1s      Request appears in the patient's banking app
T+?        Patient approves — this interval is the patient's, not the rail's
T+~2s      Patient's bank originates the credit transfer; funds final at the practice
T+~2s      pain.014 response returns, carrying the same reference token
T+same-day Posting engine matches the token to claim + service line, closes the balance

The rail's contribution is the two-second half; the open-ended middle is the part your workflow design actually controls.

Paper statementSMS/email payment linkPortal login + payRequest for payment (RTP/FedNow)
Patient actionMail a check or call to read a card numberClick an unfamiliar URL, enter card dataRecover password, log in, navigate to billingApprove inside their own banking app
Where authentication happensNowhereYour hosted pageYour identity providerThe patient's bank
Credential surface you ownNone (but you key cards by phone)Card PAN in your payment pathPasswords, resets, MFA, session managementNone
Claim reference returns with fundsOnly if the stub comes back and is keyed rightDepends on gateway metadata handlingUsually, if the session carries a tokenYes — structured reference in the message [verify field support with your bank]
Funds availabilityCheck float plus deposit cycleCard settlement cycle, net of feesCard settlement cycle, net of feesSeconds, 24/7/365 on-network
Reversal exposureReturned checkChargeback windowChargeback windowCredit-push; return by request only [verify]
Dominant drop-offIgnored, re-mailed next cycleDistrusted as phishingPassword resetPatient's bank doesn't participate

Ask only for the dollars the remittance made the patient's

Everything above is delivery mechanics. The compliance and trust exposure lives in the amount. A request generated from an estimate, or from a claim-level remainder, will bill patients for money that is not theirs — and doing it fast, in an app they trust, makes that error worse rather than better.

Source the number from service-line adjustments. Synthetic three-line professional claim:

code
CLP*PCN-4417*1*395.00*120.00*70.00*12*ICN-2026-0731-8823*11~
SVC*HC:99214*210.00*70.40**1~
CAS*CO*45*82.00~
CAS*PR*1*40.00~
CAS*PR*2*17.60~
SVC*HC:20610*145.00*49.60**1~
CAS*CO*45*83.00~
CAS*PR*2*12.40~
SVC*HC:J1030*40.00*0.00**1~
CAS*CO*97*40.00~

The service-line balancing rule is not optional — an 835 that violates it is malformed:

SVC02 (submitted charge) = SVC03 (line payment) + the sum of that line's CAS amounts (X12N 835 TR3, 005010X221A1).

Line by line:

  • 99214 — 210.00 = 70.40 + 82.00 (CO-45 contractual) + 40.00 (PR-1 deductible) + 17.60 (PR-2 coinsurance) ✓
  • 20610 — 145.00 = 49.60 + 83.00 (CO-45) + 12.40 (PR-2) ✓
  • J1030 — 40.00 = 0.00 + 40.00 (CO-97, benefit included in another service) ✓

Roll up to the claim: CLP03 − CLP04 = 395.00 − 120.00 = 275.00, and the CAS amounts across all lines sum to 82.00 + 40.00 + 17.60 + 83.00 + 12.40 + 40.00 = 275.00. CLP05 is 40.00 + 17.60 + 12.40 = 70.00, exactly the PR-group total.

So the requestable amount is $70.00. Not 275.00 — that includes 165.00 of CO-45 contractual adjustment which was never AR and should leave the balance the moment the 835 posts. And not 110.00, which would sweep in the 40.00 CO-97 bundled drug line: that is a provider-side work item with an appeal deadline attached, not a patient charge. Group-code and reason-code semantics come from the current WPC claim adjustment reason code list, which is revised on a published schedule — read the live list, not a cached copy verify retrieval date]. The mechanics of extracting this reliably at scale are covered in [line-level 835 remittance reconciliation [verify link target before publish].

Two gates must clear before a PR dollar becomes a request:

  1. COB resolved. If a secondary payer exists, the primary's PR amount is not the patient's balance.
  2. Billing prohibitions screened. Medicare providers may not bill Qualified Medicare Beneficiary individuals for Medicare cost-sharing, and other dual-eligible categories carry their own restrictions. Check the eligibility response before the request is generated, not after a complaint.

Payload boundaries, authentication, and follow-up

What can be in the message

The design rule is that PHI stays in your system of record and only opaque references move through the payment path. An amount, a currency, a practice identifier, an expiry, and a reference token that means nothing outside your database — that is the whole payload. Diagnosis codes, procedure descriptions, clinical narrative, and dates of service tied to a specialty do not belong in a message that transits institutions with no business need for it.

Note the asymmetry that makes this workable: the 835 you parsed is a covered transaction containing PHI and needs the full control set — BAA, encryption at rest and in transit, access control, audit logging, minimum necessary. The payment message downstream does not have to inherit any of that, because you did not put anything in it. Financial institutions processing payment transactions are generally excluded from business-associate status when acting solely in that capacity [verify against 45 CFR 160.103 and current HHS guidance]. Whether your specific deployment meets your obligations is a determination for your privacy officer and counsel.

Authenticating without owning credentials

On the bank rail, authentication is delegated entirely — the patient's bank already knows who they are, to a standard you cannot match. That is the strongest available posture and the main reason to prefer RfP over any link-based flow.

For the fallback channel you still need, match the authentication burden to the specific action rather than to the account:

  • Bind a signed, single-use, short-TTL token to one claim reference. Not to the patient, and not to a session that can be replayed.
  • Keep identifiers out of the URL. Query strings leak through referrer headers, proxy logs, browser history, and link previews.
  • Treat date of birth as a weak knowledge factor. For anything beyond viewing and paying the one balance already disclosed — statement history, other family members, stored instruments — require step-up with a possession factor sent to a contact point verified at registration.
  • Put no clinical detail in the SMS or email body itself, so the delivery channel never needs to be a compliant one.

What to measure and when to follow up

Instrument the funnel as discrete stages — requests generated, delivered, viewed, authorized, settled, posted — and keep the denominators honest. Cohort by dollar band, by balance age, and by PR type, because a 12 coinsurance balance and a 900 deductible balance are different products with different conversion behavior, and blending them produces a number that moves for reasons you cannot act on.

Two metrics are worth more than conversion rate. Time to first dollar from remittance receipt tells you whether the workflow is actually event-driven or has quietly re-acquired a batch cadence. Unmatched-payment rate should trend toward zero; if it doesn't, your reference token isn't surviving the round trip and you have a reconciliation problem wearing a collections costume.

For follow-up, treat declined, expired, and partial as three outcomes with three rules. A decline is information — route it to a human, never to an automatic re-send. An expiry can escalate on a written ladder. A partial payment needs a defined rule for how the remainder appears next time. Set the thresholds by dollars and age, write them down, and apply them uniformly; inconsistent outreach is how a billing process becomes a compliance problem. Once the patient approves, the money can land over real-time settlement rather than a multi-day card cycle [verify link target before publish].

FAQ

Do we still need a patient portal? For clinical access, yes. For collecting a balance, no — and coupling them is what depresses collection. The payment path should work for a patient who has never logged in and never will.

What happens when the patient's bank doesn't support RfP? You fall through, and you will be falling through for some share of requests for the foreseeable future [verify current network participation]. Build the fallback as an automatic detection-and-reroute step that carries the same line-level breakdown, so only the delivery mechanism changes and posting stays identical across channels.

Is a request for payment a collections action? No — it is a payable message the patient can decline, with no reporting or enforcement mechanism behind it. That said, when and how you may contact patients about balances is governed by your payer contracts and by state and federal law. A softer instrument does not change the rules governing the outreach. Consult counsel for your jurisdiction.

Try it against your own remittance

The shteg.ai sandbox takes a de-identified 835 and returns the patient-request view: PR-group totals per claim with CO, OA, and PI dollars excluded and labeled, per-line SVC/CAS balancing checks, a flag on any claim with unresolved secondary-payer status, and a rendering of the exact request payload — every field that would leave your environment, and nothing else.

Run one file. Compare the PR total it produces against what your last statement run billed for the same claims. The delta is the case for changing the workflow.

[Open the shteg.ai sandbox →](/sandbox) [verify link target before publish]


Educational content for practice administration and revenue-cycle staff. Not legal, billing, coding, or compliance advice. All segment values, claim identifiers, and dollar amounts in this article are synthetic illustrations and contain no patient data. Payment network capabilities, message specifications, participation, and operating rules change — verify current specifications with your financial institution and clearinghouse before making operational decisions. Patient balance collection is governed by your payer contracts and by applicable state and federal law, including protections for QMB and other dual-eligible individuals; consult counsel for your jurisdiction.


Spec check: ~1,540 words · H1 + 6 H2 · one comparison table · worked example (SVC02 = SVC03 + CAS across three lines, claim-level roll-up verified) · 3-question FAQ · sandbox CTA · disclaimer. Internal links to briefs #1 and #2 per the brief's link plan, both flagged [verify link target before publish]. No statistics asserted; network-spec and regulatory claims carry [verify] markers.

Approve the write and I'll save it to workspace/drafts/revenue-cycle-3-mssk4b1e.md.

<!-- generated_by: claude-draft-1 -->