Refunding a Transaction

Refund transactions send a refund to the cardholder of a previous sale transaction. The refund transaction type requires the transactionId to target that specific transaction.

📘

Note

This transaction does not fall specifically under Card Present or Card Not Present categories, allowing for all POS profiles. Refunds can be issued for both CP and CNP transactions using their respective transaction IDs. In the case of the deviceProfile parameter, check out API References for all the available body parameters and enumerations.

Full Refund

POST /api/v4/accounts/{accountId}/payments/{transactionId}/refund

  • {accountId} value in the path is the PayConexâ„¢ account ID number.

  • {transactionId} value in the path is the transaction ID to refund.

{
  "posProfile": "ECOMMERCE"
}

*Required Scopes: pcx:payments:*, pcx:payments:device:*, pcx:payments:card_not_present:*, pcx:payments:refund

When the previous transaction gets refunded, it assigns the transactionType to REFUND and populates the refundObject, appending a refundId to the refundObject.refundIds of the original transaction to keep track of refunds. You can see this in the Response Example below.

Partial Refund

A transaction can be refunded multiple times as long as there is a remaining amount in the refundBalance. For example, you can partially refund a 50-dollar transaction by applying the following body request, reducing the refundBalance. This allows for multiple partial refunds if you don't want to refund the entire amount in case the customer has made a mistake of inputting the wrong amount to be charged with or similar.

Request

POST /api/v4/accounts/{accountId}/payments/{transactionId}/refund

{
  "posProfile": "ECOMMERCE",
  "amounts": { 
    "total": "25",
    "currency": "USD"
  }
}

*Required Scopes: pcx:payments:*, pcx:payments:device:*, pcx:payments:card_not_present:*, pcx:payments:refund

Transaction Metadata

This is the transaction metadata of a transaction after a partial refund.

{
  "status": "CAPTURED",
  "transactionType": "SALE",
  "refundObject": {
    "refundBalance": "25.00",
    "refundIds": [
      "000000014646"
    ]
  }
}

If we were to reapply the same request, this is what we are left with:

{
  "status": "VOIDED",
  "transactionType": "REFUND",
  "refundObject": {
    "refundBalance": "0.00",
    "refundIds": [
      "000000014646",
      "000000014666"
    ]
  }
}

📘

Full Refund by default

We can conclude that without the amounts parameter specified, a Full Refund is applied by default.

The balance can also be found in amounts.balance. This is the approved amount minus the sum of all partial refunds associated with a transaction.

For example,

{
  ...
  "amounts": {
    "currency": "USD",
    "approved": "50.00",
    "requested": "50.00",
    "balance": "25.00"
  },
  ...
}

Error Responses

Besides the general error responses, once the refundBalance is zero either by a full or partial refund - the following is returned.

{
  "message": "Transaction type REFUND is not refundable",
  "errorCode": 40001,
  "errorType": "invalid_request",
  "traceId": "e4e2dc5a-e35b-4240-8cff-eef687f3b082"
}

Refund Response Example

{
  "transactionId": "000000046766",
  "status": "VOIDED",
  "timestamp": "2025-04-03T15:09:26.000000Z",
  "customer": {
    "name": "Alice",
    "billingAddress": {
      "address1": "address1",
      "address2": "address2",
      "city": "My City",
      "state": "MO",
      "zip": "90210",
      "country": "USA",
      "company": "Acme Inc."
    }
  },
  "trace": {
    "history": [
      {
        "action": "refund",
        "requestId": "6b8135d8-4061-4aab-8776-80ad99135911",
        "correlationId": "ff2f8b94-64ba-455c-a4b0-fa206f276383",
        "timestamp": "2025-04-03T10:09:24-05:00"
      }
    ],
    "networkTransactionId": "015093146471818G012"
  },
  "amounts": {
    "currency": "USD",
    "approved": "10.00",
    "requested": "0.00"
  },
  "auth": {
    "code": "OK3750",
    "processorMessage": "APPROVED",
    "message": "APPROVED",
    "networkName": "VISA"
  },
  "card": {
    "name": "Alice",
    "last4": "1111",
    "expiry": "1225",
    "brand": "VISA"
  },
  "binData": {
    "program": "UNKNOWN"
  },
  "transactionType": "VOID",
  "entryMode": "KEYED",
  "refundObject": {
    "refundBalance": "0.00",
    "refundIds": [
      "000000046746"
    ]
  }
}

Retrieving Transaction Metadata

For more details on retrieving transaction metadata, see Get Transaction Metadata.

If we now retrieve the transaction metadata of the refunded "000000046746" transaction, we see that the status of the transaction is now "VOIDED", with the transactionType of "REFUND", and the refund action is appended to trace.history. Particularly, the refundIds contains the ids that point to the individually refunded transactions.

🚧

Partial Refund Transaction

As demonstrated above, if we apply a partial refund with the refundBalance still remaining, the transaction status remains "CAPTURED" as well as the original transaction type, for example, "transactionType": "SALE".

GET /api/v4/accounts/{accountId}/payments/{transactionId}

*Required Scopes: pcx:payments:*, pcx:payments:read

{
  "transactionId": "000000046746",
  "status": "VOIDED",
  "timestamp": "2025-04-03T14:48:54.000000Z",
  "customer": {
    "name": "Alice",
    "billingAddress": {
      "address1": "address1",
      "address2": "address2",
      "city": "My City",
      "state": "MO",
      "zip": "90210",
      "country": "USA",
      "company": "Acme Inc."
    }
  },
  "shippingAddress": {
    "address1": "address1",
    "address2": "address2",
    "city": "My City",
    "state": "MO",
    "zip": "90210",
    "country": "USA",
    "company": "Acme Inc.",
    "recipient": "Alice Smith"
  },
  "trace": {
    "history": [
      {
        "action": "authorization",
        "requestId": "e77853d2-72a7-43f4-b2e5-32e611c42330",
        "correlationId": "5431fa60-c234-41f5-959e-71d1f3fa6d6f",
        "timestamp": "2025-04-03T09:45:35-05:00"
      },
      {
        "action": "capture",
        "requestId": "11002d0e-62ed-4fee-8bba-944e5b269912",
        "correlationId": "1e54498e-3d89-4033-99ff-756d63a32404",
        "timestamp": "2025-04-03T09:48:52-05:00"
      },
      {
        "action": "refund",
        "requestId": "6b8135d8-4061-4aab-8776-80ad99135911",
        "correlationId": "ff2f8b94-64ba-455c-a4b0-fa206f276383",
        "timestamp": "2025-04-03T10:09:24-05:00"
      }
    ],
    "networkTransactionId": "015093645028527G012"
  },
  "amounts": {
    "currency": "USD",
    "approved": "10.00",
    "requested": "10.00"
  },
  "auth": {
    "code": "OK0200",
    "processorMessage": "APPROVED",
    "message": "APPROVED",
    "avsResponseCode": "Y"
  },
  "card": {
    "name": "Alice",
    "last4": "1111",
    "expiry": "1225",
    "brand": "VISA"
  },
  "binData": {
    "program": "UNKNOWN"
  },
  "transactionType": "REFUND",
  "entryMode": "KEYED",
  "refundObject": {
    "refundBalance": "0.00",
    "refundIds": [
      "000000046766"
    ]
  }
}

refundObject

ParameterTypeDescriptionExample
refundBalancestringThe remaining balance available for refund. This allows for multiple partial refunds if we don't want to refund the entire amount in case the customer has made a mistake of inputting the wrong amount to be charged with or similar."10.00"
refundIdsarrayList of transaction IDs that have been refunded in this transaction. These are individual transactions under the transactionType of VOID and determine the refundBalance. There can be more than one of these in the case of Partial Refund.[ "000000014646", "000000014666" ]