Skip to main content

Developer API

Payment links from your own software

Create PatientPayments™ bill pay links for patient balances with one REST call, then get a signed webhook the moment the patient pays, the bank returns the debit, or the office issues a refund. Built for practice management systems, billing vendors, and in-house tools.

OpenAPI 3 spec at /api/v1/openapi.json · Test mode with no money moved · HMAC-signed webhooks

POST /api/v1/payment-links
curl https://api.patientpayments.com/api/v1/payment-links \
  -H "Authorization: Bearer pp_test_…" \
  -H "Idempotency-Key: 7c1e4f0a-9b2d-4e3c-8f1a-2d5b6c7e8f90" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 185.00,
    "description": "Crown - tooth #14",
    "externalReference": "INV-2026-00123",
    "patient": {
      "firstName": "Jordan",
      "lastName": "Rivera",
      "phone": "+12085551234",
      "externalId": "PMS-48213"
    }
  }'

→ 201 Created
{
  "id": "plink_3f2a9c1d4e5b4f6a8d9c5e3f2a1b0c9d",
  "url": "https://secure.patientpayments.com/pay/K7M2P9QX",
  "status": "active",
  "amount": 185.00,
  ...
}

What you can build

One integration, every balance collected

The office keeps its PatientPayments™ account, Stripe payouts, receipts, and dashboard. Your software decides when a balance is due.

Statements that pay themselves

Generate a link for every open balance in your ledger and drop it on the statement, in the portal, or in your own text and email. Patients pay by card or bank on a hosted page.

Post payments automatically

Subscribe to payment_link.paid and post the payment to the right account the second it clears. Refunds, bank returns, and disputes arrive the same way.

Nothing sensitive in your stack

Card and bank details are entered on PatientPayments™ hosted pages, never in your software. You send an amount and a name; you get back a URL and events.

How it works

Most integrations are a few dozen lines. Start in test mode, flip to a live key when the office is ready.

1

Get a key

The practice admin creates a pp_test_ or pp_live_ key under API & Webhooks.

2

Create a link

One POST with an amount, description, and the patient's name and mobile number returns a hosted payment URL.

3

Register a webhook

Point an HTTPS endpoint at us. Every event is signed with HMAC-SHA256 and retried for up to three days.

4

Simulate, then go live

In test mode, POST /simulate drives paid, processing, failed, and expired outcomes so you can test every path without a card.

Webhooks

Every state change, delivered

Events carry the full payment link, so one handler can post, reverse, and reconcile without a follow-up call. Same event id on every retry, so duplicates are easy to ignore. Missed a few while you were down? Replay up to 30 days.

Webhook integration guide →
payment_link.processingBank payment submitted, settling in 3–5 business days
payment_link.paidPayment succeeded (card immediately, bank once settled)
payment_link.failedBank payment returned after submission
payment_link.refundedOffice refunded some or all of the payment
payment_link.disputedPatient's bank opened a chargeback
payment_link.dispute_closedDispute resolved, won or lost
payment_link.expiredLink passed its expiry unpaid
payment_link.cancelledCancelled by your integration or office staff

Designed to be safe to expose

The API only ever touches the practice that issued the key, and only the data a payment link needs.

Scoped keys

Read, write, and webhook permissions are granted separately. Keys can be pinned to a single location and given an expiry.

Opaque ids

Every id is a random plink_, loc_, we_, or evt_ value. Nothing is guessable or sequential.

Signed webhooks

HMAC-SHA256 over a timestamp and the raw body, with a 5-minute replay window and zero-downtime secret rotation.

Idempotent writes

Send an Idempotency-Key and retry freely. A network blip never creates two links.

Ready to connect?

API access is switched on per practice. If you build software for practices, tell us which one you are starting with and we will enable it and send you a test key the same day.