diff --git a/services/web/app/src/Features/Subscription/RecurlyWrapper.js b/services/web/app/src/Features/Subscription/RecurlyWrapper.js
index 9660a8c5dd..5830b69bb2 100644
--- a/services/web/app/src/Features/Subscription/RecurlyWrapper.js
+++ b/services/web/app/src/Features/Subscription/RecurlyWrapper.js
@@ -286,6 +286,14 @@ const promises = {
{ userId: user._id },
'starting process of creating paypal subscription'
)
+ if (subscriptionDetails.subscription_add_ons) {
+ // TODO: support flexible licensing in paypal flow
+ const err = new Error('Add-on purchase not supported')
+ OError.tag(err, 'error in paypal subscription creation process', {
+ user_id: user._id,
+ })
+ throw err
+ }
// We use waterfall through each of these actions in sequence
// passing a `cache` object along the way. The cache is initialized
// with required data, and `async.apply` to pass the cache to the first function
@@ -343,6 +351,10 @@ const promises = {
data.account.billing_info.three_d_secure_action_result_token_id =
recurlyTokenIds.threeDSecureActionResult
}
+ if (subscriptionDetails.subscription_add_ons) {
+ data.subscription_add_ons = subscriptionDetails.subscription_add_ons
+ }
+
const customFields =
getCustomFieldsFromSubscriptionDetails(subscriptionDetails)
if (customFields) {
diff --git a/services/web/frontend/js/utils/meta.ts b/services/web/frontend/js/utils/meta.ts
index 941cfd32c6..b1b8fc948d 100644
--- a/services/web/frontend/js/utils/meta.ts
+++ b/services/web/frontend/js/utils/meta.ts
@@ -130,6 +130,7 @@ export interface Meta {
'ol-languages': SpellCheckLanguage[]
'ol-learnedWords': string[]
'ol-legacyEditorThemes': string[]
+ 'ol-licenseQuantity': number | undefined
'ol-linkSharingEnforcement': boolean
'ol-linkSharingWarning': boolean
'ol-loadingText': string
diff --git a/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js b/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js
index be55517aed..b2144b039b 100644
--- a/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js
+++ b/services/web/test/unit/src/Subscription/RecurlyWrapperTests.js
@@ -579,6 +579,9 @@ describe('RecurlyWrapper', function () {
state: 'some_state',
zip: 'some_zip',
},
+ subscription_add_ons: [
+ { subscription_add_on: { add_on_code: 'test_add_on', quantity: 2 } },
+ ],
ITMCampaign: 'itm-campaign-value',
ITMContent: 'itm-content-value',
ITMReferrer: 'itm-referrer-value',
@@ -633,6 +636,12 @@ describe('RecurlyWrapper', function () {
a-3d-token-id
+
+
+ test_add_on
+ 2
+
+
itm_campaign
@@ -884,6 +893,31 @@ describe('RecurlyWrapper', function () {
this.createSubscription.callCount.should.equal(0)
})
})
+
+ it('throw error if purchase with addon', async function () {
+ this.subscriptionDetails = {
+ currencyCode: 'EUR',
+ plan_code: 'some_plan_code',
+ coupon_code: '',
+ isPaypal: true,
+ address: {
+ address1: 'addr_one',
+ address2: 'addr_two',
+ country: 'some_country',
+ state: 'some_state',
+ zip: 'some_zip',
+ },
+ subscription_add_ons: [
+ { subscription_add_on: { add_on_code: 'test_add_on', quantity: 2 } },
+ ],
+ }
+ await expect(this.call()).to.be.rejected
+ this.checkAccountExists.callCount.should.equal(0)
+ this.createAccount.callCount.should.equal(0)
+ this.createBillingInfo.callCount.should.equal(0)
+ this.setAddressAndCompanyBillingInfo.callCount.should.equal(0)
+ this.createSubscription.callCount.should.equal(0)
+ })
})
describe('paypal actions', function () {
diff --git a/services/web/types/recurly/pricing/subscription.ts b/services/web/types/recurly/pricing/subscription.ts
index e018daf085..744d08c3ea 100644
--- a/services/web/types/recurly/pricing/subscription.ts
+++ b/services/web/types/recurly/pricing/subscription.ts
@@ -48,13 +48,18 @@ interface Coupon {
redemption_resource: string
}
+interface AddOn {
+ code: string
+ quantity: number
+}
+
// Extending the default interface as it lacks the `items` prop
export interface SubscriptionPricingInstanceCustom
extends SubscriptionPricingInstance,
SubscriptionPricingState {
id: string
items: {
- addons: unknown[]
+ addons: AddOn[]
address?: Address
coupon?: Coupon
currency: string