fix(payment): restore wallet order and English labels

This commit is contained in:
Codex
2026-07-29 15:22:43 +08:00
parent ce3f0af82d
commit ee6ab77f4d
2 changed files with 48 additions and 18 deletions
@@ -63,7 +63,7 @@ describe("StripePaymentDialog", () => {
document.body.style.overflow = ""; document.body.style.overflow = "";
}); });
it("renders Express Checkout first and a collapsed Pay by card section last", () => { it("renders express methods and wallets before card with English Stripe copy", () => {
act(() => act(() =>
root.render( root.render(
<StripePaymentDialog <StripePaymentDialog
@@ -78,19 +78,18 @@ describe("StripePaymentDialog", () => {
expect(capturedElementsOptions).toMatchObject({ expect(capturedElementsOptions).toMatchObject({
clientSecret: "pi_123_secret_payment", clientSecret: "pi_123_secret_payment",
customerSessionClientSecret: "cuss_123_secret_saved", customerSessionClientSecret: "cuss_123_secret_saved",
locale: "en",
}); });
expect(capturedExpressProps?.options).toMatchObject({ expect(capturedExpressProps?.options).toMatchObject({
paymentMethodOrder: [ paymentMethodOrder: [
"apple_pay",
"google_pay",
"link", "link",
"paypal", "paypal",
"amazon_pay", "amazon_pay",
"klarna", "klarna",
], ],
paymentMethods: { paymentMethods: {
applePay: "always", applePay: "never",
googlePay: "always", googlePay: "never",
link: "auto", link: "auto",
paypal: "auto", paypal: "auto",
amazonPay: "auto", amazonPay: "auto",
@@ -99,11 +98,11 @@ describe("StripePaymentDialog", () => {
}); });
expect(capturedPaymentProps?.options).toMatchObject({ expect(capturedPaymentProps?.options).toMatchObject({
layout: { type: "accordion", defaultCollapsed: true }, layout: { type: "accordion", defaultCollapsed: true },
paymentMethodOrder: ["card"], paymentMethodOrder: ["wechat_pay", "alipay", "card"],
wallets: { applePay: "never", googlePay: "never", link: "never" }, wallets: { applePay: "auto", googlePay: "auto", link: "never" },
}); });
const text = document.body.textContent ?? ""; const text = document.body.textContent ?? "";
expect(text).toContain("Pay by card"); expect(text).toContain("Choose a payment method");
const express = document.body.querySelector('[data-testid="express-checkout"]'); const express = document.body.querySelector('[data-testid="express-checkout"]');
const card = document.body.querySelector('[data-testid="payment-element"]'); const card = document.body.querySelector('[data-testid="payment-element"]');
expect(express).not.toBeNull(); expect(express).not.toBeNull();
@@ -114,6 +113,35 @@ describe("StripePaymentDialog", () => {
).toBeTruthy(); ).toBeTruthy();
}); });
it("keeps Payment Element wallet fallbacks when Express Checkout is unavailable", () => {
act(() =>
root.render(
<StripePaymentDialog
clientSecret="pi_123_secret_payment"
onClose={vi.fn()}
/>,
),
);
const onReady = capturedExpressProps?.onReady as
| ((event: { availablePaymentMethods: undefined }) => void)
| undefined;
expect(onReady).toBeTypeOf("function");
act(() => onReady?.({ availablePaymentMethods: undefined }));
const expressSection = document.body.querySelector(
'[aria-label="Express payment methods"]',
);
expect(expressSection).toHaveProperty("hidden", true);
expect(
document.body.querySelector('[data-testid="payment-element"]'),
).not.toBeNull();
expect(capturedPaymentProps?.options).toMatchObject({
wallets: { applePay: "auto", googlePay: "auto", link: "never" },
paymentMethodOrder: ["wechat_pay", "alipay", "card"],
});
});
it("does not pass an invalid or disabled Customer Session secret", () => { it("does not pass an invalid or disabled Customer Session secret", () => {
act(() => act(() =>
root.render( root.render(
@@ -124,6 +124,7 @@ export function StripePaymentDialog({
stripe={stripePromise} stripe={stripePromise}
options={{ options={{
clientSecret, clientSecret,
locale: "en",
...(savedCardClientSecret ...(savedCardClientSecret
? { customerSessionClientSecret: savedCardClientSecret } ? { customerSessionClientSecret: savedCardClientSecret }
: {}), : {}),
@@ -325,16 +326,14 @@ function StripePaymentForm({
<ExpressCheckoutElement <ExpressCheckoutElement
options={{ options={{
paymentMethodOrder: [ paymentMethodOrder: [
"apple_pay",
"google_pay",
"link", "link",
"paypal", "paypal",
"amazon_pay", "amazon_pay",
"klarna", "klarna",
], ],
paymentMethods: { paymentMethods: {
applePay: "always", applePay: "never",
googlePay: "always", googlePay: "never",
link: "auto", link: "auto",
paypal: "auto", paypal: "auto",
amazonPay: "auto", amazonPay: "auto",
@@ -361,17 +360,20 @@ function StripePaymentForm({
} }
/> />
</section> </section>
<section className={styles.cardSection} aria-labelledby="pay-by-card-title"> <section
<h3 id="pay-by-card-title" className={styles.cardTitle}> className={styles.cardSection}
Pay by card aria-labelledby="payment-method-title"
>
<h3 id="payment-method-title" className={styles.cardTitle}>
Choose a payment method
</h3> </h3>
<PaymentElement <PaymentElement
options={{ options={{
layout: { type: "accordion", defaultCollapsed: true }, layout: { type: "accordion", defaultCollapsed: true },
paymentMethodOrder: ["card"], paymentMethodOrder: ["wechat_pay", "alipay", "card"],
wallets: { wallets: {
applePay: "never", applePay: "auto",
googlePay: "never", googlePay: "auto",
link: "never", link: "never",
}, },
}} }}