diff --git a/.changeset/stale-spoons-brake.md b/.changeset/stale-spoons-brake.md new file mode 100644 index 00000000..559a4e0f --- /dev/null +++ b/.changeset/stale-spoons-brake.md @@ -0,0 +1,5 @@ +--- +"@godaddy/react": patch +--- + +Add gopay appId override experimental rule diff --git a/packages/react/src/components/checkout/order/use-update-order.test.ts b/packages/react/src/components/checkout/order/use-update-order.test.ts index d2932f26..c3ef35f6 100644 --- a/packages/react/src/components/checkout/order/use-update-order.test.ts +++ b/packages/react/src/components/checkout/order/use-update-order.test.ts @@ -134,7 +134,11 @@ describe('useUpdateOrder - Tax calculation address logic', () => { describe('Edge cases', () => { it('should handle pickupLocationId being undefined for pickup', () => { - const result = getTaxDestinationAddress('PICKUP', undefined, mockLocations); + const result = getTaxDestinationAddress( + 'PICKUP', + undefined, + mockLocations + ); expect(result).toBeUndefined(); }); diff --git a/packages/react/src/components/checkout/payment/checkout-buttons/applePay/godaddy.tsx b/packages/react/src/components/checkout/payment/checkout-buttons/applePay/godaddy.tsx index 9976c342..06155e81 100644 --- a/packages/react/src/components/checkout/payment/checkout-buttons/applePay/godaddy.tsx +++ b/packages/react/src/components/checkout/payment/checkout-buttons/applePay/godaddy.tsx @@ -6,6 +6,7 @@ import type { TokenizeJs, WalletError, } from '@/components/checkout/payment/types'; +import { getApplicationId } from '@/components/checkout/payment/utils/get-application-id'; import { useBuildPaymentRequest } from '@/components/checkout/payment/utils/use-build-payment-request'; import { PaymentProvider, @@ -90,7 +91,10 @@ export function GoDaddyApplePayCheckoutButton() { businessId: godaddyPaymentsConfig?.businessId || session?.businessId, storeId: session?.storeId, channelId: session?.channelId, - applicationId: godaddyPaymentsConfig?.appId, + applicationId: getApplicationId( + session, + godaddyPaymentsConfig?.appId + ), }, { country: countryCode, diff --git a/packages/react/src/components/checkout/payment/checkout-buttons/express/godaddy.tsx b/packages/react/src/components/checkout/payment/checkout-buttons/express/godaddy.tsx index 1f0745b8..9b3e3d65 100644 --- a/packages/react/src/components/checkout/payment/checkout-buttons/express/godaddy.tsx +++ b/packages/react/src/components/checkout/payment/checkout-buttons/express/godaddy.tsx @@ -14,6 +14,7 @@ import type { WalletError, WalletRequestUpdate, } from '@/components/checkout/payment/types'; +import { getApplicationId } from '@/components/checkout/payment/utils/get-application-id'; import { type PoyntExpressRequest, useBuildPaymentRequest, @@ -438,7 +439,10 @@ export function ExpressCheckoutButton() { businessId: godaddyPaymentsConfig?.businessId || session?.businessId, storeId: session?.storeId, channelId: session?.channelId, - applicationId: godaddyPaymentsConfig?.appId, + applicationId: getApplicationId( + session, + godaddyPaymentsConfig?.appId + ), }, { country: countryCode, diff --git a/packages/react/src/components/checkout/payment/checkout-buttons/googlePay/godaddy.tsx b/packages/react/src/components/checkout/payment/checkout-buttons/googlePay/godaddy.tsx index 950b71d5..1b2b08b4 100644 --- a/packages/react/src/components/checkout/payment/checkout-buttons/googlePay/godaddy.tsx +++ b/packages/react/src/components/checkout/payment/checkout-buttons/googlePay/godaddy.tsx @@ -6,6 +6,7 @@ import type { TokenizeJs, WalletError, } from '@/components/checkout/payment/types'; +import { getApplicationId } from '@/components/checkout/payment/utils/get-application-id'; import { useBuildPaymentRequest } from '@/components/checkout/payment/utils/use-build-payment-request'; import { PaymentProvider, @@ -90,7 +91,10 @@ export function GoDaddyGooglePayCheckoutButton() { businessId: godaddyPaymentsConfig?.businessId || session?.businessId, storeId: session?.storeId, channelId: session?.channelId, - applicationId: godaddyPaymentsConfig?.appId, + applicationId: getApplicationId( + session, + godaddyPaymentsConfig?.appId + ), }, { country: countryCode, diff --git a/packages/react/src/components/checkout/payment/checkout-buttons/mercadopago/mercadopago.tsx b/packages/react/src/components/checkout/payment/checkout-buttons/mercadopago/mercadopago.tsx index 53950b6d..e95b9c3d 100644 --- a/packages/react/src/components/checkout/payment/checkout-buttons/mercadopago/mercadopago.tsx +++ b/packages/react/src/components/checkout/payment/checkout-buttons/mercadopago/mercadopago.tsx @@ -3,13 +3,13 @@ import React, { useCallback, useLayoutEffect, useState } from 'react'; import { useFormContext } from 'react-hook-form'; import { useCheckoutContext } from '@/components/checkout/checkout'; import { useDraftOrderTotals } from '@/components/checkout/order/use-draft-order'; +import { useAuthorizeCheckout } from '@/components/checkout/payment/utils/use-authorize-checkout'; import { PaymentProvider, useConfirmCheckout, } from '@/components/checkout/payment/utils/use-confirm-checkout'; import { useIsPaymentDisabled } from '@/components/checkout/payment/utils/use-is-payment-disabled'; import { useLoadMercadoPago } from '@/components/checkout/payment/utils/use-load-mercadopago'; -import { useAuthorizeCheckout } from '@/components/checkout/payment/utils/use-authorize-checkout'; import { formatCurrency } from '@/components/checkout/utils/format-currency'; import { Button } from '@/components/ui/button'; import { useGoDaddyContext } from '@/godaddy-provider'; @@ -53,7 +53,7 @@ export function MercadoPagoCheckoutButton() { paymentProvider: PaymentProvider.MERCADOPAGO, }); return response?.transactionRefNum; - } + }; const handleSubmit = useCallback( async ({ formData }: any) => { @@ -124,7 +124,7 @@ export function MercadoPagoCheckoutButton() { const { bricksBuilderInstance: bricksBuilder } = getMercadoPagoInstance(mercadoPagoConfig.publicKey); - + const mercadoPagoPreferenceId = await getPreferenceId(); brickController = await bricksBuilder.create('payment', elementId, { @@ -168,7 +168,6 @@ export function MercadoPagoCheckoutButton() { }, }, }); - } catch (_err) { setError(t.errors.failedToInitializePayment); setIsBrickReady(false); @@ -230,7 +229,9 @@ export function MercadoPagoCheckoutButton() { size='lg' type='button' onClick={handleClick} - disabled={isPaymentDisabled || authorizeCheckout.isPending || !isBrickReady} + disabled={ + isPaymentDisabled || authorizeCheckout.isPending || !isBrickReady + } > {authorizeCheckout.isPending && !error ? ( <> diff --git a/packages/react/src/components/checkout/payment/checkout-buttons/paze/godaddy.tsx b/packages/react/src/components/checkout/payment/checkout-buttons/paze/godaddy.tsx index 15d16fc3..3d508f8d 100644 --- a/packages/react/src/components/checkout/payment/checkout-buttons/paze/godaddy.tsx +++ b/packages/react/src/components/checkout/payment/checkout-buttons/paze/godaddy.tsx @@ -6,6 +6,7 @@ import type { TokenizeJs, WalletError, } from '@/components/checkout/payment/types'; +import { getApplicationId } from '@/components/checkout/payment/utils/get-application-id'; import { useBuildPaymentRequest } from '@/components/checkout/payment/utils/use-build-payment-request'; import { PaymentProvider, @@ -89,7 +90,10 @@ export function PazeCheckoutButton() { businessId: godaddyPaymentsConfig?.businessId || session?.businessId, storeId: session?.storeId, channelId: session?.channelId, - applicationId: godaddyPaymentsConfig?.appId, + applicationId: getApplicationId( + session, + godaddyPaymentsConfig?.appId + ), }, { country: countryCode, diff --git a/packages/react/src/components/checkout/payment/payment-form.tsx b/packages/react/src/components/checkout/payment/payment-form.tsx index 609bbfe0..6e94a16b 100644 --- a/packages/react/src/components/checkout/payment/payment-form.tsx +++ b/packages/react/src/components/checkout/payment/payment-form.tsx @@ -28,6 +28,7 @@ import { PaymentMethodRenderer, } from '@/components/checkout/payment/payment-method-renderer'; import type { TokenizeJs } from '@/components/checkout/payment/types'; +import { getApplicationId } from '@/components/checkout/payment/utils/get-application-id'; import { PaymentAddressToggle } from '@/components/checkout/payment/utils/payment-address-toggle'; import { useGetSelectedPaymentMethod } from '@/components/checkout/payment/utils/use-get-selected-payment-method'; import { useLoadPoyntCollect } from '@/components/checkout/payment/utils/use-load-poynt-collect'; @@ -184,7 +185,10 @@ export function PaymentForm( businessId: godaddyPaymentsConfig?.businessId || session?.businessId, storeId: session?.storeId, channelId: session?.channelId, - applicationId: godaddyPaymentsConfig?.appId, + applicationId: getApplicationId( + session, + godaddyPaymentsConfig?.appId + ), }, { country: countryCode, diff --git a/packages/react/src/components/checkout/payment/payment-methods/credit-card/godaddy.tsx b/packages/react/src/components/checkout/payment/payment-methods/credit-card/godaddy.tsx index e269af99..06dc2783 100644 --- a/packages/react/src/components/checkout/payment/payment-methods/credit-card/godaddy.tsx +++ b/packages/react/src/components/checkout/payment/payment-methods/credit-card/godaddy.tsx @@ -4,6 +4,7 @@ import type { TokenizeJs, TokenizeJsEvent, } from '@/components/checkout/payment/types'; +import { getApplicationId } from '@/components/checkout/payment/utils/get-application-id'; import { usePoyntCollect } from '@/components/checkout/payment/utils/poynt-provider'; import { PaymentProvider, @@ -199,7 +200,7 @@ export function GoDaddyCreditCardForm() { businessId: godaddyPaymentsConfig?.businessId || session?.businessId, storeId: session?.storeId, channelId: session?.channelId, - applicationId: godaddyPaymentsConfig?.appId, + applicationId: getApplicationId(session, godaddyPaymentsConfig?.appId), }); collect?.current?.on('ready', () => { diff --git a/packages/react/src/components/checkout/payment/utils/get-application-id.ts b/packages/react/src/components/checkout/payment/utils/get-application-id.ts new file mode 100644 index 00000000..55377e66 --- /dev/null +++ b/packages/react/src/components/checkout/payment/utils/get-application-id.ts @@ -0,0 +1,17 @@ +import type { CheckoutSession } from '@/types'; + +/** + * Resolves the applicationId for TokenizeJs initialization. + * When the session has `experimental_rules.gopay_override` enabled, + * the goPayAppId from that rule takes precedence over the default appId. + */ +export function getApplicationId( + session: CheckoutSession | null | undefined, + defaultAppId: string | undefined +): string | undefined { + const goPayOverride = session?.experimental_rules?.gopay_override; + if (goPayOverride?.enabled && goPayOverride?.goPayAppId) { + return goPayOverride.goPayAppId; + } + return defaultAppId; +} diff --git a/packages/react/src/lib/godaddy/checkout-env.ts b/packages/react/src/lib/godaddy/checkout-env.ts index 13d8a695..ee36d32c 100644 --- a/packages/react/src/lib/godaddy/checkout-env.ts +++ b/packages/react/src/lib/godaddy/checkout-env.ts @@ -1363,6 +1363,146 @@ const introspection = { ], interfaces: [], }, + { + kind: 'INPUT_OBJECT', + name: 'CheckoutCustomerAddressInput', + inputFields: [ + { + name: 'addressLine1', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'addressLine2', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'addressLine3', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'adminArea1', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'adminArea2', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'adminArea3', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'adminArea4', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'countryCode', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'postalCode', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + ], + isOneOf: false, + }, + { + kind: 'INPUT_OBJECT', + name: 'CheckoutCustomerContactInput', + inputFields: [ + { + name: 'address', + type: { + kind: 'INPUT_OBJECT', + name: 'CheckoutCustomerAddressInput', + }, + }, + { + name: 'companyName', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'email', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'firstName', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'lastName', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + { + name: 'phone', + type: { + kind: 'SCALAR', + name: 'String', + }, + }, + ], + isOneOf: false, + }, + { + kind: 'INPUT_OBJECT', + name: 'CheckoutCustomerInput', + inputFields: [ + { + name: 'billing', + type: { + kind: 'INPUT_OBJECT', + name: 'CheckoutCustomerContactInput', + }, + }, + { + name: 'shipping', + type: { + kind: 'INPUT_OBJECT', + name: 'CheckoutCustomerContactInput', + }, + }, + ], + isOneOf: false, + }, { kind: 'OBJECT', name: 'CheckoutSession', @@ -2604,6 +2744,15 @@ const introspection = { args: [], isDeprecated: false, }, + { + name: 'gopay_override', + type: { + kind: 'OBJECT', + name: 'CheckoutSessionGoPayOverrideRule', + }, + args: [], + isDeprecated: false, + }, { name: 'localDelivery', type: { @@ -2627,6 +2776,13 @@ const introspection = { name: 'CheckoutSessionFreeShippingRuleInput', }, }, + { + name: 'gopay_override', + type: { + kind: 'INPUT_OBJECT', + name: 'CheckoutSessionGoPayOverrideRuleInput', + }, + }, ], isOneOf: false, }, @@ -2715,6 +2871,64 @@ const introspection = { ], isOneOf: false, }, + { + kind: 'OBJECT', + name: 'CheckoutSessionGoPayOverrideRule', + fields: [ + { + name: 'enabled', + type: { + kind: 'NON_NULL', + ofType: { + kind: 'SCALAR', + name: 'Boolean', + }, + }, + args: [], + isDeprecated: false, + }, + { + name: 'goPayAppId', + type: { + kind: 'NON_NULL', + ofType: { + kind: 'SCALAR', + name: 'String', + }, + }, + args: [], + isDeprecated: false, + }, + ], + interfaces: [], + }, + { + kind: 'INPUT_OBJECT', + name: 'CheckoutSessionGoPayOverrideRuleInput', + inputFields: [ + { + name: 'enabled', + type: { + kind: 'NON_NULL', + ofType: { + kind: 'SCALAR', + name: 'Boolean', + }, + }, + }, + { + name: 'goPayAppId', + type: { + kind: 'NON_NULL', + ofType: { + kind: 'SCALAR', + name: 'String', + }, + }, + }, + ], + isOneOf: false, + }, { kind: 'INPUT_OBJECT', name: 'CheckoutSessionLineItemInput', @@ -7206,6 +7420,13 @@ const introspection = { name: 'String', }, }, + { + name: 'customer', + type: { + kind: 'INPUT_OBJECT', + name: 'CheckoutCustomerInput', + }, + }, { name: 'customerId', type: { diff --git a/packages/react/src/lib/godaddy/checkout-mutations.ts b/packages/react/src/lib/godaddy/checkout-mutations.ts index 6ff26d1b..898f22cd 100644 --- a/packages/react/src/lib/godaddy/checkout-mutations.ts +++ b/packages/react/src/lib/godaddy/checkout-mutations.ts @@ -62,6 +62,10 @@ export const CreateCheckoutSessionMutation = graphql(` enabled minimumOrderTotal } + gopay_override { + enabled + goPayAppId + } } shipping { originAddress { diff --git a/packages/react/src/lib/godaddy/checkout-queries.ts b/packages/react/src/lib/godaddy/checkout-queries.ts index 1cceb93a..25462336 100644 --- a/packages/react/src/lib/godaddy/checkout-queries.ts +++ b/packages/react/src/lib/godaddy/checkout-queries.ts @@ -62,6 +62,10 @@ export const GetCheckoutSessionQuery = graphql(` enabled minimumOrderTotal } + gopay_override { + enabled + goPayAppId + } } shipping { originAddress {