Payment Management
Overview
Payment management handles post-processing operations including refunds, cancellations, disputes, retry logic, and transaction history. This guide covers the complete management lifecycle for payments after initial processing.
Table of Contents
- Refunding Payments
- Canceling Payments
- Voiding Authorizations
- Retrying Failed Payments
- Dispute Management
- Payment Transactions
- Payment Reconciliation
Refunding Payments
Full Refund
Endpoint: POST /api/v1/sales/payments/{payment}/refund
Authentication: Required (Bearer token)
Purpose: Issue full or partial refund for completed payment
Prerequisites:
- Payment must be in
completedstatus - Payment must not be fully refunded already
- Refund must be within allowed timeframe (typically 180 days)
Request Body (Full Refund):
{
"amount": 347.47,
"refund_reason": "product_return",
"reason_details": "Customer returned product - defective",
"notify_customer": true,
"refund_method": "original_payment_method"
}Response (200 OK):
{
"message": "Payment refunded successfully",
"data": {
"id": 789,
"payment_number": "PAY-12345678",
"status": "refunded",
"amount": 347.47,
"refunded_amount": 347.47,
"refund": {
"id": 890,
"refund_number": "REF-87654321",
"amount": 347.47,
"refund_reason": "product_return",
"reason_details": "Customer returned product - defective",
"refund_method": "credit_card",
"processed_at": "2025-12-19T10:00:00Z",
"expected_arrival": "2025-12-24"
},
"refunded_at": "2025-12-19T10:00:00Z",
"customer_notified": true
}
}Partial Refund
Request Body:
{
"amount": 100.00,
"refund_reason": "partial_return",
"reason_details": "Customer returned 1 of 2 items",
"notify_customer": true
}Response:
{
"data": {
"status": "partially_refunded",
"amount": 347.47,
"refunded_amount": 100.00,
"remaining_amount": 247.47,
"refund": {
"id": 890,
"amount": 100.00,
"refund_reason": "partial_return"
}
}
}Refund Reasons
Standard Refund Reasons:
customer_request- Customer requested refundproduct_return- Product returneddefective_product- Product defective or damagedwrong_item_shipped- Incorrect item shippedduplicate_charge- Duplicate payment processedcancelled_order- Order cancelledservice_not_provided- Service not deliveredbilling_error- Billing mistakeother- Other reason (provide details)
Viewing Refunds
Endpoint: GET /api/v1/sales/payments/{payment}/refunds
Response (200 OK):
{
"data": [
{
"id": 890,
"refund_number": "REF-87654321",
"amount": 100.00,
"refund_reason": "partial_return",
"refund_method": "credit_card",
"status": "completed",
"processed_at": "2025-12-19T10:00:00Z",
"expected_arrival": "2025-12-24",
"gateway_refund_id": "re_1234567890"
}
],
"meta": {
"total_refunds": 1,
"total_refunded": 100.00,
"remaining_refundable": 247.47
}
}Canceling Payments
Cancel Payment
Endpoint: POST /api/v1/sales/payments/{payment}/cancel
Authentication: Required (Bearer token)
Purpose: Cancel payment before processing completes
Prerequisites:
- Payment must be in
pendingorprocessingstatus - Payment not yet completed
- Cancellation must be possible (not all gateways support mid-processing cancellation)
Request Body:
{
"cancellation_reason": "Customer requested cancellation before processing",
"notify_customer": true,
"release_invoice_hold": true
}Response (200 OK):
{
"message": "Payment cancelled successfully",
"data": {
"id": 789,
"payment_number": "PAY-12345678",
"status": "cancelled",
"cancelled_at": "2025-12-18T10:30:00Z",
"cancellation_reason": "Customer requested cancellation before processing",
"invoice_updated": true,
"customer_notified": true
}
}What Happens on Cancellation:
- Payment status changes to
cancelled - No funds transferred
- Invoice remains unpaid
- Customer notified if requested
- Payment cannot be reactivated
Error Response:
{
"error": "Cannot cancel payment",
"message": "Payment already completed. Use refund endpoint instead.",
"current_status": "completed"
}Voiding Authorizations
Void Authorized Payment
Endpoint: POST /api/v1/sales/payments/{payment}/void
Authentication: Required (Bearer token)
Purpose: Cancel payment authorization and release reserved funds
Prerequisites:
- Payment must be in
authorizedstatus - Authorization must not be expired
- Authorization must not be captured
Request Body:
{
"void_reason": "Order cancelled - void authorization",
"notify_customer": true
}Response (200 OK):
{
"message": "Payment authorization voided successfully",
"data": {
"id": 789,
"payment_number": "PAY-12345678",
"status": "voided",
"voided_at": "2025-12-18T15:00:00Z",
"void_reason": "Order cancelled - void authorization",
"authorization_released": true,
"funds_available_to_customer": true,
"customer_notified": true
}
}Void vs Cancel vs Refund:
- Void: Release authorization (funds never captured)
- Cancel: Stop pending/processing payment (before completion)
- Refund: Return captured funds (after completion)
Retrying Failed Payments
Retry Failed Payment
Endpoint: POST /api/v1/sales/payments/{payment}/retry
Authentication: Required (Bearer token)
Purpose: Retry failed payment with same or updated details
Prerequisites:
- Payment must be in
failedstatus - Failure reason must be retryable (not fraud/blocked)
- Updated payment details available (if failure due to invalid data)
Request Body (Retry with Same Details):
{
"retry_reason": "Temporary gateway error - retrying",
"use_original_details": true
}Request Body (Retry with Updated Details):
{
"retry_reason": "Updated card details provided by customer",
"use_original_details": false,
"payment_method_token": "pm_new_token_9876",
"billing_address": {
"street": "456 New St",
"city": "San Francisco",
"state": "CA",
"postal_code": "94105",
"country": "US"
}
}Response (200 OK):
{
"message": "Payment retry initiated successfully",
"data": {
"id": 789,
"payment_number": "PAY-12345678",
"status": "processing",
"retry_count": 1,
"previous_failure_reason": "insufficient_funds",
"retry_initiated_at": "2025-12-19T11:00:00Z"
}
}Automatic Retry Logic: The system can automatically retry failed payments based on configuration:
- Retry 1: After 1 hour
- Retry 2: After 24 hours
- Retry 3: After 72 hours
- Max retries: 3 (configurable)
Non-Retryable Failures:
- Stolen card
- Fraud detected
- Invalid card number
- Expired card (unless updated)
- Customer blocked
- Payment method disabled
Dispute Management
Handling Disputed Payments (Chargebacks)
Endpoint: POST /api/v1/sales/payments/{payment}/dispute
Authentication: Required (Bearer token)
Purpose: Record and manage payment disputes/chargebacks
Request Body:
{
"dispute_reason": "fraudulent",
"dispute_amount": 347.47,
"dispute_date": "2025-12-25",
"dispute_id": "DIS-123456789",
"evidence_required": true,
"evidence_due_date": "2026-01-08",
"notes": "Customer claims unauthorized charge"
}Response (200 OK):
{
"message": "Payment dispute recorded successfully",
"data": {
"id": 789,
"payment_number": "PAY-12345678",
"status": "disputed",
"disputed_at": "2025-12-25T00:00:00Z",
"dispute": {
"id": "DIS-123456789",
"reason": "fraudulent",
"amount": 347.47,
"dispute_date": "2025-12-25",
"evidence_due_date": "2026-01-08",
"status": "open"
},
"funds_held": true,
"action_required": "submit_evidence"
}
}Dispute Reasons
Common Dispute Reasons:
fraudulent- Customer claims unauthorized chargeunrecognized- Customer doesn't recognize chargeduplicate- Customer charged twiceproduct_not_received- Product never deliveredproduct_unacceptable- Product defective/not as describedcredit_not_processed- Refund not receivedsubscription_cancelled- Charged after cancellationother- Other reason
Submitting Dispute Evidence
POST /api/v1/sales/payments/{payment}/dispute/submit-evidence
{
"evidence_type": "shipping_documentation",
"evidence_files": [
"tracking_proof.pdf",
"delivery_signature.pdf",
"invoice_copy.pdf"
],
"evidence_text": "Customer signed for delivery on 12/20/2025. Tracking number 1Z999AA10123456784 shows delivered. Invoice INV-20251217-001 attached.",
"customer_communication": [
"email_confirmation_12_17.pdf",
"shipping_notification_12_18.pdf"
]
}Viewing Failed Payments
Endpoint: GET /api/v1/sales/payments/failed
Response (200 OK):
{
"data": [
{
"id": 791,
"payment_number": "PAY-12345680",
"status": "failed",
"amount": 299.00,
"method": "credit_card",
"failure_reason": "insufficient_funds",
"failed_at": "2025-12-18T11:00:00Z",
"retry_count": 2,
"can_retry": true,
"customer": {
"id": 43,
"company_name": "Beta Corp"
}
}
],
"meta": {
"total_failed": 1,
"total_failed_amount": 299.00,
"retryable_count": 1
}
}Viewing Disputed Payments
Endpoint: GET /api/v1/sales/payments/disputed
Response (200 OK):
{
"data": [
{
"id": 789,
"payment_number": "PAY-12345678",
"status": "disputed",
"amount": 347.47,
"dispute_reason": "fraudulent",
"disputed_at": "2025-12-25T00:00:00Z",
"evidence_due_date": "2026-01-08",
"days_to_respond": 14,
"requires_urgent_action": false
}
],
"meta": {
"total_disputed": 1,
"total_disputed_amount": 347.47,
"evidence_required": 1,
"urgent_disputes": 0
}
}Payment Transactions
View Transaction History
Endpoint: GET /api/v1/sales/payments/{payment}/transactions
Authentication: Required (Bearer token)
Purpose: View complete transaction history for a payment
Response (200 OK):
{
"data": [
{
"id": 1001,
"type": "authorization",
"amount": 347.47,
"status": "succeeded",
"gateway_transaction_id": "auth_1234567890",
"created_at": "2025-12-18T09:00:00Z"
},
{
"id": 1002,
"type": "capture",
"amount": 347.47,
"status": "succeeded",
"gateway_transaction_id": "ch_1234567890",
"created_at": "2025-12-18T14:30:00Z"
},
{
"id": 1003,
"type": "refund",
"amount": -100.00,
"status": "succeeded",
"gateway_transaction_id": "re_1234567890",
"created_at": "2025-12-19T10:00:00Z"
}
],
"meta": {
"total_transactions": 3,
"net_amount": 247.47
}
}Transaction Types
Authorization:
- Reserves funds
- Does not transfer money
- Expires after hold period
Capture:
- Transfers reserved funds
- Completes payment
- Creates settlement
Refund:
- Returns funds to customer
- Reverses capture
- May have fees
Void:
- Cancels authorization
- Releases reserved funds
- No money transferred
Chargeback:
- Customer dispute
- Funds held/reversed
- Requires evidence
Payment Reconciliation
Payment Statistics
Endpoint: GET /api/v1/sales/payments/statistics
Query Parameters:
from_date(date) - Start dateto_date(date) - End datemethod(string) - Filter by payment methodstatus(string) - Filter by status
Response (200 OK):
{
"data": {
"period": {
"from": "2025-12-01",
"to": "2025-12-31"
},
"payment_counts": {
"total": 1247,
"completed": 1156,
"failed": 45,
"disputed": 3,
"refunded": 23,
"pending": 20
},
"financial_metrics": {
"total_processed": 1245678.90,
"total_refunded": 23456.78,
"total_fees": 34567.89,
"net_revenue": 1187654.23,
"average_transaction": 998.87
},
"method_breakdown": {
"credit_card": {
"count": 856,
"amount": 876543.21,
"percentage": 70.4
},
"bank_transfer": {
"count": 234,
"amount": 234567.89,
"percentage": 18.8
},
"paypal": {
"count": 157,
"amount": 134567.80,
"percentage": 10.8
}
},
"success_metrics": {
"success_rate": 96.2,
"failure_rate": 3.6,
"dispute_rate": 0.2,
"average_processing_time_seconds": 4.5
}
}
}Payment Activities
Endpoint: GET /api/v1/sales/payments/{payment}/activities
Response (200 OK):
{
"data": [
{
"id": 5001,
"type": "payment_refunded",
"description": "Partial refund issued - $100.00",
"user": {
"id": 5,
"name": "Jane Manager"
},
"metadata": {
"refund_amount": 100.00,
"refund_reason": "partial_return"
},
"created_at": "2025-12-19T10:00:00Z"
},
{
"id": 5000,
"type": "payment_completed",
"description": "Payment processed successfully",
"user": {
"id": null,
"name": "System"
},
"metadata": {
"gateway": "stripe",
"transaction_id": "ch_1234567890"
},
"created_at": "2025-12-18T14:30:00Z"
},
{
"id": 4999,
"type": "payment_authorized",
"description": "Payment authorized",
"user": {
"id": 3,
"name": "John Sales"
},
"metadata": {
"authorization_code": "AUTH-456789"
},
"created_at": "2025-12-18T09:00:00Z"
}
]
}Best Practices
Refund Promptly: Process refunds quickly to maintain customer satisfaction
Document Everything: Record detailed reasons for refunds, cancellations, and disputes
Monitor Dispute Rate: High dispute rates may indicate fraud or customer service issues
Retry Intelligently: Use exponential backoff for automatic payment retries
Track Transaction History: Maintain complete audit trail for compliance
Respond to Disputes Quickly: Submit evidence before deadline to avoid automatic loss
Reconcile Daily: Match payment records with gateway settlements daily
Handle Partial Refunds Carefully: Ensure accounting properly reflects partial refunds
Test Refund Flows: Verify refund processing in test environment before production
Notify Customers: Always inform customers of refunds, cancellations, and disputes
Related Guides
- Payment Processing - Creating and processing payments
- Invoice Workflow - Invoice payment tracking
- Sales Analytics - Payment analytics and reporting
- Order-to-Cash Workflow - Complete payment lifecycle