Skip to content

Commit

Permalink
fix(payment): waiting for payment not working for jwp ppv
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristiaanScheermeijer authored Jun 7, 2024
1 parent 1794113 commit 8d92adc
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 52 deletions.
2 changes: 1 addition & 1 deletion packages/common/src/controllers/AccountController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ export default class AccountController {
let pendingOffer: Offer | null = null;

if (!activeSubscription && !!retry && retry > 0) {
const retryDelay = 1500; // Any initial delay has already occured, so we can set this to a fixed value
const retryDelay = 1500; // Any initial delay has already occurred, so we can set this to a fixed value

return await this.reloadSubscriptions({ delay: retryDelay, retry: retry - 1 });
}
Expand Down
8 changes: 3 additions & 5 deletions packages/common/src/controllers/CheckoutController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,11 @@ export default class CheckoutController {
const { getAccountInfo } = useAccountStore.getState();

const { customerId } = getAccountInfo();

assertModuleMethod(this.checkoutService.getSubscriptionSwitches, 'getSubscriptionSwitches is not available in checkout service');
assertModuleMethod(this.checkoutService.getOffer, 'getOffer is not available in checkout service');

const { subscription } = useAccountStore.getState();

if (!subscription) return null;
if (!subscription || !this.checkoutService.getSubscriptionSwitches) return null;

assertModuleMethod(this.checkoutService.getOffer, 'getOffer is not available in checkout service');

const response = await this.checkoutService.getSubscriptionSwitches({
customerId: customerId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,38 @@ export default class JWPCheckoutService extends CheckoutService {
};
};

private formatOffer = (offer: AccessFee): Offer => {
/**
* Format a (Cleeng like) offer id for the given access fee (pricing option). For JWP, we need the asset id and
* access fee id in some cases.
*/
private formatOfferId(offer: AccessFee) {
const ppvOffers = ['ppv', 'ppv_custom'];
const offerId = ppvOffers.includes(offer.access_type.name) ? `C${offer.id}` : `S${offer.id}`;

return ppvOffers.includes(offer.access_type.name) ? `C${offer.item_id}_${offer.id}` : `S${offer.item_id}_${offer.id}`;
}

/**
* Parse the given offer id and extract the asset id.
* The offer id might be the Cleeng format (`S<assetId>_<pricingOptionId>`) or the asset id as string.
*/
private parseOfferId(offerId: string | number) {
if (typeof offerId === 'string') {
// offer id format `S<assetId>_<pricingOptionId>`
if (offerId.startsWith('C') || offerId.startsWith('S')) {
return parseInt(offerId.slice(1).split('_')[0]);
}

// offer id format `<assetId>`
return parseInt(offerId);
}

return offerId;
}

private formatOffer = (offer: AccessFee): Offer => {
return {
id: offer.id,
offerId,
offerId: this.formatOfferId(offer),
offerCurrency: offer.currency,
customerPriceInclTax: offer.amount,
customerCurrency: offer.currency,
Expand Down Expand Up @@ -97,9 +122,9 @@ export default class JWPCheckoutService extends CheckoutService {

getOffers: GetOffers = async (payload) => {
const offers = await Promise.all(
payload.offerIds.map(async (assetId) => {
payload.offerIds.map(async (offerId) => {
try {
const { data } = await InPlayer.Asset.getAssetAccessFees(parseInt(`${assetId}`));
const { data } = await InPlayer.Asset.getAssetAccessFees(this.parseOfferId(offerId));

return data?.map((offer) => this.formatOffer(offer));
} catch {
Expand Down Expand Up @@ -217,7 +242,7 @@ export default class JWPCheckoutService extends CheckoutService {

getEntitlements: GetEntitlements = async ({ offerId }) => {
try {
const response = await InPlayer.Asset.checkAccessForAsset(parseInt(offerId));
const response = await InPlayer.Asset.checkAccessForAsset(this.parseOfferId(offerId));
return this.formatEntitlements(response.data.expires_at, true);
} catch {
return this.formatEntitlements();
Expand Down
18 changes: 11 additions & 7 deletions packages/hooks-react/src/useCheckAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type IntervalCheckAccessPayload = {
interval?: number;
iterations?: number;
offerId?: string;
callback?: (hasAccess: boolean) => void;
callback?: ({ hasAccess, offerId }: { hasAccess: boolean; offerId: string }) => void;
};

const useCheckAccess = () => {
Expand All @@ -22,21 +22,25 @@ const useCheckAccess = () => {
const offers = checkoutController.getSubscriptionOfferIds();

const intervalCheckAccess = useCallback(
({ interval = 3000, iterations = 5, offerId, callback }: IntervalCheckAccessPayload) => {
if (!offerId && offers?.[0]) {
offerId = offers[0];
({ interval = 3000, iterations = 5, offerId = offers?.[0], callback }: IntervalCheckAccessPayload) => {
if (!offerId) {
callback?.({ hasAccess: false, offerId: '' });
return;
}

intervalRef.current = window.setInterval(async () => {
const hasAccess = await accountController.checkEntitlements(offerId);

if (hasAccess) {
await accountController.reloadSubscriptions({ retry: 10, delay: 2000 });
callback?.(true);
window.clearInterval(intervalRef.current);
// No duplicate retry mechanism. This can also be a TVOD offer which isn't validated using the
// reloadSubscriptions method.
await accountController.reloadSubscriptions();
callback?.({ hasAccess: true, offerId: offerId || '' });
} else if (--iterations === 0) {
window.clearInterval(intervalRef.current);
setErrorMessage(t('payment.longer_than_usual'));
callback?.(false);
callback?.({ hasAccess: false, offerId: offerId || '' });
}
}, interval);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ const WaitingForPayment = () => {
interval: 3000,
iterations: 5,
offerId,
callback: (hasAccess) => {
callback: ({ hasAccess, offerId }) => {
if (!hasAccess) return;

announce(t('checkout.payment_success'), 'success');
navigate(modalURLFromLocation(location, 'welcome'));

// close the modal for PPV/TVOD offers
if (offerId.startsWith('C') || offerId.startsWith('P')) {
// @TODO should we show a dedicated modal for TVOD access?
navigate(modalURLFromLocation(location, null));
} else {
navigate(modalURLFromLocation(location, 'welcome'));
}
},
});
//eslint-disable-next-line
Expand Down
4 changes: 2 additions & 2 deletions platforms/web/test-e2e/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default {
paymentFee: formatPrice(0, 'EUR', 'NL'),
},
inplayer: {
label: `label[for="S38279"]`,
label: `label[for="S118699_38279"]`,
price: formatPrice(6.99, 'EUR'),
paymentFee: formatPrice(0, 'EUR'),
},
Expand All @@ -93,7 +93,7 @@ export default {
paymentFee: formatPrice(0, 'EUR', 'NL'),
},
inplayer: {
label: `label[for="S38280"]`,
label: `label[for="S118699_38280"]`,
price: formatPrice(50, 'EUR'),
paymentFee: formatPrice(0, 'EUR'),
},
Expand Down
33 changes: 4 additions & 29 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1879,7 +1879,7 @@
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==

"@jridgewell/set-array@^1.2.1":
"@jridgewell/set-array@^1.0.1", "@jridgewell/set-array@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280"
integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
Expand Down Expand Up @@ -9930,7 +9930,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==

"string-width-cjs@npm:string-width@^4.2.0":
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand All @@ -9947,15 +9947,6 @@ string-width@^2.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"

string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
Expand Down Expand Up @@ -10053,7 +10044,7 @@ stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand All @@ -10074,13 +10065,6 @@ strip-ansi@^5.1.0:
dependencies:
ansi-regex "^4.1.0"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^7.0.1, strip-ansi@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
Expand Down Expand Up @@ -11694,16 +11678,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand Down

0 comments on commit 8d92adc

Please sign in to comment.