Refund a transaction
Asks the source's endpoint to refund a recorded charge, for amount or all that is left of it, then records the refund it answers with and returns it, under the source's id for the refund.
Only a payment source records purchases.
Guide: Payment sources
A project secret key: vh_sk_... for production, vh_sk_test_... for test. Keep it on your servers.
In: header
Path parameters
The project's id, proj_.... A secret key works only in the project it belongs to.
The id of the project's payment provider connection, pp_conf_....
The payment source's own id for the transaction or subscription; to request a refund, the charge's.
Request body
application/json
TypeScript definitions
Use the request body type in TypeScript.
What to refund of a payment source's charge.
The amount to refund, in the charge's minor units; everything left of the charge when left out.
Why the charge is refunded, passed to the source's endpoint.
Examples
curl -X POST "https://api.voidhash.com/api/v1/projects/proj_tz4a98xxat96iws9zmbrgj3a/payment-providers/pp_conf_m2c8v5n1x7z4q9w3e6r0t8y2/transactions/txn_20260314_0042/refund" \ -H "Authorization: Bearer vh_sk_..." \ -H "Content-Type: application/json" \ -d '{ "amount": 499, "reason": "Charged twice" }'{ "id": "rfd_20260320_0007", "paymentProviderId": "pp_conf_m2c8v5n1x7z4q9w3e6r0t8y2", "type": "refund", "status": "applied", "pendingReason": null, "purchaseId": null, "bookedAmount": 499}{ "error": { "type": "invalid_request", "code": "invalid_transaction", "message": "Product pro_monthly is a subscription; its charges name the subscriptionId and period they pay for" }}{ "error": { "type": "unauthenticated", "code": "invalid_api_key", "message": "This secret key is not valid." }}{ "error": { "type": "permission_denied", "code": "permission_denied", "message": "Insufficient permissions." }}{ "error": { "type": "not_found", "code": "transaction_not_found", "message": "This payment source has no recorded charge with this id.", "param": "externalId" }}{ "error": { "type": "conflict", "code": "payment_source_disabled", "message": "This payment source is disabled; enable it to record purchases." }}{ "error": { "type": "internal", "code": "internal_error", "message": "Something went wrong on our side. Try again, and contact support with the Request-Id header if it keeps failing." }}{ "error": { "type": "unavailable", "code": "payment_source_endpoint_unavailable", "message": "The endpoint answered 503" }}Response body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
Errors
| Status | type | code | When |
|---|---|---|---|
| 400 | invalid_request | invalid_transaction | When the refund answered cannot be recorded, which records nothing. |
| 400 | invalid_request | payment_source_required | For a store. |
| 404 | not_found | transaction_not_found | When the charge is not recorded. |
| 404 | not_found | payment_provider_not_found | For an unknown provider. |
| 409 | conflict | payment_source_disabled | For a disabled source. |
| 409 | conflict | payment_source_endpoint_not_configured | When the source's endpoint is not configured, does not support the action or refuses it. |
| 409 | conflict | payment_source_endpoint_unsupported | When the source's endpoint is not configured, does not support the action or refuses it. |
| 409 | conflict | payment_source_endpoint_rejected | When the source's endpoint is not configured, does not support the action or refuses it. |
| 503 | unavailable | payment_source_endpoint_unavailable | When it does not answer or answers outside the protocol; the message says why. |
| 503 | unavailable | payment_source_endpoint_invalid_response | When it does not answer or answers outside the protocol; the message says why. |
It can also fail with the errors every operation shares, such as unauthenticated; see Errors.
More in Payment sources
Something wrong or missing on this page? Tell us by email or on Discord.