Overview
This webhook endpoint allows external systems (e.g., payment processors like Stripe via Elation) to post patient payments directly to Cair Health. When a patient makes a payment, you can send the payment information to this endpoint, and it will automatically update the associated claim with the payment details.
Use Cases
- Payment Processing Integration: Integrate with payment processors (Stripe, Square, etc.) to automatically record patient payments
- EHR Integration: Connect with EHR systems like Elation to sync patient payment data
- Automated Payment Recording: Automatically update claims when payments are received through external systems
Authentication
This endpoint requires JWT access token authentication, consistent with all other public API endpoints.
First, obtain an access token by calling the /api/token endpoint with your clientId and clientSecret:
curl -X POST https://forecaster.cairhealth.com/api/token \
-H "Content-Type: application/json" \
-d '{
"clientId": "your-client-id",
"clientSecret": "your-client-secret"
}'
Then include the access token in the Authorization header:
Authorization: Bearer <accessToken>
Your clientId and clientSecret can be found in your admin panel.
Request Body
The Elation bill.id that maps to the Claim identifier. This should match the
Claim identifier with system
https://fhir.cairhealth.com/fhir/identifier/claim-id.
The payment amount in USD. Must be a positive number.
The date of the payment in ISO 8601 format (e.g., “2024-01-15” or
“2024-01-15T10:30:00Z”). If not provided, defaults to the current date.
The method of payment (e.g., “Credit Card”, “Debit Card”, “Stripe”, “Check”,
“Cash”).
The transaction ID or payment intent ID from the payment processor (e.g.,
Stripe payment intent ID like “pi_1234567890”).
Example Request
# First, get an access token
TOKEN_RESPONSE=$(curl -X POST https://forecaster.cairhealth.com/api/token \
-H "Content-Type: application/json" \
-d '{
"clientId": "your-client-id",
"clientSecret": "your-client-secret"
}')
ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.accessToken')
# Then use the access token to call the webhook
curl -X POST https://forecaster.cairhealth.com/api/webhooks/patient-payment \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"billId": "12345",
"paymentAmount": 150.75,
"paymentDate": "2024-01-15",
"paymentMethod": "Credit Card",
"paymentTraceId": "pi_1234567890"
}'
Response
Success Response (200)
Indicates whether the payment was processed successfully (always true for
200 responses).
A success message describing the result.
Contains the payment processing details: - claimId: The UUID of the claim
that was updated - claimLifecycleId: The lifecycle ID of the claim -
amountSetOnClaim: The amount that was set on the claim (may be less than
paymentAmount if payment exceeds patient responsibility) - excessAmount:
(Optional) Only present if the payment amount exceeds the patient’s
responsibility. This excess amount is automatically created as an unallocated
patient credit.
{
"success": true,
"message": "Payment processed successfully",
"data": {
"claimId": "550e8400-e29b-41d4-a716-446655440000",
"claimLifecycleId": "lifecycle-12345",
"amountSetOnClaim": 150.75,
"excessAmount": 0
}
}
Error Responses
400 Bad Request
Returned when the request body is invalid or missing required fields.
{
"error": "Invalid request body",
"details": [
{
"path": ["paymentAmount"],
"message": "paymentAmount must be positive"
}
]
}
401 Unauthorized
Returned when authentication fails.
{
"error": "Invalid or expired access token"
}
404 Not Found
Returned when the claim cannot be found for the provided billId.
{
"error": "Claim not found for billId: 12345"
}
500 Internal Server Error
Returned when an unexpected error occurs during payment processing.
{
"error": "Failed to process payment",
"details": "Error message describing what went wrong"
}
Payment Processing Logic
When a payment is received:
-
Claim Lookup: The system searches for a claim matching the provided
billId using the identifier system https://fhir.cairhealth.com/fhir/identifier/claim-id.
-
Patient Responsibility Calculation: The system calculates the patient’s responsibility from the associated ClaimResponse resource.
-
Payment Application:
- If the payment amount is less than or equal to the patient responsibility, the full payment amount is applied to the claim.
- If the payment amount exceeds the patient responsibility, only the responsibility amount is applied to the claim, and the excess is automatically created as an unallocated patient credit.
-
Database Updates:
- Updates the
patientPaidAmount field on all claims with the same claimLifecycleId
- Creates or updates a
PatientPaymentDetails record with payment information
-
FHIR Updates:
- Creates or updates a
PaymentReconciliation resource in FHIR
- Links the payment to the patient via the
patient-payment-issuer extension
-
Excess Payment Handling: If the payment exceeds the patient responsibility, an unallocated
PatientCredit is automatically created for the excess amount, which can be allocated to other claims later.
Notes
- The endpoint automatically handles overpayments by creating unallocated patient credits
- All claims with the same
claimLifecycleId are updated with the payment amount
- The payment date defaults to the current date if not provided
- The endpoint is idempotent - sending the same payment multiple times will update the existing payment record
Patient payment information
ISO 8601 date string (e.g., '2024-01-15'). Defaults to current date if not provided.
Payment method (e.g., 'Credit Card', 'Debit Card', 'Stripe', 'Check', 'Cash')
Stripe payment intent ID or transaction ID (e.g., 'pi_1234567890')
Payment processed successfully
Indicates whether the payment was processed successfully