Integration Best Practices Guide
This guide provides best practices for integrating with the Procare Pay Integration Service. Following these recommendations will help you build a robust, secure, and maintainable payment integration.
Getting Started: High-Level Payment Flow
The typical payment processing flow involves several key steps. Understanding this flow will help you design your integration properly.
Standard Payment Workflow
- Authenticate: Obtain a bearer token using OAuth2 client credentials flow
- Get Encryption Keys: Retrieve PAN and SAD keys for encrypting sensitive data
- Encrypt Payment Data: Encrypt card numbers and CVV codes before transmission
- Create or Retrieve Payor: Set up or lookup customer payment profile
- Process Transaction: Submit the payment request
- Handle Response: Process success or failure appropriately
- Store Transaction ID: Save the transaction ID for future reference
Authentication Best Practices
Token Management
Proper token management is critical for both security and performance.
- Cache Tokens: Don't request a new token for every API call. Cache tokens and reuse them until they expire.
- Refresh Proactively: Refresh tokens before they expire (e.g., 5-10 minutes early) to avoid service interruptions.
- Handle 401 Errors: Implement automatic token refresh when you receive a 401 Unauthorized response.
- Secure Storage: Store tokens securely in memory or encrypted storage—never log or persist them in plain text.
Credential Security
- Environment Variables: Store client ID and secret in environment variables or secure configuration management systems (AWS Secrets Manager, Azure Key Vault, etc.)
- Never Commit Credentials: Use .gitignore to prevent accidental commits of secrets to source control
- Rotate Regularly: Establish a schedule for rotating API credentials (quarterly or semi-annually)
- Least Privilege: Use credentials with the minimum necessary permissions for each application
Encryption and PCI Compliance
Data Encryption Requirements
- ALL payment card numbers (PAN) must be encrypted using the PAN key before transmission
- ALL bank account numbers must be encrypted using the PAN key
- ALL CVV/CVV2 codes must be encrypted using the SAD key
- CVV codes must NEVER be stored, even in encrypted form—use immediately and discard
- Encryption keys should be refreshed every 4-6 hours
Encryption Key Management
- Cache Keys: Cache PAN and SAD encryption keys for 4-6 hours to reduce API calls
- Use RSA PKCS#1 v1.5: Ensure your encryption implementation uses the correct padding scheme
- Base64 Encode: After encrypting, Base64-encode the result before sending to the API
- Clear Sensitive Data: Immediately clear plaintext card numbers and CVVs from memory after encryption
PCI DSS Scope Reduction
Important: To minimize your PCI DSS compliance burden, use the Procare Pay Hosted Payment Page whenever possible. Direct API integration increases your PCI scope significantly.
Error Handling and Resilience
HTTP Status Code Handling
| Status Code | Meaning | Action |
|---|---|---|
| 200/201 | Success | Process the response data |
| 400 | Bad Request | Fix the request—check required fields, formats, and validation rules. Do NOT retry without changes. |
| 401 | Unauthorized | Token expired or invalid. Refresh token and retry once. |
| 404 | Not Found | Resource doesn't exist. Verify IDs are correct. Do NOT retry. |
| 408 | Request Timeout | Retry with exponential backoff (see below) |
| 429 | Too Many Requests | Rate limit exceeded. Wait and retry with exponential backoff. |
| 500 | Internal Server Error | Temporary server issue. Retry with exponential backoff (max 3 attempts). |
| 503 | Service Unavailable | Service temporarily down. Retry with exponential backoff. |
Retry Strategy with Exponential Backoff
When encountering transient errors (408, 429, 500, 503), implement an exponential backoff retry strategy:
- First Retry: Wait 1 second
- Second Retry: Wait 2 seconds
- Third Retry: Wait 4 seconds
- Maximum Retries: Limit to 3 attempts total (original + 2 retries)
- Jitter: Add random jitter (±20%) to avoid thundering herd problems
wait_time = base_delay * (2 ^ attempt_number) + random_jitter
Where base_delay = 1 second, and random_jitter is between -200ms and +200ms
Timeout Configuration
Always configure appropriate timeouts to prevent hanging requests:
- Connection Timeout: 10 seconds (time to establish connection)
- Read Timeout: 30 seconds (time to receive response)
- Total Request Timeout: 45 seconds (overall maximum)
Idempotency and Transaction Safety
Understanding Idempotency
Idempotency ensures that retrying a request doesn't cause duplicate transactions. This is critical for payment processing where duplicate charges can cause significant customer service issues.
Best Practices for Idempotency
- Generate Unique IDs: Create a unique transaction ID (UUID or similar) before submitting a payment
- Store Transaction State: Record transaction IDs in your database before submission
- Check Before Retry: Before retrying a failed payment, search for the transaction using your unique ID
- Handle Duplicates Gracefully: If a transaction already exists, don't resubmit—use the existing result
- Use Custom Attributes: Store your unique identifier in transaction custom attributes for easy lookup
Timeout Handling Pattern
1. Generate unique transaction ID (e.g., UUID) 2. Store transaction ID with status "PENDING" in your database 3. Submit payment request with custom attribute containing your transaction ID 4. If request times out (408): a. Wait (exponential backoff) b. Search for transaction using your unique ID in custom attributes c. If found: Update your database with the result d. If not found after 3 attempts: Mark as "UNKNOWN" and investigate manually 5. Update your database with final transaction status
Performance Optimization
Caching Strategy
| Resource | Cache Duration | Notes |
|---|---|---|
| Bearer Token | 5 hour, 55 minutes | Tokens expire after 6 hours; refresh 5 min early |
| PAN Encryption Key | 4-6 hours | Keys rotate periodically |
| SAD Encryption Key | 4-6 hours | Keys rotate periodically |
| Merchant Info | 24 hours | Merchant settings rarely change |
| BIN Information | 7 days | BIN data is relatively stable |
Connection Pooling
- Reuse HTTP Clients: Don't create a new HTTP client for each request—reuse instances
- Connection Pooling: Configure connection pools with appropriate size (typically 10-50 connections)
- Keep-Alive: Enable HTTP keep-alive to reuse TCP connections
- DNS Caching: Cache DNS lookups to reduce latency
Batch Operations
When possible, use batch operations to reduce API calls:
- BIN Lookup: Use the bulk BIN lookup endpoint to validate multiple cards at once
- Transaction Search: Use the
pagesizeandpagecursorparameters on the Search Transactions endpoint to page through large result sets server-side. The maximumpagesizeis 500. Passpagination.nextCursoraspagecursoron each subsequent request and stop whenpagination.hasNextPageisfalse. - Payor Search: Look up multiple payors by providing multiple IDs in one request
Transaction Search Pagination
The Search Transactions endpoint supports server-side cursor-based pagination via the
pagesize query parameter. When you include pagesize, the response
changes from a bare array to a PaginatedTransactionResponse envelope:
{
"data": [ /* up to pagesize TransactionResponse objects */ ],
"pagination": {
"hasNextPage": true,
"nextCursor": "<opaque token>"
}
}
To retrieve all pages, loop until pagination.hasNextPage is false,
passing pagination.nextCursor as the pagecursor parameter on each
subsequent request. See the
Search Transactions page for
full code examples in C#, VB.NET, Java, and Ruby.
pagesize returns the original
flat array response. No changes are required to existing integrations that do not need pagination.
Security Best Practices
Data Protection
- Card numbers (even last 4 digits should be minimal)
- CVV codes can never be stored or logged
- Track data can never be stored or logged
- Bank account numbers
- Bearer tokens
- Encryption keys
- API credentials
HTTPS Only
- TLS 1.2+: Only use TLS 1.2 or higher (TLS 1.0 and 1.1 are deprecated)
- Certificate Validation: Always validate SSL certificates—never disable verification
- HTTPS for All: Use HTTPS for all API communications without exception
Input Validation
- Validate Before Encryption: Check card number format (Luhn algorithm) before encrypting
- Sanitize Input: Remove whitespace, dashes, and other formatting from card numbers
- Check Expiry Dates: Validate that card expiry dates are in the future
- Amount Validation: Ensure amounts are positive and within reasonable ranges
Rate Limiting
Implement client-side rate limiting to avoid hitting API limits:
- Track Request Counts: Monitor requests per second/minute
- Queue Requests: Use a queue to smooth out request spikes
- Backoff on 429: When you receive a 429 response, implement exponential backoff
- Spread Load: Distribute batch operations over time rather than sending all at once
Testing Best Practices
Test Environment Usage
- Development Testing: Use development/test environments for all testing—never test with production credentials
- Test Cards: Use provided test card numbers (e.g., 4111111111111111 for Visa)
- Test Scenarios: Test success, various failure modes, timeouts, and edge cases
- Integration Tests: Create automated integration tests for your payment flows
Testing Checklist
| Test Scenario | Expected Behavior |
|---|---|
| Successful payment | Transaction approved, status 200/201, transaction ID returned |
| Invalid card number | Validation error, status 400, clear error message |
| Expired token | 401 error, automatic token refresh and retry |
| Network timeout | Retry with backoff, check for duplicate transaction |
| Server error (500) | Retry with backoff, max 3 attempts, log error details |
| Declined card | Transaction declined, clear decline reason, no retry |
| Rate limiting (429) | Backoff and retry after delay |
| Duplicate transaction | Detect and prevent duplicate charges |
Monitoring and Observability
Key Metrics to Track
- Success Rate: Percentage of successful transactions (target: >95%)
- Response Time: P50, P95, P99 latency (target: P95 < 2 seconds)
- Error Rate: 4xx and 5xx errors per minute
- Timeout Rate: Percentage of requests that timeout
- Token Refresh Rate: How often tokens are refreshed vs cached
- Retry Rate: How often requests need to be retried
Logging Best Practices
- Log Request IDs: Include correlation IDs in all logs for tracing
- Log Business Context: Include customer ID, order ID, amount (but not card details)
- Log Timing: Record request/response times for performance analysis
- Log Errors: Capture full error details including status codes and error messages
- Structured Logging: Use JSON or structured format for easier analysis
Alerting
Set up alerts for critical issues:
- High Error Rate: Alert if error rate exceeds 5% over 5 minutes
- Slow Response Times: Alert if P95 latency exceeds 3 seconds
- Authentication Failures: Alert on repeated 401 errors
- Payment Failures: Alert if transaction approval rate drops below 85%
- Timeout Spikes: Alert if timeout rate exceeds 2%
Common Integration Patterns
Pattern 1: First-Time Payment with Profile Creation
// High-level workflow 1. Authenticate and get bearer token 2. Get PAN and SAD encryption keys 3. Encrypt card number with PAN key 4. Encrypt CVV with SAD key (for immediate use only) 5. Create payor profile with encrypted card 6. Process transaction using saved payment method ID 7. Store transaction ID in your database 8. Clear all sensitive data from memory
Pattern 2: Recurring Payment (Subscription)
// High-level workflow 1. Authenticate and get bearer token (use cached token if available) 2. Look up payor by your customer ID 3. Get the default payment method from payor profile 4. Process transaction using saved payment method ID 5. Store transaction ID in your database 6. Send receipt/confirmation to customer
Pattern 3: Refund Processing
// High-level workflow 1. Authenticate and get bearer token 2. Search for original transaction by your order ID or transaction ID 3. Validate refund amount (cannot exceed original amount) 4. Initiate refund with original transaction ID 5. Store refund transaction ID in your database 6. Update order status in your system 7. Send refund confirmation to customer
Pattern 4: Update Expired Card
// High-level workflow 1. Authenticate and get bearer token 2. Get PAN encryption key 3. Encrypt new card number 4. Look up payor profile 5. Add new payment method with setAsDefault: true 6. Optional: Delete old expired payment method 7. Confirm update with customer
Production Readiness Checklist
Before going to production, ensure you have implemented:
Security
- ✓ All sensitive data is encrypted before transmission
- ✓ CVV codes are never stored (even encrypted)
- ✓ Credentials are stored securely (not hardcoded)
- ✓ All API calls use HTTPS with TLS 1.2+
- ✓ Logging excludes all sensitive information
- ✓ Input validation is implemented
Resilience
- ✓ Exponential backoff retry logic for transient errors
- ✓ Proper timeout configuration (connection, read, total)
- ✓ Idempotency handling to prevent duplicate charges
- ✓ Graceful degradation for non-critical failures
- ✓ Circuit breaker pattern for cascading failures
Performance
- ✓ Token caching implemented
- ✓ Encryption key caching implemented
- ✓ HTTP client reuse/connection pooling configured
- ✓ Batch operations used where applicable
- ✓ Response time SLAs defined and monitored
Observability
- ✓ Comprehensive logging with correlation IDs
- ✓ Key metrics tracked (success rate, latency, error rate)
- ✓ Alerts configured for critical issues
- ✓ Dashboard created for monitoring
- ✓ On-call procedures documented
Testing
- ✓ Unit tests for all business logic
- ✓ Integration tests for API interactions
- ✓ Error scenario testing (timeouts, failures, etc.)
- ✓ Load testing to validate performance
- ✓ Security testing (penetration test if required)
Documentation
- ✓ Integration architecture documented
- ✓ Error handling procedures documented
- ✓ Runbook created for operations team
- ✓ Customer support team trained on payment flows
- ✓ Disaster recovery procedures defined
Support and Resources
Additional Documentation
- RESTful Web Services Overview - Introduction to REST APIs
- AWS Cognito OAuth2 - Authentication details
- API Documentation Home - All available endpoints
Getting Help
If you encounter issues or have questions:
- Review Documentation: Check the specific endpoint documentation for details
- Check Logs: Review your application logs and API response messages
- Test Environment: Reproduce issues in the test environment first
-
Contact Support: Reach out to the Procare Software Transaction Processing team with:
- Detailed description of the issue
- Correlation ID from the API response
- Timestamp of the occurrence
- Request/response details (excluding sensitive data)