Prove that the money of this refund went back to the payer. The refund reached the status COMPLETED. A 201 Created answer with the status PENDING is an object that exists and not money that went back.

Contract identity.
FactValue
Contract idpaypal.refund.completed
Version1.0.0
Hash771e6b42e16841a3
Completion levelrefund_completed
PublisherBuilt and signed by Provely.
CertificationProvisional
SkillPayPal REST API 0.1.0
Valid for provider API versionsv2

What is the intent?

Refund the captured payment to the payer and let the money move back.

What is the subject and the action?

MemberValue
Subject typepaypal.refund
Subject identityrefund_id = $action.result.id
Canonical effectmoney.refund
Provider operationPOST /v2/payments/captures/{capture_id}/refund
Idempotencyidempotency_key through PayPal-Request-Id, retry is safe

How does the evidence correlate with this operation?

StrategyAssuranceKeysRequired
resource_idstrongrefund_id from $action.result.idno
resource_idweakcapture_id from $input.capture_idno
fingerprintweakcapture_id from $input.capture_id; amount from $input.amountno

Which evidence does the contract require?

Minimum evidence level E2. An independent channel is required. Minimum channels: 1.

ChannelLevelIndependenceVerifierDescription
refund_readbackE2provider readbackhttpRead the refund from the Payments API. A condition path is $observed.refund_readback.status, and the amount sits at $observed.refund_readback.amount.value as a string.
capture_refunded_eventsE3provider eventwebhookThe PAYMENT.CAPTURE.REFUNDED events of the intended captured payment, since the operation started. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A count above one shows a second refund of the same capture.

Which conditions must all hold for VERIFIED?

ConditionMeaningPathOperatorExpectedEvidence
refund_presentThe Payments API holds the refund that the refund response named.$observed.refund_readback.ideq$action.result.idrefund_readback
refund_amount_matchesThe refunded amount equals the requested amount. PayPal states the value as a string, so this is a string comparison and it normalizes nothing.$observed.refund_readback.amount.valueeq$input.amountrefund_readback
refund_currency_matchesThe currency of the refunded amount equals the requested currency.$observed.refund_readback.amount.currency_codeeq$input.currency_coderefund_readback
refund_created_in_windowPayPal made the refund after the operation started.$observed.refund_readback.create_timetime_after$operation.created_atrefund_readback
refund_on_intended_captureAt least one PAYMENT.CAPTURE.REFUNDED event names the captured payment that the intent named. The refund resource names no capture, so this event is the only tie between the two.$observed.capture_refunded_events.countgte1capture_refunded_events
refund_status_completedThe refund states the status COMPLETED. That is the only status that proves that the money went back.$observed.refund_readback.statuseqCOMPLETEDrefund_readback

Which conditions give CONTRADICTED?

ConditionClassReasonPathOperatorExpected
refund_amount_mismatchwrong amountPayPal refunded a different amount than the intent stated.$observed.refund_readback.amount.valuene$input.amount
refund_currency_mismatchwrong amountPayPal refunded a different currency than the intent stated.$observed.refund_readback.amount.currency_codene$input.currency_code
refund_predates_operationpre existing stateThe refund is older than the operation. It proves nothing.$observed.refund_readback.create_timetime_before$operation.created_at
duplicate_refund_presentduplicate side effectPayPal refunded the captured payment more than once since the operation started. Do not retry.$observed.capture_refunded_events.countgt1

Which observed states map to a verdict before completion?

RuleMatchVerdictReason
refund_failed$observed.refund_readback.status eq "FAILED"FAILEDThe settlement process of the bank did not issue the refund. Retry with the first request id.
refund_still_pending$observed.refund_readback.status eq "PENDING"PENDINGThe refund is pending. The money did not move back. The runtime observes again.

How long does the runtime observe?

Timing memberValue
Initial delay2000 ms
Poll interval5000 ms
Backoffexponential factor 2, max 300000 ms
Maximum attempts900
Timeout259200000 ms
Stale read window20000 ms
On timeoutUNVERIFIABLE (evidence_unavailable_before_timeout), escalated to a person

Where do these rules come from?

  • paypal.payments.openapi#/components/schemas/refund_status/properties/status: paypal.payments.openapi, retrieved 2026-09-08
  • paypal.docs.refunds#refunds/the-status-of-a-refund: paypal.docs.refunds, retrieved 2026-09-08
  • paypal.events#/events/PAYMENT.CAPTURE.REFUNDED: paypal.events, retrieved 2026-09-08
  • paypal.docs.refunds#refunds/refund-a-captured-payment: paypal.docs.refunds, retrieved 2026-09-08
  • paypal.payments.openapi#/components/schemas/refund: paypal.payments.openapi, retrieved 2026-09-08
  • paypal.payments.openapi#/paths/~1v2~1payments~1refunds~1{refund_id}/get/responses/200: paypal.payments.openapi, retrieved 2026-09-08
  • paypal.payments.openapi#/components/schemas/money/properties/value: paypal.payments.openapi, retrieved 2026-09-08
  • paypal.payments.openapi#/components/schemas/money/properties/currency_code: paypal.payments.openapi, retrieved 2026-09-08
  • paypal.payments.openapi#/components/schemas/activity_timestamps/properties/create_time: paypal.payments.openapi, retrieved 2026-09-08
  • paypal.docs.refunds#refunds/events: paypal.docs.refunds, retrieved 2026-09-08
  • paypal.docs.refunds#refunds/the-status-of-the-capture-after-a-refund: paypal.docs.refunds, retrieved 2026-09-08

Can paypal.refund.completed return VERIFIED from the action response alone?

No. The minimum evidence level is E2. The action response is E1. The completion conditions read refund_readback and capture_refunded_events.

What happens after the timeout?

The verdict is UNVERIFIABLE with the reason evidence_unavailable_before_timeout. The operation goes to a person for review.