Capturing and cancelling charges
Learn how to inform Digital River that products are fulfilled or cancelled so that we can attempt to capture or cancel payment
Last updated
Learn how to inform Digital River that products are fulfilled or cancelled so that we can attempt to capture or cancel payment
Last updated
Once you create an order, and handle the necessary events, you can use the Fulfillments API to notify Digital River of fulfilled and/or cancelled items. Each time you define and submit a POST/fulfillments
request, you're informing our payment services how many items in an order are fulfilled and/or cancelled. We then use that information to capture or cancel the appropriate amount of an order's payment charges.
Once you submit a POST/fulfillments
, your integration should also be set up to handle fulfillment-related events.
Before you submit a POST/fulfillment
request, you must first receive and handle the necessary events. The specific events you must process depend on the order's fulfillment model:
Upstream requirement | Digital River coordinated fulfillments (distributed model) | Digital River coordinated fulfillments (orchestrated model) | Third party coordinated fulfillments |
---|---|---|---|
In third-party coordinated fulfillments, you need to synchronously or asynchronously receive an order in an accepted
state.
In most integrations, you respond to this order state change by sending a fulfillment request to your logistics partner and when the products are shipped, your partner sends you a shipment notification. You should respond to this notification by defining a POST/fulfillments
with the quantity
of each shipped line item and then submitting the payment capture request.
Similarly, when an item is successfully cancelled, your fulfiller typically sends you a cancelled shipment notification. Respond to this notification by defining a POST/fulfillments
with the cancelQuantity
of each cancelled line item and then submitting the payment cancel request.
In Digital River coordinated fulfillments, the specific events you must process depend on whether you're using the distributed or orchestrated models.
In the distributed model, you need to handle an accepted
order by creating a fulfillment order. You must then wait to receive a fulfillment_order.shipped
event before handling that by defining a POST/fulfillments
with the quantity
of each shipped line item and then submitting the payment capture request.
Similarly, in this model, you must also wait to receive a fulfillment_order.cancelled
event before handling that by defining a POST/fulfillments
with the cancelQuantity
of each cancelled line item and then submitting the payment cancel request.
In the orchestrated model, you don't need to respond to any of these events. Our orchestration service monitors the key commerce and fulfillment events and then handles the payment capture and cancel process.
Once you receive and handle the necessary events, define a POST /fulfillments
request.
You do this by providing an order identifier, information about each fulfilled and/or cancelled item, as well as any shipment identifiers and tracking data provided by your fulfiller.
In the request's items
array, you specify each line item's unique identifier and the quantity fulfilled and/or cancelled. The request doesn't need to specify both a quantity
and cancelQuantity
, but it must contain one or the other.
If you specify a quantity
, thereby informing our payment services that these items are fulfilled, we attempt to capture the appropriate amount of the payment charge. Conversely, if you specify a cancelQuantity
, we attempt to cancel the relevant charge amount.
In Digital River coordinated fulfillments that use the distributed model, a POST /fulfillments
must include a single shipmentId
and one or more items[].shipmentItemId
(s).
To obtain these identifiers, configure a webhook to listen for the event with a type
of fulfillment_order.shipped
event and then pass them in the body of a POST /fulfillments
.
You can also include information on the name of the trackingCompany
, the trackingNumber
provided by the shipping carrier, and the trackingUrl
that customers use to monitor the shipment.
In third-party coordinated fulfillments, you typically receive this tracking information from your fulfiller when they notify you of a shipment.
In Digital River coordinated fulfillments that use the distributed model, you can retrieve this information from the fulfillment_order.shipped
event.
Each time you send a POST/fulfillments
and receive a 201 Created
, the payload contains a fulfillment with a unique identifier. The request also triggers a fulfillment.created
event.
Depending on your integration, you might find subscribing to the fulfillment created event useful. We recommend, however, that all integrations handle charge capture, charge cancel, order fulfilled, and order complete events.
The data.object
of an event with a type
of fulfillment.created
contains a fulfillment and orderDetails
. The event's orderDetails
has nearly all the same data as the associated order. The primary exception is that orderDetails
doesn't contain the order's payment
.
You can also access orderDetails
by retrieving the fulfillment.
Having orderDetails
in fulfillment.created
allows you to directly access the data needed to define shipment confirmation and/or cancellation confirmation email notifications without having to retrieve orderId
and make a get order request.
In Digital River coordinated fulfillments that use the orchestrated model, the fulfillment.created
event can also be useful for accessing tracking data. The event provides a trackingCompany
name, a trackingNumber
, and a trackingUrl
.
You can also obtain this data from the fulfillment_order.shipped
event.
In this case, you could use the event to trigger a shipped notification to the customer (typically an email) that contains this tracking information and/or add it to the customer's order management page.
Your integration should be set up to handle order.charge.capture.complete
and order.charge.capture.failed
events. The payload of both consists of a charge and contains a fulfillmentId
that identifies the fulfillment that triggered the event.
An order.charge.capture.complete
event indicates that Digital River fully or partially captured one of an order's charges.
You can handle this event by notifying customers of the amount captured, the payment method used to make the capture, relevant product details, and any shipment tracking information that may be available.
The event's captures[].amount
and captures[].createdTime
provides the data you need to inform customers how much and when they were charged.
To access data on the payment source associated with the capture, pass the event's sourceId
as a path parameter in a GET/sources/{sourceId}
.
In this example, the customer used a credit card, so from the 200 OK
response you'd most likely retrieve creditCard.brand
and creditCard.lastFourDigits
.
To access product and tracking data, use the event's captures[].fulfillmentId
to retrieve the fulfillment that triggered the capture.
From the 200 OK
response, you can use orderDetails.items[].productDetails
to get each product's name
, description
, image
, and other data. Depending on your integration, the fulfillment may also contain shipment tracking data.
You can use the event's orderId
to look up the order in your system and provide some or all of this capture, payment, product, and shipping information on the customer's order details page. For example:
We billed your creditCard.brand
ending in creditCard.lastFourDigits
in the amount of captures[].amount
on captures[].createdTime
. This payment is for the following products:
name
| description
| image
In rare cases, a capture fails. If this happens, Digital River creates an order.charge.capture.failed
event.
To handle this event, we recommend that you:
Send a shipment cancellation request to your fulfillment logistics partner. The event's captures[].fulfillmentId
allows you to retrieve the fulfillment, access its shipmentId
and items[].shipmentItemId
and then use these identifiers to cancel the shipment.
Verify with your fulfiller to determine whether they have the ability to cancel a shipment within a certain window of time. If you're using Digital River's fulfillment service, refer to Cancelling physical fulfillments.
Contact the customer to arrange a return or alternate payment.
Failed captures are usually due to expired charge authorizations. This might happen when you're running a pre-order sale and there's a lengthy period between submission of a POST/orders
that authorizes the charge and a POST/fulfillments
that captures payment.
Failed captures might also be due to fulfillment delays on the part of your logistics partner.
On the Testing scenarios page, we provide credit card information that you can use to check how your integration handles failed charge captures.
The failed capture event contains a failureCode
. We also provide a failureMessage
that may help diagnose the issue. To access this message:
Save the unique id
of the event's capture.
Retrieve the event's data.object.id
, which uniquely identifies the charge.
Send this charge identifier as a path parameter in a GET/charges/{id}
.
In the 200 OK
response, use the saved capture identifier to search captures[]
for the appropriate element and retrieve its failureMessage
.
In nearly all cases, however, failureCode
is failed-request
and failureMessage
is Failed to operate on charge
. This indicates that Digital River was unable to determine a reason for the capture failure.
We recommend that your integration be setup to handle successful charge cancellations.
The order.charge.cancel.complete
event typically originates with a customer making a request on your site to cancel an entire order (or a certain quantity of one or more line items in an order).
This request, in turn, should eventually trigger a POST/fulfillments
that specifies a cancelQuantity
for each line item that the customer wants to cancel.
In physical fulfillments, make sure you send a shipment cancellation request to your fulfiller, and receive a successful response before sending the charge cancellation request to Digital River.
For Digital River coordinated fulfillments, refer to Cancelling physical fulfillments.
Upon receipt of the charge cancellation event, inform customers of the cancelled payment.
To do this, retrieve the event's orderId
, cancels[].createdTime
and cancels[].amount
. To access information about the source, retrieve the event's sourceId
and pass it as a path parameter in a GET/sources/{sourceId}
.
In this example order, the customer used a credit card, so you'd retrieve creditCard.brand
and creditCard.lastFourDigits
from the response.
You can use the event's orderId
to locate the order in your system and display the cancel payment information to customers on their order details page. For example:
On cancels[].createdTime
we cancelled billing on your creditCard.brand
ending in creditCard.lastFourDigits
in the amount of cancels[].amount
.
Once you submit one or more POST/fulfillments
that result in every line item's state
transitioning to fulfilled
, then the order's state
also becomes fulfilled
and an order.fulfilled
event is fired.
If you use a third-party service to generate customer notifications, refer to How Digital River returns product data for details on how that service can use this event.
At this point, if you submit any additional POST/fulfillments
on the order, you receive the following error:
If your integration is set up to respond to shipment notifications from your fulfiller by synchronously submitting a POST/fulfillments
, then you can use order.fulfilled
as a trigger to send a notification to customers informing them that all of an order's goods have been shipped.
When the order moves into a complete
state, an order.complete
event is fired. Upon receipt of this event, use the event's data.object.id
or data.object.upstreamId
to look up the order in your system and set its status to complete.
If you use a third-party service to generate customer notifications, refer to How Digital River returns product data for details on how that service can use this event.
The order.complete
event can also act as a trigger to populate the customer's order details page. The following lists some of the information you may decide to display on this page, along with the field in the event that contains the data. Most likely, you've already used prior API responses and events to store much of this data in your system.
You can also use order.complete
as a trigger to activate a request refund button on the customer's order details page. When handling the button's click event, make sure you use the Refunds API to process the request.
Order details page | Event's data.object field |
---|---|
✔
✔
The fulfillment_order.shipped
event
✔
The fulfillment_order.cancelled
event
✔
Order number
id
Date of order
createdTime
Shipping address
shipTo.address
Billing address
billTo.address
Order total
totalAmount
Total before tax
subtotal
Fees
totalFees
Taxes
totalTax
Duties
totalDuty
Shipping and handling
totalShipping
Product details
items[].productDetails
Product cost
items[].amount
Product quantity
items[].quantity
Payment method(s)
payment.sources[].type
Billing date(s)
payment.charges[].captures[].createdTime
Billing amount(s)
payment.charges[].captures[].amount
Billing cancellation date(s)
payment.charges[].cancels[].createdTime
Billing cancellation amount(s)
payment.charges[].cancels[].amount