Processing orders
Learn the basics of processing an order.
To process an order, we recommend that your integration convert the checkout to an order, and then handle the immediate response as well as listen for and handle order-related events.

Converting a checkout to an order

Once all currency, address, product, and payment requirements are met, you can convert a checkout to an order by sending checkoutId in the payload of a POST/orders request. Submission of this request primarily acts as a payment authorization call. After the request is sent, your integration should both process the immediate response and listen for order-related webhook events.
POST/orders
1
curl --location --request POST 'https://api.digitalriver.com/orders' \
2
--header 'Content-Type: application/json' \
3
--header 'Authorization: Bearer <API_key>' \
4
--data-raw '{
5
"checkoutId": "177452470336"
6
}'
Copied!
You do have the ability to submit a POST/orders whose payload contains checkoutId plus additional parameters (provided they meet the request's specifications). However, when processing the request, Digital River ignores these additional values. If you'd like to update a checkout, you must do so prior to converting it to an order.
As an example, let's say you have a Checkout with an email address of [email protected].
Checkout
1
{
2
"id": "856adaff-0176-4bdb-91cb-7304dfd1e7a9",
3
...
4
"email": "[email protected]",
5
...
6
}
Copied!
You submit a POST/orders that contains the upstream checkoutId, an updated email, and also adds an upstreamId.
POST/orders
1
curl --location --request POST 'https://api.digitalriver.com/orders' \
2
--header 'Content-Type: application/json' \
3
--header 'Authorization: Bearer <API_key>' \
4
...
5
--data-raw '{
6
"checkoutId": "856adaff-0176-4bdb-91cb-7304dfd1e7a9",
7
"email": "[email protected]",
8
"upstreamId": "1J9F17710A6"
9
}'
Copied!
The response contains a 201 Created status code. However, email is not updated and upstreamId is not attached.
Order
1
{
2
"id": "189917880336",
3
...
4
"email": "[email protected]",
5
...
6
"checkoutId": "856adaff-0176-4bdb-91cb-7304dfd1e7a9"
7
}
Copied!
Although not the preferred approach, you can omit checkoutId in a POST/orders by creating an order with a registered customer's identifier.

Handling the POST/orders response

After you convert a checkout to an order, assuming all upstream checkout requirements are met, the response contains either a 409 Conflict or 201 Created status code.
When handling the POST/orders response, your integration needs to capture the initial order status and use that information to update the status of the commerce system. This ensures that downstream fulfillment operations are correctly handled.

409 Conflict

A POST/orders response with a 409 Conflict status code indicates that Digital River did not create an order and either a payment authorization or a fraud review failure occurred. The error's code and message contain more specific information about the payment failure or the suspected fraud.
Use this error information to update the upstream commerce platform's order. Specifically, you should update its status, payment status, and fraud status.
You should also use message to inform the end customer of the problem. Do not, however, share the code with the customer. Doing so may aid parties that are attempting to carry out fraudulent or malicious activities.
For additional information on how your integration should process 409 Conflict responses, refer to the page on handling rejected orders.

201 Created

A POST/orders response with a 201 Created status code indicates an order's state is pending payment, in review, or accepted.
From the response payload, retrieve the order's id, state, fraudState, and charges[].state, and use theses values to update the corresponding attributes in the upstream commerce platform's order.
When a POST/orders returns a 201 Created and the state is pending_payment or in_review, additional validations must be conducted. These ultimately result in either an accepted or failed order. To be notified of these asynchronous order accepted or order failed events, you should listen for order-related webhook events.

Pending payment

If an order's state is pending_payment, then fraud review has been successfully completed but the transaction's charge is not yet authorized. For more information, refer to handling pending payment orders.

In review

If an order's state is in_review, then this indicates that Digital River is conducting a secondary fraud review. For more information, refer to handling in review orders.

Accepted

If an order's state is accepted, then the customer successfully passed fraud review and the charge is authorized. For more information, refer to handing accepted orders.

Important events early in the order lifecyle

In addition to handling the POST/orders response, your integration must also monitor key webhook events that occur early in an order's lifecycle. These events notify you of charge authorization failures, fraud blocks, pending charge authorizations, ongoing fraud reviews, accepted orders, and cancelled orders.
Each time you receive one of these events, retrieve state, fraudState, and charges[].state (if available) from its payload, and use these values to update the corresponding attributes in the upstream commerce system's order.

The charge authorization failure event

An asynchronous charge authorization failure triggers an order.charge.failed event.
If you receive this event, you can iterate over the order's charges array and inspect each for a failure code or message. The failureMessage is not always available. But when it is, you can use it to provide more specific payment failure information to the customer.
Do not display the failureCode to the end customer. Doing so potentially aids malicious and fraudulent actors.

The fraud block event

When Digital River detects an anomaly during its fraud review, or the customer is determined to be on the Denied Persons List, we send an order.blocked event. The payload of this event consists of an order in a blocked state. The order's fraudState is also blocked. These are both terminal states so you should inform the end customer that the transaction failed.

The pending charge authorization event

An order.pending_payment event indicates that Digital River detected no fraudulent activity during its fraud review. The order, however, shouldn't be fulfilled because the transaction's payment is not yet authorized.
For more information, refer to handling pending payment orders.

The in-process fraud review event

An order.review_opened event indicates that Digital River is conducting a secondary fraud review and has moved the order into an in_review state. Since our fraud review is not yet complete, the order shouldn't be fulfilled.
For more information, refer to handling in review orders.

The order accepted event

When all payment charges are authorized and no irregularities are detected during the fraud review, Digital River sends you an order.accepted event. Upon arrival, move the commerce system's order into a ready to fulfill state.
Unless you synchronously receive an order in an accepted state, your integration should wait until it receives the order.accepted event before fulfilling an order. Doing so reduces the risk of fraud and the frequency of charge-backs.
For more information, refer to handling accepted orders.

The order cancelled event

When an order moves into a cancelled state, an order.cancelled event is created. The event’s data.object contains an order in a cancelled state. The event is not currently configured to provide you a reason for the cancellation. As a result, cancelReason will not be populated in the payload.

Event origins

Depending on how you build your integration, the order.cancelled event may have multiple origins. For example, if your site contains a cancel order button, then order.cancelled may originate with shoppers requesting to fully cancel their order.
For Digital River fulfillments, this button’s click event handler should trigger a POST/ fulfillment-cancellations that requests to fully cancel each line item in the fulfillment order.
For more information, refer to cancelling physical fulfillments.
If your integration allows shoppers to submit line-item level cancellation requests (as opposed to the more standard full order cancellation requests), you can’t always use order.cancelled as the event that triggers a cancel complete shopper notification. This is because, once an order is accepted, it doesn't become cancelled until all of its charges are also cancelled.
The order.cancelled event may also be triggered when a shopper fails to transfer payment by a designated date and time and, as a result, the source expires. This applies to wire transfers, Konibini payments, and other types of sources with a receiver payment flow.
For example, in checkouts with a primary source type of wireTransfer, once you successfully convert the checkout to an order, the order typically becomes pending_payment. When handling this order state change event, you should provide instructions to the customer on how to complete payment.
For more information, refer to handling pending payment orders.
If the shopper doesn’t push the funds within the allotted time, then the source expires, no charge authorization is created and the order.cancelled event is fired. In this scenario, since no charge is created, you won’t receive any order charge related events.

Handling the order.cancelled event

Upon receiving the order.cancelled event, we recommend you:
  • Update the master order record in your system
  • Notify shoppers (typically by email) that their order has been successfully cancelled and no payment was collected. In the email, we suggest you provide:
    • The order number
    • The order cancellation date (you can retrieve this information from the order's stateTransitions.cancelled)
    • An itemization of the cancelled goods
    • The payment method used by the shopper
    • The total amount cancelled
    • The customer’s billing address
    • Your contact information

Handling order state changes

The following provides information on how to handle pending payment, in review, and accepted orders.

Handling pending payment orders

A pending_payment order indicates that the transaction's payment is not yet authorized. Orders in this state should not be fulfilled.
Instead, from the body of the POST/orders response or the data.object of the order.pending_payment event, retrieve the payment source identifier of the transaction's primary payment source.
order.pending_payment
1
{
2
"id": "65beb271-e660-444d-8919-69c991d63d6d",
3
"type": "order.pending_payment",
4
"data": {
5
"object": {
6
"id": "196623140336",
7
...
8
"payment": {
9
"sources": [
10
{
11
"id": "f853f415-7f85-4695-bd93-7f479efdc4a8",
12
"type": "wireTransfer",
13
"amount": 11.33,
14
...
15
"wireTransfer": {
16
"accountHolder": "Global Collect BV",
17
"bankName": "Rabobank N.A.",
18
"city": "Ontario",
19
"country": "US",
20
"referenceId": "890701505439",
21
"accountNumber": "0487369908",
22
"swiftCode": "RABOUS66XXX"
23
}
24
}
25
],
26
"session": {
27
"id": "affcead4-92b4-425d-b995-3ebb3fc046f8",
28
"amountContributed": 11.33,
29
"amountRemainingToBeContributed": 0.0,
30
"state": "pending_funds",
31
"clientSecret": "affcead4-92b4-425d-b995-3ebb3fc046f8_1773afaa-5bb3-4668-b466-b5a49b63653b"
32
}
33
},
34
"state": "pending_payment",
35
...
36
"checkoutId": "ab3b00eb-5f32-4c84-8ef3-dc659016d502"
37
}
38
},
39
...
40
"digitalriverVersion": "2021-03-23"
41
}
Copied!
Send this value as a path parameter in a GET/sources/{id} request. From the response, retrieve the source's clientSecret.
Source
1
{
2
"id": "f853f415-7f85-4695-bd93-7f479efdc4a8",
3
"createdTime": "2021-08-23T02:24:02Z",
4
"type": "wireTransfer",
5
...
6
"clientSecret": "f853f415-7f85-4695-bd93-7f479efdc4a8_abec5143-4f72-486c-b377-34d31ddb3c13",
7
"wireTransfer": {
8
"accountHolder": "Global Collect BV",
9
"bankName": "Rabobank N.A.",
10
"city": "Ontario",
11
"country": "US",
12
"referenceId": "74243814931",
13
"accountNumber": "5215726630",
14
"swiftCode": "RABOUS29XXX"
15
},
16
"liveMode": false
17
}
Copied!
Then pass both the source's unique identifier and client secret to the create method of your front end's delayed payment instructions element.
1
let options = {
2
"sourceId": "f853f415-7f85-4695-bd93-7f479efdc4a8",
3
"sourceClientSecret": "f853f415-7f85-4695-bd93-7f479efdc4a8_abec5143-4f72-486c-b377-34d31ddb3c13"
4
}
5
6
let delayedPaymentInstructions = digitalRiver.createElement('delayedpaymentinstructions', options);
Copied!
Ensure that the element is mounted on an appropriate page on your site.
1
<div id="delayed-payment-container"></div>
2
...
3
delayedPaymentInstructions.mount("delayed-payment-container");
Copied!
You can optionally configure the element to listen for the ready event. This event signifies that the delayed payment instructions are loaded in the specified DOM element.
1
delayedPaymentInstructions.on('ready', function(event) {
2
//delayed payment instructions element is ready
3
});
Copied!
Direct the customer to the page that contains the element with the loaded instructions.
The instructions usually provide customers with the number of days that they have to push payment.
If the customer follows the instructions and the charge on the payment source is authorized, your integration will receive the order.accepted event. If they don't make payment within the allotted timeframe, you receive order.cancelled.

Handling in review orders

Orders that are in_review should not be fulfilled. Make sure you're listening for the order.accepted and order.blocked events. After an order is no longer in an in_review state, you'll always receive one of these two events.

Handling accepted orders

When the state of an order is accepted, you should move the commerce platform's order into a ready to fulfill state and direct the customer to the order confirmation page. At this point, fulfillment operations can be initiated.

The order object

The following looks at some of the key attributes in an order and how you might use them in downstream requests. For a complete list, refer to the Orders API reference documentation.

Unique identifier

Order
1
{
2
"id": "177452480336",
3
...
Copied!

Ship to values

An order's shipTo values are displayed on invoices and credit memos.
1
...
2
"customerId": "987654321",
3
...
4
"shipTo": {
5
"address": {
6
"line1": "10380 Bren Rd W",
7
"line2": "string",
8
"city": "Minnetonka",
9
"postalCode": "55129",
10
"state": "MN",
11
"country": "US"
12
},
13
"name": "Jane Doe",
14
"phone": "952-111-1111",
15
"email": "[email protected]",
16
"organization": "Digital River"
17
},
Copied!

Amounts, fees, and taxes

The order's total amount, fees, taxes, and other costs are the same as those presented to customers when they confirmed the purchase. You can retrieve these values and display them to customers on their order confirmation page.
1
...
2
"totalAmount": 177.67,
3
"subtotal": 172.5,
4
"totalFees": 0.0,
5
"totalTax": 5.17,
6
"totalDuty": 0.0,
7
"totalDiscount": 7.5,
8
"totalShipping": 5.0,
9
...
Copied!

Line items

You can use an order's items array to retrieve detailed price, tax, and quantity information for each product in an order. This information can then be displayed to customers on their order confirmation and order details pages.
Each line item is returned with a unique id. You need this identifier when initiating physical fulfillments, capturing and cancelling payments, handling third-party returns, and issuing refunds. For more information on how to use subscriptionInfo, refer to the Subscriptions page.
1
...
2
"items": [
3
{
4
"id": "96415480336",
5
"skuId": "08141946",
6
"amount": 100.0,
7
"quantity": 1,
8
"state": "created",
9
"stateTransitions": {
10
"created": "2020-05-21T17:26:34Z"
11
},
12
"tax": {
13
"rate": 0.0,
14
"amount": 0.0
15
},
16
"subscriptionInfo": {
17
"billingAgreementId": "cfeba2ac-d532-49e4-99f4-7a433507facf",
18
"terms": "Insert terms here",
19
"autoRenewal": true,
20
"freeTrial": false
21
}
22
},
23
{
24
"id": "96415490336",
25
"skuId": "05081978",
26
"amount": 67.5,
27
"quantity": 1,
28
"discount": {
29
"percentOff": 10.0,
30
"quantity": 1
31
},
32
"state": "created",
33
"stateTransitions": {
34
"created": "2020-05-21T17:26:34Z"
35
},
36
"tax": {
37
"rate": 0.07125,
38
"amount": 4.81
39
}
40
}
41
],
42
...
Copied!

Tax invoices and credit memos

For some orders, Digital River populates invoicePDFs and creditMemoPDFs with information that you can use to access and share tax invoice and credit memo files.
1
...
2
"invoicePDFs": [
3
{
4
"url": "https://api.digitalriver.com/files/23c7e1a5-25e4-41a9-b935-eda98dfa238b/content",
5
"id": "23c7e1a5-25e4-41a9-b935-eda98dfa238b"
6
}
7
],
8
"creditMemoPDFs": [
9
{
10
"url": "https://api.digitalriver.com/files/5cec4a32-853f-485a-90a0-15ea0a614355/content",
11
"id": "5cec4a32-853f-485a-90a0-15ea0a614355"
12
}
13
],
14
...
Copied!

State and fraud state

For more information about an order's state and fraudState, refer to the Order lifecycle page.

Tax identifiers

Orders with applied tax identifiers contain an array of tax identifier objects.
JSON
1
...
2
"taxIdentifiers": [{
3
"id": "a6809a63-e6a9-4016-abbc-f33d19fccb5b",
4
"customerId": "5774321009",
5
"type": "uk",
6
"value": "GB000283536",
7
"state": "verified",
8
"stateTransitions":
9
{"pending": "2020-05-13T11:00:00.000Z", "verified": "2020-05-15T16:00:00.000Z"},
10
"verified_name": "Descon Ltd",
11
"verified_address": "Design House, 18b Tromode, Isle of Man",
12
"createdTime": "2020-08-01T02:25:53Z",
13
"updatedTime": "2020-08-01T05:47:21Z"
14
}],
15
...
Copied!

Charges

An order's charges array contains one or more elements, each representing a charge created from a primary or secondary payment source. Each charge contains a unique identifier, an amount, a state, and the identifier of the payment source used to create the charge.
1
...
2
"charges": [
3
{
4
"id": "d3a02b03-1378-431e-81a5-9cb6dd54d90b",
5
"createdTime": "2020-05-21T17:26:37Z",
6
"currency": "USD",
7
"amount": 177.67,
8
"state": "capturable",
9
"captured": false,
10
"refunded": false,
11
"sourceId": "deabb3a4-14e4-4702-a13b-ddaac23277d3"
12
}
13
],
14
...
Copied!

Request to be forgotten

An order's requestToBeForgotten indicates whether an order's data is scheduled for deletion. This is the only attribute (other than metadata) that can be modified in an update order request.
1
...
2
"requestToBeForgotten": false,
3
...
4
}
Copied!

Updating an order

Besides metadata, the only order attribute that you can update is requestToBeForgotten.
To update an order, submit a POST/orders/{id} request and pass in the order identifier as a path parameter. If the customer has requested that the order be forgotten, then set the requestToBeForgotten parameter to true.

Reusing the checkout identifier

If you attempt to pass a checkoutId in a POST/orders request, and that Checkout has already been consumed by a different POST/orders request, you'll get back a response with a 404 Not Found status:
JSON
1
{
2
"type": "not_found",
3
"errors": [
4
{
5
"code": "not_found",
6
"parameter": "orderId",
7
"message": "Order 180139250336 not found"
8
}
9
]
10
}
Copied!

Using a registered customer to create an order

We strongly recommend that you build your integration so that checkouts are converted to orders.
You do, however, have the ability to submit a POST/orders that omits checkoutId, thereby bypassing the Checkouts API. In this case, the request should contain a registered customer and a reusable payment source saved to that customer's account. The POST/orders must also meet all currency, address, shipping method, product, and payment session requirements.
POST/orders
1
curl --location --request POST 'https://api.digitalriver.com/orders' \
2
--header 'Content-Type: application/json' \
3
--header 'Authorization: Bearer <API_key>' \
4
...
5
--data-raw '{
6
"customerId": "534313260336",
7
"currency": "USD",
8
"taxInclusive": false,
9
"email": "[email protected]",
10
"shipTo": {
11
"address": {
12
"line1": "10380 Bren Road W",
13
"city": "Minnetonka",
14
"postalCode": "55343",
15
"state": "MN",
16
"country": "US"
17
},
18
"name": "John Doe"
19
},
20
"shipFrom": {
21
"address": {
22
"country": "US"
23
}
24
},
25
"shippingChoice": {
26
"amount": 5,
27
"description": "standard",
28
"serviceLevel": "SG"
29
},
30
"items": [
31
{
32
"skuId": "aa4dbf0c-2336-4b9c-8cff-5d12664b8266",
33
"quantity": 2,
34
"price": 10
35
}
36
]
37
}'
Copied!
Last modified 2mo ago