Skip to content

temp(paykit): workaround for stripe SDK checkout/payment_intent ID in… - #430

Merged
redeyecz merged 3 commits into
masterfrom
feat/paykit_sdk_update_4
Jun 4, 2026
Merged

temp(paykit): workaround for stripe SDK checkout/payment_intent ID in…#430
redeyecz merged 3 commits into
masterfrom
feat/paykit_sdk_update_4

Conversation

@redeyecz

@redeyecz redeyecz commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

…consistency

Summary by CodeRabbit

  • New Features

    • Improved Stripe Checkout Session integration with enhanced payment status retrieval, more reliable capture and refund operations, and better session cancellation handling.
  • Tests

    • Added comprehensive unit tests for Stripe Checkout Session workflows, covering payment status checks, capture operations, refunds, and session expiration.

@semanticdiff-com

semanticdiff-com Bot commented Jun 4, 2026

Copy link
Copy Markdown

@vercel

vercel Bot commented Jun 4, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
new-engine-ui-storybook Ready Ready Preview, Comment Jun 4, 2026 6:13pm

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@redeyecz, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 33 minutes and 54 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a695bee7-2b52-41db-ba4b-ca3e82ef8deb

📥 Commits

Reviewing files that changed from the base of the PR and between b74023f and 5fe1a45.

📒 Files selected for processing (2)
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts

Walkthrough

This PR extends the PayKit Stripe payment provider to reliably handle Stripe Checkout Session IDs across payment operations. It introduces checkout-session type definitions, refactors the runtime client factory to preserve the provider instance, and implements comprehensive session-aware helpers for status mapping, customer extraction, and payment operations.

Changes

Stripe Checkout Session Support

Layer / File(s) Summary
Type definitions and runtime client factory
apps/medusa-be/src/modules/payment-paykit/types/index.ts, apps/medusa-be/src/modules/payment-paykit/runtime.ts
PaykitPayment now includes payment_intent_id, PaykitPaymentClient exposes stripeCheckoutSessions with retrieve() and expire() methods, and new Stripe types PaykitStripeCheckoutSession and PaykitStripePaymentIntent define session and intent shapes. createPaykitClientWithProvider refactored to bundle both client and provider instance in CreatedPaykitClient.
Checkout session support infrastructure
apps/medusa-be/src/modules/payment-paykit/services/stripe.ts (helpers section)
Helper utilities extract Stripe customer objects from checkout sessions and payment intents, derive PaymentIntent IDs, map Stripe statuses to Paykit session statuses, convert checkout sessions to PaykitPayment objects with amount/currency selection, and wrap the client to intercept payments.retrieve() for checkout session IDs.
Stripe payment operations
apps/medusa-be/src/modules/payment-paykit/services/stripe.ts (operations section)
capturePayment, refundPayment, and cancelPayment/deletePayment reimplemented to resolve correct Stripe operation PaymentIntent IDs from either checkout sessions or direct payment references, normalise amounts with currency awareness, and preserve both provider and operation IDs in returned data. Checkout sessions are expired directly when supported.
Checkout session unit tests
apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts, apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
Test helper mocks stripeCheckoutSessions capability. New unit tests verify getPaymentStatus retrieves checkout sessions with expanded payment_intent, map session/payment-intent states correctly, capturePayment resolves and uses payment_intent_id, refundPayment preserves session IDs whilst creating refunds via intent, and cancelPayment expires checkout sessions via dedicated path.

Sequence Diagrams

sequenceDiagram
  participant PaykitStripePaymentProvider
  participant withStripeCheckoutSessionRetrieve
  participant stripeCheckoutSessions
  participant StripePaymentsAPI
  
  PaykitStripePaymentProvider->>withStripeCheckoutSessionRetrieve: payments.retrieve(cs_id)
  withStripeCheckoutSessionRetrieve->>stripeCheckoutSessions: retrieve(cs_id, expand: payment_intent)
  stripeCheckoutSessions->>StripePaymentsAPI: checkout_sessions.retrieve(cs_id)
  StripePaymentsAPI-->>stripeCheckoutSessions: session with payment_intent expanded
  stripeCheckoutSessions-->>withStripeCheckoutSessionRetrieve: PaykitStripeCheckoutSession
  withStripeCheckoutSessionRetrieve->>withStripeCheckoutSessionRetrieve: toPaykitPaymentFromStripeCheckoutSession
  withStripeCheckoutSessionRetrieve-->>PaykitStripePaymentProvider: PaykitPayment
Loading
flowchart TD
  getOpId["getStripeOperationPaymentId(id, data)"]
  isCS{"id is checkout session ID?"}
  retrieve["retrieve session with payment_intent"]
  extract["extract payment_intent.id"]
  fallback["use id as PaymentIntent ID"]
  return["return operation PaymentIntent ID"]
  
  getOpId --> isCS
  isCS -->|yes| retrieve
  isCS -->|no| fallback
  retrieve --> extract
  extract --> return
  fallback --> return
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • TechsioCZ/new-engine#428: Modifies shared payment-paykit module runtime and type definitions around client construction and typing; this PR's checkout-session additions build upon the same runtime/type refactoring paths.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is partially related to the changeset. It references the main objective (a Stripe SDK workaround), but is incomplete and truncated—the full intent is cut off, making it unclear for readers scanning commit history. Complete the title by appending the full message (e.g., 'temp(paykit): workaround for stripe SDK checkout/payment_intent ID inconsistency') to clearly convey the changeset purpose.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/paykit_sdk_update_4
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/paykit_sdk_update_4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 4, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a workaround for a PayKit Stripe SDK inconsistency where createPayment returns a Checkout Session ID (cs_...) but retrievePayment and other operations don't accept those IDs. The fix intercepts all payment operations, detects cs_ prefixed IDs, and routes them through the raw Stripe Checkout Session API via provider._native.checkout.sessions.

  • Client wrapping: withStripeCheckoutSessionRetrieve wraps payments.retrieve to fall back to the Checkout Session API for cs_ IDs; requireStripeCheckoutSessionRetriever drills into the provider's internal _native Stripe SDK instance to expose checkout.sessions.
  • Operation routing: getStripeOperationPaymentId resolves a cs_ ID to its underlying PaymentIntent ID before capture, refund, or cancel; cancelOrExpireCheckoutSessionPayment adds status-aware branching that avoids calling expire on already-complete or expired sessions.
  • Tests: Comprehensive unit tests cover retrieval fallback, status mapping, capture/refund via PaymentIntent ID, and all cancel/expire branches.

Confidence Score: 4/5

Safe to merge as a workaround; the checkout-session cancel branching correctly avoids the previously broken expire-on-complete behavior, and all new paths are covered by unit tests.

The new cancelOrExpireCheckoutSessionPayment logic is correct and well-tested. The duplicated isRecord/isPaymentAmount and the plain Error throw are non-blocking style issues that do not affect correctness on the changed paths.

apps/medusa-be/src/modules/payment-paykit/services/stripe.ts — the duplicated utility functions and plain Error throw are worth a second look.

Important Files Changed

Filename Overview
apps/medusa-be/src/modules/payment-paykit/services/stripe.ts Core of the PR — adds ~300 lines of checkout session routing logic; the cs_ cancel/expire branching is correct and addresses previous issues, but isRecord/isPaymentAmount are re-defined here despite identical copies in base.ts, and requireStripeCheckoutSessionRetriever throws a plain Error rather than MedusaError.
apps/medusa-be/src/modules/payment-paykit/runtime.ts Refactors createPaykitClient to also return the raw provider via the new createPaykitClientWithProvider export; change is clean and backward-compatible.
apps/medusa-be/src/modules/payment-paykit/types/index.ts Adds payment_intent_id to PaykitPayment, stripeCheckoutSessions to PaykitPaymentClient, and new PaykitStripeCheckoutSession/PaykitStripePaymentIntent types — all well-typed and consistent with usage in stripe.ts.
apps/medusa-be/src/modules/payment-paykit/tests/stripe.unit.spec.ts Adds thorough tests for all new code paths: retrieval fallback, status mapping from PI vs session, capture/refund with PI ID, and all cancel/expire branches.
apps/medusa-be/src/modules/payment-paykit/tests/helpers.ts One-line addition wiring stripeCheckoutSessions override into the mock client factory — correct and minimal.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[cancelPayment / deletePayment] --> B[cancelOrExpirePayment]
    B --> C{Is cs_ ID AND stripeCheckoutSessions?}
    C -- No --> D[getStripeOperationPaymentId]
    D --> E[client.payments.cancel]
    C -- Yes --> F[cancelOrExpireCheckoutSessionPayment]
    F --> G[stripeCheckoutSessions.retrieve]
    G --> H{session found?}
    H -- No --> I[return undefined, fall through]
    I --> D
    H -- Yes --> J{session.status === open?}
    J -- Yes --> K{expire available?}
    K -- Yes --> L[stripeCheckoutSessions.expire]
    L --> M[return expired session data]
    K -- No --> N[return data unchanged]
    J -- No --> O[map session to PaykitPayment]
    O --> P{status === requires_capture?}
    P -- Yes --> Q[client.payments.cancel with PI id]
    Q --> R[return canceled PI data preserving cs_ id]
    P -- No --> S[return current session state]
    S --> T[may include status: succeeded for paid sessions]
Loading

Fix All in Codex

Reviews (3): Last reviewed commit: "temp(paykit): added regression tests" | Re-trigger Greptile

Comment thread apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
Comment thread apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
Comment thread apps/medusa-be/src/modules/payment-paykit/services/stripe.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/medusa-be/src/modules/payment-paykit/services/stripe.ts`:
- Around line 214-243: withStripeCheckoutSessionRetrieve: wrap the call to
client.payments.retrieve(id) in a try/catch and, when the id matches
isStripeCheckoutSessionId(id) and the Stripe SDK throws the "wrong_resource" /
wrong-resource-type error (use the error shape from `@paykit-sdk/stripe`), fall
back to client.stripeCheckoutSessions.retrieve(id) as currently done;
cancelOrExpirePayment: before calling
stripeCheckoutSessions.expire(providerPaymentId) (in cancelOrExpirePayment),
retrieve the session state and only call expire when the session is in an
expirable state (e.g., "open"); add tests for non-open/cancelled/paid sessions
to ensure no expire is attempted. getCaptureAmount/getExplicitCaptureAmount:
replace blind casts from Reflect.get(...) / input.data?.amount with runtime
numeric validation similar to the base provider's isPaymentAmount check
(validate type and range) before normalising and returning the amount.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 12387b11-b79c-446e-8d73-c2e28e7e77fa

📥 Commits

Reviewing files that changed from the base of the PR and between c078178 and b74023f.

📒 Files selected for processing (5)
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Greptile Review
  • GitHub Check: main
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (9)
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Module directories use hyphens (my-module/), but module keys in config use underscores (my_module)

Files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
apps/medusa-be/src/{api,modules,workflows,admin,subscribers,jobs}/**

📄 CodeRabbit inference engine (AGENTS.md)

In Medusa backend applications, organize custom code using the directory structure: api/, modules/, workflows/, admin/, subscribers/, jobs/

Files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Run npx tsc --noEmit for typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable per const/let statement, not multiple on one line
Use nullish coalescing operator (??) instead of logical OR (||) for default values
Do not use non-null assertions (!); use type guards or validation instead
Annotate type as unknown when accessing dynamic object properties before applying type guards
Use comments only to explain 'why', never 'what'; self-document code with clear naming
Extract pure functions to separate files for testability without runtime dependencies
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding module/key strings
Do not use non-null assertions in TypeScript code; validate or use type guards instead
Validate data before type casting; never use as Type without prior validation

Files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Run bunx biome check --write . to lint and auto-format code

Files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
apps/medusa-be/src/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/**/*.ts: Use const and explicit typing with dbService.sqlRaw<Type>() for SQL query results
Resolve logger using container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query using container.resolve<Query>(ContainerRegistrationKeys.QUERY)
Use Modules.LOCKING (not Modules.LOCK) to resolve locking services
Use Modules.CACHING (not Modules.CACHE) to resolve caching services
Throw MedusaError with appropriate type and message for error responses
Use MedusaError.Types.INVALID_DATA for 400 validation errors
Use MedusaError.Types.NOT_FOUND for 404 errors
Use MedusaError.Types.UNAUTHORIZED for 401 authentication errors
Use MedusaError.Types.NOT_ALLOWED for 400 permission errors
Use MedusaError.Types.DUPLICATE_ERROR for 422 duplicate entry errors
Use MedusaError.Types.CONFLICT for 409 conflict errors
Use caching module's computeKey() to generate stable cache keys from filters and pagination
Use caching module's get() with type assertion for cache retrieval
Use caching module's set() with TTL and tags for cache storage and bulk invalidation
Use caching module's clear() with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations using CHUNK_SIZE constant instead of unbounded loops

Files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Modules use isolated containers; Query/Link unavailable during service initialization, defer to onApplicationStart

Files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for running tests in backend and UI library projects

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
apps/medusa-be/src/modules/*/__tests__/*.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/*/__tests__/*.spec.ts: Use moduleIntegrationTestRunner() for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests using vi.mock() to prevent actual initialization during testing
Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
🧠 Learnings (18)
📚 Learning: 2026-04-29T15:44:04.609Z
Learnt from: KaiUweCZE
Repo: TechsioCZ/new-engine PR: 378
File: libs/storefront-data/package.json:285-286
Timestamp: 2026-04-29T15:44:04.609Z
Learning: In `libs/storefront-data/package.json`, `medusajs/js-sdk` and `medusajs/types` are intentionally pinned to an exact version in `devDependencies` (e.g., `"2.14.1"`). This is because the package generates TypeScript declaration files against the Medusa SDK/types, and a previous deploy failure was caused by different Medusa type versions being resolved in the build graph. The `peerDependencies` range remains broad (e.g., `>=2.12.0`) for consumers, while exact `devDependencies` pins ensure reproducible declaration generation. Do not flag these exact pins as inconsistencies.

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/tests/unit/**/*.unit.spec.ts : Use factory functions like `createMockEntity(overrides)` for test data generation

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/tests/unit/**/*.unit.spec.ts : Do not test mocked methods; test real behavior instead

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/src/modules/*/__tests__/*.spec.ts : Mock loaders in tests using `vi.mock()` to prevent actual initialization during testing

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/tests/unit/**/*.unit.spec.ts : Clear mocks with `mockFn.mockReset()` instead of `vi.clearAllMocks()` for `mockResolvedValueOnce` chains

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/src/modules/*/__tests__/*.spec.ts : Use `moduleIntegrationTestRunner()` for module tests with real DB instead of mocking MedusaService methods

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/tests/unit/**/*.unit.spec.ts : Focus unit tests on critical paths: validation, money calculations, and core business logic

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-21T11:46:40.903Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 323
File: apps/medusa-be/integration-tests/http/promotions-custom-rules.spec.ts:0-0
Timestamp: 2026-05-21T11:46:40.903Z
Learning: In `apps/medusa-be/integration-tests/http/promotions-custom-rules.spec.ts`, the test intentionally uses a custom `requestJson`/`createClient`/`fetch`-based HTTP harness (running against a full Docker stack) instead of `medusaIntegrationTestRunner()`. This is a deliberate decision because `medusaIntegrationTestRunner()` had issues with publishable-key resolution in the monorepo due to package-hoisting caveats. Do not flag the absence of `medusaIntegrationTestRunner()` in this file; it is marked for future refactoring when the monorepo/hoisting issue is resolved.

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/integration-tests/http/**/*.spec.ts : Use `headers: { 'x-publishable-api-key': pak.token }` for store auth in integration tests

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/src/modules/*/__tests__/*.spec.ts : Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/tests/unit/**/*.unit.spec.ts : Skip unit tests for: getters, static arrays, trivial transforms, constants, and pass-through methods

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/integration-tests/http/**/*.spec.ts : Write HTTP integration tests for: business logic routes, security-critical middleware, multi-step DB ops

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/tests/unit/jobs/**/*.spec.ts : Place job tests in `tests/unit/jobs/` not in `src/jobs/__tests__/` to avoid Medusa loading them at runtime

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/integration-tests/http/**/*.spec.ts : Use `medusaIntegrationTestRunner()` for HTTP integration tests with `api.get()`, `api.post()`, `api.delete()`

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/src/modules/**/provider.ts : Use provider containers for extending existing modules (payment, fulfillment) with dependencies declared in `medusa-config.ts`

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/src/modules/**/client.ts : Separate HTTP client logic from orchestration; use dedicated class for pure HTTP operations

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
📚 Learning: 2026-05-07T19:18:05.075Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 390
File: apps/medusa-be/src/api/admin/packeta-labels/route.ts:121-121
Timestamp: 2026-05-07T19:18:05.075Z
Learning: In `apps/medusa-be`, the hard-coded fulfillment provider ID string (e.g. `"packeta_packeta"`) is intentionally kept inline for now, consistent with the PPL implementation pattern. Extracting these into shared constants (e.g. `PACKETA_FULFILLMENT_PROVIDER_ID`) is deferred to a future refactor pass when more providers are added. Do not flag this as an issue in code reviews.

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
📚 Learning: 2026-05-11T23:01:30.923Z
Learnt from: CR
Repo: TechsioCZ/new-engine PR: 0
File: apps/medusa-be/CLAUDE.md:0-0
Timestamp: 2026-05-11T23:01:30.923Z
Learning: Applies to apps/medusa-be/**/*.{ts,tsx} : Use `Modules.*` and `ContainerRegistrationKeys.*` constants instead of hardcoding module/key strings

Applied to files:

  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
🔇 Additional comments (2)
apps/medusa-be/src/modules/payment-paykit/services/stripe.ts (2)

261-276: ⚡ Quick win

refactor(stripe): narrow dynamic capture amounts before casting.

These helpers cast dynamic values straight to RefundPaymentInput["amount"], so malformed persisted data reaches amount normalisation without a useful validation error. Read the property as unknown, validate it, then narrow.

[ suggest_essential_refactor ]

As per coding guidelines, "Annotate type as unknown when accessing dynamic object properties before applying type guards" and "Validate data before type casting; never use as Type without prior validation".


488-511: ⚡ Quick win

fix(stripe): guard stripeCheckoutSessions.expire() so payments.cancel() fallback still works.

In cancelOrExpirePayment(), expiring every cs_* id can cause Stripe to throw when the Checkout Session is already completed/expired/cancelled; because this block returns early, the method never reaches the client.payments.cancel() fallback. Wrap client.stripeCheckoutSessions.expire(providerPaymentId) in a try/catch and fall back to payments.cancel() only for the “session not open/invalid state” error case; otherwise rethrow, using the repo’s existing error predicate/helper if one exists.

Comment thread apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
@redeyecz
redeyecz merged commit af40c56 into master Jun 4, 2026
7 checks passed
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 0.6.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant