Skip to content
Last updated

Recipe: Process a one-time sale

When to use a one-step sale

  • Instant delivery — digital goods, downloads, or services fulfilled immediately
  • Point of sale — in-person transactions where the item is handed to the customer
  • Simple checkout — any scenario where you do not need a separate capture step

If you need to hold funds before charging, use Authorize and capture instead.

Flow

image

Prerequisites

Step 1: Send the sale request

Set type to card_sale and include the card details. The amount is in the smallest currency unit (cents for USD).

curl -X POST \
  https://api.dev.paradisegateway.net/v1/transactions \
  -H "Content-Type: application/json" \
  -H "APIKEY: YOUR-API-KEY" \
  -d '{
    "type": "card_sale",
    "amount": 1999,
    "card": {
      "pan": "4111111111111111",
      "expiry_month": "12",
      "expiry_year": "2027",
      "cvv": "123",
      "cardholder_name": "John Doe",
      "address": { "line1": "456 Oak Ave", "zip": "90210" }
    }
  }'

Step 2: Handle the response

{
  "id": "TRANSACTION-01KEW33R7ZOW22U44YHES8UHXD",
  "type": "card_sale",
  "amount": 1999,
  "transaction_state": "captured",
  "response_status": "approved",
  "response_code": "00",
  "response_message": "Approved",
  "avs_result_code": "Y",
  "cvv_result": "M",
  "correlation_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
}

Check the result

FieldValueMeaning
response_statusapprovedPayment succeeded
response_statusdeclinedIssuer refused — ask for a different card
response_statuserrorGateway/processor issue — retry with backoff
avs_result_codeYAddress and ZIP match
cvv_resultMCVV matches
if txn["response_status"] == "approved":
    print(f"Payment approved — ID: {txn['id']}")
elif txn["response_status"] == "declined":
    print(f"Declined: {txn['response_message']} — ask for a different card")
else:
    print(f"Error: {txn['response_message']} — retry or escalate")

Using a stored token

If the customer has a stored payment method, pass payment_token instead of raw card data.

curl -X POST \
  https://api.dev.paradisegateway.net/v1/transactions \
  -H "Content-Type: application/json" \
  -H "APIKEY: YOUR-API-KEY" \
  -d '{
    "type": "card_sale",
    "amount": 1999,
    "payment_token": "PAYMENTTOKEN-01JQXYZ123ABC456DEF789GHI"
  }'

See Process a payment with a stored token for details.

Best practices

  • Always check response_status — do not assume success from HTTP 200 alone. A 200 with response_status: declined is a decline.
  • Log correlation_id — include it in your records for debugging and support.
  • Include AVS data — send address.line1 and address.zip to improve approval rates.
  • Use idempotency keys — include an Idempotency-Key header on retries to prevent duplicate charges.
  • Validate before sending — Luhn-check the card number, verify expiry is in the future, ensure amount is positive.

Further reading