Links

Subscription management

If you're using Digital River's subscription service, gain a better understanding of how to manage subscriptions after the acquisition process is complete
With Digital River's subscription service, after the acquisition checkout process is complete, you'll need to manage the subscription. On this page, you'll find information on how to:

Activating a subscription

After the order's state moves to accepted, you can activate a subscription. To do this, you could retrieve any items[].subscriptionInfo.subscriptionId from the data.object of the event with a type of order.accepted and send it as a path parameter in a POST /subscriptions/{subscriptionId}.
If you're using the Direct Integrations checkout solution, you could also get any items[].subscriptionInfo.subscriptionId from the body of the POST/ orders response.
In the body of the update subscription request, set state to active.
curl --location --request POST 'https://api.digitalriver.com/subscriptions/DR_3ce5dc58-6bba-4ee2-b8d1-e1b974a4fe93' \
...
--data-raw '{
"state": "active"
}'
No other values can be sent in the body of this request. If you attempt to do so, then the following error is returned:
409 Conflict
{
"type": "conflict",
"errors": [
{
"code": "restricted_update",
"parameter": "metadata",
"message": "Additional data cannot be updated when updating state to active."
}
]
}
You can activate a subscription any time after an order's state moves to accepted. For example, if you're selling a digital service subscription that requires no provisioning, you might build your integration so that the activation request is immediately submitted. In other scenarios, such as when a customer must install and initialize a device, you may decide to build a delay into the activation process.
When you activate the subscription, we search the acquisition order for the primary payment source, retrieve its identifier, and assign that value to sourceId in the subscription object. On the next invoice date, we then both create a charge and attempt to capture payment using this reusable source.
After activation, the following key subscription attributes are populated: contractBindingUntil, nextReminderDate, currentPeriodEndDate, nextInvoiceDate, and activated.
Every subscription contains a billingAgreementId that references a billing agreement. For PSD2 and SCA compliance purposes, we continue to associate this billing agreement with the subscription throughout the subscription's lifecycle.
Subscription after activation
{
"id": "47ce1ba0-a548-40a2-a601-a43c41fbe68f",
"contractBindingUntil": "2023-02-09T17:40:56Z",
"createdTime": "2022-02-09T17:40:21Z",
"updatedTime": "2022-02-09T17:40:56Z",
"stateTransitions": {
"activated": "2022-02-09T17:40:56Z"
},
"billingAgreementId": "8f1ef7b9-e5c5-46d1-ac14-1c9d566f0f57",
"customerId": "562799360336",
"sourceId": "1fc4353a-e1ab-476b-8ebd-db181c1a21a7",
"taxInclusive": false,
"currency": "USD",
"planId": "82cbf763-fa27-401a-aa69-5e6640539ce7",
"state": "active",
"items": [
{
"price": 100.0,
"skuId": "865a15d2-4e00-4c09-8813-7b82a078491b",
"quantity": 1
}
],
"currentPeriodEndDate": "2022-03-09T17:40:56Z",
"nextInvoiceDate": "2022-03-04T17:40:56Z",
"nextReminderDate": "2022-02-27T17:40:56Z",
"liveMode": false
}

Fulfilling the acquisition

Once the order's state is accepted, you should fulfill the goods and then submit the payment capture request.

Notifying customers of a subscription acquisition

Once a subscription is successfully acquired, you must notify the customer. In the Subscription Notifications article (refer to Learning tools for access information), you can find a complete list of this notification's requirements.‌

Renewing subscriptions

On a subscription's nextReminderDate, make sure you send a renewal reminder to customers. Your integration should also be able to handle both successful and failed billing attempts.

Sending a reminder

Before attempting to collect a recurring payment, the subscription service determines whether the necessary pre-conditions are met. If they are, the service opens a draft invoice and, on the subscription's nextRemiderDate, creates an event with a type of subscription.reminder.
You can configure when you receive this event by setting the plan's reminderOffsetDays.
The event's data.object contains the subscription along with an invoice whose state is draft.
Use the event's data to obtain the customer's contact information and to populate your reminder notification. This notification (typically an email) should include the subscription's name and a description of its goods, the amount the customer is to be charged, and the upcoming billing date.
In the Subscription Notifications article (refer to Learning tools for access information), you'll find a complete list of renewal reminder requirements.
In invoice.items[].productDetails you can access the subscription's product data (such as name, description, image, and url) and pass this information to customers in the notification, thereby making them aware of what they're being billed for.
There are numerous ways to build your notification. We do, however, suggest that you convert any date-time values into a more human-readable form. The following are some (partial) examples of what you might add:
This is a reminder that your invoice.description subscription is set to renew on or after nextInvoiceDate. To ensure that your subscription continues without interruption, your creditCard.brand credit card ending in creditCard.lastFourDigits will be charged invoice.totalAmount in invoice.currency .
For digital services (such as SaaS), you might also want to include the date and time that customers activated their subscription:
You activated your subscription via our online store on stateTransitions.activated.
Additionally, we suggest you use the reminder event to determine whether the subscription's designated credit card is set to expire before the nextInvoiceDate. If this is the case, remind customers to update their payment information and provide a link to the appropriate page on your site. For example:
We noticed that your credit card ending in lastFourDigits is set to expire expirationMonth , expirationYear. This expiration date is prior to your next recurring payment on nextInvoiceDate. To avoid disruptions to your subscription, please visit your account management page and update your payment information.

Handling successful renewals

To be notified of a successful billing attempt, configure a webhook to listen for the event with a type of subscription.extended.
The event's data.object contains the subscription along with the invoice used to capture payment. Since settlement has successfully occurred, the invoice's state is paid.
You could handle subscription.extended by calling a function that moves the subscription in your system into a ready to fulfill state and then initiates the fulfillment process.
The event should also trigger a notification (typically an email) that informs customers of the successful renewal. The following is a partial list of the data you might retrieve from the event and pass in this notification:
  • orderId: Gives customers access to the identifier of the transaction's order.
  • nextInvoiceDate: Provides customers the date of the next billing attempt.
  • name and image in items[].productDetails: Reminds customers what products and/or services are included in the subscription.
  • payment.sources[]: Contains source data that you can share with customers so they have basic information on what payment method is funding the subscription.
  • totalAmount and totalTax: Informs customers how much they were charged and taxed. The event also contains similar amounts at the items[]-level.
In the Subscription Notifications article (refer to Learning tools for access information), you can find a comprehensive list of the information you're required to include in the renewal notification.

Handling failed renewals

To be notified of renewal problems, you can configure a webhook to listen for payment failures and subscription failures.

Payment failures

An event with a type of subscription.payment_failed indicates that Digital River's autorenewal service made an unsuccessful attempt to capture payment.
The event's data.object contains both the subscription and the invoice.
The event most likely stems from changes to the subscription's payment source. For example, if a subscription is funded with a credit card, then that card might have expired, its billing address could have changed, or the customer might have cancelled it altogether.
However, since the state of the subscription remains activePendingInvoice, you might still be able to collect payment.
Whatever the structure of your dunning process, we recommend you handle subscription.payment_failed by using the event's data.object to construct a notification that:
  • Informs customers of the failed payment capture attempt. For example: We were unable to charge your creditCard.brand ending in creditCard.lastFourDigits.
  • Provides a link to a page on your site where customer's can resolve the issue. For example: To avoid disruptions to your subscription, please visit your account management page.
  • Provides your contact information. For example: If you have any questions, visit our support site at <web address>, contact us at <email address>, or call <phone number>.
If customers click the link, redirect them to a page where they can provide a new payment method.
For details, refer to Account management flows on the Building payment workflows page.
You'll also need to pass the source's identifier in the body of an update subscription request.
curl --location --request POST 'https://api.digitalriver.com/subscriptions/9a1f34b3-a5f5-4c5d-ab04-9a021b97a26d' \
...
--header 'Authorization: Bearer <Your secret API key>' \
...
--data-raw '{
"sourceId": "19f15727-0712-473a-8b78-cc627efc0dfc"
}'
Prior to the next billing attempt, Digital River voids the invoice that we weren't able to collect and creates a new invoice using the subscription's updated source.

Subscription failures

An event with a type of subscription.failed indicates that our autorenewal service was unable to capture payment during the designated collection period. As a result, the invoice has become uncollectible and the subscription has moved into a terminally failed state.
We recommend you handle subscription.failed by setting the status of the subscription in your own system to failed as well.
You could also send customers a failure notification that provides them the ability to reactivate their subscription. If customers select this option, you'll need to take them through the acquisition process again.
For example, the notification might:
  • Inform customers of the failed renewal. Despite repeated attempts, we were unable to charge your designated payment method and, as a result, your subscription has been deactivated.
  • Provide a link to the page on your site where customer's can resolve the issue. To reactivate your subscription, please visit your account management page.
  • Provide your contact information. If you have any questions, visit our support site at <web address>, contact us at <email address>, or call <phone number>.

Trial subscription management

In this section, you'll find information on:

Activating trial subscriptions

You can use the same process to activate both trial and non-trial subscriptions. For details, refer to Activating a subscription.
curl --location --request POST 'https://api.digitalriver.com/subscriptions/124eeee4-6cf4-40e9-94a6-cba64798fc42' \
...
--data-raw '{
"state": "active"
}'
Once activated, a free trial subscription's state transitions from draft to activeFree and the activatedFree timestamp is populated.
Subscription
{
"id": "124eeee4-6cf4-40e9-94a6-cba64798fc42",
"contractBindingUntil": "2022-02-18T15:03:12Z",
"createdTime": "2022-02-11T15:01:31Z",
"updatedTime": "2022-02-11T15:03:12Z",
"stateTransitions": {
"activatedFree": "2022-02-11T15:03:12Z"
},
"billingAgreementId": "6e4d986e-c054-43e0-a233-d6c1e9f60765",
"customerId": "563089630336",
"sourceId": "8687447b-a04d-4838-af6c-0de0810f23a7",
"taxInclusive": false,
"currency": "USD",
"planId": "186cf07e-a1ea-4ec0-9d9a-8aa93b3af43a",
"locale": "en_US",
"state": "activeFree",
"items": [
{
"price": 0.0,
"skuId": "sku_3e5ab173-d52e-4d9e-8888-2a00f6bb188e",
"quantity": 2
}
],
"currentPeriodEndDate": "2022-02-18T15:03:12Z",
"nextInvoiceDate": "2022-02-18T15:03:12Z",
"nextReminderDate": "2022-02-15T15:03:12Z",
"liveMode": false
}

Updating the subscription's price and plan

Immediately following a successful activation request, we recommend that your integration use a POST /subscriptions/{id} to (1) update the subscription's planId so that it references a paid period plan and, (2) for each items[], set the price or aggregatePrice equal to the post-trial period amount that customers agreed to pay during the subscription acquisition process.
POST/ subscriptions/{subscriptionId}
curl --location --request POST 'https://api.digitalriver.com/subscriptions/124eeee4-6cf4-40e9-94a6-cba64798fc42' \
...
--data-raw '{
"planId": "f55d07a2-a78f-406a-b6c6-ad8e1cc1531b",
"items": [
{
"price": 29.95,
"skuId": "sku_3e5ab173-d52e-4d9e-8888-2a00f6bb188e",
"quantity": 2
}
]
}'
After you submit this request, the subscription's planId references the paid period plan. However, until currentPeriodEndDate elapses, the subscription's behavior is controlled by the trial period plan.
Subscription
{
"id": "124eeee4-6cf4-40e9-94a6-cba64798fc42",
"contractBindingUntil": "2022-02-18T15:03:12Z",
"createdTime": "2022-02-11T15:01:31Z",
"updatedTime": "2022-02-11T15:05:08Z",
"stateTransitions": {
"activatedFree": "2022-02-11T15:03:12Z"
},
"billingAgreementId": "6e4d986e-c054-43e0-a233-d6c1e9f60765",
"customerId": "563089630336",
"sourceId": "8687447b-a04d-4838-af6c-0de0810f23a7",
"taxInclusive": false,
"currency": "USD",
"planId": "f55d07a2-a78f-406a-b6c6-ad8e1cc1531b",
"locale": "en_US",
"state": "activeFree",
"items": [
{
"price": 29.95,
"skuId": "sku_3e5ab173-d52e-4d9e-8888-2a00f6bb188e",
"quantity": 2
}
],
"currentPeriodEndDate": "2022-02-18T15:03:12Z",
"nextInvoiceDate": "2022-02-18T15:03:12Z",
"nextReminderDate": "2022-02-15T15:03:12Z",
"liveMode": false
}
On the nextReminderDate, Digital River creates an event whose type is subscription.reminder and whose data.object contains an invoice in a draft state.
Assuming you updated the subscription's items[].price or items[].aggregatePrice, the invoice's totalAmount will be greater than zero and equal to the aggregated price of all the subscription's items[], plus taxes and fees calculated by Digital River.
This totalAmount is how much customers will be charged on the subscription's nextInvoiceDate, which (if you configured your trial period plan correctly) should be the same as the currentPeriodEndDate. In other words, customers won't be charged until the free trial period is over.

Handling trial conversions

Before a trial converts to a paid subscription, you should send customers an expiration reminder. After a successful conversion occurs, make sure you also send a conversion notification.

Sending a free trial expiration reminder

We recommend that you use subscription.reminder to trigger an email (or some other type of notification) to the customer. In the event's payload, currentPeriodEndDate, nextInvoiceDate, and totalAmount provide the data you need to inform customers (1) on what date their free trial is scheduled to expire, (2) when their first payment is scheduled, and (3) in what amount.

Sending a trial conversion notification

On the nextInvoiceDate, Digital River moves the invoice to open and the subscription to activePendingInvoice and then attempts to collect payment for the number of days specified by the trial period plan's collectionPeriodDays.
If any of these collection attempts are successful, Digital River marks the invoice as paid and the subscription as active, populates the subscription's activated timestamp and creates an event whose type is subscription.extended.
You should use subscription.extended as a trigger to notify customers (typically by email) that their trial has been converted into a paid subscription. For details, refer to Handling successful renewals.
If payment capture fails, then the invoice becomes uncollectible and the subscription moves into a failed state. To learn more, refer to Handling failed renewals.

Ending trial subscriptions

To avoid getting charged, customers may opt to cancel their subscription during its trial period. In these cases, you have two options:

Extending free trial periods

Sometimes you might want to extend a customer's free trial period or keep customers at a no-charge level indefinitely. To do this, after you activate the subscription, do not update its price. By not performing this operation, a subscription's items[] will have a price or aggregatePrice of 0.0on the nextInvoiceDate, and, as a result, Digital River doesn't make any invoice collection attempts and the subscription's state remains activeFree.

Reverting to a free subscription

You can also push an active subscription back into an activeFree state. This is useful if you offer various subscription pricing tiers and customers request that their access be downgraded to the basic, free level.
To do this, send a POST /subscriptions/{id} request that updates the price or aggregatePrice of each of the subscription's items[] to 0.0 and the planId to an appropriate plan. On the nextInvoiceDate, the subscription's state reverts to activeFree.

Modifying subscription payments

For more details on how subscriptions can be modified, refer to Updating subscriptions.
When customers want to manage their subscriptions, you can retrieve a list of subscriptions associated with their record:
Request
Response
curl --location --request GET 'https://api.digitalriver.com/subscriptions?customerId=f9acfc5b-42de-4807-8248-eb1cb8069a04' \
--header 'Authorization: Bearer <Secret API key>' \
...
{
"hasMore": false,
"data": [
{
"id": "eabd010b-26f5-44e7-a91d-1b3e23198310",
"contractBindingUntil": "2022-03-02T16:15:15Z",
"createdTime": "2022-01-31T16:14:10Z",
"updatedTime": "2022-01-31T16:15:15Z",
"stateTransitions": {
"activatedFree": "2022-01-31T16:15:15Z"
},
"billingAgreementId": "fbeabcdd-52d4-48a9-9437-5b4ccf6f8df1",
"customerId": "f9acfc5b-42de-4807-8248-eb1cb8069a04",
"sourceId": "596245ab-8479-4df4-ae1c-853ed0e11073",
"taxInclusive": false,
"currency": "USD",
"planId": "2919a6a2-c3ab-4a5b-8a6a-8f8a72a177a5",
"locale": "en_US",
"state": "activeFree",
"items": [
{
"price": 0.0,
"skuId": "7eee0e8c-b08e-4b9b-b241-8ba4e2a5876a",
"quantity": 1
}
],
"currentPeriodEndDate": "2022-04-28T16:15:15Z",
"nextInvoiceDate": "2022-04-28T16:15:15Z",
"nextReminderDate": "2022-04-27T16:15:15Z",
"liveMode": false
}
]
For each subscription, access its payment source by passing sourceId in a GET /sources/{sourceId} request.
To modify a subscription's payment source, its state must be active, activeFree, or activePendingInvoice. If this precondition is met, you can:

Update credit card information

If a subscription's sourceId references a source with a type of creditCard, then you can provide customers the ability to update that card's billing information or expiration date.
Subscription
Source
{
"id": "f9f73fd2-b56d-40d2-92fe-de4987671c34",
...
"sourceId": "26ab35a7-64f7-4cf5-82e6-18cc444cd993",
...
"state": "activeFree",
...
}
{
"id": "26ab35a7-64f7-4cf5-82e6-18cc444cd993",
"createdTime": "2022-02-11T15:44:33Z",
"type": "creditCard",
"currency": "USD",
"amount": 7.0,
"reusable": true,
"state": "chargeable",
"customerId": "563089660336",
"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"
}
},
"clientSecret": "26ab35a7-64f7-4cf5-82e6-18cc444cd993_4a4be490-2c12-4978-af07-3b2b6b184ba5",
"creditCard": {
"brand": "Visa",
"expirationMonth": 3,
"expirationYear": 2030,
"lastFourDigits": "1111"
},
"liveMode": false
}
If you want to display the card's current billing information and card information to customers, you can retrieve that data from the source's owner and creditCard blocks.

Billing address information

If customers opt to edit their billing information, present them with a form to enter the full name, email, and address (line 1, line 2, city, state, country, postal code) associated with the credit card.

Card expiration date

If customers opt to edit their credit card's expiration date, use a cardexpiration element to provide them with an input field.

Configuring the update source method

Once customers enter and save their changes, pass the submitted data to updateSource(). Make sure you configure the appropriate version of the method, depending on whether customers submit updated (a) billing address information, (b) card expiration information or (c) both. In both versions, you need to add the source's id and clientSecret to the method's configuration object.

Replace an existing source with a new source

When customers want to change how they pay for a subscription, you can allow them to supply a new payment method.
How you replace a subscription's current source with a new source depends on whether you're using Drop-in payments or DigitalRiver.js with Elements.
In both cases, first collect and store the customer's billing information.
Drop-in payments
Elements
Build the createDropin() method's configuration object:
let digitalriverpayments = new DigitalRiver("pk_hc_a209389e4588433bb6e00b32466b82c3", {
"locale": "en_GB"
});
let configuration = {
"options": {
"flow": "managePaymentMethods",
"showComplianceSection": true,
"showTermsOfSaleDisclosure": true,
"usage": "subscription"
},
"billingAddress": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phoneNumber": "952-253-1234",
"address": {
"line1": "16 Byward St",
"city": "London",
"state": "England",
"postalCode": "EC3R 5BA",
"country": "GB"
}
},
...
}
let dropin = digitalriverpayments.createDropin(configuration);
dropin.mount("drop-in-container");
Pass the configuration object to createDropin(). If the request is successful, the onReady event contains the transaction's eligible payment methods:
{
"paymentMethodTypes": [
"creditCard",
"payPalBilling"
]
}
Each payment method and its disclosures are displayed in the window. If customers click the button without accepting these agreements and terms, Drop-in blocks the transaction from proceeding.
If customers accept the terms, submit their information and the resulting create source request is successful, the onSuccess event contains a source that is readyForStorage and chargeable.
Configure retrieveAvailablePaymentMethods() using the following filters:
  • Set currency to the same value as the subscription's currency
  • Use the billing address country you collect from customers to set country
  • Both supportsStorage and supportsRecurring should be true
...
digitalriver.retrieveAvailablePaymentMethods({
"currency": "EUR",
"country": "FR",
"supportsStorage": true,
"supportsRecurring": true
}).then(function(result) {
//do something with the result, this could include showing or hiding specific payment methods that are applicable to the display
});
...
If the request is successful, the response contains the transaction's eligible payment methods:
[
{
"type": "creditCard",
"flow": "standard",
"supportsRecurring": true,
"supportsFreeTrial": true,
"images": {
"iconImage": "https://ui1.img.digitalrivercontent.net/Storefront/images/paymentMethodLogos/creditcard.png"
},
"supportsStorage": true,
"defaultMandate": {
"terms": "Yes, please save this account and payment information for future purchases."
},
"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": "Yes, please save this account and payment information for future purchases."
}
"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": "Yes, please save this account and payment information for future purchases."
},
"displayName": "Google Pay",
"localizedDisplayName": "Google Pay"
}
]
For each available payment method:
  • Create the appropriate elements to collect the customer's sensitive payment information.
  • Retrieve defaultMandate.terms and display that text with some sort of acceptance control. Your code should be written so that customers must accept these terms before the transaction can proceed.
When customers submit their information, configure and call the createSource() method:
  • Set type to the payment method selected by the customer
  • Set usage to subscription and futureUse to true
  • Use that payment method's defaultMandate.terms to set mandate.terms
  • Since this is an account management flow, you can't provide a checkout's payment session identifier. As a result, you must pass the billing information you collect from customers in billingAddress.
var payload = {
"type": "creditCard",
"futureUse": true,
"usage": "subscription",
"billingAddress": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phoneNumber": "952-253-1234",
"address": {
"line1": "16 Byward St",
"city": "London",
"state": "England",
"postalCode": "EC3R 5BA",
"country": "GB"
}
},
...
"mandate": {
"terms": "Yes, please save this account and payment information for future purchases."
}
}
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 details refer to the DigitalRiver.js Quick start guide.
Send the source, customer, and subscription identifiers to your back-end.
Use a POST /customers/{customerId}/sources/{sourceId} to attach the source to the customer. This flips the source's reusable attribute to true.
To update the subscription, send its identifier as a path parameter in a POST /subscriptions/{subscriptionId}. In the body of the request, specify the new sourceId.
curl --location --request POST 'https://api.digitalriver.com/subscriptions/b8dc06d6-941e-483c-89a1-263874bff3b4' \
...
--data-raw '{
"sourceId": "e4adbcac-1551-4743-9a3e-48dc3883241b"
}
If you receive a 200 OK, notify customers that their subscription's designated payment method has been successfully updated.

Replace an existing source with a saved source

When customers want to change how they pay for a subscription, you can give them the option of selecting one of their saved payment sources.
To access these sources, send the customer's identifier in a GET /customers/{customerId} request. From the response, you can retrieve any of the sources[], since, by default, they're all chargeable and reusable.
Customer
{
"id": "533319260336",
"createdTime": "2021-05-06T21:51:08Z",
"email": "[email protected]",
"shipping": {
"address": {
"line1": "123 Boulevard",
"city": "Saint Paul",
"postalCode": "55155",
"state": "MN",
"country": "US"
},
"name": "John Doe",
"phone": "555-555-5555"
},
"defaultSourceId": "5e359d60-1d23-4234-84ee-e1c9b3ed7edc",
"sources": [
{
"id": "19f47eba-418f-41b3-882c-462e335770e7",
"createdTime": "2022-03-30T21:14:05Z",
"type": "payPalBilling",
"currency": "USD",
"amount": 27.01,
"reusable": true,
"state": "chargeable",
"owner": {
"firstName": "Maya",
"lastName": "Brown",
"email": "[email protected]",
"address": {
"line1": "10381 Bren Rd W",
"city": "Minnetonka",
"postalCode":