Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magento 2.4.7 checkout fixes #2465

Merged
merged 11 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/big-feet-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-cart-payment-method': patch
---

Solve issue where the Component prop would we forwarded tot the DOM element of the PaymentMethodActionCard
5 changes: 5 additions & 0 deletions .changeset/big-glasses-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-cart-shipping-address': patch
---

Make sure we are toggling the selected shipping method when a user selects a previously selected shipping method
6 changes: 6 additions & 0 deletions .changeset/fifty-timers-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphcommerce/magento-cart-payment-method': patch
'@graphcommerce/magento-graphql': patch
---

Support Magento 2.4.7 placeOrder.errors field to handle possible errors while placing the order. An `assertOrderPlaced` method was created to assert a valid placed order.
5 changes: 5 additions & 0 deletions .changeset/shy-years-judge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/react-hook-form': patch
---

Solve an issue where the payment submission would remain in a spinning state when placing an order failed: `useFormGql` will now set `root` error on the form when there is an error response on the GraphQL operation, an error is thrown in onBeforeSubmit and in onSuccess.
5 changes: 5 additions & 0 deletions .changeset/smooth-ghosts-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/mollie-magento-payment': patch
---

Support Magento 2.4.7 placeOrder.errors field when placing a Mollie order
5 changes: 5 additions & 0 deletions .changeset/soft-paws-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphcommerce/magento-cart-shipping-method': patch
---

Make sure we are correctly selecting the shipping method form when a user selects a previously selected method again.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import { Trans } from '@lingui/react'
import type { SxProps, Theme } from '@mui/material'
import { useEffect } from 'react'
import type { PaymentOptionsProps } from '../Api/PaymentMethod'
import { usePaymentMethodContext } from '../PaymentMethodContext/paymentMethodContextType'
import { useCartLock } from '../hooks'
import { usePaymentMethodContext } from '../PaymentMethodContext/paymentMethodContextType'

function PaymentMethodActionCard(
props: ActionCardItemRenderProps<PaymentOptionsProps> & {
sx?: SxProps<Theme>
},
) {
const { onReset, code, step, child, Container, sx = [] } = props
const { onReset, code, step, child, Container, sx = [], ...rest } = props
const { selectedMethod, selectedModule, modules } = usePaymentMethodContext()

const selectedAndOptions =
Expand All @@ -29,6 +29,8 @@ function PaymentMethodActionCard(

return (
<Card
code={code}
child={child}
sx={[
{
'& .ActionCard-title': { typography: 'h6' },
Expand All @@ -52,7 +54,7 @@ function PaymentMethodActionCard(
<selectedModule.PaymentOptions {...selectedMethod} step={step} Container={Container} />
)
}
{...props}
{...rest}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
mutation PaymentMethodPlaceOrderNoop($cartId: String!) {
placeOrder(input: { cart_id: $cartId }) {
errors {
code
message
}

order {
order_number
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useFormCompose } from '@graphcommerce/react-hook-form'
import { t } from '@lingui/macro'
import type { PaymentPlaceOrderProps } from '../Api/PaymentMethod'
import { usePaymentMethodContext } from '../PaymentMethodContext/paymentMethodContextType'
import { assertOrderPlaced } from './assertOrderPlaced'
import { PaymentMethodPlaceOrderNoopDocument } from './PaymentMethodPlaceOrderNoop.gql'

export function PaymentMethodPlaceOrderNoop(props: PaymentPlaceOrderProps) {
Expand All @@ -11,11 +12,8 @@ export function PaymentMethodPlaceOrderNoop(props: PaymentPlaceOrderProps) {

const form = useFormGqlMutationCart(PaymentMethodPlaceOrderNoopDocument, {
onComplete: async (result) => {
if (!result.data?.placeOrder?.order)
throw Error(
t`An error occurred while processing your payment. Please contact the store owner`,
)

assertOrderPlaced(result)
console.log('result', result)
await onSuccess(result.data.placeOrder.order.order_number)
},
submitWhileLocked: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { FetchResult } from '@graphcommerce/graphql'
import { ApolloError } from '@graphcommerce/graphql'
import { t } from '@lingui/macro'
import type { PaymentMethodPlaceOrderNoopMutation } from './PaymentMethodPlaceOrderNoop.gql'

export type PlacedOrder<T extends FetchResult<PaymentMethodPlaceOrderNoopMutation>> = NonNullable<
NonNullable<NonNullable<T['data']>['placeOrder']>['order']
>

export type AssertedOrderPlaced<T extends FetchResult<PaymentMethodPlaceOrderNoopMutation>> = T & {
data: {
placeOrder: { order: PlacedOrder<T> }
}
}

export function throwGenericPlaceOrderError() {
throw new ApolloError({
graphQLErrors: [
{
message: t`An error occurred while processing your payment. Please contact the store owner`,
},
],
})
}

/** Assert that the order was place successfully. */
export function assertOrderPlaced<T extends FetchResult<PaymentMethodPlaceOrderNoopMutation>>(
result: T,
): asserts result is AssertedOrderPlaced<T> {
if (result.errors && result.errors.length > 0) {
const graphQLErrors = result.errors.filter((e) => e !== null)
throw new ApolloError({ graphQLErrors })
}

if (result.data?.placeOrder?.errors && result.data.placeOrder.errors.length > 0) {
const graphQLErrors = result.data.placeOrder.errors.filter((e) => e !== null)
throw new ApolloError({ graphQLErrors })
}

if (!result.data?.placeOrder?.order?.order_number) {
console.info('Error while placing order', result)
throwGenericPlaceOrderError()
}
}
4 changes: 3 additions & 1 deletion packages/magento-cart-payment-method/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
export * from './Api/PaymentMethod'
export * from './hooks'
export * from './PaymentMethodActionCardList/PaymentMethodActionCardListForm'
export * from './PaymentMethodButton/PaymentMethodButton'
export * from './PaymentMethodContext/PaymentMethodContext'
export * from './PaymentMethodContext/paymentMethodContextType'
export * from './PaymentMethodOptions/PaymentMethodOptions'
export * from './PaymentMethodOptionsNoop/PaymentMethodOptionsNoop'
export * from './PaymentMethodOptionsNoop/PaymentMethodOptionsNoop.gql'
export * from './PaymentMethodPlaceOrder/PaymentMethodPlaceOrder'
export * from './PaymentMethodPlaceOrderNoop/assertOrderPlaced'
export * from './PaymentMethodPlaceOrderNoop/PaymentMethodPlaceOrderNoop'
export * from './PaymentMethodPlaceOrderNoop/PaymentMethodPlaceOrderNoop.gql'
export * from './PaymentMethodToggles/PaymentMethodToggles'
export * from './PaymentMethodActionCardList/PaymentMethodActionCardListForm'
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
useFormGqlMutationCart,
} from '@graphcommerce/magento-cart'
import { CustomerDocument } from '@graphcommerce/magento-customer'
import { FormRow, filterNonNullableKeys } from '@graphcommerce/next-ui'
import { filterNonNullableKeys, FormRow } from '@graphcommerce/next-ui'
import { i18n } from '@lingui/core'
import { Trans } from '@lingui/macro'
import type { SxProps, Theme } from '@mui/material'
Expand Down Expand Up @@ -86,7 +86,6 @@ export function CustomerAddressForm(props: CustomerAddressListProps) {
}
>(Mutation, {
defaultValues: { customer_address_id: cartAddressId },
skipUnchanged: true,
onBeforeSubmit: (vars) => {
const { customer_address_id } = vars
if (customer_address_id === -1) return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export function ShippingMethodForm(props: ShippingMethodFormProps) {
ShippingMethodFormMutation,
ShippingMethodFormMutationVariables & { carrierMethod?: string }
>(ShippingMethodFormDocument, {
skipUnchanged: true,
defaultValues: { carrierMethod },
onBeforeSubmit: (variables) => {
const [carrier, method] = (variables.carrierMethod ?? '').split('-')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ type PlaceOrderOutput {
The ID of the order.
"""
order: Order
"""
An array of place order errors.
"""
errors: [PlaceOrderError]! @deprecated(reason: "Magento >= 2.4.7")

"""
Full order information.
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ mutation AdyenPaymentOptionsAndPlaceOrder(
}
}
placeOrder(input: { cart_id: $cartId }) {
errors {
code
message
}

order {
order_number
adyen_payment_status {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { FormPersist, TextFieldElement, useFormCompose } from '@graphcommerce/ecommerce-ui'
import { useFormGqlMutationCart } from '@graphcommerce/magento-cart'
import type { PaymentOptionsProps } from '@graphcommerce/magento-cart-payment-method'
import { usePaymentMethodContext } from '@graphcommerce/magento-cart-payment-method'
import {
assertOrderPlaced,
throwGenericPlaceOrderError,
usePaymentMethodContext,
} from '@graphcommerce/magento-cart-payment-method'
import { FormRow } from '@graphcommerce/next-ui'
import { t } from '@lingui/macro'
import { useRouter } from 'next/router'
Expand Down Expand Up @@ -40,15 +44,18 @@ export function HppOptions(props: PaymentOptionsProps) {
brandCode,
}),
onComplete: async (result) => {
assertOrderPlaced(result.data?.placeOrder)
const merchantReference = result.data?.placeOrder?.order.order_number
const action = result?.data?.placeOrder?.order.adyen_payment_status?.action

if (result.errors) return

if (!merchantReference || !selectedMethod?.code || !action) {
throw Error(
t`An error occurred while processing your payment. Please contact the store owner`,
console.error(
'Adyen: Order was placed, but no merchant reference or action was returned, this is an issue on the Magento Adyen side.',
result,
)
throwGenericPlaceOrderError()
}

const url = JSON.parse(action).url as string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ export type AdyenPaymentResponse = {
additionalData?: Types.checkout.PaymentResponse['additionalData']
}

/**
* @deprecated Will be removed
* @public
*/
/** @public */
export function parsePaymentResponse(
status?: AdyenPaymentResponseFragment | null,
): AdyenPaymentResponse {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
mutation MSPPaymentPlaceOrder($cartId: String!) {
placeOrder(input: { cart_id: $cartId }) {
errors {
code
message
}

order {
order_number
multisafepay_payment_url {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { useMutation } from '@graphcommerce/graphql'
import { useCartQuery, useFormGqlMutationCart } from '@graphcommerce/magento-cart'
import { BillingPageDocument } from '@graphcommerce/magento-cart-checkout'
import type { PaymentPlaceOrderProps } from '@graphcommerce/magento-cart-payment-method'
import { usePaymentMethodContext } from '@graphcommerce/magento-cart-payment-method'
import {
assertOrderPlaced,
throwGenericPlaceOrderError,
usePaymentMethodContext,
} from '@graphcommerce/magento-cart-payment-method'
import { ErrorSnackbar } from '@graphcommerce/next-ui'
import { t } from '@lingui/macro'
import { useRouter } from 'next/router'
Expand All @@ -27,14 +31,11 @@ export function MSPPaymentPlaceOrder(props: PaymentPlaceOrderProps) {
*/
const form = useFormGqlMutationCart(MSPPaymentPlaceOrderDocument, {
onComplete: async (result, variables) => {
const url = result.data?.placeOrder?.order.multisafepay_payment_url

if (result.errors) return
assertOrderPlaced(result)
const url = result.data.placeOrder.order.multisafepay_payment_url

if (!selectedMethod?.code) {
throw Error(
t`An error occurred while processing your payment. Please contact the store owner`,
)
throwGenericPlaceOrderError()
}

if (url?.error || !url?.payment_url) {
Expand All @@ -47,7 +48,7 @@ export function MSPPaymentPlaceOrder(props: PaymentPlaceOrderProps) {

await lock({
method: selectedMethod.code,
order_number: result.data?.placeOrder?.order.order_number,
order_number: result.data.placeOrder.order.order_number,
})

await new Promise((resolve) => setTimeout(resolve, 1000))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ mutation PayPalPaymentHandler($cartId: String!, $paymentMethod: PaymentMethodInp
}
}
placeOrder(input: { cart_id: $cartId }) {
errors {
code
message
}

order {
order_number
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { ApolloErrorSnackbar } from '@graphcommerce/ecommerce-ui'
import { useMutation } from '@graphcommerce/graphql'
import { useCurrentCartId } from '@graphcommerce/magento-cart'
import type { PaymentHandlerProps } from '@graphcommerce/magento-cart-payment-method'
import { usePaymentMethodContext } from '@graphcommerce/magento-cart-payment-method'
import {
assertOrderPlaced,
usePaymentMethodContext,
} from '@graphcommerce/magento-cart-payment-method'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { usePayPalCartLock } from '../../hooks/usePayPalCartLock'
Expand Down Expand Up @@ -41,15 +44,15 @@ export function PayPalPaymentHandler(props: PaymentHandlerProps) {
if (!cartId) return

const fetchData = async () => {
const res = await placeOrder()
const result = await placeOrder()

if (res.errors || !res.data?.placeOrder?.order) {
try {
assertOrderPlaced(result)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
onSuccess(result.data.placeOrder.order.order_number)
} catch (e) {
await unlock({ token: null, PayerID: null })
return
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
onSuccess(res.data?.placeOrder?.order.order_number)
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { useFormCompose } from '@graphcommerce/ecommerce-ui'
import { useFormGqlMutationCart } from '@graphcommerce/magento-cart'
import type { PaymentPlaceOrderProps } from '@graphcommerce/magento-cart-payment-method'
import {
assertOrderPlaced,
type PaymentPlaceOrderProps,
} from '@graphcommerce/magento-cart-payment-method'
import { ApolloError } from '@apollo/client'
import { GraphQLError } from 'graphql'
import { useRouter } from 'next/router'
import { usePayPalCartLock } from '../../hooks/usePayPalCartLock'
import { PayPalPaymentPlaceOrderDocument } from './PayPalPaymentPlaceOrder.gql'
Expand All @@ -17,15 +22,16 @@ export function PayPalPaymentPlaceOrder(props: PaymentPlaceOrderProps) {
urls: { cancel_url: 'checkout/payment', return_url: 'checkout/payment' },
}),
onComplete: async (result) => {
if (result.errors) return
if (result.errors && result.errors.length > 0) return

const start = result.data?.createPaypalExpressToken?.paypal_urls?.start
const token = result.data?.createPaypalExpressToken?.token

if (!start)
throw Error(
'Error while starting the PayPal payment, please try again with a different payment method',
)
if (!start) {
const message =
'Error while starting the PayPal payment, please try again with a different payment method'
throw new ApolloError({ graphQLErrors: [{ message }] })
}

await lock({ token, method: code, PayerID: null })
// We are going to redirect, but we're not waiting, because we need to complete the submission to release the buttons
Expand Down
Loading
Loading