From 335ce15b22c2a7d91d9444214adc1388416e7c54 Mon Sep 17 00:00:00 2001 From: Brendan Ryan Date: Tue, 14 Apr 2026 20:09:03 -0700 Subject: [PATCH 1/3] fix: respect html text overrides --- .changeset/fix-html-text-overrides.md | 5 +++++ src/server/Transport.test.ts | 20 ++++++++++++++++++++ src/server/internal/html/config.ts | 10 +++++++++- src/tempo/server/internal/html/main.ts | 3 ++- test/html/server.ts | 24 ++++++++++++++++++++++++ test/html/tempo.test.ts | 8 ++++++++ 6 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 .changeset/fix-html-text-overrides.md diff --git a/.changeset/fix-html-text-overrides.md b/.changeset/fix-html-text-overrides.md new file mode 100644 index 00000000..3fd9ccc3 --- /dev/null +++ b/.changeset/fix-html-text-overrides.md @@ -0,0 +1,5 @@ +--- +'mppx': patch +--- + +Fix Tempo HTML pay button text overrides and make the HTML page title follow a custom `paymentRequired` label when `title` is omitted. diff --git a/src/server/Transport.test.ts b/src/server/Transport.test.ts index 2a231e67..a8f6ce55 100644 --- a/src/server/Transport.test.ts +++ b/src/server/Transport.test.ts @@ -269,6 +269,26 @@ describe('http', () => { expect(body).toContain('Gotta Pay') }) + test('uses paymentRequired as the title when title is omitted', async () => { + const transport = Transport.http() + const request = new Request('https://example.com', { + headers: { Accept: 'text/html' }, + }) + + const response = await transport.respondChallenge({ + challenge, + input: request, + html: { + ...htmlOptions, + text: { paymentRequired: 'Gotta Pay' }, + }, + }) + + const body = await response.text() + expect(body).toContain('Gotta Pay') + expect(body).toContain('Gotta Pay') + }) + test('applies custom theme logo', async () => { const transport = Transport.http() const request = new Request('https://example.com', { diff --git a/src/server/internal/html/config.ts b/src/server/internal/html/config.ts index 365f55d3..89a9cd02 100644 --- a/src/server/internal/html/config.ts +++ b/src/server/internal/html/config.ts @@ -172,7 +172,15 @@ export function resolveOptions(options: Options): { }, (options.theme as never) ?? {}, ) - const text = sanitizeRecord(mergeDefined(defaultText, (options.text as never) ?? {})) + const textOverrides = (options.text as Text | undefined) ?? undefined + const mergedText = mergeDefined(defaultText, (textOverrides as never) ?? {}) + const text = sanitizeRecord({ + ...mergedText, + title: + typeof textOverrides?.title === 'string' && textOverrides.title.length > 0 + ? mergedText.title + : mergedText.paymentRequired, + }) return { theme, text } } diff --git a/src/tempo/server/internal/html/main.ts b/src/tempo/server/internal/html/main.ts index e305d27e..9fd5f3d6 100644 --- a/src/tempo/server/internal/html/main.ts +++ b/src/tempo/server/internal/html/main.ts @@ -73,8 +73,9 @@ const provider = Provider.create({ }) const button = document.createElement('button') +const buttonLabel = c.text.pay === 'Pay' ? 'Continue with' : c.text.pay button.innerHTML = - 'Continue with ' + `${buttonLabel} ` button.onclick = async () => { try { c.error() diff --git a/test/html/server.ts b/test/html/server.ts index 2483ef5b..0500fb9b 100644 --- a/test/html/server.ts +++ b/test/html/server.ts @@ -41,6 +41,19 @@ export async function startServer(port: number): Promise { ], secretKey: 'test-html-server-secret-key', }) + const tempoCustomTextMppx = Mppx.create({ + methods: [ + tempo.charge({ + account, + currency: '0x20c0000000000000000000000000000000000000', + feePayer: true, + html: { text: { pay: 'Buy Now' } }, + recipient: account.address, + testnet: true, + }), + ], + secretKey: 'test-html-server-secret-key', + }) const stripeMppx = stripeEnabled ? Mppx.create({ methods: [ @@ -81,6 +94,17 @@ export async function startServer(port: number): Promise { return result.withReceipt(Response.json({ url: 'https://example.com/photo.jpg' })) } + if (url.pathname === '/tempo/charge-custom-text') { + const result = await tempoCustomTextMppx.tempo.charge({ + amount: '0.01', + description: 'Random stock photo', + })(request) + + if (result.status === 402) return result.challenge + + return result.withReceipt(Response.json({ url: 'https://example.com/photo.jpg' })) + } + if (url.pathname === '/stripe/charge') { if (!stripeMppx) return new Response('Not Found', { status: 404 }) diff --git a/test/html/tempo.test.ts b/test/html/tempo.test.ts index b9f03bfa..d840f8d1 100644 --- a/test/html/tempo.test.ts +++ b/test/html/tempo.test.ts @@ -17,6 +17,14 @@ test('charge via tempo html payment page', async ({ page }) => { await expect(page.locator('body')).toContainText('"url":', { timeout: 30_000 }) }) +test('charge via tempo html payment page respects custom pay text', async ({ page }) => { + await page.goto('/tempo/charge-custom-text', { + waitUntil: 'domcontentloaded', + }) + + await expect(page.getByRole('button', { name: /buy now tempo/i })).toBeVisible() +}) + test('service worker endpoint returns javascript', async ({ page }) => { const response = await page.goto('/tempo/charge?__mppx_worker') expect(response?.headers()['content-type']).toContain('application/javascript') From ea0fafc6c2e768cace52c2bd1b6859dae1235e74 Mon Sep 17 00:00:00 2001 From: Brendan Ryan Date: Tue, 14 Apr 2026 20:20:35 -0700 Subject: [PATCH 2/3] style: format tempo html button markup --- src/tempo/server/internal/html/main.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tempo/server/internal/html/main.ts b/src/tempo/server/internal/html/main.ts index 9fd5f3d6..148cb623 100644 --- a/src/tempo/server/internal/html/main.ts +++ b/src/tempo/server/internal/html/main.ts @@ -74,8 +74,7 @@ const provider = Provider.create({ const button = document.createElement('button') const buttonLabel = c.text.pay === 'Pay' ? 'Continue with' : c.text.pay -button.innerHTML = - `${buttonLabel} ` +button.innerHTML = `${buttonLabel} ` button.onclick = async () => { try { c.error() From 11d28fb4fb06386a3af12f53babd8a6262a5f528 Mon Sep 17 00:00:00 2001 From: Brendan Ryan Date: Tue, 14 Apr 2026 20:40:50 -0700 Subject: [PATCH 3/3] Update .changeset/fix-html-text-overrides.md Co-authored-by: tmm --- .changeset/fix-html-text-overrides.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fix-html-text-overrides.md b/.changeset/fix-html-text-overrides.md index 3fd9ccc3..dd5da1f3 100644 --- a/.changeset/fix-html-text-overrides.md +++ b/.changeset/fix-html-text-overrides.md @@ -2,4 +2,4 @@ 'mppx': patch --- -Fix Tempo HTML pay button text overrides and make the HTML page title follow a custom `paymentRequired` label when `title` is omitted. +Fixed Tempo HTML pay button text overrides and make the HTML page title follow a custom `paymentRequired` label when `title` is omitted.