Powered by Coinflow
Payments · Documentation
Operational

Crypto Refunds

This page is for advanced / cryptocurrency-native companies. If that’s not you, head back to the Quickstart for the standard flows.

Once a crypto payment has successfully settled, you can programmatically issue a refund to your customer’s wallet. Refunds are processed on-chain, and you’ll receive a transaction hash that can be shared with the end user as proof of refund.

Before issuing a refund:

  • The original payment must be settled
  • You must have the paymentId
  • You must provide a valid destination wallet address

Step 1: Initiate a Refund

Send a PUT request to the refund endpoint with the desired refund details.

Request

curl --location --request PUT 'https://api-sandbox.coinflow.cash/api/merchant/payments/{paymentId}/refund' \
--header 'Authorization: coinflow_sandbox_11111111111111111111111111111111_11111111111111111111111111111111' \
--header 'Content-Type: application/json' \
--data '{
  "refundReason": "userCancellation",
  "destinationWallet": "123abcd",
  "partialAmount": {
    "cents": 200
  }
}'

Parameters

Field Type Description
refundReason string Reason for refund (e.g. userCancellation)
destinationWallet string Wallet address where funds will be sent
partialAmount object Amount to refund in cents (optional; omit for full refund)

Response

"RefundPipeline{paymentId}"

This indicates the refund has been initiated and is being processed.


Step 2: Retrieve Payment Refund Details

To confirm the refund and retrieve on-chain details, fetch the payment by ID.

Request

curl --location 'https://api-sandbox.coinflow.cash/api/merchant/payments/{paymentId}' \
--header 'Authorization: coinflow_sandbox_11111111111111111111111111111111_11111111111111111111111111111111'

Step 3: Inspect Refund Data

Within the response, reference the following fields:

Full Example Response

{
  "_id": "69fa33f366fad13675d6c897",
  "paymentId": "51e5ac49-d3ad-412c-afdb-acb1a5b50b3d",
  "totals": {
    "subtotal": { "cents": 300, "currency": "USD" },
    "creditCardFees": { "cents": 2, "currency": "USD" },
    "chargebackProtectionFees": { "cents": 0, "currency": "USD" },
    "gasFees": { "cents": 0, "currency": "USD" },
    "fxFees": { "cents": 0, "currency": "USD" },
    "total": { "cents": 302, "currency": "USD" },
    "merchantPaidCreditCardFees": { "cents": 0, "currency": "USD" },
    "merchantPaidGasFees": { "cents": 0, "currency": "USD" },
    "merchantPaidFxFees": { "cents": 0, "currency": "USD" }
  },
  "customer": "69fa33f366fad13675d6c894",
  "merchant": "68dae987ec61c5361b320e50",
  "webhookInfo": {
    "item": "sword",
    "email": ""
  },
  "chargebackProtectionDecision": "Not Enabled",
  "cryptoInfo": {
    "status": "REFUNDED",
    "sessionId": "0f495375-1796-4d12-a3a2-07cc6563a23d",
    "actualPaymentAmountUSD": "4.01196",
    "blockchainLogoUrl": "https://static.logo.xyz/logos/solana-7228edcd.png",
    "originatingTransactionHash": "5xWjaoesF1SyRaz4vgX2jKmz6whsxWBAWqeKuvj46dPn9idbYTi7PvGzTa2iMUpY4poyK7G4CS6FSr1Zm1e1234",
    "originatingWallet": "9rpv2W6qyShwcwTgZXpiFuC5kFGYpzhYugmpKK5L1234",
    "paymentCurrency": "solana:103/token:111111111111111111111111111",
    "sponsoredTransactionHash": "4JpcdKKjMi1MzM5fayUwncyfaN8CKEJgPzdGmoU2SF8UfKyn4N75HmhoxRmia8WZn7W5dk91T6ttcy9MM73TPKS9",
    "tier": "stables",
    "token": "USDC",
    "tokenAmount": "4.01196",
    "tokenLogoUrl": "https://static.logo.com/logos/usdc-8aaf5df7.png",
    "refundAddress": "91eEM5xHu8tY82tiNkjzJNXGLM7NhyCEVaRhvs9p1234",
    "refundTransactionHash": "2cboz1RP9H9nY5yhcSz3xCBfZhMXrkfWf4rZbKnmGAK42xWyuP6R66iTDc2AwFPSonKDGqycR9ZtpGnmy4qQ1234"
  },
  "settlementType": "USDC",
  "blockchain": "solana",
  "createdAt": "2026-05-05T18:16:19.342Z",
  "updatedAt": "2026-05-05T18:19:44.138Z",
  "refundInfo": {
    "amount": { "cents": 200, "currency": "USD" },
    "refundedAt": "2026-05-05T18:19:30.297Z",
    "count": 1
  }
}

Step 4: Share Refund Receipt

Provide the cryptoInfo.refundTransactionHash to your customer.

  • This is the on-chain transaction hash
  • It can be used to verify the refund on a blockchain explorer
  • Acts as a proof of refund

Notes & Best Practices

  • Refunds are irreversible once submitted on-chain
  • Always validate the destinationWallet before initiating
  • Use partial refunds (partialAmount) when issuing refunds for a portion of the original payment
  • Monitor cryptoInfo.status to confirm refund completion (REFUNDED)