Skip to main content
Refund captured payments to customers after an initial transaction. Common scenarios include:
  • Customer returns a product or requests a refund from a service
  • Customer cancels an order after payment
  • Customer requests a partial refund
This integration uses the Payments API v2 to process full or partial refunds with the capture ID from the original payment. Add refund endpoints to your existing PayPal integration with comprehensive error handling and negative testing capabilities.

Prerequisites

  • Complete the quick start PayPal integration.
  • You have a capture ID from the original payment transaction.
  • You have a database or system to track payment and refund history.

Integrate server side

Add the following to your existing server file from the quick start integration.
# Refund a captured payment
curl -X POST https://api-m.sandbox.paypal.com/v2/payments/captures/CAPTURE_ID/refund \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -d '{
    "amount": {
      "value": "25.00",
      "currency_code": "USD"
    },
    "note_to_payer": "Refund processed"
  }'

# Get refund status
curl -X GET https://api-m.sandbox.paypal.com/v2/payments/refunds/REFUND_ID \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Test endpoints

# Test full refund (replace with actual capture ID)
curl -X POST http://localhost:3000/api/captures/3C679366HH908993F/refund \
  -H "Content-Type: application/json"

# Expected success response:
# {"id":"WH4YN4SYEDZJA","status":"COMPLETED","amount":"100.00"}

# Test partial refund with note
curl -X POST http://localhost:3000/api/captures/3C679366HH908993F/refund \
  -H "Content-Type: application/json" \
  -d '{"amount": "25.00", "note": "Partial refund for damaged item"}'

# Test refund status check
curl http://localhost:3000/api/refunds/WH4YN4SYEDZJA

# Expected response:
# {"id":"WH4YN4SYEDZJA","status":"COMPLETED","amount":"25.00"}

Best practices

Use the following best practices to ensure refunds are processed safely, accurately, and in compliance with operational and regulatory requirements.
  • Store capture IDs: Always save capture IDs from successful payments in your database for future refunds.
  • Use idempotency keys: Use idempotency keys when processing refunds to avoid duplicate refunds in case of network issues.
  • Validate refund amounts: Check the refund amount doesn’t exceed original payment or remaining refundable balance.
  • Log all refunds: Keep an audit trail of who initiated refunds, when, and why. This is critical for compliance.
  • Provide refund notes: Include clear explanation in the note_to_payer field for customer clarity.
  • Handle partial refunds: Track cumulative refunded amounts to prevent over-refunding.
  • Process refunds within 180 days: Process refunds within 180 days of the original capture date. Your customer’s bank may have shorter windows. After extended periods, manual intervention through PayPal support may be required.
  • Implement approval workflows: Processed refunds cannot be cancelled. Build approval workflows for refunds over a certain threshold.
  • Have backup manual refund process: Have a manual refund process as backup. Log failed attempts and escalate to PayPal support with the error details.

Important details

  • Find capture IDs: The capture ID is returned as capture.result.id when you capture a payment. Store this value in your database immediately. You’ll need it for any future refunds on that transaction.
  • Refund processing time: In sandbox mode, refunds complete instantly. In production, customers see refunds in their account within 3-5 business days, though timing varies by payment method.
  • Webhook notifications: Set up webhooks to receive PAYMENT.CAPTURE.REFUNDED events for real-time status updates. Always verify webhook signatures for security.
  • No refunds to different payment methods: Refunds always go back to the customer’s original payment method.
  • No currency conversion: Always refund in the same currency as the original payment. PayPal handles any exchange rate adjustments automatically.

Test your integration

Make sure you have sandbox account credentials for both buyer and seller roles. Complete a test payment to get a valid capture ID.

Standard testing

Test scenarioSetupExpected result
Full refund successDefault settingsEntire payment amount refunded.
Partial refund successDefault settingsSpecified amount refunded.
Multiple partial refund successDefault settingsEach refunds succeeds until limit.
Invalid capture IDFake IDL XXX123404 error: capture not found.
Refund after 3 daysWait 3 daysSuccess if within 180 days

Negative testing

For negative testing:
  1. Make sure to enable negative testing in your sandbox business account as described in the quick start prerequisites.
  2. In the .env file, set ENABLE_NEGATIVE_TESTING=true and set NEGATIVE_TEST_TYPE to one of the error codes in the table.
  3. Restart the server after changing the .env file: node server.js.
Test scenarioError codeExpected result
Exceed original amountREFUND_AMOUNT_EXCEEDEDError: refund amount exceeds capture.
Already fully refundedCAPTURE_FULLY_REFUNDEDError: already fully refunded.
Refund after 180 daysREFUND_NOT_ALLOWED_AFTER_180_DAYSError: refund period expired.
Permission deniedPERMISSION_DENIED403 error: no refund permission.
Internal server errorINTERNAL_SERVER_ERRORError: 500 error occurred at refund.

Go-live checklist

  • Test full and partial refunds in sandbox.
  • Implement refund approval workflow.
  • Set up refund logging and audit trail.
  • Add authentication to refund endpoints.
  • Configure refund permission roles.
  • Set up webhook listeners for refund events.
  • Test with real $1 payment and refund it.

Post-launch monitoring

These values are suggested monitoring thresholds for your integration, not performance guarantees from PayPal.
MetricTargetAction if below target
Refund success rate98%Check API errors and validate capture IDs.
Refund processing time<5 secondsOptimize database queries.
Failed refund rate<2%Review error logs, check amounts.
Refund-to-payment ratio<5%Analyze if high - may indicate quality issues.
API response time<2 secondsCheck PayPal API status.