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 to notify Digital River of fulfilled and/or cancelled items. Each time you define and submit a request, you inform our payment services how many items in an are fulfilled and/or cancelled. We then use that information to or the appropriate amount of an order's payment .
Once you submit a POST /fulfillments
, your integration should also be set up to handle fulfillment-related events.
Before you submit a request, you must first receive and handle the necessary events. The specific events you must process depend on the order's fulfillment model:
✔
✔
✔
✔
In third-party coordinated fulfillments, you need to synchronously or asynchronously receive an in an 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 use the distributed or orchestrated models.
In the distributed model, you need to handle an 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 these events. Our orchestration service monitors the key commerce and fulfillment events and then handles the payment capture and cancel process.
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).
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.
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.
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
.
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.
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.
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
.
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
To handle this event, we recommend that you:
Contact the customer to arrange a return or alternate payment.
Failed captures might also be due to fulfillment delays from 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.
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 could not determine a reason for the capture failure.
Upon receipt of the charge cancellation event, inform customers of the cancelled payment.
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
.
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.
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.
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
An in an state
The event
The event​
Once you receive and handle the necessary events, define a request.
You do this by providing an , information about each fulfilled and/or cancelled item, and any shipment identifiers and tracking data provided by your fulfiller.
To obtain these identifiers, configure a webhook to listen for the with a type
of fulfillment_order.shipped
event and then pass them in the body of a POST /fulfillments
.
Each time you send a POST /fulfillments
and receive a 201 Created
, the payload contains a with a unique identifier. The request also triggers a fulfillment.created
event.
The data.object
of an with a type
of fulfillment.created
contains a and orderDetails
. The event's orderDetails
has nearly all the same data as the associated . The primary exception is that orderDetails
doesn't contain the order's payment
.
You can also access orderDetails
by .
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 .
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 and contains a fulfillmentId
that identifies the that triggered the event.
An order.charge.capture.complete
event indicates that Digital River fully or partially captured one of an .
In the following example, the charge's remains capturable
because the is only partially fulfilled.
To access data on the payment source associated with the capture, pass the event's sourceId
as a path parameter in a .
To access product and tracking data, use the event's captures[].fulfillmentId
to 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 may also contain shipment tracking data.
In rare cases, a fails. If this happens, Digital River creates an order.charge.capture.failed
event.
Send a shipment cancellation request to your fulfillment logistics partner. The event's captures[].fulfillmentId
allows you to , access its shipmentId
and items[].shipmentItemId
and then use these identifiers to cancel the shipment.
Verify with your fulfiller to determine whether they can cancel a shipment within a certain window of time. If using Digital River's fulfillment service, refer to Cancelling physical fulfillments.
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 that and a ts
that payment.
Retrieve the event's data.object.id
, which uniquely identifies the .
Send this charge identifier as a path parameter in a .
We recommend that your integration be set up to handle successful cancellations.
The order.charge.cancel.complete
event typically originates with a customer requesting your site to cancel an entire (or a certain quantity of one or more line items in an order).
This request, in turn, should eventually trigger a that specifies a cancelQuantity
for each line item that the customer wants to cancel.
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 .
Once you submit one or more POST/fulfillments
that result in every line item's state
transitioning to fulfilled
, then the state
also becomes fulfilled
and an order.fulfilled
event is fired.
At this point, if you submit any additional POST /fulfillments
on the , you receive the following error:
When the moves into a 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.
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, use the to process the request.