Issuing refunds
Learn how to use the Refunds API to issue full and partial refunds
The Refunds API allows you to reimburse customers for product costs, shipping expenses, taxes, duties, and regulatory fees.
Once you configure and create a refund, your integration should be set up to handle refund state changes.
To tailor a refund so that customers are only reimbursed for specific, non-product related expenses, you must specify type
.
Refund preconditions
Before submitting a POST/refunds
request, make sure you have:
Order fulfilled
The Refunds API should only be used once an order is partially or completely fulfilled.
This is due to the fact that refunds can only be created on order's with charge captures[]
in a state
of complete
. To be notified of this state
change event, you can subscribe to order.charge.capture.complete
.
If you'd like to cancel a charge before it's captured, use the Fulfillments API. For details, refer to Capturing and cancelling payment charges.
Once a capture is complete
, Digital River increases availableToRefundAmount
.
Available to refund amount
Prior to submitting a POST/refunds
, you can make a GET/orders/{id}
to determine whether the amount
you're requesting is less than or equal to what's available.
A 200 OK
response contains an availableToRefundAmount
at both the order-level and the item-level.
At a high level, Digital River calculates these values by using the following formula:
availableToRefundAmount =
charge(s)
amount
captured
− (
completed refunds
amount +
pending refunds
amount)
If you submit a POST/refunds
whose amount
is greater than the order's availableToRefundAmount
, or whose items[].amount
is greater than that items[].availableToRefundAmount
, then a 400 Bad Request
is thrown:
Available to refund amount: order-level
At the order-level, availableToRefundAmount
reflects the unrefunded portion of an order's capturedAmount
. This availableToRefundAmount
may include product prices and any expenses related to shipping, duties, fees, and assessed taxes.
Available to refund amount: item-level
In orders, items[].availableToRefundAmount
reflects the unrefunded portion of that line item's captured amount
plus its tax.amount
. It doesn't include expenses related to shipping, duties, or fees.
If you'd like to refund shipping costs associated with an order's individual items[]
, then you can determine what customers paid by accessing items[].shipping.amount
and items[].shipping.taxAmount
.
In the following example, note that each line item's availableToRefundAmount
excludes its shipping.amount
and shipping.taxAmount
.
Currency
A POST/refunds
requires currency
. After you submit this request, Digital River doesn't perform a currency conversion. As a result, the value you pass must be the same as the associated order's currency
. If they're different, a 400 Bad Request
is thrown:
Configuring and creating refunds
Prior to submitting a POST/refunds
request, specific preconditions must exist. Once satisfied, you can request a variety of refunds. The following sections provide information on how to reimburse:
Product refunds
You can issue product refunds at the order level and the line item level.
Order level product refunds
If you'd like to refund an order's product costs, then ensure that the body of your POST/refunds
:
Omits
type
Either (1) sets
percent
to a value in the range of0.01
to100.00
inclusive or (2) setsamount
to a value that's less than or equal to the order'savailableToRefundAmount
If you set percent
to 100
or amount
to the order's availableToRefundAmount
, then Digital River attempts to reimburse the full availableToRefundAmount
.
If you pass any lower percent
or amount
, then an order's product costs, shipping expenses, duties, and taxes are proportionally refunded.
Product refund requests do not reimburse regulatory fees. To do that, you must set type
to fees
in a separate POST/refunds
Line-item level product refunds
If you'd like to refund an items[]
product costs, then ensure that the body of your POST/refunds
:
Omits
items[].type
Specifies an
items[].quantity
that is less than or equal to the correspondingitems[].quantity
in the orderEither (1) sets
items[].percent
to a value in the range of0.01
to100.00
, inclusive or (2) setsitems[].amount
to a value that's less than or equal to thatitems[].availableToRefundAmount
.
If you configure the request this way, Digital River will attempt to refund the specified quantity
of items[]
by the given percent
or amount
.
Along with product costs, line item-level refund requests using this configuration proportionally reimburse that items[].tax.amount
. They do not, however, refund any shipping, regulatory fee, importer tax, or duty amounts (along with taxes assessed on those amounts) that are associated with that items[]
.
To get those expenses back, you could submit a separate POST/refunds
that specifies items[].type
.
Refund types
If you want to only reimburse specific, non-product related costs, such as shipping, duties, regulatory fees, and taxes, your POST/refunds
must specify type
at either the order-level or the line item-level.
When issuing refunds on product costs, make sure you omit type
in your POST/refunds
request.
When type
is shipping
, fees
, or duty
, any taxes assessed on those particular components of the order are also refunded.
For details on how to configure a refund request when type
is tax
or importer_tax
, refer to Refunding taxes.
Refunding taxes
In POST/refunds
, by setting type
to tax
, you can reimburse just the tax component of an order. You can't, however, partially refund taxes using type
.
The Refunds API doesn't support tax-only reimbursements at the items[]
level.
If you submit a POST/refunds
that specifies a type
of tax
, then either (1) percent
must be 100
or (2) amount
must be equal to the unrefunded portion of an order's totalTax
. If either of these conditions are not met, then a 400 Bad Request
is returned.
When refunding taxes, we recommend you use percent
instead of amount
. This is because an order's totalTax
doesn't always reflect how much refundable tax exists. Previous refunds may have reduced what's available.
In these cases, if you retrieve an order's totalTax
, and use that value to set amount
in a POST/refunds
, then a 400 Bad Request
is returned.
After you successfully submit a POST/refunds
with a type
of tax
, Digital River attempts to reclaim the unrefunded portion of an order's totalTax
.
Refunding shipping
You also have the ability to issue refunds only on shipping costs. To do this, set type
to shipping
and specify an amount
or percent
.
We recommend using percent
instead of amount
. This is because an order's totalShipping
doesn't always reflect the actual refundable shipping costs. Previous refunds may have reduced what's available.
In these cases, if you retrieve totalShipping
, and use that value to set amount
in a POST/refunds
, then a 400 Bad Request
is returned.
Depending on the value you assign percent
, passing a type
of shipping
fully or partially refunds both an order's shippingChoice.amount
and shippingChoice.tax
Handling refund state changes
After submitting a refund request, we recommend that your integration be set up to listen for the following events:
Pending refunds
When a POST/refunds
is successful, Digital River sets the refund's state
to pending
and creates a refund.pending
event.
This state
indicates that Digital River and the payment processor have all the information they need to initiate the refund process.
A 201 Created
response code doesn't signify that the bank approved the refund. It only means that your refund request was successfully sent. To be notified of approved refunds, listen for the refund.complete
event.
In refunds that have a state
of pending
, refundedAmount
is always 0.0
.
You can use refund.pending
to trigger a notification to customers, informing them that their refund is being processed. Ensure you also update the refund status on their order details page.
Pending information refunds
In some cases, customers must first supply their banking details before payment processors act on a refund request. This is common when the purchase was made with a wire transfer or other delayed payment method.
When the bank requests this additional information, Digital River moves the refund's state
to pending_information
and creates a refund.pending_information
event.
For more information on how to handle this state
change, refer to the Refunding asynchronous payment methods page.
Completed refunds
When a refund is successfully processed, Digital River moves its state
to succeeded
and creates an event with a type
of refund.complete
.
To notify customers of successfully processed refunds, you can also configure a webhook to listen for order.refunded
.
In the payload, amount
is how much you requested be refunded and refundedAmount
is the actual reimbursed amount.
You can use refund.complete
to trigger a refund confirmation email to customers. The message (typically an email) should notify them that their refund request was successful and inform them how much they were reimbursed. Ensure you also update the refund status on their order details page.
Failed refunds
If your refund request fails, Digital River moves the refund's state
to failed
and creates a refund.failed
event. In these cases, refundedAmount
is 0.0
.
For information on how to test refund failures, refer to Testing scenarios.
Some common reasons for a refund failure include:
A closed account
A frozen account due to suspected fraud
An expired credit card
If a refund fails, your integration can attempt to submit another POST/refunds
using the same itemId
(s) and/or orderId
. Alternatively, you can try to manually process the refund in Digital River Dashboard.
Providing a total refunded amount
An order's refundedAmount
contains the total amount of all refunds issued on an order. This is a useful value to display to customers on their order details page.
Last updated