{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-docs/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["tabs","tab"]},"type":"markdown"},"seo":{"title":"Reefpay Docs","description":"Reefpay is the groundbreaking payment gateway that lets you integrate with the future of payments.","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"recipe-cancels-and-refunds","__idx":0},"children":["Recipe: Cancels and refunds"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"when-to-cancel-vs-refund","__idx":1},"children":["When to cancel vs. refund"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The correct reversal method depends on whether the transaction has settled."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"img","attributes":{"src":"https://files.modern-mermaid.live/images/1776277139735-mermaid-diagram-1776277139819.png","alt":"image"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Action"},"children":["Action"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"When"},"children":["When"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"API call"},"children":["API call"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Funds returned"},"children":["Funds returned"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Cancel"]}," (void)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Before settlement"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /v1/transactions/{id}/cancel"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Hold released immediately"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Refund"]}," (full)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["After settlement"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /v1/transactions/{id}/cancel"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: card_refund"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["3–5 business days"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Refund"]}," (partial)"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["After settlement"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Same, with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amount"]}," field"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["3–5 business days"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-check-the-transaction-state","__idx":2},"children":["Step 1: Check the transaction state"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before attempting a reversal, confirm the current state."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"curl","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"curl -X GET \\\n  https://api.dev.paradisegateway.net/v1/transactions/TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC \\\n  -H \"APIKEY: YOUR-API-KEY\"\n","lang":"shell"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"import os, requests\n\nAPI_KEY = os.environ[\"PARADISE_API_KEY\"]\nBASE = os.environ.get(\"PARADISE_BASE_URL\", \"https://api.dev.paradisegateway.net\")\nHEADERS = {\"Content-Type\": \"application/json\", \"APIKEY\": API_KEY}\n\ntxn_id = \"TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC\"\nresp = requests.get(f\"{BASE}/v1/transactions/{txn_id}\", headers=HEADERS)\ntxn = resp.json()\nprint(f\"State: {txn['transaction_state']}\")\n","lang":"python"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const API_KEY = process.env.PARADISE_API_KEY;\nconst BASE = process.env.PARADISE_BASE_URL || \"https://api.dev.paradisegateway.net\";\nconst headers = { \"Content-Type\": \"application/json\", \"APIKEY\": API_KEY };\n\nconst txnId = \"TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC\";\nconst resp = await fetch(`${BASE}/v1/transactions/${txnId}`, { headers });\nconst txn = await resp.json();\nconsole.log(`State: ${txn.transaction_state}`);\n","lang":"javascript"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"C#","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"using var client = new HttpClient();\nclient.DefaultRequestHeaders.Add(\"APIKEY\", Environment.GetEnvironmentVariable(\"PARADISE_API_KEY\"));\nvar baseUrl = Environment.GetEnvironmentVariable(\"PARADISE_BASE_URL\") ?? \"https://api.dev.paradisegateway.net\";\n\nvar txnId = \"TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC\";\nvar resp = await client.GetAsync($\"{baseUrl}/v1/transactions/{txnId}\");\nvar json = await resp.Content.ReadAsStringAsync();\nConsole.WriteLine(json);\n","lang":"csharp"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Java","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"HttpClient client = HttpClient.newHttpClient();\nString baseUrl = System.getenv().getOrDefault(\"PARADISE_BASE_URL\", \"https://api.dev.paradisegateway.net\");\nString apiKey = System.getenv(\"PARADISE_API_KEY\");\n\nString txnId = \"TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC\";\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(baseUrl + \"/v1/transactions/\" + txnId))\n    .header(\"APIKEY\", apiKey)\n    .GET()\n    .build();\nHttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());\nSystem.out.println(response.body());\n","lang":"java"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Go","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"req, _ := http.NewRequest(\"GET\", base+\"/v1/transactions/\"+txnId, nil)\nreq.Header.Set(\"APIKEY\", apiKey)\nresp, _ := http.DefaultClient.Do(req)\ndefer resp.Body.Close()\nbody, _ := io.ReadAll(resp.Body)\nfmt.Println(string(body))\n","lang":"go"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"PHP","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"php","header":{"controls":{"copy":{}}},"source":"$txnId = \"TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC\";\n$ch = curl_init(\"{$base}/v1/transactions/{$txnId}\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_HTTPHEADER => [\"APIKEY: {$apiKey}\"],\n]);\n$response = curl_exec($ch);\necho $response;\n","lang":"php"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Ruby","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ruby","header":{"controls":{"copy":{}}},"source":"uri = URI(\"#{base}/v1/transactions/#{txn_id}\")\nreq = Net::HTTP::Get.new(uri)\nreq[\"APIKEY\"] = api_key\nres = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }\nputs res.body\n","lang":"ruby"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2a-cancel-before-settlement","__idx":3},"children":["Step 2a: Cancel (before settlement)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Cancel releases the hold immediately. Works for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authorized"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["captured"]}," (pre-settlement) transactions."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"curl","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"curl -X POST \\\n  https://api.dev.paradisegateway.net/v1/transactions/TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC/cancel \\\n  -H \"Content-Type: application/json\" \\\n  -H \"APIKEY: YOUR-API-KEY\"\n","lang":"shell"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"cancel_resp = requests.post(\n    f\"{BASE}/v1/transactions/{txn_id}/cancel\",\n    headers=HEADERS,\n)\nresult = cancel_resp.json()\nprint(f\"State: {result['transaction_state']}\")  # → \"canceled\"\n","lang":"python"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const cancelResp = await fetch(`${BASE}/v1/transactions/${txnId}/cancel`, {\n  method: \"POST\",\n  headers,\n});\nconst result = await cancelResp.json();\nconsole.log(`State: ${result.transaction_state}`);  // → \"canceled\"\n","lang":"javascript"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"C#","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"var cancelResp = await client.PostAsync(\n    $\"{baseUrl}/v1/transactions/{txnId}/cancel\",\n    new StringContent(\"{}\", System.Text.Encoding.UTF8, \"application/json\"));\nvar cancelJson = await cancelResp.Content.ReadAsStringAsync();\nConsole.WriteLine(cancelJson);\n","lang":"csharp"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Java","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"java","header":{"controls":{"copy":{}}},"source":"HttpRequest cancelReq = HttpRequest.newBuilder()\n    .uri(URI.create(baseUrl + \"/v1/transactions/\" + txnId + \"/cancel\"))\n    .header(\"Content-Type\", \"application/json\")\n    .header(\"APIKEY\", apiKey)\n    .POST(HttpRequest.BodyPublishers.ofString(\"{}\"))\n    .build();\nHttpResponse<String> cancelResp = client.send(cancelReq, HttpResponse.BodyHandlers.ofString());\nSystem.out.println(cancelResp.body());\n","lang":"java"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Go","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"req, _ := http.NewRequest(\"POST\", base+\"/v1/transactions/\"+txnId+\"/cancel\", strings.NewReader(\"{}\"))\nreq.Header.Set(\"Content-Type\", \"application/json\")\nreq.Header.Set(\"APIKEY\", apiKey)\nresp, _ := http.DefaultClient.Do(req)\ndefer resp.Body.Close()\nbody, _ := io.ReadAll(resp.Body)\nfmt.Println(string(body))\n","lang":"go"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"PHP","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"php","header":{"controls":{"copy":{}}},"source":"$ch = curl_init(\"{$base}/v1/transactions/{$txnId}/cancel\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\"Content-Type: application/json\", \"APIKEY: {$apiKey}\"],\n    CURLOPT_POSTFIELDS => \"{}\",\n]);\necho curl_exec($ch);\n","lang":"php"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Ruby","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"ruby","header":{"controls":{"copy":{}}},"source":"uri = URI(\"#{base}/v1/transactions/#{txn_id}/cancel\")\nreq = Net::HTTP::Post.new(uri)\nreq[\"Content-Type\"] = \"application/json\"\nreq[\"APIKEY\"] = api_key\nreq.body = \"{}\"\nres = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }\nputs res.body\n","lang":"ruby"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2b-refund-after-settlement","__idx":4},"children":["Step 2b: Refund (after settlement)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For settled transactions, send a refund. Include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: card_refund"]}," and optionally an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amount"]}," for partial refunds."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"full-refund","__idx":5},"children":["Full refund"]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"curl","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"curl -X POST \\\n  https://api.dev.paradisegateway.net/v1/transactions/TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC/cancel \\\n  -H \"Content-Type: application/json\" \\\n  -H \"APIKEY: YOUR-API-KEY\" \\\n  -d '{ \"type\": \"card_refund\" }'\n","lang":"shell"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"refund_resp = requests.post(\n    f\"{BASE}/v1/transactions/{txn_id}/cancel\",\n    headers=HEADERS,\n    json={\"type\": \"card_refund\"},\n)\nresult = refund_resp.json()\nprint(f\"State: {result['transaction_state']}\")  # → \"refunded\"\n","lang":"python"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const refundResp = await fetch(`${BASE}/v1/transactions/${txnId}/cancel`, {\n  method: \"POST\",\n  headers,\n  body: JSON.stringify({ type: \"card_refund\" }),\n});\nconst result = await refundResp.json();\nconsole.log(`State: ${result.transaction_state}`);  // → \"refunded\"\n","lang":"javascript"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"partial-refund","__idx":6},"children":["Partial refund"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"curl -X POST \\\n  https://api.dev.paradisegateway.net/v1/transactions/TRANSACTION-01KEW32V6YNV11T33XGDR7TGWC/cancel \\\n  -H \"Content-Type: application/json\" \\\n  -H \"APIKEY: YOUR-API-KEY\" \\\n  -d '{ \"type\": \"card_refund\", \"amount\": 1500 }'\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"decision-logic-implementation","__idx":7},"children":["Decision logic implementation"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"def reverse_transaction(txn_id: str, partial_amount: int | None = None) -> dict:\n    txn = requests.get(f\"{BASE}/v1/transactions/{txn_id}\", headers=HEADERS).json()\n    state = txn[\"transaction_state\"]\n\n    if state in (\"authorized\", \"captured\"):\n        resp = requests.post(f\"{BASE}/v1/transactions/{txn_id}/cancel\", headers=HEADERS)\n    elif state == \"settled\":\n        payload = {\"type\": \"card_refund\"}\n        if partial_amount:\n            payload[\"amount\"] = partial_amount\n        resp = requests.post(\n            f\"{BASE}/v1/transactions/{txn_id}/cancel\",\n            headers=HEADERS,\n            json=payload,\n        )\n    else:\n        raise ValueError(f\"Cannot reverse transaction in state: {state}\")\n\n    return resp.json()\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"common-mistakes","__idx":8},"children":["Common mistakes"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Mistake"},"children":["Mistake"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Result"},"children":["Result"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Fix"},"children":["Fix"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Refunding a pre-settlement transaction"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Error — not settled yet"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Cancel instead"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Canceling a settled transaction"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Error — already settled"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Refund instead"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Refunding more than the original amount"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Error — amount exceeds original"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Check original ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["amount"]}," first"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Not checking state first"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Unpredictable errors"]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Always ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET"]}," the transaction before reversing"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"further-reading","__idx":9},"children":["Further reading"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/how-tos/manage-transactions/cancel-auth"},"children":["Cancel an authorized transaction"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/how-tos/manage-transactions/refund-settled-auth"},"children":["Refund a settled transaction"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/transactions/cancels-and-refunds"},"children":["Cancels and refunds concepts"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/transactions/transaction-lifecycle"},"children":["Transaction lifecycle"]}]}]}]},"headings":[{"value":"Recipe: Cancels and refunds","id":"recipe-cancels-and-refunds","depth":1},{"value":"When to cancel vs. refund","id":"when-to-cancel-vs-refund","depth":2},{"value":"Step 1: Check the transaction state","id":"step-1-check-the-transaction-state","depth":2},{"value":"Step 2a: Cancel (before settlement)","id":"step-2a-cancel-before-settlement","depth":2},{"value":"Step 2b: Refund (after settlement)","id":"step-2b-refund-after-settlement","depth":2},{"value":"Full refund","id":"full-refund","depth":3},{"value":"Partial refund","id":"partial-refund","depth":3},{"value":"Decision logic implementation","id":"decision-logic-implementation","depth":2},{"value":"Common mistakes","id":"common-mistakes","depth":2},{"value":"Further reading","id":"further-reading","depth":2}],"frontmatter":{"title":"Recipe: Cancels and refunds","shortTitle":"Cancels and refunds","intro":"Decide whether to cancel or refund a transaction, then execute the right API call. This recipe covers the complete post-payment reversal flow with timing rules and edge cases.","type":"tutorial","seo":{"title":""}},"lastModified":"2026-06-05T02:46:44.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/tutorials/payment-cookbook/cancels-and-refunds","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}