@economist/web-apple-pay 0.1.3-beta.21 → 0.1.3-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +26 -17
- package/dist/src/apple-pay-button.js +26 -17
- package/dist/src/apple-pay-button.stories.js +26 -17
- package/dist/src/apple-pay-modal.stories.js +26 -17
- package/dist/src/clients/payment-checkout/apple-session.js +3 -1
- package/dist/src/clients/payment-checkout/payment-handler.js +24 -16
- package/dist/src/clients/payment-checkout/types.d.ts +1 -1
- package/dist/src/index.js +26 -17
- package/dist/src/utils/expressCheckoutRedirect.d.ts +18 -1
- package/dist/src/utils/expressCheckoutRedirect.js +3 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1245,6 +1245,8 @@ var redirectToCheckoutComplete = (params) => {
|
|
|
1245
1245
|
url.searchParams.set("lmo_offer", params.skuId);
|
|
1246
1246
|
url.searchParams.set("status", params.status);
|
|
1247
1247
|
url.searchParams.set("redirectToCheckout", "true");
|
|
1248
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
1249
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1248
1250
|
return url.pathname + url.search;
|
|
1249
1251
|
};
|
|
1250
1252
|
var redirectToCheckoutFallback = (params) => {
|
|
@@ -1255,6 +1257,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1255
1257
|
url.searchParams.set("inlineError", params.inlineError);
|
|
1256
1258
|
if (params.email) url.searchParams.set("email", params.email);
|
|
1257
1259
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
1260
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1258
1261
|
return url.pathname + url.search;
|
|
1259
1262
|
};
|
|
1260
1263
|
|
|
@@ -1348,7 +1351,8 @@ function redirectToFallbackCheckout(config) {
|
|
|
1348
1351
|
trackFallbackCheckout(config.skuId);
|
|
1349
1352
|
window.location.href = redirectToCheckoutFallback({
|
|
1350
1353
|
skuId: config.skuId,
|
|
1351
|
-
inlineError: MSG_PAYMENT_GENERIC_ERROR
|
|
1354
|
+
inlineError: MSG_PAYMENT_GENERIC_ERROR,
|
|
1355
|
+
country: config.countryCode
|
|
1352
1356
|
});
|
|
1353
1357
|
}
|
|
1354
1358
|
async function handleMerchantValidation(event, session, config) {
|
|
@@ -1558,37 +1562,43 @@ function validateContacts(event, sessionData, supportedBillingCountries) {
|
|
|
1558
1562
|
}
|
|
1559
1563
|
return void 0;
|
|
1560
1564
|
}
|
|
1561
|
-
function redirectFallback(skuId, returnUrl, options) {
|
|
1565
|
+
function redirectFallback(skuId, returnUrl, country, options) {
|
|
1562
1566
|
writeCheckoutRedirect(returnUrl);
|
|
1563
1567
|
trackFallbackCheckout(skuId);
|
|
1564
1568
|
window.location.href = redirectToCheckoutFallback({
|
|
1565
1569
|
skuId,
|
|
1570
|
+
country,
|
|
1566
1571
|
...options
|
|
1567
1572
|
});
|
|
1568
1573
|
}
|
|
1569
1574
|
var ERROR_HANDLERS = {
|
|
1570
|
-
EMAIL_COLLISION: ({ skuId, returnUrl, validatedEmail }) => redirectFallback(skuId, returnUrl, {
|
|
1575
|
+
EMAIL_COLLISION: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1571
1576
|
emailError: MSG_EMAIL_COLLISION,
|
|
1572
1577
|
email: validatedEmail
|
|
1573
1578
|
}),
|
|
1574
|
-
PAYMENT_DECLINED: ({ skuId, returnUrl }) => (
|
|
1579
|
+
PAYMENT_DECLINED: ({ skuId, returnUrl, country }) => (
|
|
1575
1580
|
// Matches sma-checkout catch-all: always redirect with generic inlineError.
|
|
1576
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1581
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1577
1582
|
),
|
|
1578
|
-
ELIGIBILITY_REJECTED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_ELIGIBILITY }),
|
|
1579
|
-
REGISTRATION_FAILED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_REGISTRATION }),
|
|
1580
|
-
|
|
1583
|
+
ELIGIBILITY_REJECTED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_ELIGIBILITY }),
|
|
1584
|
+
REGISTRATION_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_REGISTRATION }),
|
|
1585
|
+
ACCOUNT_CREATION_FAILED: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1586
|
+
emailError: MSG_REGISTRATION,
|
|
1587
|
+
email: validatedEmail
|
|
1588
|
+
}),
|
|
1589
|
+
VALIDATION_ERROR: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED }),
|
|
1590
|
+
RECAPTCHA_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED })
|
|
1581
1591
|
};
|
|
1582
1592
|
function handleStructuredError(ctx) {
|
|
1583
1593
|
const handler = ERROR_HANDLERS[ctx.walletError.errorType];
|
|
1584
1594
|
if (handler) {
|
|
1585
1595
|
handler(ctx);
|
|
1586
1596
|
} else {
|
|
1587
|
-
redirectFallback(ctx.skuId, ctx.returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1597
|
+
redirectFallback(ctx.skuId, ctx.returnUrl, ctx.country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1588
1598
|
}
|
|
1589
1599
|
}
|
|
1590
1600
|
async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
1591
|
-
const { skuId, returnUrl, queryString } = config;
|
|
1601
|
+
const { skuId, returnUrl, queryString, country } = config;
|
|
1592
1602
|
let validatedEmail;
|
|
1593
1603
|
try {
|
|
1594
1604
|
validatedEmail = validateContacts(
|
|
@@ -1608,13 +1618,16 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1608
1618
|
});
|
|
1609
1619
|
trackWalletPaymentSuccess(skuId, result.basketId);
|
|
1610
1620
|
session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
|
|
1621
|
+
const successEmail = sessionData.loggedIn ? sessionData.emailAddress : validatedEmail;
|
|
1611
1622
|
const userStatus = sessionData.loggedIn ? "lex" : "nex";
|
|
1612
1623
|
writeCheckoutRedirect(returnUrl);
|
|
1613
1624
|
window.location.href = redirectToCheckoutComplete({
|
|
1614
1625
|
basketId: result.basketId,
|
|
1615
1626
|
status: userStatus,
|
|
1616
1627
|
skuId: decodeSku(skuId),
|
|
1617
|
-
queryString
|
|
1628
|
+
queryString,
|
|
1629
|
+
email: successEmail,
|
|
1630
|
+
country
|
|
1618
1631
|
});
|
|
1619
1632
|
} catch (err) {
|
|
1620
1633
|
if (err instanceof ContactValidationError) {
|
|
@@ -1623,17 +1636,13 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1623
1636
|
}
|
|
1624
1637
|
console.error("[web-apple-pay] onpaymentauthorized error", { skuId, err });
|
|
1625
1638
|
const walletError = parseWalletApiError(err);
|
|
1626
|
-
console.warn("[web-apple-pay] handlePaymentAuthorized: walletError result", {
|
|
1627
|
-
walletError,
|
|
1628
|
-
validatedEmail
|
|
1629
|
-
});
|
|
1630
1639
|
trackWalletPaymentFailure(skuId, walletError?.errorType ?? "UNKNOWN");
|
|
1631
1640
|
failApplePaySession(session);
|
|
1632
1641
|
if (!walletError) {
|
|
1633
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1642
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1634
1643
|
return;
|
|
1635
1644
|
}
|
|
1636
|
-
handleStructuredError({ skuId, returnUrl, validatedEmail, walletError });
|
|
1645
|
+
handleStructuredError({ skuId, returnUrl, country, validatedEmail, walletError });
|
|
1637
1646
|
}
|
|
1638
1647
|
}
|
|
1639
1648
|
|
|
@@ -1240,6 +1240,8 @@ var redirectToCheckoutComplete = (params) => {
|
|
|
1240
1240
|
url.searchParams.set("lmo_offer", params.skuId);
|
|
1241
1241
|
url.searchParams.set("status", params.status);
|
|
1242
1242
|
url.searchParams.set("redirectToCheckout", "true");
|
|
1243
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
1244
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1243
1245
|
return url.pathname + url.search;
|
|
1244
1246
|
};
|
|
1245
1247
|
var redirectToCheckoutFallback = (params) => {
|
|
@@ -1250,6 +1252,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1250
1252
|
url.searchParams.set("inlineError", params.inlineError);
|
|
1251
1253
|
if (params.email) url.searchParams.set("email", params.email);
|
|
1252
1254
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
1255
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1253
1256
|
return url.pathname + url.search;
|
|
1254
1257
|
};
|
|
1255
1258
|
|
|
@@ -1343,7 +1346,8 @@ function redirectToFallbackCheckout(config) {
|
|
|
1343
1346
|
trackFallbackCheckout(config.skuId);
|
|
1344
1347
|
window.location.href = redirectToCheckoutFallback({
|
|
1345
1348
|
skuId: config.skuId,
|
|
1346
|
-
inlineError: MSG_PAYMENT_GENERIC_ERROR
|
|
1349
|
+
inlineError: MSG_PAYMENT_GENERIC_ERROR,
|
|
1350
|
+
country: config.countryCode
|
|
1347
1351
|
});
|
|
1348
1352
|
}
|
|
1349
1353
|
async function handleMerchantValidation(event, session, config) {
|
|
@@ -1553,37 +1557,43 @@ function validateContacts(event, sessionData, supportedBillingCountries) {
|
|
|
1553
1557
|
}
|
|
1554
1558
|
return void 0;
|
|
1555
1559
|
}
|
|
1556
|
-
function redirectFallback(skuId, returnUrl, options) {
|
|
1560
|
+
function redirectFallback(skuId, returnUrl, country, options) {
|
|
1557
1561
|
writeCheckoutRedirect(returnUrl);
|
|
1558
1562
|
trackFallbackCheckout(skuId);
|
|
1559
1563
|
window.location.href = redirectToCheckoutFallback({
|
|
1560
1564
|
skuId,
|
|
1565
|
+
country,
|
|
1561
1566
|
...options
|
|
1562
1567
|
});
|
|
1563
1568
|
}
|
|
1564
1569
|
var ERROR_HANDLERS = {
|
|
1565
|
-
EMAIL_COLLISION: ({ skuId, returnUrl, validatedEmail }) => redirectFallback(skuId, returnUrl, {
|
|
1570
|
+
EMAIL_COLLISION: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1566
1571
|
emailError: MSG_EMAIL_COLLISION,
|
|
1567
1572
|
email: validatedEmail
|
|
1568
1573
|
}),
|
|
1569
|
-
PAYMENT_DECLINED: ({ skuId, returnUrl }) => (
|
|
1574
|
+
PAYMENT_DECLINED: ({ skuId, returnUrl, country }) => (
|
|
1570
1575
|
// Matches sma-checkout catch-all: always redirect with generic inlineError.
|
|
1571
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1576
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1572
1577
|
),
|
|
1573
|
-
ELIGIBILITY_REJECTED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_ELIGIBILITY }),
|
|
1574
|
-
REGISTRATION_FAILED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_REGISTRATION }),
|
|
1575
|
-
|
|
1578
|
+
ELIGIBILITY_REJECTED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_ELIGIBILITY }),
|
|
1579
|
+
REGISTRATION_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_REGISTRATION }),
|
|
1580
|
+
ACCOUNT_CREATION_FAILED: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1581
|
+
emailError: MSG_REGISTRATION,
|
|
1582
|
+
email: validatedEmail
|
|
1583
|
+
}),
|
|
1584
|
+
VALIDATION_ERROR: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED }),
|
|
1585
|
+
RECAPTCHA_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED })
|
|
1576
1586
|
};
|
|
1577
1587
|
function handleStructuredError(ctx) {
|
|
1578
1588
|
const handler = ERROR_HANDLERS[ctx.walletError.errorType];
|
|
1579
1589
|
if (handler) {
|
|
1580
1590
|
handler(ctx);
|
|
1581
1591
|
} else {
|
|
1582
|
-
redirectFallback(ctx.skuId, ctx.returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1592
|
+
redirectFallback(ctx.skuId, ctx.returnUrl, ctx.country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1583
1593
|
}
|
|
1584
1594
|
}
|
|
1585
1595
|
async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
1586
|
-
const { skuId, returnUrl, queryString } = config;
|
|
1596
|
+
const { skuId, returnUrl, queryString, country } = config;
|
|
1587
1597
|
let validatedEmail;
|
|
1588
1598
|
try {
|
|
1589
1599
|
validatedEmail = validateContacts(
|
|
@@ -1603,13 +1613,16 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1603
1613
|
});
|
|
1604
1614
|
trackWalletPaymentSuccess(skuId, result.basketId);
|
|
1605
1615
|
session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
|
|
1616
|
+
const successEmail = sessionData.loggedIn ? sessionData.emailAddress : validatedEmail;
|
|
1606
1617
|
const userStatus = sessionData.loggedIn ? "lex" : "nex";
|
|
1607
1618
|
writeCheckoutRedirect(returnUrl);
|
|
1608
1619
|
window.location.href = redirectToCheckoutComplete({
|
|
1609
1620
|
basketId: result.basketId,
|
|
1610
1621
|
status: userStatus,
|
|
1611
1622
|
skuId: decodeSku(skuId),
|
|
1612
|
-
queryString
|
|
1623
|
+
queryString,
|
|
1624
|
+
email: successEmail,
|
|
1625
|
+
country
|
|
1613
1626
|
});
|
|
1614
1627
|
} catch (err) {
|
|
1615
1628
|
if (err instanceof ContactValidationError) {
|
|
@@ -1618,17 +1631,13 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1618
1631
|
}
|
|
1619
1632
|
console.error("[web-apple-pay] onpaymentauthorized error", { skuId, err });
|
|
1620
1633
|
const walletError = parseWalletApiError(err);
|
|
1621
|
-
console.warn("[web-apple-pay] handlePaymentAuthorized: walletError result", {
|
|
1622
|
-
walletError,
|
|
1623
|
-
validatedEmail
|
|
1624
|
-
});
|
|
1625
1634
|
trackWalletPaymentFailure(skuId, walletError?.errorType ?? "UNKNOWN");
|
|
1626
1635
|
failApplePaySession(session);
|
|
1627
1636
|
if (!walletError) {
|
|
1628
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1637
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1629
1638
|
return;
|
|
1630
1639
|
}
|
|
1631
|
-
handleStructuredError({ skuId, returnUrl, validatedEmail, walletError });
|
|
1640
|
+
handleStructuredError({ skuId, returnUrl, country, validatedEmail, walletError });
|
|
1632
1641
|
}
|
|
1633
1642
|
}
|
|
1634
1643
|
|
|
@@ -1248,6 +1248,8 @@ var redirectToCheckoutComplete = (params) => {
|
|
|
1248
1248
|
url.searchParams.set("lmo_offer", params.skuId);
|
|
1249
1249
|
url.searchParams.set("status", params.status);
|
|
1250
1250
|
url.searchParams.set("redirectToCheckout", "true");
|
|
1251
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
1252
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1251
1253
|
return url.pathname + url.search;
|
|
1252
1254
|
};
|
|
1253
1255
|
var redirectToCheckoutFallback = (params) => {
|
|
@@ -1258,6 +1260,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1258
1260
|
url.searchParams.set("inlineError", params.inlineError);
|
|
1259
1261
|
if (params.email) url.searchParams.set("email", params.email);
|
|
1260
1262
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
1263
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1261
1264
|
return url.pathname + url.search;
|
|
1262
1265
|
};
|
|
1263
1266
|
|
|
@@ -1351,7 +1354,8 @@ function redirectToFallbackCheckout(config) {
|
|
|
1351
1354
|
trackFallbackCheckout(config.skuId);
|
|
1352
1355
|
window.location.href = redirectToCheckoutFallback({
|
|
1353
1356
|
skuId: config.skuId,
|
|
1354
|
-
inlineError: MSG_PAYMENT_GENERIC_ERROR
|
|
1357
|
+
inlineError: MSG_PAYMENT_GENERIC_ERROR,
|
|
1358
|
+
country: config.countryCode
|
|
1355
1359
|
});
|
|
1356
1360
|
}
|
|
1357
1361
|
async function handleMerchantValidation(event, session, config) {
|
|
@@ -1561,37 +1565,43 @@ function validateContacts(event, sessionData, supportedBillingCountries) {
|
|
|
1561
1565
|
}
|
|
1562
1566
|
return void 0;
|
|
1563
1567
|
}
|
|
1564
|
-
function redirectFallback(skuId, returnUrl, options) {
|
|
1568
|
+
function redirectFallback(skuId, returnUrl, country, options) {
|
|
1565
1569
|
writeCheckoutRedirect(returnUrl);
|
|
1566
1570
|
trackFallbackCheckout(skuId);
|
|
1567
1571
|
window.location.href = redirectToCheckoutFallback({
|
|
1568
1572
|
skuId,
|
|
1573
|
+
country,
|
|
1569
1574
|
...options
|
|
1570
1575
|
});
|
|
1571
1576
|
}
|
|
1572
1577
|
var ERROR_HANDLERS = {
|
|
1573
|
-
EMAIL_COLLISION: ({ skuId, returnUrl, validatedEmail }) => redirectFallback(skuId, returnUrl, {
|
|
1578
|
+
EMAIL_COLLISION: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1574
1579
|
emailError: MSG_EMAIL_COLLISION,
|
|
1575
1580
|
email: validatedEmail
|
|
1576
1581
|
}),
|
|
1577
|
-
PAYMENT_DECLINED: ({ skuId, returnUrl }) => (
|
|
1582
|
+
PAYMENT_DECLINED: ({ skuId, returnUrl, country }) => (
|
|
1578
1583
|
// Matches sma-checkout catch-all: always redirect with generic inlineError.
|
|
1579
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1584
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1580
1585
|
),
|
|
1581
|
-
ELIGIBILITY_REJECTED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_ELIGIBILITY }),
|
|
1582
|
-
REGISTRATION_FAILED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_REGISTRATION }),
|
|
1583
|
-
|
|
1586
|
+
ELIGIBILITY_REJECTED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_ELIGIBILITY }),
|
|
1587
|
+
REGISTRATION_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_REGISTRATION }),
|
|
1588
|
+
ACCOUNT_CREATION_FAILED: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1589
|
+
emailError: MSG_REGISTRATION,
|
|
1590
|
+
email: validatedEmail
|
|
1591
|
+
}),
|
|
1592
|
+
VALIDATION_ERROR: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED }),
|
|
1593
|
+
RECAPTCHA_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED })
|
|
1584
1594
|
};
|
|
1585
1595
|
function handleStructuredError(ctx) {
|
|
1586
1596
|
const handler = ERROR_HANDLERS[ctx.walletError.errorType];
|
|
1587
1597
|
if (handler) {
|
|
1588
1598
|
handler(ctx);
|
|
1589
1599
|
} else {
|
|
1590
|
-
redirectFallback(ctx.skuId, ctx.returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1600
|
+
redirectFallback(ctx.skuId, ctx.returnUrl, ctx.country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1591
1601
|
}
|
|
1592
1602
|
}
|
|
1593
1603
|
async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
1594
|
-
const { skuId, returnUrl, queryString } = config;
|
|
1604
|
+
const { skuId, returnUrl, queryString, country } = config;
|
|
1595
1605
|
let validatedEmail;
|
|
1596
1606
|
try {
|
|
1597
1607
|
validatedEmail = validateContacts(
|
|
@@ -1611,13 +1621,16 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1611
1621
|
});
|
|
1612
1622
|
trackWalletPaymentSuccess(skuId, result.basketId);
|
|
1613
1623
|
session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
|
|
1624
|
+
const successEmail = sessionData.loggedIn ? sessionData.emailAddress : validatedEmail;
|
|
1614
1625
|
const userStatus = sessionData.loggedIn ? "lex" : "nex";
|
|
1615
1626
|
writeCheckoutRedirect(returnUrl);
|
|
1616
1627
|
window.location.href = redirectToCheckoutComplete({
|
|
1617
1628
|
basketId: result.basketId,
|
|
1618
1629
|
status: userStatus,
|
|
1619
1630
|
skuId: decodeSku(skuId),
|
|
1620
|
-
queryString
|
|
1631
|
+
queryString,
|
|
1632
|
+
email: successEmail,
|
|
1633
|
+
country
|
|
1621
1634
|
});
|
|
1622
1635
|
} catch (err) {
|
|
1623
1636
|
if (err instanceof ContactValidationError) {
|
|
@@ -1626,17 +1639,13 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1626
1639
|
}
|
|
1627
1640
|
console.error("[web-apple-pay] onpaymentauthorized error", { skuId, err });
|
|
1628
1641
|
const walletError = parseWalletApiError(err);
|
|
1629
|
-
console.warn("[web-apple-pay] handlePaymentAuthorized: walletError result", {
|
|
1630
|
-
walletError,
|
|
1631
|
-
validatedEmail
|
|
1632
|
-
});
|
|
1633
1642
|
trackWalletPaymentFailure(skuId, walletError?.errorType ?? "UNKNOWN");
|
|
1634
1643
|
failApplePaySession(session);
|
|
1635
1644
|
if (!walletError) {
|
|
1636
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1645
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1637
1646
|
return;
|
|
1638
1647
|
}
|
|
1639
|
-
handleStructuredError({ skuId, returnUrl, validatedEmail, walletError });
|
|
1648
|
+
handleStructuredError({ skuId, returnUrl, country, validatedEmail, walletError });
|
|
1640
1649
|
}
|
|
1641
1650
|
}
|
|
1642
1651
|
|
|
@@ -1240,6 +1240,8 @@ var redirectToCheckoutComplete = (params) => {
|
|
|
1240
1240
|
url.searchParams.set("lmo_offer", params.skuId);
|
|
1241
1241
|
url.searchParams.set("status", params.status);
|
|
1242
1242
|
url.searchParams.set("redirectToCheckout", "true");
|
|
1243
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
1244
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1243
1245
|
return url.pathname + url.search;
|
|
1244
1246
|
};
|
|
1245
1247
|
var redirectToCheckoutFallback = (params) => {
|
|
@@ -1250,6 +1252,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1250
1252
|
url.searchParams.set("inlineError", params.inlineError);
|
|
1251
1253
|
if (params.email) url.searchParams.set("email", params.email);
|
|
1252
1254
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
1255
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1253
1256
|
return url.pathname + url.search;
|
|
1254
1257
|
};
|
|
1255
1258
|
|
|
@@ -1343,7 +1346,8 @@ function redirectToFallbackCheckout(config) {
|
|
|
1343
1346
|
trackFallbackCheckout(config.skuId);
|
|
1344
1347
|
window.location.href = redirectToCheckoutFallback({
|
|
1345
1348
|
skuId: config.skuId,
|
|
1346
|
-
inlineError: MSG_PAYMENT_GENERIC_ERROR
|
|
1349
|
+
inlineError: MSG_PAYMENT_GENERIC_ERROR,
|
|
1350
|
+
country: config.countryCode
|
|
1347
1351
|
});
|
|
1348
1352
|
}
|
|
1349
1353
|
async function handleMerchantValidation(event, session, config) {
|
|
@@ -1553,37 +1557,43 @@ function validateContacts(event, sessionData, supportedBillingCountries) {
|
|
|
1553
1557
|
}
|
|
1554
1558
|
return void 0;
|
|
1555
1559
|
}
|
|
1556
|
-
function redirectFallback(skuId, returnUrl, options) {
|
|
1560
|
+
function redirectFallback(skuId, returnUrl, country, options) {
|
|
1557
1561
|
writeCheckoutRedirect(returnUrl);
|
|
1558
1562
|
trackFallbackCheckout(skuId);
|
|
1559
1563
|
window.location.href = redirectToCheckoutFallback({
|
|
1560
1564
|
skuId,
|
|
1565
|
+
country,
|
|
1561
1566
|
...options
|
|
1562
1567
|
});
|
|
1563
1568
|
}
|
|
1564
1569
|
var ERROR_HANDLERS = {
|
|
1565
|
-
EMAIL_COLLISION: ({ skuId, returnUrl, validatedEmail }) => redirectFallback(skuId, returnUrl, {
|
|
1570
|
+
EMAIL_COLLISION: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1566
1571
|
emailError: MSG_EMAIL_COLLISION,
|
|
1567
1572
|
email: validatedEmail
|
|
1568
1573
|
}),
|
|
1569
|
-
PAYMENT_DECLINED: ({ skuId, returnUrl }) => (
|
|
1574
|
+
PAYMENT_DECLINED: ({ skuId, returnUrl, country }) => (
|
|
1570
1575
|
// Matches sma-checkout catch-all: always redirect with generic inlineError.
|
|
1571
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1576
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1572
1577
|
),
|
|
1573
|
-
ELIGIBILITY_REJECTED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_ELIGIBILITY }),
|
|
1574
|
-
REGISTRATION_FAILED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_REGISTRATION }),
|
|
1575
|
-
|
|
1578
|
+
ELIGIBILITY_REJECTED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_ELIGIBILITY }),
|
|
1579
|
+
REGISTRATION_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_REGISTRATION }),
|
|
1580
|
+
ACCOUNT_CREATION_FAILED: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1581
|
+
emailError: MSG_REGISTRATION,
|
|
1582
|
+
email: validatedEmail
|
|
1583
|
+
}),
|
|
1584
|
+
VALIDATION_ERROR: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED }),
|
|
1585
|
+
RECAPTCHA_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED })
|
|
1576
1586
|
};
|
|
1577
1587
|
function handleStructuredError(ctx) {
|
|
1578
1588
|
const handler = ERROR_HANDLERS[ctx.walletError.errorType];
|
|
1579
1589
|
if (handler) {
|
|
1580
1590
|
handler(ctx);
|
|
1581
1591
|
} else {
|
|
1582
|
-
redirectFallback(ctx.skuId, ctx.returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1592
|
+
redirectFallback(ctx.skuId, ctx.returnUrl, ctx.country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1583
1593
|
}
|
|
1584
1594
|
}
|
|
1585
1595
|
async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
1586
|
-
const { skuId, returnUrl, queryString } = config;
|
|
1596
|
+
const { skuId, returnUrl, queryString, country } = config;
|
|
1587
1597
|
let validatedEmail;
|
|
1588
1598
|
try {
|
|
1589
1599
|
validatedEmail = validateContacts(
|
|
@@ -1603,13 +1613,16 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1603
1613
|
});
|
|
1604
1614
|
trackWalletPaymentSuccess(skuId, result.basketId);
|
|
1605
1615
|
session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
|
|
1616
|
+
const successEmail = sessionData.loggedIn ? sessionData.emailAddress : validatedEmail;
|
|
1606
1617
|
const userStatus = sessionData.loggedIn ? "lex" : "nex";
|
|
1607
1618
|
writeCheckoutRedirect(returnUrl);
|
|
1608
1619
|
window.location.href = redirectToCheckoutComplete({
|
|
1609
1620
|
basketId: result.basketId,
|
|
1610
1621
|
status: userStatus,
|
|
1611
1622
|
skuId: decodeSku(skuId),
|
|
1612
|
-
queryString
|
|
1623
|
+
queryString,
|
|
1624
|
+
email: successEmail,
|
|
1625
|
+
country
|
|
1613
1626
|
});
|
|
1614
1627
|
} catch (err) {
|
|
1615
1628
|
if (err instanceof ContactValidationError) {
|
|
@@ -1618,17 +1631,13 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1618
1631
|
}
|
|
1619
1632
|
console.error("[web-apple-pay] onpaymentauthorized error", { skuId, err });
|
|
1620
1633
|
const walletError = parseWalletApiError(err);
|
|
1621
|
-
console.warn("[web-apple-pay] handlePaymentAuthorized: walletError result", {
|
|
1622
|
-
walletError,
|
|
1623
|
-
validatedEmail
|
|
1624
|
-
});
|
|
1625
1634
|
trackWalletPaymentFailure(skuId, walletError?.errorType ?? "UNKNOWN");
|
|
1626
1635
|
failApplePaySession(session);
|
|
1627
1636
|
if (!walletError) {
|
|
1628
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1637
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1629
1638
|
return;
|
|
1630
1639
|
}
|
|
1631
|
-
handleStructuredError({ skuId, returnUrl, validatedEmail, walletError });
|
|
1640
|
+
handleStructuredError({ skuId, returnUrl, country, validatedEmail, walletError });
|
|
1632
1641
|
}
|
|
1633
1642
|
}
|
|
1634
1643
|
|
|
@@ -100,6 +100,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
100
100
|
url.searchParams.set("inlineError", params.inlineError);
|
|
101
101
|
if (params.email) url.searchParams.set("email", params.email);
|
|
102
102
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
103
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
103
104
|
return url.pathname + url.search;
|
|
104
105
|
};
|
|
105
106
|
|
|
@@ -192,7 +193,8 @@ function redirectToFallbackCheckout(config) {
|
|
|
192
193
|
trackFallbackCheckout(config.skuId);
|
|
193
194
|
window.location.href = redirectToCheckoutFallback({
|
|
194
195
|
skuId: config.skuId,
|
|
195
|
-
inlineError: MSG_PAYMENT_GENERIC_ERROR
|
|
196
|
+
inlineError: MSG_PAYMENT_GENERIC_ERROR,
|
|
197
|
+
country: config.countryCode
|
|
196
198
|
});
|
|
197
199
|
}
|
|
198
200
|
async function handleMerchantValidation(event, session, config) {
|
|
@@ -279,6 +279,8 @@ var redirectToCheckoutComplete = (params) => {
|
|
|
279
279
|
url.searchParams.set("lmo_offer", params.skuId);
|
|
280
280
|
url.searchParams.set("status", params.status);
|
|
281
281
|
url.searchParams.set("redirectToCheckout", "true");
|
|
282
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
283
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
282
284
|
return url.pathname + url.search;
|
|
283
285
|
};
|
|
284
286
|
var redirectToCheckoutFallback = (params) => {
|
|
@@ -289,6 +291,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
289
291
|
url.searchParams.set("inlineError", params.inlineError);
|
|
290
292
|
if (params.email) url.searchParams.set("email", params.email);
|
|
291
293
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
294
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
292
295
|
return url.pathname + url.search;
|
|
293
296
|
};
|
|
294
297
|
|
|
@@ -324,37 +327,43 @@ function validateContacts(event, sessionData, supportedBillingCountries) {
|
|
|
324
327
|
}
|
|
325
328
|
return void 0;
|
|
326
329
|
}
|
|
327
|
-
function redirectFallback(skuId, returnUrl, options) {
|
|
330
|
+
function redirectFallback(skuId, returnUrl, country, options) {
|
|
328
331
|
writeCheckoutRedirect(returnUrl);
|
|
329
332
|
trackFallbackCheckout(skuId);
|
|
330
333
|
window.location.href = redirectToCheckoutFallback({
|
|
331
334
|
skuId,
|
|
335
|
+
country,
|
|
332
336
|
...options
|
|
333
337
|
});
|
|
334
338
|
}
|
|
335
339
|
var ERROR_HANDLERS = {
|
|
336
|
-
EMAIL_COLLISION: ({ skuId, returnUrl, validatedEmail }) => redirectFallback(skuId, returnUrl, {
|
|
340
|
+
EMAIL_COLLISION: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
337
341
|
emailError: MSG_EMAIL_COLLISION,
|
|
338
342
|
email: validatedEmail
|
|
339
343
|
}),
|
|
340
|
-
PAYMENT_DECLINED: ({ skuId, returnUrl }) => (
|
|
344
|
+
PAYMENT_DECLINED: ({ skuId, returnUrl, country }) => (
|
|
341
345
|
// Matches sma-checkout catch-all: always redirect with generic inlineError.
|
|
342
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
346
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
343
347
|
),
|
|
344
|
-
ELIGIBILITY_REJECTED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_ELIGIBILITY }),
|
|
345
|
-
REGISTRATION_FAILED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_REGISTRATION }),
|
|
346
|
-
|
|
348
|
+
ELIGIBILITY_REJECTED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_ELIGIBILITY }),
|
|
349
|
+
REGISTRATION_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_REGISTRATION }),
|
|
350
|
+
ACCOUNT_CREATION_FAILED: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
351
|
+
emailError: MSG_REGISTRATION,
|
|
352
|
+
email: validatedEmail
|
|
353
|
+
}),
|
|
354
|
+
VALIDATION_ERROR: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED }),
|
|
355
|
+
RECAPTCHA_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED })
|
|
347
356
|
};
|
|
348
357
|
function handleStructuredError(ctx) {
|
|
349
358
|
const handler = ERROR_HANDLERS[ctx.walletError.errorType];
|
|
350
359
|
if (handler) {
|
|
351
360
|
handler(ctx);
|
|
352
361
|
} else {
|
|
353
|
-
redirectFallback(ctx.skuId, ctx.returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
362
|
+
redirectFallback(ctx.skuId, ctx.returnUrl, ctx.country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
354
363
|
}
|
|
355
364
|
}
|
|
356
365
|
async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
357
|
-
const { skuId, returnUrl, queryString } = config;
|
|
366
|
+
const { skuId, returnUrl, queryString, country } = config;
|
|
358
367
|
let validatedEmail;
|
|
359
368
|
try {
|
|
360
369
|
validatedEmail = validateContacts(
|
|
@@ -374,13 +383,16 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
374
383
|
});
|
|
375
384
|
trackWalletPaymentSuccess(skuId, result.basketId);
|
|
376
385
|
session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
|
|
386
|
+
const successEmail = sessionData.loggedIn ? sessionData.emailAddress : validatedEmail;
|
|
377
387
|
const userStatus = sessionData.loggedIn ? "lex" : "nex";
|
|
378
388
|
writeCheckoutRedirect(returnUrl);
|
|
379
389
|
window.location.href = redirectToCheckoutComplete({
|
|
380
390
|
basketId: result.basketId,
|
|
381
391
|
status: userStatus,
|
|
382
392
|
skuId: decodeSku(skuId),
|
|
383
|
-
queryString
|
|
393
|
+
queryString,
|
|
394
|
+
email: successEmail,
|
|
395
|
+
country
|
|
384
396
|
});
|
|
385
397
|
} catch (err) {
|
|
386
398
|
if (err instanceof ContactValidationError) {
|
|
@@ -389,17 +401,13 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
389
401
|
}
|
|
390
402
|
console.error("[web-apple-pay] onpaymentauthorized error", { skuId, err });
|
|
391
403
|
const walletError = parseWalletApiError(err);
|
|
392
|
-
console.warn("[web-apple-pay] handlePaymentAuthorized: walletError result", {
|
|
393
|
-
walletError,
|
|
394
|
-
validatedEmail
|
|
395
|
-
});
|
|
396
404
|
trackWalletPaymentFailure(skuId, walletError?.errorType ?? "UNKNOWN");
|
|
397
405
|
failApplePaySession(session);
|
|
398
406
|
if (!walletError) {
|
|
399
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
407
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
400
408
|
return;
|
|
401
409
|
}
|
|
402
|
-
handleStructuredError({ skuId, returnUrl, validatedEmail, walletError });
|
|
410
|
+
handleStructuredError({ skuId, returnUrl, country, validatedEmail, walletError });
|
|
403
411
|
}
|
|
404
412
|
}
|
|
405
413
|
export {
|
|
@@ -104,7 +104,7 @@ export type PurchaseResponse = {
|
|
|
104
104
|
* Structured error body returned by all /v1/wallet/* endpoints on 4xx/5xx.
|
|
105
105
|
*/
|
|
106
106
|
export type WalletApiError = {
|
|
107
|
-
errorType: '
|
|
107
|
+
errorType: 'NOT_FOUND' | 'SERVICE_UNAVAILABLE' | 'INTERNAL_SERVER_ERROR' | 'NOT_IMPLEMENTED' | 'EMAIL_COLLISION' | 'ACCOUNT_CREATION_FAILED' | 'PAYMENT_DECLINED' | 'RECAPTCHA_FAILED' | 'ELIGIBILITY_REJECTED' | 'INVALID_REQUEST' | 'VALIDATION_ERROR' | 'UNAUTHORIZED' | 'BAD_REQUEST' | 'REGISTRATION_FAILED';
|
|
108
108
|
message: string;
|
|
109
109
|
};
|
|
110
110
|
/**
|
package/dist/src/index.js
CHANGED
|
@@ -1245,6 +1245,8 @@ var redirectToCheckoutComplete = (params) => {
|
|
|
1245
1245
|
url.searchParams.set("lmo_offer", params.skuId);
|
|
1246
1246
|
url.searchParams.set("status", params.status);
|
|
1247
1247
|
url.searchParams.set("redirectToCheckout", "true");
|
|
1248
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
1249
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1248
1250
|
return url.pathname + url.search;
|
|
1249
1251
|
};
|
|
1250
1252
|
var redirectToCheckoutFallback = (params) => {
|
|
@@ -1255,6 +1257,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1255
1257
|
url.searchParams.set("inlineError", params.inlineError);
|
|
1256
1258
|
if (params.email) url.searchParams.set("email", params.email);
|
|
1257
1259
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
1260
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
1258
1261
|
return url.pathname + url.search;
|
|
1259
1262
|
};
|
|
1260
1263
|
|
|
@@ -1348,7 +1351,8 @@ function redirectToFallbackCheckout(config) {
|
|
|
1348
1351
|
trackFallbackCheckout(config.skuId);
|
|
1349
1352
|
window.location.href = redirectToCheckoutFallback({
|
|
1350
1353
|
skuId: config.skuId,
|
|
1351
|
-
inlineError: MSG_PAYMENT_GENERIC_ERROR
|
|
1354
|
+
inlineError: MSG_PAYMENT_GENERIC_ERROR,
|
|
1355
|
+
country: config.countryCode
|
|
1352
1356
|
});
|
|
1353
1357
|
}
|
|
1354
1358
|
async function handleMerchantValidation(event, session, config) {
|
|
@@ -1558,37 +1562,43 @@ function validateContacts(event, sessionData, supportedBillingCountries) {
|
|
|
1558
1562
|
}
|
|
1559
1563
|
return void 0;
|
|
1560
1564
|
}
|
|
1561
|
-
function redirectFallback(skuId, returnUrl, options) {
|
|
1565
|
+
function redirectFallback(skuId, returnUrl, country, options) {
|
|
1562
1566
|
writeCheckoutRedirect(returnUrl);
|
|
1563
1567
|
trackFallbackCheckout(skuId);
|
|
1564
1568
|
window.location.href = redirectToCheckoutFallback({
|
|
1565
1569
|
skuId,
|
|
1570
|
+
country,
|
|
1566
1571
|
...options
|
|
1567
1572
|
});
|
|
1568
1573
|
}
|
|
1569
1574
|
var ERROR_HANDLERS = {
|
|
1570
|
-
EMAIL_COLLISION: ({ skuId, returnUrl, validatedEmail }) => redirectFallback(skuId, returnUrl, {
|
|
1575
|
+
EMAIL_COLLISION: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1571
1576
|
emailError: MSG_EMAIL_COLLISION,
|
|
1572
1577
|
email: validatedEmail
|
|
1573
1578
|
}),
|
|
1574
|
-
PAYMENT_DECLINED: ({ skuId, returnUrl }) => (
|
|
1579
|
+
PAYMENT_DECLINED: ({ skuId, returnUrl, country }) => (
|
|
1575
1580
|
// Matches sma-checkout catch-all: always redirect with generic inlineError.
|
|
1576
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1581
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
|
|
1577
1582
|
),
|
|
1578
|
-
ELIGIBILITY_REJECTED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_ELIGIBILITY }),
|
|
1579
|
-
REGISTRATION_FAILED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_REGISTRATION }),
|
|
1580
|
-
|
|
1583
|
+
ELIGIBILITY_REJECTED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_ELIGIBILITY }),
|
|
1584
|
+
REGISTRATION_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_REGISTRATION }),
|
|
1585
|
+
ACCOUNT_CREATION_FAILED: ({ skuId, returnUrl, country, validatedEmail }) => redirectFallback(skuId, returnUrl, country, {
|
|
1586
|
+
emailError: MSG_REGISTRATION,
|
|
1587
|
+
email: validatedEmail
|
|
1588
|
+
}),
|
|
1589
|
+
VALIDATION_ERROR: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED }),
|
|
1590
|
+
RECAPTCHA_FAILED: ({ skuId, returnUrl, country }) => redirectFallback(skuId, returnUrl, country, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED })
|
|
1581
1591
|
};
|
|
1582
1592
|
function handleStructuredError(ctx) {
|
|
1583
1593
|
const handler = ERROR_HANDLERS[ctx.walletError.errorType];
|
|
1584
1594
|
if (handler) {
|
|
1585
1595
|
handler(ctx);
|
|
1586
1596
|
} else {
|
|
1587
|
-
redirectFallback(ctx.skuId, ctx.returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1597
|
+
redirectFallback(ctx.skuId, ctx.returnUrl, ctx.country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1588
1598
|
}
|
|
1589
1599
|
}
|
|
1590
1600
|
async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
1591
|
-
const { skuId, returnUrl, queryString } = config;
|
|
1601
|
+
const { skuId, returnUrl, queryString, country } = config;
|
|
1592
1602
|
let validatedEmail;
|
|
1593
1603
|
try {
|
|
1594
1604
|
validatedEmail = validateContacts(
|
|
@@ -1608,13 +1618,16 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1608
1618
|
});
|
|
1609
1619
|
trackWalletPaymentSuccess(skuId, result.basketId);
|
|
1610
1620
|
session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
|
|
1621
|
+
const successEmail = sessionData.loggedIn ? sessionData.emailAddress : validatedEmail;
|
|
1611
1622
|
const userStatus = sessionData.loggedIn ? "lex" : "nex";
|
|
1612
1623
|
writeCheckoutRedirect(returnUrl);
|
|
1613
1624
|
window.location.href = redirectToCheckoutComplete({
|
|
1614
1625
|
basketId: result.basketId,
|
|
1615
1626
|
status: userStatus,
|
|
1616
1627
|
skuId: decodeSku(skuId),
|
|
1617
|
-
queryString
|
|
1628
|
+
queryString,
|
|
1629
|
+
email: successEmail,
|
|
1630
|
+
country
|
|
1618
1631
|
});
|
|
1619
1632
|
} catch (err) {
|
|
1620
1633
|
if (err instanceof ContactValidationError) {
|
|
@@ -1623,17 +1636,13 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
|
|
|
1623
1636
|
}
|
|
1624
1637
|
console.error("[web-apple-pay] onpaymentauthorized error", { skuId, err });
|
|
1625
1638
|
const walletError = parseWalletApiError(err);
|
|
1626
|
-
console.warn("[web-apple-pay] handlePaymentAuthorized: walletError result", {
|
|
1627
|
-
walletError,
|
|
1628
|
-
validatedEmail
|
|
1629
|
-
});
|
|
1630
1639
|
trackWalletPaymentFailure(skuId, walletError?.errorType ?? "UNKNOWN");
|
|
1631
1640
|
failApplePaySession(session);
|
|
1632
1641
|
if (!walletError) {
|
|
1633
|
-
redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1642
|
+
redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
|
|
1634
1643
|
return;
|
|
1635
1644
|
}
|
|
1636
|
-
handleStructuredError({ skuId, returnUrl, validatedEmail, walletError });
|
|
1645
|
+
handleStructuredError({ skuId, returnUrl, country, validatedEmail, walletError });
|
|
1637
1646
|
}
|
|
1638
1647
|
}
|
|
1639
1648
|
|
|
@@ -43,6 +43,14 @@ export declare const decodeSku: (sku: string) => string;
|
|
|
43
43
|
/**
|
|
44
44
|
* Builds the success redirect URL.
|
|
45
45
|
* /checkout/complete?basketId={id}&lmo_offer={sku}&status={userStatus}&redirectToCheckout=true
|
|
46
|
+
* &email={email}&country={country}
|
|
47
|
+
*
|
|
48
|
+
* `email` — the user's email address (from session for lex users, from Apple Pay
|
|
49
|
+
* shipping contact for nex users). Always appended when non-empty so checkout
|
|
50
|
+
* can pre-fill the account field.
|
|
51
|
+
*
|
|
52
|
+
* `country` — the offer country code forwarded from the payment handler config.
|
|
53
|
+
* Always appended when non-empty to preserve geo-context across the redirect.
|
|
46
54
|
*
|
|
47
55
|
* The origin article URL is written to localStorage by the caller via
|
|
48
56
|
* writeCheckoutRedirect() before this redirect fires.
|
|
@@ -52,15 +60,23 @@ export declare const redirectToCheckoutComplete: (params: {
|
|
|
52
60
|
status: "nex" | "lex";
|
|
53
61
|
skuId: string;
|
|
54
62
|
queryString?: string;
|
|
63
|
+
email?: string;
|
|
64
|
+
country?: string;
|
|
55
65
|
}) => string;
|
|
56
66
|
/**
|
|
57
67
|
* Builds the fallback redirect URL for error scenarios.
|
|
58
|
-
* /checkout?lmo_offer={offerPath}&inlineError
|
|
68
|
+
* /checkout?lmo_offer={offerPath}&inlineError=...&email={email}&country={country}
|
|
59
69
|
*
|
|
60
70
|
* The skuId is decoded via decodeSku() before being set as lmo_offer, producing
|
|
61
71
|
* a Limio offer path (e.g. /offers2/UK-UK.DIGITAL.1YAR.X.DISC.30.NYT) as
|
|
62
72
|
* checkout expects. If decoding fails (malformed SKU), the raw skuId is used.
|
|
63
73
|
*
|
|
74
|
+
* `email` — always appended when non-empty so checkout can pre-fill the email
|
|
75
|
+
* field on the fallback page (e.g. for EMAIL_COLLISION flows).
|
|
76
|
+
*
|
|
77
|
+
* `country` — the offer country code, always appended when non-empty to preserve
|
|
78
|
+
* geo-context across the redirect.
|
|
79
|
+
*
|
|
64
80
|
* Builds on top of the current page URL (window.location.href) so that any
|
|
65
81
|
* existing query params (UTM tags, campaign flags) are preserved — matching
|
|
66
82
|
* sma-checkout: src/lib/navigate-to-checkout/index.tsx
|
|
@@ -73,4 +89,5 @@ export declare const redirectToCheckoutFallback: (params: {
|
|
|
73
89
|
inlineError?: string;
|
|
74
90
|
emailError?: string;
|
|
75
91
|
email?: string;
|
|
92
|
+
country?: string;
|
|
76
93
|
}) => string;
|
|
@@ -39,6 +39,8 @@ var redirectToCheckoutComplete = (params) => {
|
|
|
39
39
|
url.searchParams.set("lmo_offer", params.skuId);
|
|
40
40
|
url.searchParams.set("status", params.status);
|
|
41
41
|
url.searchParams.set("redirectToCheckout", "true");
|
|
42
|
+
if (params.email) url.searchParams.set("email", params.email);
|
|
43
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
42
44
|
return url.pathname + url.search;
|
|
43
45
|
};
|
|
44
46
|
var redirectToCheckoutFallback = (params) => {
|
|
@@ -49,6 +51,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
49
51
|
url.searchParams.set("inlineError", params.inlineError);
|
|
50
52
|
if (params.email) url.searchParams.set("email", params.email);
|
|
51
53
|
if (params.emailError) url.searchParams.set("emailError", params.emailError);
|
|
54
|
+
if (params.country) url.searchParams.set("country", params.country);
|
|
52
55
|
return url.pathname + url.search;
|
|
53
56
|
};
|
|
54
57
|
export {
|
package/package.json
CHANGED