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.

How a charge is created

Whether you're using Low-code checkouts 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 provider, Digital River moves the charge's state to capturable and creates an event with a type of order.charge.capturable.

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.

{
    "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"
            }
        ],
        ...
    }
    ...
}

How captures, cancels, and refunds work

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 event with a type of order.charge.cancel.pending, 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,
    ...
}

Captures

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 a POST/ fulfillments that specifies an items[].quantity is submitted, Digital River attempts to capture payment.

For more details, refer to the Capturing and cancelling payment charges page.

The following POST /fulfillments seeks to partially capture payment on an order.

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 event with a type of order.charge.capture.pending.

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.

{
    "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 order.charge.capture.complete.

Cancels

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.

For more details, refer to the Capturing and cancelling payment charges page.

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.

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 order.complete is created.

{
    "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,
    ...
}

Charge refunds

In an order, a payment.charges[].refunds[] represents a partial or full reversal of a payment.charges[].captures[].

{
    "id": "312049410336",
    ...
    "payment": {
        "charges": [
            {
                "id": "7574d182-b47a-4740-911b-8c584665493a",
                "createdTime": "2024-04-29T16:08:43Z",
                "currency": "USD",
                "amount": 100.0,
                "state": "complete",
                "captured": true,
                "captures": [
                    {
                        "id": "d07e1f98-c206-4e08-9f8a-4601f74c18e8",
                        "createdTime": "2024-04-29T16:08:50Z",
                        "amount": 100.0,
                        "state": "complete"
                    }
                ],
                "refunded": true,
                "refunds": [
                    {
                        "createdTime": "2024-04-29T16:12:11Z",
                        "amount": 36.0,
                        "state": "complete"
                    }
                ],
                "sourceId": "bc8cd140-bdf1-4a50-8ad1-eee0b157a3d8",
                "type": "customer_initiated"
            }
        ],
        ...
    },
    ...
    "capturedAmount": 100.0,
    "cancelledAmount": 0.0,
    "availableToRefundAmount": 64.0,
    "checkoutId": "aabbd115-7e1e-4a0b-ae1c-036972ddbab6"
}

How refunds differ from charge refunds

An order might contain one or more charges[].refunds[]. Each element of this array represents a charge refund, which is not the same object as a refund. This is because, for batch processing purposes, Digital River often aggregates numerous refunds into a lesser number of charge refunds.

For details on how to create refunds, refer to Issuing refunds or Third-party coordinated returns.

For example, the following GET /refunds request is searching for all the refunds created on an order.

The response shows that, in this particular example, two unique refunds exist, each represented by an element in data[] and both with the same orderId.

This is because two POST /refunds were previously submitted. Digital River however added the amount of these unique refunds together to arrive at a single charges[].refunds[].amount.

curl --location 'https://api.digitalriver.com/refunds?orderId=312049410336' \
...
--header 'Authorization: Bearer <Secret API Key>' \
...
--data ''

By passing charges[].id, which is the same in both refunds, as a path parameter in a GET /charges/{id}, you can access the unique id of this single charge refund. Note that its value is different than the id of each of the two refunds.

curl --location 'https://api.digitalriver.com/charges/7574d182-b47a-4740-911b-8c584665493a' \
...
--header 'Authorization: Bearer <Secret API key>' \
...
--data ''

Handling charge failures

When a payment authorization request is unsuccessful, the charge's state becomes failed. The same is true for failed captures, cancels, and refunds.

Each of these objects contains a failureMessage and failureCode that you may be able to use to pinpoint a reason for the failure.

For more information, refer to authorization declines and handling rejected orders.

The charge lifecycle

A charge's state can be pending, capturable, processing, complete, cancelled, or failed.

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 event with a type of order.charge.capturable is created.

The state values for a successful charge (i.e. the happy path) are pending > capturable > processing > complete .

The following table lists the possible states of a charge and their corresponding events:

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 updated