Handling subscription acquisitions
If you're pairing the Direct Integration solution with Digital River's subscription service, learn how to handle acquisitions.
If you're pairing the Direct Integrations checkout solution with Digital River's subscription service, this page explains how to process it:
Once you convert the checkout to an order, you must activate the subscription, fulfill the goods, and manage renewals. Refer to the Managing a subscription page for details on handling these and other processes.
Subscription acquisitions
During subscription acquisitions, you must:
Creating a subscription
In checkouts, you define subscriptions in items[]. Checkouts can contain either a single items[] with subscriptionInfo or multiple subscription line items. We also support mixed cart checkouts.
For each items[].subscriptionInfo in the request:
Use
planIdto associate the subscription with a plan. For details, refer to Defining a business model.Pass
terms. To do this, make aGET /plans/{planId}request. From the response, retrieve the plan'stermsand use that value to set the line item'sterms. If you don't sendterms, a400 Bad Requestwith acodeofmissing_parameteris thrown.
For details, refer to Displaying terms and acquiring consent.
Set
autoRenewaltotrueor omit the value. If you setautoRenewaltofalse, you receive a400 Bad Requestwith acodeofinvalid_parameter.Use
freeTrialto set up trial periods. For details, refer to Trial subscription acquisitions.If you don't provide a unique
subscriptionId, we generate one for you.
In subscription acquisitions, make sure you also set the checkout's chargeType to customer_initiated.
curl --location --request POST 'https://api.digitalriver.com/checkouts' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <API_key>' \
...
--data-raw '{
"customerId": "0aa4bb94-2995-4689-9b57-f11d1beb18c9",
"sourceId": "586ffca0-ca4f-4d87-a933-192afa36cc6b",
"locale": "en_US",
"email": "[email protected]",
"currency": "USD",
"items": [{
"skuId": "d273122b-e78d-4fcb-a1ab-10c07c871ee7",
"quantity": 5,
"price": 5.01,
...
"subscriptionInfo": {
"planId": "460d1943-5ac1-48b8-98e8-237c6e3019a7",
"terms": "These are the terms...."
},
"metadata": {
"key1_ItemLevel": "tets"
}
}],
...
}'Checkouts with multiple subscriptions
Checkouts can contain multiple items[] with subscriptionInfo. All the recurring items, however, must share the same planId and (if you set the value) subscriptionId. Once you submit the request, Digital River adds these line items to a single subscription.
If you attempt to create checkouts with multiple items[] that reference different plans, then the following error is returned:
{
"type": "conflict",
"errors": [
{
"code": "plan_limit_reached",
"parameter": "planId",
"message": "Only one unique subscription plan can be supported in a checkout"
}
]
}Checkouts with subscription and non-subscription items
Digital River's subscription service supports building checkouts containing subscription and non-subscription line items and successfully converting those checkouts to orders. However, the subscription line items must all reference the same plan.
A common use case for these mixed checkouts is to process transactions that combine a one-time physical product with a digital subscription service.
Handling the acquisition checkout response
After you submit the POST/ checkouts request, Digital River creates a subscription, sets it to state to draft and then generates an event with a type of subscription.created.
In the response's body and the event's data.object, the subscriptionId uniquely identifies that subscription. At a minimum, make sure you persist this value.
At this point, no additional subscription line items can be added to the checkout. Furthermore, you're restricted to what product information can be updated.
Since Digital River's subscription service doesn't support manual renewals, autoRenewal always returns true .
Refer to the Third party subscription services page for details on how to handle manual renewals, where you invite customers to actively renew subscriptions at a designated time.
{
"id": "88aaf811-a8a8-4b7a-9a23-5bc0241e039a",
"createdTime": "2021-08-11T20:06:32Z",
"customerId": "0aa4bb94-2995-4689-9b57-f11d1beb18c9",
"currency": "USD",
"email": "[email protected]",
"billTo": {
"address": {
"line1": "10380 Bren Road West",
"city": "Minnetonka",
"postalCode": "55343",
"state": "MN",
"country": "US"
},
"name": "Digital Development",
"email": "[email protected]",
"organization": "DR",
"additionalAddressInfo": {
"neighborhood": "Centro"
}
},
"totalAmount": 26.9,
"subtotal": 25.05,
"totalFees": 0.0,
"totalTax": 1.85,
"totalImporterTax": 0.0,
"totalDuty": 0.0,
"totalDiscount": 0.0,
"totalShipping": 0.0,
"items": [
{
"id": "b0ae5bf9-6df7-4185-91f2-7e2589acbe8d",
"skuId": "d273122b-e78d-4fcb-a1ab-10c07c871ee7",
"amount": 25.05,
"quantity": 5,
"metadata": {
"key1_ItemLevel": "tets"
},
"tax": {
"rate": 0.07375,
"amount": 1.85
},
"importerTax": {
"amount": 0.0
},
"duties": {
"amount": 0.0
},
"subscriptionInfo": {
"subscriptionId": "192a2549-8b16-482e-b1bb-b4a64cd6a0c0",
"planId": "460d1943-5ac1-48b8-98e8-237c6e3019a7",
"terms": "Please accept terms",
"autoRenewal": true,
"freeTrial": false
},
"fees": {
"amount": 0.0,
"taxAmount": 0.0
}
}
],
"updatedTime": "2021-08-11T20:06:32Z",
"locale": "en_US",
"customerType": "individual",
"sellingEntity": {
"id": "C5_INC-ENTITY",
"name": "DR globalTech Inc."
},
"liveMode": false,
"payment": {
"sources": [
{
"id": "586ffca0-ca4f-4d87-a933-192afa36cc6b",
"type": "creditCard",
"amount": 26.9,
"owner": {
"firstName": "Digital",
"lastName": "Development",
"email": "[email protected]",
"address": {
"line1": "10380 Bren Road West",
"city": "Minnetonka",
"postalCode": "55343",
"state": "MN",
"country": "US"
},
"organization": "DR",
"additionalAddressInfo": {
"neighborhood": "Centro"
}
},
"creditCard": {
"brand": "Visa",
"expirationMonth": 7,
"expirationYear": 2027,
"lastFourDigits": "1111"
}
}
],
"session": {
"id": "9fb4036f-5051-4255-9189-16e449d69ca6",
"amountContributed": 26.9,
"amountRemainingToBeContributed": 0.0,
"state": "requires_confirmation",
"clientSecret": "9fb4036f-5051-4255-9189-16e449d69ca6_3c6275e8-e065-4bb9-b75a-829f62b78c2c"
}
}
}If you retrieve the subscription, you'll notice that key fields have yet to be populated at this stage of the acquisition process. This is because the subscription's state is still draft and the contractBindingUntil, nextReminderDate, currentPeriodEndDate, and nextInvoiceDate are generated when you activate the subscription.
{
"id": "7f784dd8-a76f-4d3a-84e1-abdc9c7ac3b9",
"createdTime": "2022-02-07T14:02:46Z",
"updatedTime": "2022-02-07T14:02:46Z",
"stateTransitions": {},
"taxInclusive": false,
"currency": "USD",
"planId": "82cbf763-fa27-401a-aa69-5e6640539ce7",
"state": "draft",
"items": [
{
"price": 100.0,
"skuId": "bd933514-43fa-40d3-863c-8ff6fce0db76",
"quantity": 1
}
],
"liveMode": false
}Displaying terms and acquiring consent
During acquisitions, you must disclose a subscription's terms and then acquire the customer's active acceptance of them. How you do this depends on whether you use Drop-in payments or DigitalRiver.js with elements. In either case, the plan's terms should match those displayed to customers.
A subscription's terms are displayed in the modal window if you're using Drop-in payments. For details, see the Acquiring payment section on this page.
If you're using DigitalRiver.js with elements, present our standardized subscription terms and save the payment agreement by calling the get compliance details method, retrieving autorenewalPlanTerms.localizedText and then displaying that text with an appropriate acceptance control.

Your code should be written so customers can accept these terms before the checkout can proceed. You can then use autorenewalPlanTerms.localizedText to set mandate.terms in the createSource() method's configuration object.
After you convert an acquisition checkout to an order, the subscription's terms are stored in the billing agreement.
Acquiring payment
During acquisition checkouts, you can give customers the option to:
Creating a new payment source
How you create a payment source to fund a recurring transaction depends on whether your integration uses Drop-in payments or DigitalRiver.js with elements.
For more details, refer to the subscriptions section on the Building payment workflows page.
After building a checkout with subscription information, configure createDropin():
Use the checkout's payment session identifier to set
sessionIdIf your integration sends the customer's billing information in the checkout's
billTo, then it's not necessary to passbillingAddressIn
options, set:flowtocheckoutshowComplianceSectiontotrueusagetosubscriptionshowTermsOfSaleDisclosuretotrueandshowSavePaymentAgreementtofalse. These two settings (along with the checkout'sautoRenewalvalue oftrue), prompt Drop-in payments to display the combined autorenewal and save payment agreement.
let digitalriverpayments = new DigitalRiver("pk_hc_a209389e4588433bb6e00b32466b82c3", {
"locale": "en_US"
});
let configuration = {
"sessionId": "2bc96772-1142-4289-9d20-f6905591d7e4",
"options": {
"flow": "checkout",
"showComplianceSection": true,
"showSavePaymentAgreement": false,
"showTermsOfSaleDisclosure": true,
"usage": "subscription"
}
...
}
let dropin = digitalriverpayments.createDropin(configuration);
dropin.mount("drop-in-container");Pass the configuration object to createDropin()and mount Drop-in payments in the appropriate container. If the request is successful, onReady returns the transaction's eligible payment methods:
{
"paymentMethodTypes": [
"creditCard",
"payPalBilling",
"googlePay",
"klarnaCreditRecurring",
"msts"
]
}Each payment method, accompanied by the subscription's terms and conditions, is displayed in the modal window.
If customers click the configurable continue button without agreeing to the terms, Drop-in prevents the transaction from proceeding.

If customers consent to the terms and submit their payment information and the resulting create source request is successful, then the onSuccess event's data contains a source that is readyForStorage and chargeable. The object also contains the agreed-upon terms (mandate.terms) and the time the customer accepted those terms (mandate.signedTime).
For details, refer to the Drop-in payments integration guide and the Drop-in payments builder tool.
After building a checkout with subscription information, send the checkout's payment session identifier to your front end and use it to set sessionId in the configuration object of retrieveAvailablePaymentMethods().
...
digitalRiver.retrieveAvailablePaymentMethods({
"sessionId": "1c86a97f-45ea-4d73-8c99-ca533e392ab1"
}).then(function(result) {
//do something with the result
console.log(result)
});
...If the request is successful, the response contains the payment methods that apply to the transaction.
[
{
"type": "creditCard",
"flow": "standard",
"supportsRecurring": true,
"supportsFreeTrial": true,
"images": {
"iconImage": "https://ui1.img.digitalrivercontent.net/Storefront/images/paymentMethodLogos/creditcard.png"
},
"supportsStorage": true,
"defaultMandate": {
"terms": "I agree that Digital River may store my payment information for future purchases including the processing of any subsequent subscription renewals which may occur at a future date."
},
"displayName": "Credit Card",
"localizedDisplayName": "Credit Card"
},
{
"type": "payPalBilling",
"flow": "redirect",
"supportsRecurring": true,
"supportsFreeTrial": true,
"images": {
"iconImage": "https://ui1.img.digitalrivercontent.net/Storefront/images/paymentMethodLogos/paypalBilling.png"
},
"supportsStorage": true,
"defaultMandate": {
"terms": "I agree that Digital River may store my payment information for future purchases including the processing of any subsequent subscription renewals which may occur at a future date."
},
"displayName": "PayPal Billing",
"localizedDisplayName": "PayPal"
},
{
"type": "googlePay",
"flow": "standard",
"supportsRecurring": true,
"supportsFreeTrial": true,
"images": {
"iconImage": "https://ui1.img.digitalrivercontent.net/Storefront/images/paymentMethodLogos/googlepay.png"
},
"supportsStorage": true,
"defaultMandate": {
"terms": "I agree that Digital River may store my payment information for future purchases including the processing of any subsequent subscription renewals which may occur at a future date."
},
"displayName": "Google Pay",
"localizedDisplayName": "Google Pay"
}
]Based on these payment methods, create the appropriate elements to collect the customer's sensitive payment information.
After customers select a payment method, accept the terms, and submit their payment information, configure createSource():
Set
typeto the payment method selected by the customerUse the checkout's payment session identifier to set
sessionId.Set
usagetosubscriptionandfutureUsetotrueUse the agreed-upon terms to set
mandate.termsIf your integration passes a customer's billing information in the checkout's
billTo, then it's not necessary to sendbillingAddress
var payload = {
"type": "creditCard",
"sessionId": "1c86a97f-45ea-4d73-8c99-ca533e392ab1",
"futureUse": true,
"usage": "subscription",
...
"mandate": {
"terms": "By checking the box below and completing your purchase..."
}
}
digitalriver.createSource(payload).then(function(result) {
if (result.error) {
//handle errors
} else {
var source = result.source;
//send source to back end
sendToBackend(source);
}
});If the create source request is successful, the response contains a source that is readyForStorage and chargeable.
For more information, refer to the Elements integration guide.
Next, send the customer identifier and source to your backend.
Submit a POST /customers/{customerId}/sources/{sourceId} to attach the source to the customer. This flips the source's reusable attribute to true You can usethe object in both the subscription's acquisition and as the designated source in renewals.
Once saved to the customer, your integration should attach the source to the checkout.
You should also retrieve mandate.terms from the source and use this value to set each of the checkout's items[].subscriptionInfo.terms. This ensures that the subscription's terms are added to the billing agreement.
Authenticating a saved payment source
Drop-in payments do not currently support retrieving saved payment methods.
If you give customers the option to select a saved payment source during subscription acquisitions, then after building a checkout with subscription information, send the payment session identifier to your front end and use it to set sessionId in the configuration object of retrieveAvailablePaymentMethods().
...
digitalRiver.retrieveAvailablePaymentMethods({
"sessionId": "1c86a97f-45ea-4d73-8c99-ca533e392ab1"
}).then(function(result) {
//do something with the result
console.log(result)
});
...[
{
"type": "creditCard",
"flow": "standard",
"supportsRecurring": true,
"supportsFreeTrial": true,
"images": {
"iconImage": "https://ui1.img.digitalrivercontent.net/Storefront/images/paymentMethodLogos/creditcard.png"
},
"supportsStorage": true,
"defaultMandate": {
"terms": "I agree that Digital River may store my payment information for future purchases including the processing of any subsequent subscription renewals which may occur at a future date."
},
"displayName": "Credit Card",
"localizedDisplayName": "Credit Card"
},
{
"type": "payPalBilling",
"flow": "redirect",
"supportsRecurring": true,
"supportsFreeTrial": true,
"images": {
"iconImage": "https://ui1.img.digitalrivercontent.net/Storefront/images/paymentMethodLogos/paypalBilling.png"
},
"supportsStorage": true,
"defaultMandate": {
"terms": "I agree that Digital River may store my payment information for future purchases including the processing of any subsequent subscription renewals which may occur at a future date."
},
"displayName": "PayPal Billing",
"localizedDisplayName": "PayPal"
},
{
"type": "googlePay",
"flow": "standard",
"supportsRecurring": true,
"supportsFreeTrial": true,
"images": {
"iconImage": "https://ui1.img.digitalrivercontent.net/Storefront/images/paymentMethodLogos/googlepay.png"
},
"supportsStorage": true,
"defaultMandate": {
"terms": "I agree that Digital River may store my payment information for future purchases including the processing of any subsequent subscription renewals which may occur at a future date."
},
"displayName": "Google Pay",
"localizedDisplayName": "Google Pay"
}
]For each payment method contained in the response, determine if its type matches the type of one or more of the customer's sources[]. If it does, you can retrieve those saved sources[] from the customer and display them as options on your payments page.
If the customer selects a saved source, passes its sources[].id and sources[].clientSecret (along with the checkout's payment session identifier) to authenticateSource(). This method determines whether strong customer authentication is required.
{
"id": "533319260336",
...
"sources": [
{
"id": "5e359d60-1d23-4234-84ee-e1c9b3ed7edc",
...
"type": "creditCard",
"reusable": true,
"state": "chargeable",
...
"clientSecret": "5e359d60-1d23-4234-84ee-e1c9b3ed7edc_bf74c04c-8586-41e2-964a-f5e618d2b7e3",
...
},
{
"id": "19f47eba-418f-41b3-882c-462e335770e7",
...
"type": "payPalBilling",
"reusable": true,
"state": "chargeable",
...
"clientSecret": "19f47eba-418f-41b3-882c-462e335770e7_cc871d23-474d-4a3f-9803-4e98fa39f2ee",
...
}
],
...
}{
"id": "50a72152-4a61-4e4a-b9e1-2ab5db891105",
...
"payment": {
"session": {
"id": "f5dd814a-ecee-4f7e-bf7c-4635f0c19c91",
...
}
}
}...
digitalriver.authenticateSource({
"sessionId": "f5dd814a-ecee-4f7e-bf7c-4635f0c19c91",
"sourceId": "5e359d60-1d23-4234-84ee-e1c9b3ed7edc",
"sourceClientSecret": "5e359d60-1d23-4234-84ee-e1c9b3ed7edc_bf74c04c-8586-41e2-964a-f5e618d2b7e3",
"returnUrl": "https://mypage.com"
});
...If the response status is complete or authentication_not_required, the method resolves, allowing your integration to attach the authenticated source to the checkout.
For additional details, refer to the section on retrieving saved payment sources during subscription acquisitions on the Building payment workflows page.
Managing subscriptions after acquisition
After you convert the checkout to an order, you'll need to activate the subscription and process renewals. To learn more, refer to the Managing a subscription page.
Trial subscription acquisitions
You handle free-trial subscription acquisitions in much the same way as standard acquisitions.
In free trials, however, you must configure the checkout slightly differently.
Once customers initiate checkout, determine whether their cart contains trial-based subscription products. If it does, use items[].subscriptionInfo to describe those products in your POST /checkouts.
Each trial-based subscription line item in the request must specify a price of 0.0, set freeTrial to true, and pass a planId that references a trial period plan.
curl --location --request POST 'https://api.digitalriver.com/checkouts' \
--header 'Content-Type: application/json' \
...
--data-raw '{
"customerId": "563089630336",
"sourceId": "8687447b-a04d-4838-af6c-0de0810f23a7",
"locale": "en_US",
"email": "[email protected]",
"currency": "USD",
"items": [
{
"skuId": "sku_3e5ab173-d52e-4d9e-8888-2a00f6bb188e",
"quantity": 2,
"price": 0.0,
"subscriptionInfo": {
"planId": "186cf07e-a1ea-4ec0-9d9a-8aa93b3af43a",
"terms": "The terms of the subscription",
"autoRenewal": true,
"freeTrial": true
}
}
]
}'If you create or update a checkout and (1) freeTrial is true and price or aggregatePrice contain a value that's greater than 0.0 or (2) freeTrial is false and price or aggregatePrice are 0.0, then the following error is thrown:
{
"type": "bad_request",
"errors": [
{
"code": "invalid_parameter",
"parameter": "items",
"message": "The value of the Free Trial flag is not consistent with the item price or the aggregate price."
}
]
}Managing trial subscriptions after acquisition
Refer to Trial subscription management on the Managing a subscription page for details on how to process a trial subscription after you convert the checkout to an order.
Last updated