Skip to content

test: add merchant checkout e2e; fix: drop Solana memo requirement#46

Merged
akbarsaputrait merged 5 commits into
masterfrom
feat/merchant-e2e-and-solana-memo
Jul 8, 2026
Merged

test: add merchant checkout e2e; fix: drop Solana memo requirement#46
akbarsaputrait merged 5 commits into
masterfrom
feat/merchant-e2e-and-solana-memo

Conversation

@akbarsaputrait

@akbarsaputrait akbarsaputrait commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

Adds end-to-end tests for merchant checkout payments and removes the memo requirement from Solana payment flows. Merchant payments create a payId server-side (destination fixed by merchant config), so the tests only vary the source wallet and reuse the existing checkout pay-in helpers. Separately, Solana transactions no longer carry a memo, so memo handling is stripped from the three places it was still applied.

Changes Made

Merchant e2e (test)

  • Added startMerchantCheckout() helper — POSTs to /payment-api/payments/merchant, feeds the returned id into the checkout page's manual-payId input, opens the modal. In-modal pay-in steps stay identical to Checkout.
  • Added E2E.merchant config (appId gate, api url, amount_local/currency_local), all env-overridable.
  • Added three source-only specs: merchant/{evm,solana,stellar}.spec.ts. Destination is server-fixed, so the 6-way source×dest matrix collapses to 3.
  • Registered merchant-{evm,solana,stellar} Playwright projects (chained into the sequential real-funds run before the deposit projects) and matching test:e2e:merchant-* scripts.
  • Documented the merchant env vars in .env.e2e.example.

Solana memo removal (fix)

  • PayWithSolanaToken: dropped memo from the built paymentData.
  • usePaymentState: dropped memo from generateSolanaDeepLink for deposit addresses.
  • WaitingDepositAddress: excluded SOLANA/SOLANA_USDT/SOLANA_USDC from the shouldShowMemo check (previously only BSC was excluded).
  • Stellar, BSC, and other-chain memo handling untouched.

Chore

  • Tightened .codegraph/.gitignore to ignore all local codegraph data.
  • Refreshed pnpm-lock.yaml and bundle-analysis.html (build artifacts).

How to Test

Merchant e2e (real funds, mainnet — opt-in):

  1. cp examples/nextjs-app/.env.e2e.example .env.e2e, fill in E2E_MERCHANT_APP_ID (e.g. pos_rozostudio) plus the source wallet secret for the path you want.
  2. pnpm setup-wallets (EVM/Solana paths only).
  3. Terminal A: cd examples/nextjs-app && pnpm dev.
  4. Terminal B: pnpm test:e2e:merchant-evm (or -solana / -stellar).
  5. Verify the run creates a merchant payId, pays it from the chosen source, and reaches Payment Completed.
  6. Without E2E_MERCHANT_APP_ID, confirm the merchant specs skip rather than fail.

Solana memo (manual):

  1. Run a Solana payment / deposit-address flow.
  2. Verify no memo field is generated in the deep link or shown in the deposit-address UI.
  3. Confirm Stellar/BSC deposit flows still show their memo.

Typecheck: cd examples/nextjs-app && pnpm typecheck (passes, exit 0). All three merchant projects list via playwright test --list.

Testing Checklist

  • E2E specs added (merchant EVM/Solana/Stellar)
  • Typecheck passes
  • Merchant specs skip cleanly when env unset
  • Manual real-funds run per source (reviewer, opt-in)
  • Manual Solana memo verification

Reviewer Notes

  • The merchant POST sends source: {chainId:"8453", tokenSymbol:"USDC"} as the initial hint for all three specs (matching the reference cURL). When the user picks a different source token in-modal, the SDK reconciles the actual pay-in chain via the /checkout API — so a Solana/Stellar pay-in over a Base-hinted order is handled correctly and needs no per-spec source override.
  • Merchant specs are real-funds and gated behind E2E_MERCHANT_APP_ID + the matching wallet secret, so CI's mocked project never touches them.
  • pnpm-lock.yaml / bundle-analysis.html are generated churn from a local connectkit rebuild — no intentional dependency change.

Solana transactions no longer require a memo field. Removed memo handling
from three locations:

- PayWithSolanaToken: drop memo from the built paymentData
- usePaymentState: drop memo from generateSolanaDeepLink for deposit addresses
- WaitingDepositAddress: exclude SOLANA/SOLANA_USDT/SOLANA_USDC from the
  shouldShowMemo check (previously only BSC was excluded)

Stellar, BSC, and other chain memo handling is untouched.
Merchant payments create a payId server-side via /payment-api/payments/merchant,
where the destination (chain/token/receiver) is fixed by the merchant config.
Tests only vary the source wallet, so this adds three source-only specs
(EVM/Solana/Stellar) that reuse the existing checkout pay-in helpers.

- helpers: add startMerchantCheckout() — POSTs the merchant order, feeds the
  returned id into the checkout page's manual payId input, opens the modal
- env: add E2E.merchant config (appId gate, api url, amount_local/currency_local)
- specs: merchant/{evm,solana,stellar}.spec.ts, skipped unless E2E_MERCHANT_APP_ID
  and the matching source wallet secret are set
- playwright.config + package.json: register merchant-{evm,solana,stellar} projects
- .env.e2e.example: document merchant vars
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
intent-example Ready Ready Preview, Comment Jul 8, 2026 4:02am

Request Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26f52027e1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/connectkit/src/components/Pages/WaitingDepositAddress/index.tsx Outdated
…eporting in e2e tests

- Updated playwright-core dependency from 1.60.0 to 1.61.1 in pnpm-lock.yaml and pnpm-workspace.yaml.
- Added reportPayment function to helpers.ts for capturing payment summaries in Playwright reports.
- Integrated reportPayment in merchant payment flow tests for EVM, Solana, and Stellar to ensure payId is reported after each test.

@shawnmuggle shawnmuggle left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: LGTM ✅ (2-pass local review — Claude deep review + codex second opinion)

Verdict: no P0, no P1. Approving. 3 × P2 (non-blocking, follow-up).

Solana memo removal — verified safe (not a P0)

codex's second pass flagged 2 × P0 (PayWithSolanaToken, usePaymentState dropping memo → "memo-routed Solana orders become uncredited"). I traced the actual code and both P0s rest on the assumption that the backend reconciles Solana pay-ins by memo — which the code contradicts:

  • Solana pay-in transfers to hydratedOrder.intentAddr / order.intentAddr — a per-order unique deposit address. Reconciliation is by unique address + the explicit txHash+paymentId report to the backend (setPaymentCompleted / PAYMENT_SUBMITTED), not by on-chain memo.
  • The old memo was only an optional Object.assign when hydratedOrder.memo was set; it never determined the destination or amount.
  • The diff correctly keeps memo for Stellar only (Only Stellar needs a memo (destination tag)), because Stellar uses a shared address + memo to disambiguate orders. Solana uses unique addresses, so memo is redundant. This asymmetry is exactly right.

So the memo removal is the intended product change and is safe on the client side.

P2 (non-blocking follow-ups)

  1. WaitingDepositAddress null-option (underpaid-recovery) branch still builds the Solana deep link with memo and sets depAddr.memo — the new shouldShowMemo filter only covers the selected-option branch (as codex-bot noted inline). Technically inconsistent but harmless: that branch also uses the unique order.intentAddr. Worth a cleanup pass for full consistency.
  2. Merchant Solana/Stellar E2E send source: {chainId:"8453", tokenSymbol:"USDC"} (Base hint) but pay from Solana/Stellar, relying on the SDK to reconcile the real pay-in chain via /checkout. This matches your Reviewer Notes and is a valid test-design choice — but consider asserting the actual pay-in chain mid-test so a silent mis-route (Base pay-in over a Base-hinted merchant order) can't pass as green.
  3. Backend confirmation: a pure client-side diff can't prove the Solana indexer never reads memo. Recommend a one-line confirmation from the backend side before merge that Solana settlement is unique-address-based.

Verified clean

  • reportPayment() only attaches payId/route/status/project — no wallet secrets in Playwright annotations/attachments.
  • startMerchantCheckout(): solid error handling (res.ok check, missing-payId throw) and a real race-condition guard (waits for "Pay with Stellar" to prove the order hydrated).
  • Merchant test:e2e:merchant-* scripts use --no-deps, so they don't cascade the real-funds dependency chain; all real-funds projects are test.skip-gated on the wallet secret, so mocked CI never touches them.
  • .env.e2e.example / env.ts contain placeholders only, no committed secrets.

Nice, well-scoped PR — clear commit split, honest Reviewer Notes, and the Stellar-vs-Solana memo asymmetry is handled correctly.

@akbarsaputrait akbarsaputrait merged commit be26b6a into master Jul 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants