Charges
Learn about what a charge is, how it's created, and how captures, cancels, and refunds work
A charge represents a payment authorization. The charge creation process is handled by Digital River. Throughout a charge's lifecycle, the object can contain one or more captures, cancels, and refunds.
Whether you're using Prebuilt Checkout or Direct Integrations, the payment authorization process remains the same.
At the time of order creation, Digital River creates a charge whose
amount
is equal to the associated source's amount
and then submits an authorization request that gets routed to the appropriate payment provider. For example, as you build a Direct Integrations' checkout, customers might provide credit card information during the payment collection stage. This information is then used to create a primary source that you associate with the checkout. After you convert the checkout to an order, Digital River creates a charge and then sends an authorization request to a payment processor who forwards it to a payment provider. If the request is approved by the payment provider, then Digital River moves the charge's
state
to capturable
and creates an order.charge.capturable
event. Once a provider authorizes payment, the charge on a credit card typically remains
capturable
for seven days.A charge's
amount
represents the initial authorization on a customer's payment method. But it's ultimately all the captures, cancellations, and refunds during an order's lifecycle that determines how much a customer pays.Order
{
"id": "178727320336",
...
"state": "accepted",
...
"payment": {
"charges": [
{
"id": "b469adb4-d9d1-4baa-80b1-e55c26feb4e8",
"createdTime": "2020-07-02T20:10:47Z",
"currency": "USD",
"amount": 145.16,
"state": "capturable",
"captured": false,
"refunded": false,
"sourceId": "9d9cff59-2b43-4b0a-a171-f49a243e5ea8"
}
],
...
}
...
}
An order's
payment.charges[]
contains an enduring record of all the captures[]
, cancels[]
, and refunds[]
that occur during that order's lifecycle.Order
{
"id": "178728710336",
"createdTime": "2020-07-02T21:43:28Z",
...
"payment": {
"charges": [
{
"id": "c23d5317-3410-4abb-af86-8c8570b9dc90",
"createdTime": "2020-07-02T21:43:30Z",
"currency": "USD",
"amount": 145.16,
"state": "complete",
"captured": true,
"captures": [
{
"id": "075224cd-0d07-440f-9c16-a17f16cb9692",
"createdTime": "2020-07-02T21:50:35Z",
"amount": 64.52,
"state": "complete"
},
{
"id": "966387d3-3693-4d35-bf8e-9f190b58e2a8",
"createdTime": "2020-07-02T21:50:35Z",
"amount": 24.2,
"state": "complete"
}
],
"refunded": true,
"refunds": [
{
"createdTime": "2020-07-02T22:39:00Z",
"amount": 53.77,
"state": "complete"
}
],
"cancels": [
{
"id": "5c13a17a-8c30-4550-be27-ddd84894b45e",
"createdTime": "2020-07-02T21:54:51Z",
"amount": 32.26,
"state": "complete"
},
{
"id": "58d9ff72-d043-4e00-9552-fb6dd8144a6c",
"createdTime": "2020-07-02T21:54:51Z",
"amount": 24.18,
"state": "complete"
}
],
"sourceId": "9d9cff59-2b43-4b0a-a171-f49a243e5ea8",
"type": "customer_initiated"
}
],
...
}
All captures, cancels, and refunds have an initial
state
of pending
and then either transition to complete
or failed
. With each of these state
transitions, a corresponding event is created.For example, when you initiate the payment cancellation process, Digital River creates an
order.charge.cancel.pending
event. This is eventually followed either by order.charge.cancel.complete
or order.charge.cancel.failed
.During an order's lifecycle, an order's
totalAmount
and each of its payment.charges[].amount
(s) remain unaltered. The actual amount a payment method is debited or credited is reflected by capturedAmount
and refundedAmount
, respectively.Order
{
"id": "178728710336",
...
"totalAmount": 145.16,
...
"refundedAmount": 53.77,
"state": "complete",
...
"charges": [
{
"id": "c23d5317-3410-4abb-af86-8c8570b9dc90",
"createdTime": "2020-07-02T21:43:30Z",
"currency": "USD",
"amount": 145.16,
"state": "processing",
"captured": true,
"captures": [
...
],
"refunded": true,
"refunds": [
{
"createdTime": "2020-07-02T22:39:00Z",
"amount": 53.77,
"state": "complete"
}
],
"cancels": [
...
],
"sourceId": "9d9cff59-2b43-4b0a-a171-f49a243e5ea8"
}
],
...
"capturedAmount": 88.72,
"cancelledAmount": 56.44,
"availableToRefundAmount": 34.94,
...
}
A capture represents the settling of an authorization. In other words, how much a customer's payment method is debited. Some payment methods require that a charge's full
amount
be captured all at once, while others permit multiple captures.When you submit a
POST/fulfillments
that specifies an items[].quantity
, Digital River attempts to capture payment. POST/fulfillments
curl --location --request POST 'https://api.digitalriver.com/fulfillments' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <API_key>' \
...
"orderId": "178728710336",
"items": [
{
"itemId": "98014170336",
"quantity": 1
},
{
"itemId": "98014180336",
"quantity": 2
}
]
}'
Once submitted, you can be notified that the capture process has begun by listening for the
order.charge.capture.pending
event.In the above example, the
POST/fulfillments
informed our payment services that two line items were fulfilled. As a result, the order contains two captures[]
, each with a unique id
and a captured amount
. As more goods are fulfilled, and you respond by submitting additional POST/fulfillments
, an order's capturedAmount
provides a running total of how much has been settled.Order
{
"id": "178728710336",
...
"payment": {
"charges": [
{
"id": "c23d5317-3410-4abb-af86-8c8570b9dc90",
"createdTime": "2020-07-02T21:43:30Z",
"currency": "USD",
"amount": 145.16,
"state": "complete",
"captured": true,
"captures": [
{
"id": "075224cd-0d07-440f-9c16-a17f16cb9692",
"createdTime": "2020-07-02T21:50:35Z",
"amount": 64.52,
"state": "complete"
},
{
"id": "966387d3-3693-4d35-bf8e-9f190b58e2a8",
"createdTime": "2020-07-02T21:50:35Z",
"amount": 24.2,
"state": "complete"
}
],
...
"sourceId": "9d9cff59-2b43-4b0a-a171-f49a243e5ea8",
"type": "customer_initiated"
}
],
"sources": [
{
"id": "9d9cff59-2b43-4b0a-a171-f49a243e5ea8",
"type": "creditCard",
"amount": 145.16,
...
},
"creditCard": {
"brand": "Visa",
"expirationMonth": 7,
"expirationYear": 2027,
"lastFourDigits": "1111"
}
}
],
...
},
...
"capturedAmount": 88.72,
...
}
In this example, since the order's primary payment source has a
type
of creditCard
, each captures[]
will (typically) briefly transition to a state
of pending
before becoming complete
. Once a capture moves into this state
, Digital River creates an order.charge.capture.complete
event.A cancel negates all or part of a payment authorization. Cancels don't result in the debiting or crediting of a customer's payment method. That same underlying payment method determines whether a charge can be partially cancelled or only supports full cancellations.
When you send a
POST/fulfillments
that specifies an items[].cancelQuantity
, Digital River attempts to cancel payment.POST/fulfillments
curl --location --request POST 'https://api.digitalriver.com/fulfillments' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <API_key>' \
...
--data-raw '{
"orderId": "178728710336",
"items": [
{
"itemId": "98014170336",
"cancelQuantity": 1
},
{
"itemId": "98014180336",
"cancelQuantity": 1
}
]
}'
Once submitted, you can be notified that the cancellation process has begun by listening for the
order.charge.cancel.pending
event.In the above example, the
POST/fulfillments
informed our payment services that two line items were cancelled. As a result, the order contains two cancels[]
, each with a unique id
and a cancelled amount
.In this particular example, since all of the order's
charges[]
are either captured or cancelled, the order's state
moves to complete
and an order.complete
event is triggered. Order
{
"id": "178728710336",
...
"totalAmount": 145.16,
...
"state": "complete",
...
"payment": {
"charges": [
{
"id": "c23d5317-3410-4abb-af86-8c8570b9dc90",
"createdTime": "2020-07-02T21:43:30Z",
"currency": "USD",
"amount": 145.16,
"state": "processing",
"captured": true,
"captures": [
...
],
"refunded": false,
"cancels": [
{
"id": "5c13a17a-8c30-4550-be27-ddd84894b45e",
"createdTime": "2020-07-02T21:54:51Z",
"amount": 32.26,
"state": "complete"
},
{
"id": "58d9ff72-d043-4e00-9552-fb6dd8144a6c",
"createdTime": "2020-07-02T21:54:51Z",
"amount": 24.18,
"state": "complete"
}
],
"sourceId": "9d9cff59-2b43-4b0a-a171-f49a243e5ea8"
}
],
...
}
"capturedAmount": 88.72,
"cancelledAmount": 56.44,
"availableToRefundAmount": 88.71,
...
}
You should be aware however that
refunds[]
in charges are not the same object as refunds you create when submitting POST/refunds
. This is because, for batch processing purposes, Digital River often aggregates charge refunds[]
.The following attempts to demonstrate this distinction:
Refunds
Order
Charge
The following
GET/refunds
request is searching for all the refunds created by a client system that are associated with a specific order. curl --location --request GET 'https://api.digitalriver.com/refunds?orderId=178728710336' \
--header 'Authorization: Bearer <API_key>' \
Refunds
{
"hasMore": false,
"data": [
{
"id": "re_40af9cbd-0f38-4362-9e24-c6338f3795c4",
...
"items": [
{
"amount": 21.51,
"quantity": 1,
"refundedAmount": 21.51,
...
},
{
"amount": 32.26,
"quantity": 1,
"refundedAmount": 32.26,
...
}
],
"orderId": "178728710336",
...
"refundedAmount": 53.769999999999996,
...
}
]
}
curl --location --request GET 'https://api.digitalriver.com/orders/178728710336' \
--header 'Authorization: Bearer <API_key>' \
{
"id": "178728710336",
...
"payment": {
"charges": [
{
"id": "c23d5317-3410-4abb-af86-8c8570b9dc90",
...
"refunds": [
{
"createdTime": "2020-07-02T22:39:00Z",
"amount": 53.77,
"state": "complete"
}
],
...
}
],
...
"refundedAmount": 53.77,
...
}
The following
GET/charges/{id}
request passes the charge identifier from the order as a a path parameter.curl --location --request GET 'https://api.digitalriver.com/charges/c23d5317-3410-4abb-af86-8c8570b9dc90' \
--header 'Authorization: Bearer <API_key>' \
The response contains an array of charge
refunds[]
, each with a unique id
. Note that the id
of the charge-level refund is not the same as the id
of the client system created refund.{
"id": "c23d5317-3410-4abb-af86-8c8570b9dc90",
...
"orderId": "178728710336",
...
"refunded": true,
"refunds": [
{
"id": "5e32af54-aff5-49a8-b72e-37aa8e3d03af",
"createdTime": "2020-07-02T22:39:00Z",
"amount": 53.77,
"state": "complete"
}
],
...
}
Each of these objects contains a
failureMessage
and failureCode
that you may be able to use to pinpoint a reason for the failure.When a charge's
state
changes, Digital River creates a corresponding event. For example, when the charge's state
changes from pending
to capturable
an order.charge.capturable
event is emitted.The
state
values for a successful charge (i.e. the happy path) are pending
> capturable
> processing
> complete
.1) When the charge... | (2) its state transitions to... | (3) and an...event is emitted. |
---|---|---|
...is awaiting authorization, typically because additional customer action is required | pending | order.charge.pending |
...is authorized by the payment provider | capturable | order.charge.capturable |
...is being processed by the payment provider | processing | order.charge.processing |
...is captured in full (or captured in part with the remainder cancelled) and there are no pending charge operations. | complete | order.charge.complete |
...is cancelled in full and there are no pending charge operations. | cancelled | order.charge.cancelled |
fails to authorize | failed | order.charge.failed |
For different success and error scenarios, you can create tests to determine whether your integration returns the expected
state
value.Last modified 3mo ago