Card refunds

With Moov, you have the ability to refund card payments. Issuing a refund will debit the destination of the original transfer’s wallet balance and transfer funds back to the source card that was used. You have the option to issue a full or partial refund. When a refund is initiated, Moov submits the credit information to your customer’s card issuer. Your customer will see a credit to their card in approximately 5-7 business days, although the actual timing will vary by bank.

Refund guidelines

  • Only one refund can be initiated at a time per transfer
  • You cannot refund more than the original transfer amount
  • Refunds cannot be canceled after they are issued
  • To avoid a potential double charge, do not attempt to refund a payment that has been disputed by the cardholder
  • If the refund fails, you are able to initiate the refund again, for the same transfer

Initiating a refund via the API

Full refund

To initiate a full refund using the API, use the refund a transfer endpoint without a payload.

1
2
3
curl -X POST https://api.moov.io/transfers/{transferID}/refunds \
  -H 'Authorization: Bearer {token}' \
  -H 'X-Idempotency-Key: UUID' \
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const myHeaders = new Headers();
myHeaders.append("X-Idempotency-Key", "UUID");
const requestOptions = {
  method: 'POST',
  headers: myHeaders
};

fetch(`https://api.moov.io/transfers/${transferID}/refunds`, requestOptions)
  .then(response => response.json())
  .then(result => console.log(result));
1
2
3
4
5
6
const moov = new Moov(...);
try {
  const { transferID } = moov.transfers.refund(transferID);
} catch (err) {
  // ...
}

Partial refund

To initiate a partial refund using the API, you can use the refund a transfer endpoint and include an amount in the payload.

1
2
3
4
5
6
curl -X POST https://api.moov.io/transfers/{transferID}/refunds \
  -H 'Authorization: Bearer {token}' \
  -H 'X-Idempotency-Key: UUID' \
  --data-raw '{
    "amount": 1000, // $10.00
      }'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const myHeaders = new Headers();
myHeaders.append("X-Idempotency-Key", "UUID");
const requestOptions = {
  method: 'POST',
  headers: myHeaders
},
  body: {
    "amount": 1000, // $10.00
    };  

fetch(`https://api.moov.io/transfers/${transferID}/refunds`, requestOptions)
  .then(response => response.json())
  .then(result => console.log(result));

Initiating a refund via the Moov Dashboard

In the dashboard, you can initiate a refund on the transfer details page:

Initiate a refund

Once initiated, you can choose whether or not it’s a full or partial refund and note how much you’re refunding.

Initiate a refund.

Afterwards, Moov will populate relevant information and status in the transfer details section and the timeline.

Refund statuses

To retrieve the status of a refund, you can use GET /transfers/{transferID}/refunds/{refundID}.

1
2
curl -X GET https://api.moov.io/transfers/{transferID}/refunds/{refundID} \
  -H 'Authorization: Bearer {token}' \
1
2
3
4
5
6
7
8
9
const myHeaders = new Headers();
const requestOptions = {
  method: 'GET',
  headers: myHeaders,
};

fetch(`https://api.moov.io/transfers/${transferID}/refunds/${refundID}`, requestOptions)
  .then(response => response.json())
  .then(result => console.log(result));
1
2
3
4
5
6
const moov = new Moov(...);
try {
  const refund = moov.transfers.getRefund(transferID, refundID);
} catch (err) {
  // ...
}

If a transfer has a refund in any status, we’ll also include that information in the transfers object itself.

There are two webhook events you can subscribe to that will provide you with relevant updates:

  • refund.created notifies you when the refund was successfully created
  • refund.updated notifies you once the refund status changes to any of the following:
    • pending
    • completed
    • failed