{"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-process-a-one-time-sale","__idx":0},"children":["Recipe: Process a one-time sale"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"when-to-use-a-one-step-sale","__idx":1},"children":["When to use a one-step sale"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Instant delivery"]}," — digital goods, downloads, or services fulfilled immediately"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Point of sale"]}," — in-person transactions where the item is handed to the customer"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Simple checkout"]}," — any scenario where you do not need a separate capture step"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you need to hold funds before charging, use ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/payment-cookbook/authorize-and-capture"},"children":["Authorize and capture"]}," instead."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"flow","__idx":2},"children":["Flow"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"img","attributes":{"src":"https://files.modern-mermaid.live/images/1776276832818-mermaid-diagram-1776276832914.png","alt":"image"},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":3},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A valid API key — see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/how-tos/setup/obtain-credentials"},"children":["Obtain API credentials"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A TSYS integration configured for card processing"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-send-the-sale-request","__idx":4},"children":["Step 1: Send the sale request"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["card_sale"]}," and include the card details. The amount is in the smallest currency unit (cents for USD)."]},{"$$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 \\\n  -H \"Content-Type: application/json\" \\\n  -H \"APIKEY: YOUR-API-KEY\" \\\n  -d '{\n    \"type\": \"card_sale\",\n    \"amount\": 1999,\n    \"card\": {\n      \"pan\": \"4111111111111111\",\n      \"expiry_month\": \"12\",\n      \"expiry_year\": \"2027\",\n      \"cvv\": \"123\",\n      \"cardholder_name\": \"John Doe\",\n      \"address\": { \"line1\": \"456 Oak Ave\", \"zip\": \"90210\" }\n    }\n  }'\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\nresp = requests.post(f\"{BASE}/v1/transactions\", headers=HEADERS, json={\n    \"type\": \"card_sale\",\n    \"amount\": 1999,\n    \"card\": {\n        \"pan\": \"4111111111111111\",\n        \"expiry_month\": \"12\",\n        \"expiry_year\": \"2027\",\n        \"cvv\": \"123\",\n        \"cardholder_name\": \"John Doe\",\n        \"address\": {\"line1\": \"456 Oak Ave\", \"zip\": \"90210\"},\n    },\n})\ntxn = resp.json()\nprint(f\"Transaction {txn['id']}: {txn['response_status']}\")\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 resp = await fetch(`${BASE}/v1/transactions`, {\n  method: \"POST\",\n  headers,\n  body: JSON.stringify({\n    type: \"card_sale\",\n    amount: 1999,\n    card: {\n      pan: \"4111111111111111\",\n      expiry_month: \"12\",\n      expiry_year: \"2027\",\n      cvv: \"123\",\n      cardholder_name: \"John Doe\",\n      address: { line1: \"456 Oak Ave\", zip: \"90210\" },\n    },\n  }),\n});\nconst txn = await resp.json();\nconsole.log(`Transaction ${txn.id}: ${txn.response_status}`);\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();\nvar baseUrl = Environment.GetEnvironmentVariable(\"PARADISE_BASE_URL\") ?? \"https://api.dev.paradisegateway.net\";\nclient.DefaultRequestHeaders.Add(\"APIKEY\", Environment.GetEnvironmentVariable(\"PARADISE_API_KEY\"));\n\nvar resp = await client.PostAsJsonAsync($\"{baseUrl}/v1/transactions\", new {\n    type = \"card_sale\",\n    amount = 1999,\n    card = new {\n        pan = \"4111111111111111\",\n        expiry_month = \"12\",\n        expiry_year = \"2027\",\n        cvv = \"123\",\n        cardholder_name = \"John Doe\",\n        address = new { line1 = \"456 Oak Ave\", zip = \"90210\" },\n    },\n});\nConsole.WriteLine(await resp.Content.ReadAsStringAsync());\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\");\n\nHttpRequest request = HttpRequest.newBuilder()\n    .uri(URI.create(baseUrl + \"/v1/transactions\"))\n    .header(\"Content-Type\", \"application/json\")\n    .header(\"APIKEY\", System.getenv(\"PARADISE_API_KEY\"))\n    .POST(HttpRequest.BodyPublishers.ofString(\"\"\"\n        {\n          \"type\": \"card_sale\",\n          \"amount\": 1999,\n          \"card\": {\n            \"pan\": \"4111111111111111\",\n            \"expiry_month\": \"12\",\n            \"expiry_year\": \"2027\",\n            \"cvv\": \"123\",\n            \"cardholder_name\": \"John Doe\",\n            \"address\": { \"line1\": \"456 Oak Ave\", \"zip\": \"90210\" }\n          }\n        }\"\"\"))\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":"payload := `{\n  \"type\": \"card_sale\",\n  \"amount\": 1999,\n  \"card\": {\n    \"pan\": \"4111111111111111\",\n    \"expiry_month\": \"12\",\n    \"expiry_year\": \"2027\",\n    \"cvv\": \"123\",\n    \"cardholder_name\": \"John Doe\",\n    \"address\": {\"line1\": \"456 Oak Ave\", \"zip\": \"90210\"}\n  }\n}`\nreq, _ := http.NewRequest(\"POST\", base+\"/v1/transactions\", strings.NewReader(payload))\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":"$payload = json_encode([\n    \"type\" => \"card_sale\",\n    \"amount\" => 1999,\n    \"card\" => [\n        \"pan\" => \"4111111111111111\",\n        \"expiry_month\" => \"12\",\n        \"expiry_year\" => \"2027\",\n        \"cvv\" => \"123\",\n        \"cardholder_name\" => \"John Doe\",\n        \"address\" => [\"line1\" => \"456 Oak Ave\", \"zip\" => \"90210\"],\n    ],\n]);\n$ch = curl_init(\"{$base}/v1/transactions\");\ncurl_setopt_array($ch, [\n    CURLOPT_RETURNTRANSFER => true,\n    CURLOPT_POST => true,\n    CURLOPT_HTTPHEADER => [\"Content-Type: application/json\", \"APIKEY: {$apiKey}\"],\n    CURLOPT_POSTFIELDS => $payload,\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\")\nreq = Net::HTTP::Post.new(uri)\nreq[\"Content-Type\"] = \"application/json\"\nreq[\"APIKEY\"] = api_key\nreq.body = { type: \"card_sale\", amount: 1999, card: {\n  pan: \"4111111111111111\", expiry_month: \"12\", expiry_year: \"2027\",\n  cvv: \"123\", cardholder_name: \"John Doe\",\n  address: { line1: \"456 Oak Ave\", zip: \"90210\" }\n} }.to_json\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-2-handle-the-response","__idx":5},"children":["Step 2: Handle the response"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"id\": \"TRANSACTION-01KEW33R7ZOW22U44YHES8UHXD\",\n  \"type\": \"card_sale\",\n  \"amount\": 1999,\n  \"transaction_state\": \"captured\",\n  \"response_status\": \"approved\",\n  \"response_code\": \"00\",\n  \"response_message\": \"Approved\",\n  \"avs_result_code\": \"Y\",\n  \"cvv_result\": \"M\",\n  \"correlation_id\": \"b2c3d4e5-f6a7-8901-bcde-f12345678901\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"check-the-result","__idx":6},"children":["Check the result"]},{"$$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":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Value"},"children":["Value"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Meaning"},"children":["Meaning"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["approved"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Payment succeeded"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["declined"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Issuer refused — ask for a different card"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Gateway/processor issue — retry with backoff"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["avs_result_code"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Y"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Address and ZIP match"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cvv_result"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["M"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["CVV matches"]}]}]}]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"if txn[\"response_status\"] == \"approved\":\n    print(f\"Payment approved — ID: {txn['id']}\")\nelif txn[\"response_status\"] == \"declined\":\n    print(f\"Declined: {txn['response_message']} — ask for a different card\")\nelse:\n    print(f\"Error: {txn['response_message']} — retry or escalate\")\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"using-a-stored-token","__idx":7},"children":["Using a stored token"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the customer has a stored payment method, pass ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["payment_token"]}," instead of raw card data."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"shell","header":{"controls":{"copy":{}}},"source":"curl -X POST \\\n  https://api.dev.paradisegateway.net/v1/transactions \\\n  -H \"Content-Type: application/json\" \\\n  -H \"APIKEY: YOUR-API-KEY\" \\\n  -d '{\n    \"type\": \"card_sale\",\n    \"amount\": 1999,\n    \"payment_token\": \"PAYMENTTOKEN-01JQXYZ123ABC456DEF789GHI\"\n  }'\n","lang":"shell"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/how-tos/process-payments/process-payment-with-token"},"children":["Process a payment with a stored token"]}," for details."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"best-practices","__idx":8},"children":["Best practices"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Always check ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_status"]}]}," — do not assume success from HTTP 200 alone. A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["response_status: declined"]}," is a decline."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Log ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["correlation_id"]}]}," — include it in your records for debugging and support."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Include AVS data"]}," — send ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["address.line1"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["address.zip"]}," to improve approval rates."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Use idempotency keys"]}," — include an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Idempotency-Key"]}," header on retries to prevent duplicate charges."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Validate before sending"]}," — Luhn-check the card number, verify expiry is in the future, ensure amount is positive."]}]},{"$$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/process-payments/process-credit-card"},"children":["Process a credit card sale (how-to)"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/payment-cookbook/handle-declined-transactions"},"children":["Handle declined transactions"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/payment-cookbook/handle-payment-failures"},"children":["Handle payment failures"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/transactions/sale-vs-auth"},"children":["Sale vs. authorization"]}]}]}]},"headings":[{"value":"Recipe: Process a one-time sale","id":"recipe-process-a-one-time-sale","depth":1},{"value":"When to use a one-step sale","id":"when-to-use-a-one-step-sale","depth":2},{"value":"Flow","id":"flow","depth":2},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"Step 1: Send the sale request","id":"step-1-send-the-sale-request","depth":2},{"value":"Step 2: Handle the response","id":"step-2-handle-the-response","depth":2},{"value":"Check the result","id":"check-the-result","depth":3},{"value":"Using a stored token","id":"using-a-stored-token","depth":2},{"value":"Best practices","id":"best-practices","depth":2},{"value":"Further reading","id":"further-reading","depth":2}],"frontmatter":{"title":"Recipe: Process a one-time sale","shortTitle":"Process a sale","intro":"Complete a one-step credit card sale that authorizes and captures in a single request. This is the fastest path to accepting a payment.","type":"tutorial","seo":{"title":""}},"lastModified":"2026-06-05T02:46:44.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/tutorials/payment-cookbook/process-a-sale","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}