Payment sessions
Learn the basics of payment sessions
A payment session tracks a transaction's payment. On this page, you'll find information on:
Payment sessions allow you to gain access to Drop-in payments. This solution lessens your front-end development burden. To take just one example, Drop-in payments automatically retrieves a transaction's applicable payment methods and then presents them to customers during the payment collection stage of a checkout.
Additionally, payment sessions simplify source creation. Without them, you'll need to retrieve numerous data points from the checkout and ensure they're properly formatted before passing them to
createSource()
. With payment sessions however you simply retrieve the checkout's payment.session.id
and then pass that value to the appropriate source creation method, thereby minimizing your data transfer requirementsPayment sessions also allow you to comply with PSD2 and SCA regulations. If you reference this object when creating credit card sources, Digital River, when necessary, automatically collects a customer's authentication data.
You can use payment sessions to:
If you're using DigitalRiver.js with elements to collect payment, you can call
retrieveAvailablePaymentMethods()
to get a transaction's applicable payment methods and then present them as options during checkouts. digitalriver.retrieveAvailablePaymentMethods({
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f"
}).then(function(result) {
//do something with the data
});
Both of Digital River's source creation methods can be configured with the checkout's
payment.session.id
. The data our payment service needs to create the source is then retrieved from that referenced object.Drop-in payments
DigitalRiver.js with elements
let configuration = {
"sessionId": "172deb0f-de6f-4d2c-9555-53f3894b6318",
"options": {
"flow": "checkout",
"showComplianceSection": true
},
onSuccess: function(data) {},
onError: function(data) {},
onReady: function(data) {},
onCancel: function(data) {}
}
let dropin = digitalriverpayments.createDropin(configuration);
dropin.mount("drop-in");
let payload = {
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"type": "payPal",
"payPal": {
"returnUrl": "https://mywebsite.com/paymentCallBack.html",
"cancelUrl": "https://mywebsite.com/paymentCallBack.html"
}
}
digitalriver.createSource(payload).then(function(result) {
if(result.state === "chargeable") {
sendToBackEnd(result);
} else {
doErrorScenario();
}
});
Before creating an order, a checkout's
payment.session
should be in a state
of requires_confirmation
and its amountRemainingToBeContributed
should be 0
. Checkout
{
"id": "8f349290-a6ec-438a-8623-ca0c6e6f65fa",
...
"payment": {
...
"session": {
"id": "1403a59f-37a8-4d9e-8e13-838cf6f2a0cc",
"amountContributed": 27.01,
"amountRemainingToBeContributed": 0.0,
"state": "requires_confirmation",
"clientSecret": "1403a59f-37a8-4d9e-8e13-838cf6f2a0cc_a2a14087-2aa7-4876-b4f9-d16b5ae6817b"
}
}
}
The following section provides information on a payment session object's:
A payment session has a defined lifecycle. Each stage of that lifecycle is represented by a
state
. When building your integration, we recommend you pay close attention to:- The aggregated
amount
of any secondarysources[]
associated with the checkout is less than the checkout'stotalAmount
.
In both cases, Digital River won't be able to generate an aggregated
amount
of charges[]
large enough to cover the checkout's totalAmount
. As a result, the amountRemainingToContribute
remains greater than 0.0
and any attempt to create an order is blocked.For example, if you attach a primary source to a checkout, then the
amountRemainingToContribute
drops to 0.0
and the payment session's state
transitions to requires_confirmation
.A payment session in a
state
of pending_redirect
indicates that customers were successfully redirected to the payment provider's portal but have yet to complete the actions necessary to authorize payment. This
state
only occurs when customers choose a payment method whose resulting source has a redirect
authentication flow
.If an order's
payment.session.state
persists as pending_redirect
, then customers either selected the cancel payment option or clicked their web browser's back button.A payment session
state
of pending_funds
indicates that customers must complete an asynchronous process before payment is authorized. This
state
occurs when customers choose a payment method whose resulting source has a receiver
authentication flow
.For example, an order with a
payment.sources[].type
of konbini
and a payment.session.state
of pending_funds
means that customers have yet to complete payment at the designated convenience store (e.g. 7-11 or FamilyMart).A
pending
payment session state
means that customers have completed all the necessary actions (such as SCA and redirects) but certain back-end payment processes remain incomplete.Once all of an order's payment
charges[]
are capturable
, its payment.session.state
typically transitions to complete
.Once you associate a primary payment
sources[]
with a checkout, Digital River uses it to fund the transaction in full and payment.session.amountRemainingToContribute
drops to 0.0
.But when checkouts only contain secondary payment
sources[]
, you need to confirm that sufficient funds exist to cover the checkout's totalAmount
. If this isn't the case, and you convert the checkout to an order, you receive the following error:400 Bad Request
{
"type": "bad_request",
"errors": [
{
"code": "order_submit_failed",
"message": "Payment session status is invalid."
}
]
}
By comparing values in the checkout's
payment.session
, you can determine how much additional funding, if any, is required. The amountContributed
represents the aggregated amount
of all the checkout's payment.sources[]
. The amountRemainingToBeContributed
is how much is needed to fund the transaction.If
amountContributed
is equal to the checkout's totalAmount
or the amountRemainingToBeContributed
is 0.0
, then you don't need to request any more payment methods from the customer, and, once the payment session's state
is requires_confirmation
, you can create the order.But if
amountContributed
is less than the checkout's totalAmount
or amountRemainingToBeContributed
is greater than 0.0
, then the customer needs to supply additional payment methods before you create the order. This only happens however when you have yet to associate a primary payment source with the checkout. Once that's done, amountRemainingToBeContributed
drops to 0.0
.If you collect payment by using DigitalRiver.js with elements, and you're not currently using payment sessions, but want to migrate to this solution, then the conversion process is fairly straightforward.
In the Digital River APIs, payment sessions are automatically enabled. This means that each time you create a checkout, the response contains a payment session identifier that you use to configure
createSource()
.You'll need to update your code to integrate with payment sessions. For each of your enabled payment methods, add
sessionId
to the payload that gets passed to createSource()
.You'll also need to remove some parameters. The specific parameters that must be removed depends on the payment method.
For each payment method, you can find instructions and example code in the following sections: Credit Card, PayPal, PayPal Billing, PayPal Credit, SEPA Direct Debit, Wire Transfer, Cash on Delivery - Japan, Payco - Korea Payments, Bank Transfer - Korea Payments, Online Banking - IBP, bPay, Konbini, Klarna, Klarna Recurring, TreviPay.
For credit cards, you add
sessionId
to the payload but do not remove any existing parameters.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
var payload = {
"type": "creditCard",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "10380 Bren Road West",
line2: "Suite 123",
city: "Minnetonka",
state: "MN",
postalCode: "55343",
country: "US"
}
}
}
digitalriver.createSource(cardCVV, payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
var payload = {
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"type": "creditCard",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "10380 Bren Road West",
line2: "Suite 123",
city: "Minnetonka",
state: "MN",
postalCode: "55343",
country: "US"
}
}
}
digitalriver.createSource(cardCVV, payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
For PayPal, you add
sessionId
to the payload and remove amount
, currency
, payPal.items
, payPal.taxAmount
, payPal.shippingAmount
, payPal.amountsEstimated
, payPal.requestShipping
, and payPal.shipping
.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
var payload = {
"type": "payPal",
"amount": 120.99,
"currency": "USD",
"payPal": {
"returnUrl": "http://mypage.com",
"cancelUrl": "https://mypage.com/cancel",
"items": [{
"name": "Cell Phone (Unlocked)",
"quantity": 1,
"unitAmount": 100
},
{
"name": "Headphones",
"quantity": 1,
"unitAmount": 15
}
],
"taxAmount": 0.99,
"shippingAmount": 5,
"amountsEstimated": true,
"requestShipping": true,
"shipping": {
"recipient": "John Doe",
"phoneNumber": "952-555-1212",
"address": {
"line1": "54321 Fake St.",
"line2": "Apt. 3C",
"city": "Minnetonka",
"state": "MN",
"country": "US",
"postalCode": "55341"
}
}
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
var payload = {
"type": "payPal",
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"payPal": {
"returnUrl": "http://mypage.com",
"cancelUrl": "https://mypage.com/cancel"
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
For PayPal Billing, you add
sessionId
to the payload and remove amount
, currency
, payPalBilling.items
, payPalBilling.taxAmount
, payPalBilling.shippingAmount
, payPalBilling.amountsEstimated
, payPalBilling.requestShipping
, and payPalBilling.shipping
.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
var payload = {
"type": "payPalBilling",
"amount": 120.99,
"currency": "USD",
"payPal": {
"returnUrl": "http://mypage.com",
"cancelUrl": "https://mypage.com/cancel",
"items": [{
"name": "Cell Phone (Unlocked)",
"quantity": 1,
"unitAmount": 100
},
{
"name": "Headphones",
"quantity": 1,
"unitAmount": 15
}
],
"taxAmount": 0.99,
"shippingAmount": 5,
"amountsEstimated": true,
"requestShipping": true,
"shipping": {
"recipient": "John Doe",
"phoneNumber": "952-555-1212",
"address": {
"line1": "54321 Fake St.",
"line2": "Apt. 3C",
"city": "Minnetonka",
"state": "MN",
"country": "US",
"postalCode": "55341"
}
}
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
var payload = {
"type": "payPalBilling",
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"payPal": {
"returnUrl": "http://mypage.com",
"cancelUrl": "https://mypage.com/cancel"
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
For PayPal Credit, you add
sessionId
to the payload and remove amount
, currency
, payPal.items
, payPal.taxAmount
, payPal.shippingAmount
, payPal.amountsEstimated
, payPal.requestShipping
, and payPal.shipping
.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
var payload = {
"type": "payPalCredit",
"amount": 120.99,
"currency": "USD",
"payPal": {
"returnUrl": "http://mypage.com",
"cancelUrl": "https://mypage.com/cancel",
"items": [{
"name": "Cell Phone (Unlocked)",
"quantity": 1,
"unitAmount": 100
},
{
"name": "Headphones",
"quantity": 1,
"unitAmount": 15
}
],
"taxAmount": 0.99,
"shippingAmount": 5,
"amountsEstimated": true,
"requestShipping": true,
"shipping": {
"recipient": "John Doe",
"phoneNumber": "952-555-1212",
"address": {
"line1": "54321 Fake St.",
"line2": "Apt. 3C",
"city": "Minnetonka",
"state": "MN",
"country": "US",
"postalCode": "55341"
}
}
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
var payload = {
"type": "payPalCredit",
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"payPal": {
"returnUrl": "http://mypage.com",
"cancelUrl": "https://mypage.com/cancel"
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
For SEPA Direct Debit, you add
sessionId
to the payload and remove amount
and currency
.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
let payload = {
"type": "directDebit",
"amount": 100,
"currency": "EUR",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "123 Main Street",
line2: "",
city: "Paris",
postalCode: "14390",
country: "FR"
}
},
"directDebit": {
"returnUrl": "https://mypage.com"
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
var payload = {
"type": "directDebit",
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "123 Main Street",
line2: "",
city: "Paris",
postalCode: "14390",
country: "FR"
}
},
"directDebit": {
"returnUrl": "https://mypage.com"
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
For Wire Transfer, you add
sessionId
to the payload and remove amount
and currency
.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
let payload = {
"type": "wireTransfer",
"amount": 100,
"currency": "EUR",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "123 Main Street",
line2: "",
city: "Paris",
postalCode: "14390",
country: "FR"
}
},
"wireTransfer": {
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
var data = {
"type": "wireTransfer",
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "123 Main Street",
line2: "",
city: "Paris",
postalCode: "14390",
country: "FR"
}
},
"wireTransfer": {
}
}
digitalriver.createSource(data).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
For Cash on Delivery - Japan, you add
sessionId
to the payload and remove amount
and currency
.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
let payload = {
"type": "codJapan",
"amount": 100,
"currency": "EUR",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "123 Main Street",
line2: "",
city: "Paris",
postalCode: "14390",
country: "FR"
}
},
"codJapan": {
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
var payload = {
"type": "codJapan",
"sessionId": "ea03bf6f-84ef-4993-b1e7-b7d5ecf71d1f",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
phoneNumber: "000-000-0000",
address: {
line1: "123 Main Street",
line2: "",
city: "Paris",
postalCode: "14390",
country: "FR"
}
},
"codJapan": {
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});
For Payco - Korea Payments, you add
sessionId
to the payload and remove amount
and currency
.The following tabs provide code examples of how sources are created without and with payment sessions.
Without payment sessions
With payment sessions
let payload = {
"type": "payco",
"amount": 100,
"currency": "KRW",
"owner": {
firstName: "John",
lastName: "Doe",
email: "[email protected]",
address: {
line1: "1234 Fake Street",