Skip to content

Add Razorpay as a standard checkout payment method. - #1451

Open
pchawla-godaddy wants to merge 16 commits into
godaddy:mainfrom
pchawla-godaddy:vnext-84816
Open

pchawla-godaddy wants to merge 16 commits into
godaddy:mainfrom
pchawla-godaddy:vnext-84816

Conversation

@pchawla-godaddy

@pchawla-godaddy pchawla-godaddy commented Sep 9, 2026 •

Copy link
Copy Markdown

Wire the C2 checkout UI to authorize, open Razorpay Standard Checkout, encode the signed callback, and confirm, matching the checkout-api contract.
https://godaddy-corp.atlassian.net/browse/VNEXT-84816

Summary

Changeset

  • Changeset added (docs)

Test Plan

Screen.Recording.2026-09-14.at.4.33.52.PM.mov

Wire the C2 checkout UI to authorize, open Razorpay Standard Checkout, encode the signed callback, and confirm, matching the checkout-api contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pchawla-godaddy
pchawla-godaddy requested a review from a team as a code owner September 9, 2026 07:08
@changeset-bot

changeset-bot Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: aff7119

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@godaddy/react Patch
@godaddy/localizations Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rsharma2-godaddy rsharma2-godaddy 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.

we might have ro re-attempt this PR, since some changes were requested
can you also add the button to pay with razorpay with the icon in the video

Comment thread packages/react/src/components/checkout/checkout.tsx Outdated
pchawla-godaddy and others added 2 commits September 14, 2026 11:36
Read the widget key and order id from the authorize response instead of a client config prop, matching the merged checkout-api contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread .changeset/bright-cats-pay.md Outdated
pchawla-godaddy and others added 2 commits September 15, 2026 11:30
Co-authored-by: Phil Bennett <114938978+pbennett1-godaddy@users.noreply.github.com>
Comment thread packages/react/src/components/checkout/payment/utils/use-load-razorpay.ts Outdated
Comment thread packages/react/src/components/checkout/payment/utils/use-load-razorpay.ts Outdated
Comment thread packages/react/src/components/checkout/payment/utils/use-load-razorpay.ts Outdated
pchawla-godaddy and others added 5 commits September 15, 2026 23:46
…maining review gaps.

Load state now lives in RazorpayLoaderProvider instead of module globals, failed script loads retry with backoff, and payment-method null handling plus create-session Razorpay fields match the checkout-api contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
checkout-api now dynamically resolves PayPal's public SDK-bootstrap
values (clientId/merchantId/partnerAttributionId/disableFunding) and
persists them on the session as paymentProviderConfiguration.paypal
(checkout-api PR godaddy#183, "Hosted Checkout Consumption"). Prefer an
explicit paypalConfig prop (existing embedded-checkout integrations)
and fall back to that session field otherwise, so the hosted checkout
URL flow — where no prop is ever supplied — can initialize PayPal too.

- Add paymentProviderConfiguration to both the create-session mutation
  and get-session query selection sets, and regenerate checkout-env.ts
  against checkout-api's current schema.
- Add partnerAttributionId to PayPalConfig and wire it into the PayPal
  JS SDK's dataPartnerAttributionId option.
- Don't offer PayPal as a payment method when neither source has a
  usable clientId, mirroring the existing GoDaddy CC/ACH gating
  pattern in payment-form.tsx's availablePaymentMethods.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@wcole1-godaddy wcole1-godaddy 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.

Requesting changes for three payment lifecycle issues: the unconditional two-minute widget cutoff, SDK load recovery after remount, and overlapping payment attempts. Details and suggested fixes are inline.

Validation: CI passes. Isolated source-level probes reproduced the stale-script state and duplicate authorization/widget opens, and verified that the timer closes the widget without a payment attempt. Vitest was not run locally because dependencies are not installed; no live gateway transaction was performed.

Comment thread packages/react/src/components/checkout/payment/utils/razorpay-loader-context.tsx Outdated
pchawla-godaddy and others added 3 commits September 17, 2026 11:21
…back

Fall back to session-provided PayPal config when no prop is supplied
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	packages/react/src/components/checkout/payment/payment-form.tsx
@wcole1-godaddy

Copy link
Copy Markdown
Contributor

Critic review

Reviewed commit 06be7664647524199422455bb294277f68ca8e31. Two actionable lifecycle findings:

[P2] Preserve confirmation errors across the parent's unmount

packages/react/src/components/checkout/payment/checkout-buttons/razorpay/razorpay.tsx:110–115

After Razorpay reports success, useConfirmCheckout sets isConfirmingCheckout=true, causing PaymentForm to replace the Razorpay button with its generic processing button. If confirmation then rejects with a transport error, the catch calls setError on the unmounted component. Once confirmation state resets, the newly mounted button has no error, so the shopper receives no indication that confirmation failed.

Suggested fix: Store the failure in surviving checkout-level state, or keep the Razorpay component mounted during confirmation. Add coverage for a confirmation rejection while the parent transitions into and out of its processing state.

[P2] Invalidate pending widget initialization when the selected method unmounts

packages/react/src/components/checkout/payment/checkout-buttons/razorpay/razorpay.tsx:216–217

The payment-method accordion remains enabled while Razorpay authorization is pending. If the shopper switches methods before authorization resolves, the old component's async continuation still constructs and opens the Razorpay widget after unmount, over the newly selected payment flow. Switching away and back also creates a fresh attempt lock while the original continuation remains active.

Suggested fix: Invalidate pending attempts on unmount and check attempt identity after asynchronous boundaries, before opening the SDK. Add coverage for switching methods while authorization is pending.

Validation

  • Both behaviors reproduced in isolated lifecycle tests against the reviewed component.
  • CI checks and @godaddy/react typecheck pass.
  • All 61 tests across the eight focused PR test files pass.
  • Full React suite: 818 passed and one billing test timed out at 15 seconds. All 13 tests in that billing file pass on an isolated single-worker rerun.

Existing tests miss these lifecycle transitions: the Razorpay unit tests keep isConfirmingCheckout false, while checkout integration tests replace the Razorpay button with an inert mock.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pchawla-godaddy

Copy link
Copy Markdown
Author

Addressed both lifecycle findings in 662a2a8.

  • Confirmation failures now use checkout-level checkoutErrors; non-GraphQL/transport failures set TRANSACTION_PROCESSING_FAILED, so the error survives the Razorpay button being replaced during confirmation.
  • Each payment attempt now has an identity that is invalidated on unmount and checked after validation, draft-order sync, and authorization. Stale continuations cannot construct/open Razorpay after switching methods, and a remounted attempt remains isolated.
  • Added lifecycle coverage for confirmation rejection across unmount/remount, authorization resolving after unmount, and switch-away/switch-back with stale authorization.

Validation:

  • Razorpay button tests: 10 passed
  • Eight focused PR test files: 64 passed
  • Full React suite: 80 files / 822 tests passed (TZ=UTC)
  • @godaddy/react typecheck: passed
  • @godaddy/react lint: passed

The critic findings were a top-level PR comment rather than resolvable review threads. Could you please re-review the latest commit?

…iguration.paypal exists

Session paymentMethods.paypal can be null while paymentProviderConfiguration.paypal
is populated (session created with explicit paymentMethods input, discovery still
resolves the provider config). Both the accordion's availablePaymentMethods filter
and useGetSelectedPaymentMethod's consumer in payment-form.tsx now fall back to a
synthesized standard PayPal method config, gated on paypalConfig?.clientId actually
being present, so this stays testing-only and never fires for a real absent config.

TEMP FOR TESTING — DO NOT COMMIT to a real release; must be reverted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…y.configured

Add razorpay { configured } to the checkout session GraphQL queries/mutations
and hand-edit checkout-env.ts to add the corresponding schema type, mirroring
the existing PayPal provider-config pattern. Expose it via checkoutContext as
razorpayConfig (an object, not a bare boolean, so future fields don't require
a signature change) and require it in payment-form's availablePaymentMethods
gating before ever offering the Razorpay button.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

6 participants