Document the actions in the checkout and payment-method stores (https://github.com/woocommerce/woocommerce-blocks/pull/7255)
* Remove setPristine as it's not used * Comment checkout actions * Rename setProcessingResponse to setPaymentResult and remove setOrderId from the checkout data store actions * Add comments to payment actions * Update documentation with data stores * Fix accidentally changing data exposed to the observers * Document missing parameters for actions
This commit is contained in:
parent
6d5f4dbe7a
commit
33910f316f
|
@ -152,7 +152,7 @@ export const CheckoutEventsProvider = ( {
|
|||
checkoutState.orderId,
|
||||
checkoutState.customerId,
|
||||
checkoutState.orderNotes,
|
||||
checkoutState.processingResponse,
|
||||
checkoutState.paymentResult,
|
||||
previousStatus,
|
||||
previousHasError,
|
||||
createErrorNotice,
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
export const ACTION_TYPES = {
|
||||
SET_IDLE: 'SET_IDLE',
|
||||
SET_PRISTINE: 'SET_PRISTINE',
|
||||
SET_REDIRECT_URL: 'SET_REDIRECT_URL',
|
||||
SET_COMPLETE: 'SET_CHECKOUT_COMPLETE',
|
||||
SET_BEFORE_PROCESSING: 'SET_BEFORE_PROCESSING',
|
||||
SET_AFTER_PROCESSING: 'SET_AFTER_PROCESSING',
|
||||
SET_PROCESSING_RESPONSE: 'SET_PROCESSING_RESPONSE',
|
||||
SET_PAYMENT_RESULT: 'SET_PAYMENT_RESULT',
|
||||
SET_PROCESSING: 'SET_CHECKOUT_IS_PROCESSING',
|
||||
SET_HAS_ERROR: 'SET_CHECKOUT_HAS_ERROR',
|
||||
SET_CUSTOMER_ID: 'SET_CHECKOUT_CUSTOMER_ID',
|
||||
SET_ORDER_ID: 'SET_CHECKOUT_ORDER_ID',
|
||||
SET_ORDER_NOTES: 'SET_CHECKOUT_ORDER_NOTES',
|
||||
INCREMENT_CALCULATING: 'INCREMENT_CALCULATING',
|
||||
DECREMENT_CALCULATING: 'DECREMENT_CALCULATING',
|
||||
|
|
|
@ -12,79 +12,133 @@ import { ReturnOrGeneratorYieldUnion } from '../mapped-types';
|
|||
// `Thunks are functions that can be dispatched, similar to actions creators
|
||||
export * from './thunks';
|
||||
|
||||
export const setPristine = () => ( {
|
||||
type: types.SET_PRISTINE,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the checkout status to `idle`
|
||||
*/
|
||||
export const setIdle = () => ( {
|
||||
type: types.SET_IDLE,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the checkout status to `before_processing`
|
||||
*/
|
||||
export const setBeforeProcessing = () => ( {
|
||||
type: types.SET_BEFORE_PROCESSING,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the checkout status to `processing`
|
||||
*/
|
||||
export const setProcessing = () => ( {
|
||||
type: types.SET_PROCESSING,
|
||||
} );
|
||||
|
||||
export const setRedirectUrl = ( redirectUrl: string ) => ( {
|
||||
type: types.SET_REDIRECT_URL,
|
||||
redirectUrl,
|
||||
} );
|
||||
|
||||
export const setProcessingResponse = ( data: PaymentResult ) => ( {
|
||||
type: types.SET_PROCESSING_RESPONSE,
|
||||
data,
|
||||
/**
|
||||
* Set the checkout status to `after_processing`
|
||||
*/
|
||||
export const setAfterProcessing = () => ( {
|
||||
type: types.SET_AFTER_PROCESSING,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the checkout status to `complete`
|
||||
*/
|
||||
export const setComplete = ( data: Record< string, unknown > = {} ) => ( {
|
||||
type: types.SET_COMPLETE,
|
||||
data,
|
||||
} );
|
||||
|
||||
export const setBeforeProcessing = () => ( {
|
||||
type: types.SET_BEFORE_PROCESSING,
|
||||
/**
|
||||
* Set the url to redirect to after checkout completes`
|
||||
*
|
||||
* @param redirectUrl the url to redirect to
|
||||
*/
|
||||
export const setRedirectUrl = ( redirectUrl: string ) => ( {
|
||||
type: types.SET_REDIRECT_URL,
|
||||
redirectUrl,
|
||||
} );
|
||||
|
||||
export const setAfterProcessing = () => ( {
|
||||
type: types.SET_AFTER_PROCESSING,
|
||||
/**
|
||||
* Store the result of the payment attempt from the /checkout StoreApi call
|
||||
*
|
||||
* @param data The result of the payment attempt through the StoreApi /checkout endpoints
|
||||
*/
|
||||
export const setPaymentResult = ( data: PaymentResult ) => ( {
|
||||
type: types.SET_PAYMENT_RESULT,
|
||||
data,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set whether the checkout has an error or not
|
||||
*
|
||||
* @param hasError Wether the checkout has an error or not
|
||||
*/
|
||||
export const setHasError = ( hasError = true ) => ( {
|
||||
type: types.SET_HAS_ERROR,
|
||||
hasError,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Used when any of the totals, taxes, shipping, etc need to be calculated, the `calculatingCount` will be increased
|
||||
* A `calculatingCount` of 0 means nothing is being updated.
|
||||
*/
|
||||
export const incrementCalculating = () => ( {
|
||||
type: types.INCREMENT_CALCULATING,
|
||||
} );
|
||||
|
||||
/**
|
||||
* When any of the totals, taxes, shipping, etc are done beign calculated, the `calculatingCount` will be decreased
|
||||
* A `calculatingCount` of 0 means nothing is being updated.
|
||||
*/
|
||||
export const decrementCalculating = () => ( {
|
||||
type: types.DECREMENT_CALCULATING,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the customer id
|
||||
*
|
||||
* @param customerId ID of the customer who is checking out.
|
||||
*/
|
||||
export const setCustomerId = ( customerId: number ) => ( {
|
||||
type: types.SET_CUSTOMER_ID,
|
||||
customerId,
|
||||
} );
|
||||
|
||||
export const setOrderId = ( orderId: number ) => ( {
|
||||
type: types.SET_ORDER_ID,
|
||||
orderId,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Whether to use the shipping address as the billing address
|
||||
*
|
||||
* @param useShippingAsBilling True if shipping address should be the same as billing, false otherwise
|
||||
*/
|
||||
export const setUseShippingAsBilling = ( useShippingAsBilling: boolean ) => ( {
|
||||
type: types.SET_SHIPPING_ADDRESS_AS_BILLING_ADDRESS,
|
||||
useShippingAsBilling,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Whether an account should be created for the user while checking out
|
||||
*
|
||||
* @param shouldCreateAccount True if an account should be created, false otherwise
|
||||
*/
|
||||
export const setShouldCreateAccount = ( shouldCreateAccount: boolean ) => ( {
|
||||
type: types.SET_SHOULD_CREATE_ACCOUNT,
|
||||
shouldCreateAccount,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the notes for the order
|
||||
*
|
||||
* @param orderNotes String that represents a note for the order
|
||||
*/
|
||||
export const setOrderNotes = ( orderNotes: string ) => ( {
|
||||
type: types.SET_ORDER_NOTES,
|
||||
orderNotes,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Register some extra data for an extension.
|
||||
*
|
||||
* @param extensionData An object containing the data to register for an extension
|
||||
*/
|
||||
export const setExtensionData = (
|
||||
extensionData: Record< string, Record< string, unknown > >
|
||||
) => ( {
|
||||
|
@ -94,11 +148,10 @@ export const setExtensionData = (
|
|||
|
||||
export type CheckoutAction =
|
||||
| ReturnOrGeneratorYieldUnion<
|
||||
| typeof setPristine
|
||||
| typeof setIdle
|
||||
| typeof setComplete
|
||||
| typeof setProcessing
|
||||
| typeof setProcessingResponse
|
||||
| typeof setPaymentResult
|
||||
| typeof setBeforeProcessing
|
||||
| typeof setAfterProcessing
|
||||
| typeof setRedirectUrl
|
||||
|
@ -106,7 +159,6 @@ export type CheckoutAction =
|
|||
| typeof incrementCalculating
|
||||
| typeof decrementCalculating
|
||||
| typeof setCustomerId
|
||||
| typeof setOrderId
|
||||
| typeof setUseShippingAsBilling
|
||||
| typeof setShouldCreateAccount
|
||||
| typeof setOrderNotes
|
||||
|
|
|
@ -15,7 +15,7 @@ export type CheckoutState = {
|
|||
// If any of the totals, taxes, shipping, etc need to be calculated, the count will be increased here
|
||||
calculatingCount: number;
|
||||
// The result of the payment processing
|
||||
processingResponse: PaymentResult | null;
|
||||
paymentResult: PaymentResult | null;
|
||||
// True when the checkout is in an error state. Whatever caused the error (validation/payment method) will likely have triggered a notice.
|
||||
hasError: boolean;
|
||||
// This is the url that checkout will redirect to when it's ready.
|
||||
|
@ -47,6 +47,6 @@ export const defaultState: CheckoutState = {
|
|||
checkoutData.shipping_address
|
||||
),
|
||||
shouldCreateAccount: false,
|
||||
processingResponse: null,
|
||||
paymentResult: null,
|
||||
extensionData: {},
|
||||
};
|
||||
|
|
|
@ -14,10 +14,6 @@ import { CheckoutAction } from './actions';
|
|||
const reducer = ( state = defaultState, action: CheckoutAction ) => {
|
||||
let newState = state;
|
||||
switch ( action.type ) {
|
||||
case types.SET_PRISTINE:
|
||||
newState = defaultState;
|
||||
break;
|
||||
|
||||
case types.SET_IDLE:
|
||||
newState =
|
||||
state.status !== STATUS.IDLE
|
||||
|
@ -39,10 +35,10 @@ const reducer = ( state = defaultState, action: CheckoutAction ) => {
|
|||
: state;
|
||||
break;
|
||||
|
||||
case types.SET_PROCESSING_RESPONSE:
|
||||
case types.SET_PAYMENT_RESULT:
|
||||
newState = {
|
||||
...state,
|
||||
processingResponse: action.data as PaymentResult,
|
||||
paymentResult: action.data as PaymentResult,
|
||||
};
|
||||
break;
|
||||
|
||||
|
@ -114,15 +110,6 @@ const reducer = ( state = defaultState, action: CheckoutAction ) => {
|
|||
}
|
||||
break;
|
||||
|
||||
case types.SET_ORDER_ID:
|
||||
if ( action.orderId !== undefined ) {
|
||||
newState = {
|
||||
...state,
|
||||
orderId: action.orderId,
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case types.SET_SHIPPING_ADDRESS_AS_BILLING_ADDRESS:
|
||||
if (
|
||||
action.useShippingAsBilling !== undefined &&
|
||||
|
|
|
@ -11,17 +11,6 @@ describe.only( 'Checkout Store Reducer', () => {
|
|||
expect( reducer( undefined, {} ) ).toEqual( defaultState );
|
||||
} );
|
||||
|
||||
it( 'should handle SET_PRISTINE', () => {
|
||||
const expectedState = {
|
||||
...defaultState,
|
||||
status: STATUS.PRISTINE,
|
||||
};
|
||||
|
||||
expect( reducer( defaultState, actions.setPristine() ) ).toEqual(
|
||||
expectedState
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'should handle SET_IDLE', () => {
|
||||
const expectedState = {
|
||||
...defaultState,
|
||||
|
@ -48,7 +37,7 @@ describe.only( 'Checkout Store Reducer', () => {
|
|||
).toEqual( expectedState );
|
||||
} );
|
||||
|
||||
it( 'should handle SET_PROCESSING_RESPONSE', () => {
|
||||
it( 'should handle SET_PAYMENT_RESULT', () => {
|
||||
const mockResponse = {
|
||||
message: 'success',
|
||||
redirectUrl: 'https://example.com',
|
||||
|
@ -59,14 +48,11 @@ describe.only( 'Checkout Store Reducer', () => {
|
|||
const expectedState = {
|
||||
...defaultState,
|
||||
status: STATUS.IDLE,
|
||||
processingResponse: mockResponse,
|
||||
paymentResult: mockResponse,
|
||||
};
|
||||
|
||||
expect(
|
||||
reducer(
|
||||
defaultState,
|
||||
actions.setProcessingResponse( mockResponse )
|
||||
)
|
||||
reducer( defaultState, actions.setPaymentResult( mockResponse ) )
|
||||
).toEqual( expectedState );
|
||||
} );
|
||||
|
||||
|
@ -206,18 +192,6 @@ describe.only( 'Checkout Store Reducer', () => {
|
|||
);
|
||||
} );
|
||||
|
||||
it( 'should handle SET_ORDER_ID', () => {
|
||||
const expectedState = {
|
||||
...defaultState,
|
||||
status: STATUS.IDLE,
|
||||
orderId: 1,
|
||||
};
|
||||
|
||||
expect( reducer( defaultState, actions.setOrderId( 1 ) ) ).toEqual(
|
||||
expectedState
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'should handle SET_SHIPPING_ADDRESS_AS_BILLING_ADDRESS', () => {
|
||||
const expectedState = {
|
||||
...defaultState,
|
||||
|
|
|
@ -38,7 +38,7 @@ export const processCheckoutResponse = ( response: CheckoutResponse ) => {
|
|||
} ) => {
|
||||
const paymentResult = getPaymentResultFromCheckoutResponse( response );
|
||||
dispatch.setRedirectUrl( paymentResult?.redirectUrl || '' );
|
||||
dispatch.setProcessingResponse( paymentResult );
|
||||
dispatch.setPaymentResult( paymentResult );
|
||||
dispatch.setAfterProcessing();
|
||||
};
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ export const emitAfterProcessingEvents: emitAfterProcessingEventsType = ( {
|
|||
orderId: state.orderId,
|
||||
customerId: state.customerId,
|
||||
orderNotes: state.orderNotes,
|
||||
processingResponse: state.processingResponse,
|
||||
processingResponse: state.paymentResult,
|
||||
};
|
||||
if ( state.hasError ) {
|
||||
// allow payment methods or other things to customize the error
|
||||
|
|
|
@ -19,7 +19,7 @@ export type CheckoutAfterProcessingWithErrorEventData = {
|
|||
orderId: CheckoutState[ 'orderId' ];
|
||||
customerId: CheckoutState[ 'customerId' ];
|
||||
orderNotes: CheckoutState[ 'orderNotes' ];
|
||||
processingResponse: CheckoutState[ 'processingResponse' ];
|
||||
processingResponse: CheckoutState[ 'paymentResult' ];
|
||||
};
|
||||
export type CheckoutAndPaymentNotices = {
|
||||
checkoutNotices: Notice[];
|
||||
|
|
|
@ -17,6 +17,12 @@ import { PaymentStatus } from './types';
|
|||
// `Thunks are functions that can be dispatched, similar to actions creators
|
||||
export * from './thunks';
|
||||
|
||||
/**
|
||||
* Set the status of the payment
|
||||
*
|
||||
* @param status An object that holds properties representing different status values
|
||||
* @param paymentMethodData A config object for the payment method being used
|
||||
*/
|
||||
export const setPaymentStatus = (
|
||||
status: PaymentStatus,
|
||||
paymentMethodData?: Record< string, unknown >
|
||||
|
@ -26,6 +32,11 @@ export const setPaymentStatus = (
|
|||
paymentMethodData,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set whether the payment methods have been initialised or not
|
||||
*
|
||||
* @param initialized True if the `checkCanPay` methods have been run on all available payment methods
|
||||
*/
|
||||
export const setPaymentMethodsInitialized = ( initialized: boolean ) => {
|
||||
return async ( { select, dispatch } ) => {
|
||||
// If the currently selected method is not in this new list, then we need to select a new one, or select a default.
|
||||
|
@ -40,6 +51,11 @@ export const setPaymentMethodsInitialized = ( initialized: boolean ) => {
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether the express payment methods have been initialised or not
|
||||
*
|
||||
* @param initialized True if the `checkCanPay` methods have been run on all express available payment methods
|
||||
*/
|
||||
export const setExpressPaymentMethodsInitialized = (
|
||||
initialized: boolean
|
||||
) => ( {
|
||||
|
@ -47,6 +63,11 @@ export const setExpressPaymentMethodsInitialized = (
|
|||
initialized,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set a flag for whether to save the current payment method for next time
|
||||
*
|
||||
* @param shouldSavePaymentMethod Whether to save the current payment method for next time
|
||||
*/
|
||||
export const setShouldSavePaymentMethod = (
|
||||
shouldSavePaymentMethod: boolean
|
||||
) => ( {
|
||||
|
@ -54,6 +75,12 @@ export const setShouldSavePaymentMethod = (
|
|||
shouldSavePaymentMethod,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the payment method the user has chosen. This should change every time the user selects a new payment method
|
||||
*
|
||||
* @param activePaymentMethod The name of the payment method selected by the user
|
||||
* @param paymentMethodData The extra data associated with a payment
|
||||
*/
|
||||
export const setActivePaymentMethod = (
|
||||
activePaymentMethod: string,
|
||||
paymentMethodData: Record< string, unknown > = {}
|
||||
|
@ -63,6 +90,11 @@ export const setActivePaymentMethod = (
|
|||
paymentMethodData,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Set the extra data for the chosen payment method
|
||||
*
|
||||
* @param paymentMethodData The extra data associated with a payment
|
||||
*/
|
||||
export const setPaymentMethodData = (
|
||||
paymentMethodData: Record< string, unknown > = {}
|
||||
) => ( {
|
||||
|
@ -118,6 +150,9 @@ export const removeRegisteredExpressPaymentMethod = ( name: string ) => ( {
|
|||
name,
|
||||
} );
|
||||
|
||||
/**
|
||||
* The store is initialised once we have checked whether the payment methods registered can pay or not
|
||||
*/
|
||||
export function initializePaymentMethodDataStore() {
|
||||
return async ( { dispatch } ) => {
|
||||
const expressRegistered = await checkPaymentMethodsCanPay( true );
|
||||
|
|
|
@ -35,7 +35,7 @@ The following data is available:
|
|||
- `orderId`: The order id for the order attached to the current checkout.
|
||||
- `customerId`: The ID of the customer if the customer has an account, or `0` for guests.
|
||||
- `calculatingCount`: If any of the totals, taxes, shipping, etc need to be calculated, the count will be increased here.
|
||||
- `processingResponse`: The result of the payment processing.
|
||||
- `paymentResult`: The result of processing the payment.
|
||||
- `useShippingAsBilling`: Should the billing form be hidden and inherit the shipping address?
|
||||
- `shouldCreateAccount`: Should a user account be created with this order?
|
||||
- `extensionData`: This is used by plugins that extend Cart & Checkout to pass custom data to the Store API on checkout processing
|
||||
|
@ -62,20 +62,18 @@ Data can be accessed through the following selectors:
|
|||
|
||||
The following actions can be dispatched from the Checkout data store:
|
||||
|
||||
- `setPristine()`: Set `state.status` to `pristine`
|
||||
- `setIdle()`: Set `state.status` to `idle`
|
||||
- `setComplete()`: Set `state.status` to `complete`
|
||||
- `setProcessing()`: Set `state.status` to `processing`
|
||||
- `setProcessingResponse( response: PaymentResult )`: Set `state.processingResponse` to `response`
|
||||
- `setPaymentResult( response: PaymentResult )`: Set `state.paymentResult` to `response`
|
||||
- `setBeforeProcessing()`: Set `state.status` to `before_processing`
|
||||
- `setAfterProcessing()`: Set `state.status` to `after_processing`
|
||||
- `processCheckoutResponse( response: CheckoutResponse )`: This is a thunk that will extract the paymentResult from the CheckoutResponse, and dispatch 3 actions: `setRedirectUrl`, `setProcessingResponse` and `setAfterProcessing`.
|
||||
- `processCheckoutResponse( response: CheckoutResponse )`: This is a thunk that will extract the paymentResult from the CheckoutResponse, and dispatch 3 actions: `setRedirectUrl`, `setPaymentResult` and `setAfterProcessing`.
|
||||
- `setRedirectUrl( url: string )`: Set `state.redirectUrl` to `url`
|
||||
- `setHasError( trueOrFalse: bool )`: Set `state.hasError` to `trueOrFalse`
|
||||
- `incrementCalculating()`: Increment `state.calculatingCount`
|
||||
- `decrementCalculating()`: Decrement `state.calculatingCount`
|
||||
- `setCustomerId( id: number )`: Set `state.customerId` to `id`
|
||||
- `setOrderId( id: number )`: Set `state.orderId` to `id`
|
||||
- `setUseShippingAsBilling( useShippingAsBilling: boolean )`: Set `state.useShippingAsBilling` to `useShippingAsBilling`
|
||||
- `setShouldCreateAccount( shouldCreateAccount: boolean )`: Set `state.shouldCreateAccount` to `shouldCreateAccount`
|
||||
- `setOrderNotes( orderNotes: string )`: Set `state.orderNotes` to `orderNotes`
|
||||
|
@ -122,53 +120,20 @@ The shipping method data context exposes the api interfaces for the following th
|
|||
- `onShippingRateSelectSuccess`: This is a function for registering a callback to be invoked when shipping rate selection is successful.
|
||||
- `onShippingRateSelectFail`: This is a function for registering a callback to be invoked when shipping rates selection is unsuccessful.
|
||||
|
||||
### Payment Method Data Context
|
||||
### Payment Method Events Context
|
||||
|
||||
The payment method data context exposes the api interfaces for the following things (typedef `PaymentMethodDataContext`) via the `usePaymentMethodData` hook.
|
||||
The payment method events context exposes any event handlers related to payments (typedef `PaymentMethodEventsContext`) via the `usePaymentMethodEventsContext` hook.
|
||||
|
||||
- `setPaymentStatus`: used to set the current active payment method flow status. Calling it returns an object of dispatcher methods with the following methods: `started()`, `processing()`, `completed()`, `error( errorMessage)`, `failed( errorMessage, paymentMethodData, billingData )`, `success( paymentMethodData, billingData, shippingData )`. Note `paymentMethodData` is attached to the order processing request so payment methods could hook in server side to do any processing of the payment as a part of checkout processing (and receive extra information from the payment method client side).
|
||||
- `currentStatus`: This is an object that returns helper methods for determining the current status of the active payment method flow. Includes: `isPristine()`, `isStarted()`, `isProcessing()`, `isFinished()`, `hasError()`, `hasFailed()`, `isSuccessful()`.
|
||||
- `paymentStatuses`: This is an object of payment method status constants.
|
||||
- `paymentMethodData`: This is the current extra data tracked in the context state. This is arbitrary data provided by the payment method extension after it has completed payment for checkout to include in the processing request. Typically this would contain things like payment `token` or `payment_method` name.
|
||||
- `errorMessage`: This exposes the current set error message provided by the active payment method (if present).
|
||||
- `activePaymentMethod`: This is the current active payment method in the checkout.
|
||||
- `setActivePaymentMethod`: This is used to set the active payment method and any related payment method data.
|
||||
- `onPaymentProcessing`: This is an event subscriber that can be used to subscribe observers to be called when the status for the context is `PROCESSING`.
|
||||
- `customerPaymentMethods`: This is an object containing any saved payment method information for the current logged in user. It is provided via the server and used to generate the ui for the shopper to select a saved payment method from a previous purchase.
|
||||
- `paymentMethods`: This is an object containing all the _initialized_ registered payment methods.
|
||||
- `expressPaymentMethods`: This is an object containing all the _initialized_ express payment methods.
|
||||
- `paymentMethodsInitialized`: This is `true` when all registered payment methods have been initialized.
|
||||
- `expressPaymentMethodsInitialized`: This is `true` when all registered express payment methods have been initialized.
|
||||
- `setExpressPaymentError`: This is exposed to express payment methods to enable them to set a specific error notice. This is needed because express payment methods might need to show/trigger an error outside any of the checkout block events.
|
||||
|
||||
### Checkout Context
|
||||
### Checkout Events Context
|
||||
|
||||
This context is the main one. Internally via the `<CheckoutProvider>` it handles wrapping children in `<ShippingMethodDataProvider>`, `<CustomerDataProvider>` and `<PaymentMethodDataProvider>`. So the checkout components just need to be wrapped by `<CheckoutProvider>`.
|
||||
|
||||
The provider receives the following props:
|
||||
|
||||
- `redirectUrl`: A string, this is used to indicate where the checkout redirects to when it is complete. This is optional and can be used to set a default url to redirect to.
|
||||
|
||||
Via `useCheckoutContext`, the following are exposed:
|
||||
The checkout events contexy exposes any event handlers related to the processing of the checkout:
|
||||
|
||||
- `onSubmit`: This is a callback to be invoked either by submitting the checkout button, or by express payment methods to start checkout processing after they have finished their initialization process when their button has been clicked.
|
||||
- `isComplete`: True when checkout has finished processing and the subscribed checkout processing callbacks have all been invoked along with a successful processing of the checkout by the server.
|
||||
- `isIdle`: When the checkout status is `IDLE` this flag is true. Checkout will be this status after any change to checkout state after the block is loaded. It will also be this status when retrying a purchase is possible after processing happens with an error.
|
||||
- `isBeforeProcessing`: When the checkout status is `BEFORE_PROCESSING` this flag is true. Checkout will be this status when the user submits checkout for processing.
|
||||
- `isProcessing`: When the checkout status is `PROCESSING` this flag is true. Checkout will be this status when all the observers on the event emitted with the `BEFORE_PROCESSING` status are completed without error. It is during this status that the block will be sending a request to the server on the checkout endpoint for processing the order.
|
||||
- `isAfterProcessing`: When the checkout status is `AFTER_PROCESSING` this flag is true. Checkout will have this status after the the block receives the response from the server side processing request.
|
||||
- `isComplete`: When the checkout status is `COMPLETE` this flag is true. Checkout will have this status after all observers on the events emitted during the `AFTER_PROCESSING` status are completed successfully. When checkout is at this status, the shopper's browser will be redirected to the value of `redirectUrl` at that point (usually the `order-received` route).
|
||||
- `isCalculating`: This is true when the total is being re-calculated for the order. There are numerous things that might trigger a recalculation of the total: coupons being added or removed, shipping rates updated, shipping rate selected etc. This flag consolidates all activity that might be occurring (including requests to the server that potentially affect calculation of totals). So instead of having to check each of those individual states you can reliably just check if this boolean is true (calculating) or false (not calculating).
|
||||
- `hasError`: This is true when anything in the checkout has created an error condition state. This might be validation errors, request errors, coupon application errors, payment processing errors etc.
|
||||
- `redirectUrl`: The current set url that the checkout will redirect to when it is complete.
|
||||
- `onCheckoutValidationBeforeProcessing`: Used to register observers that will be invoked at validation time, after the checkout has been submitted but before the processing request is sent to the server.
|
||||
- `onCheckoutAfterProcessingWithSuccess`: Used to register observers that will be invoked after checkout has been processed by the server successfully.
|
||||
- `onCheckoutAfterProcessingWithError`: Used to register observers that will be invoked after checkout has been processed by the server and there was an error.
|
||||
- `dispatchActions`: This is an object with various functions for dispatching status in the checkout. It is not exposed to extensions but is for internal use only.
|
||||
- `orderId`: The order id for the order attached to the current checkout.
|
||||
- `isCart`: This is true if the cart is being viewed. Note: usage of `CheckoutProvider` will automatically set this to false. There is also a `CartProvider` that wraps children in the `ShippingDataProvider` and exposes the same api as checkout context. The `CartProvider` automatically sets `isCart` to true. This allows components that implement `useCheckoutContext` to use the same api in either the cart or checkout context but still have specific behaviour to whether `isCart` is true or not.
|
||||
- `hasOrder`: This is true when orderId is truthy.
|
||||
- `customerId`: The ID of the customer if the customer has an account, or `0` for guests.
|
||||
|
||||
## Hooks
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
- [General Concepts](#general-concepts)
|
||||
- [Tracking flow through status](#tracking-flow-through-status)
|
||||
- [`CheckoutProvider` Exposed Statuses](#checkoutprovider-exposed-statuses)
|
||||
- [Checkout Data Store Status](#checkout-data-store-status)
|
||||
- [Special States:](#special-states)
|
||||
- [`ShippingProvider` Exposed Statuses](#shippingprovider-exposed-statuses)
|
||||
- [`PaymentMethodDataProvider` Exposed Statuses](#paymentmethoddataprovider-exposed-statuses)
|
||||
- [Payment Method Data Store Status](#payment-method-data-store-status)
|
||||
- [Emitting Events](#emitting-events)
|
||||
- [`onCheckoutValidationBeforeProcessing`](#oncheckoutvalidationbeforeprocessing)
|
||||
- [`onPaymentProcessing`](#onpaymentprocessing)
|
||||
|
@ -50,7 +50,7 @@ To surface the flow state, the block uses statuses that are tracked in the vario
|
|||
|
||||
The following statuses exist in the Checkout.
|
||||
|
||||
#### Checkout Data Store Exposed Statuses
|
||||
#### Checkout Data Store Status
|
||||
|
||||
There are various statuses that are exposed on the Checkout data store via selectors. All the selectors are detailed below and in the [Checkout API docs](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/trunk/docs/block-client-apis/checkout/checkout-api.md).
|
||||
|
||||
|
@ -100,9 +100,23 @@ The status is exposed on the `currentErrorStatus` object provided by the `useShi
|
|||
- `hasInvalidAddress`: When the address provided for shipping is invalid, this will be true.
|
||||
- `hasError`: This is `true` when the error status for shipping is either `UNKNOWN` or `hasInvalidAddress`.
|
||||
|
||||
### `PaymentMethodDataProvider` Exposed Statuses
|
||||
### Payment Method Data Store Status
|
||||
|
||||
This context provider exposes everything related to payment method data and registered payment methods. The statuses exposed via this provider help inform the current state of _client side_ processing for payment methods and are updated via the payment method data event emitters. _Client side_ means the state of processing any payments by registered and active payment methods when the checkout form is submitted via those payment methods registered client side components. It's still possible that payment methods might have additional server side processing when the order is being processed but that is not reflected by these statuses (more in the [payment method integration doc](../../../third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md)).
|
||||
The status of the payment lives in the payment data store. It can be retrieved with the `getCurrentStatus` selector, liek so:
|
||||
|
||||
```jsx
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { PAYMENT_METHOD_DATA_STORE_KEY } from '@woocommerce/blocks-data';
|
||||
|
||||
const MyComponent = ( props ) => {
|
||||
const currentStatus = useSelect( ( select ) =>
|
||||
select( PAYMENT_METHOD_DATA_STORE_KEY ).getCurrentStatus()
|
||||
);
|
||||
// do something with status
|
||||
};
|
||||
```
|
||||
|
||||
The status here will help inform the current state of _client side_ processing for the payment and are updated via the store actions at different points throughout the checkout processing cycle. _Client side_ means the state of processing any payments by registered and active payment methods when the checkout form is submitted via those payment methods registered client side components. It's still possible that payment methods might have additional server side processing when the order is being processed but that is not reflected by these statuses (more in the [payment method integration doc](../../../third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md)).
|
||||
|
||||
The possible _internal_ statuses that may be set are:
|
||||
|
||||
|
@ -113,8 +127,6 @@ The possible _internal_ statuses that may be set are:
|
|||
- `FAILED`: This status is set after an observer hooked into the payment processing event returns a fail response. This in turn will end up causing the checkout `hasError` flag to be set to true.
|
||||
- `ERROR`: This status is set after an observer hooked into the payment processing event returns an error response. This in turn will end up causing the checkout `hasError` flag to be set to true.
|
||||
|
||||
The provider exposes the current status of the payment method data context via the `currentStatus` object. You can retrieve this via the `usePaymentMethodEventsContext` hook.
|
||||
|
||||
The `currentStatus` object has the following properties:
|
||||
|
||||
- `isPristine`: This is true when the current payment status is `PRISTINE`.
|
||||
|
@ -348,7 +360,7 @@ const onCheckoutProcessingData = {
|
|||
orderId,
|
||||
customerId,
|
||||
orderNotes,
|
||||
processingResponse,
|
||||
paymentResult,
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -358,7 +370,7 @@ The properties are:
|
|||
- `orderId`: Is the id of the current order being processed.
|
||||
- `customerId`: Is the id for the customer making the purchase (that is attached to the order).
|
||||
- `orderNotes`: This will be any custom note the customer left on the order.
|
||||
- `processingResponse`: This is the value of [`payment_result` from the checkout response](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/34e17c3622637dbe8b02fac47b5c9b9ebf9e3596/src/RestApi/StoreApi/Schemas/CheckoutSchema.php#L103-L138). The data exposed on this object is (via the object properties):
|
||||
- `paymentResult`: This is the value of [`payment_result` from the /checkout StoreApi response](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/34e17c3622637dbe8b02fac47b5c9b9ebf9e3596/src/RestApi/StoreApi/Schemas/CheckoutSchema.php#L103-L138). The data exposed on this object is (via the object properties):
|
||||
- `paymentStatus`: Whatever the status is for the payment after it was processed server side. Will be one of `success`, `failure`, `pending`, `error`.
|
||||
- `paymentDetails`: This will be an arbitrary object that contains any data the payment method processing server side sends back to the client in the checkout processing response. Payment methods are able to hook in on the processing server side and set this data for returning.
|
||||
|
||||
|
@ -484,4 +496,3 @@ This event emitter doesn't care about any registered observer response and will
|
|||
🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/internal-developers/block-client-apis/checkout/checkout-flow-and-events.md)
|
||||
|
||||
<!-- /FEEDBACK -->
|
||||
|
||||
|
|
|
@ -4,28 +4,28 @@
|
|||
|
||||
In general, perform smoke tests, ensure you can check out with carts containing:
|
||||
|
||||
- Only physical products,
|
||||
- Only virtual products,
|
||||
- A mix of physical and virtual products,
|
||||
- Products on sale,
|
||||
- Products with different tax rates.
|
||||
- Check out using coupons, and the amount charged to the payment method is correct.
|
||||
- Only physical products,
|
||||
- Only virtual products,
|
||||
- A mix of physical and virtual products,
|
||||
- Products on sale,
|
||||
- Products with different tax rates.
|
||||
- Check out using coupons, and the amount charged to the payment method is correct.
|
||||
|
||||
Ensure the amount charged is correct.
|
||||
|
||||
### Subscriptions
|
||||
|
||||
- Check out using WooCommerce Subscriptions products, ensure the checkout works and the stripe key is saved to the order.
|
||||
- Go to the Subscription in the dashboard, process a renewal for it, ensure the payment goes through and is collected in your stripe account. (This check is to ensure the tokens are saved correctly)
|
||||
- Check out using WooCommerce Subscriptions products, ensure the checkout works and the stripe key is saved to the order.
|
||||
- Go to the Subscription in the dashboard, process a renewal for it, ensure the payment goes through and is collected in your stripe account. (This check is to ensure the tokens are saved correctly)
|
||||
|
||||
### Stripe failures
|
||||
|
||||
Check out using the following cards to ensure following scenarios happen: (use any CVV and expiration date in the future)
|
||||
|
||||
- `4242 4242 4242 4242` - Checkout succeeds
|
||||
- `4000 0025 0000 3155` - SCA prompt appears, if you choose to fail, then checkout fails, if you choose to succeed then the checkout succeeds
|
||||
- `4000 0082 6000 3178` - Choose to succeed, but the payment should still fail because of insufficient funds
|
||||
- `4000 0000 0000 9979`- Checkout fails with generic card error. (This card is marked stolen).
|
||||
- `4242 4242 4242 4242` - Checkout succeeds
|
||||
- `4000 0025 0000 3155` - SCA prompt appears, if you choose to fail, then checkout fails, if you choose to succeed then the checkout succeeds
|
||||
- `4000 0082 6000 3178` - Choose to succeed, but the payment should still fail because of insufficient funds
|
||||
- `4000 0000 0000 9979`- Checkout fails with generic card error. (This card is marked stolen).
|
||||
|
||||
### Express Payment methods
|
||||
|
||||
|
@ -40,30 +40,30 @@ If using GPay, then ensure your account is linked in Chrome. You may need to dis
|
|||
Prerequisite: Install [`woocommerce-gateway-stripe`](https://github.com/woocommerce/woocommerce-gateway-stripe) from GitHub, we will need to edit code here. Set it up and get it running in dev mode.
|
||||
Go to: [https://github.com/woocommerce/woocommerce-gateway-stripe/blob/8ffd22aff3b06eda02a1ae2fd8368b71450b36a9/client/blocks/credit-card/use-payment-processing.js#L66](https://github.com/woocommerce/woocommerce-gateway-stripe/blob/8ffd22aff3b06eda02a1ae2fd8368b71450b36a9/client/blocks/credit-card/use-payment-processing.js#L66)
|
||||
|
||||
- Add a `console.log` to the `onSubmit` at the very top of the function.
|
||||
- In your browser, open dev tools and view the console. Ensure `preserve log` is enabled!
|
||||
- Check out (both successfully and unsuccessfully) and ensure the console log you added to `onSubmit` is called **both** times.
|
||||
- Add a `console.log` to the `onSubmit` at the very top of the function.
|
||||
- In your browser, open dev tools and view the console. Ensure `preserve log` is enabled!
|
||||
- Check out (both successfully and unsuccessfully) and ensure the console log you added to `onSubmit` is called **both** times.
|
||||
|
||||
### Interaction with unusable payment methods
|
||||
|
||||
- Install and activate [WooCommerce Bookings](https://github.com/woocommerce/woocommerce-bookings). Add a bookable product, ensure to add a cost to it on the edit product page, then:
|
||||
- Add a _normal_ (i.e. Beanie, Hoodie etc.) product to the cart and ensure you can check out successfully.
|
||||
- Then add a bookable product, ensure you can check out successfully.
|
||||
- Install and activate [WooCommerce Bookings](https://github.com/woocommerce/woocommerce-bookings). Add a bookable product, ensure to add a cost to it on the edit product page, then:
|
||||
- Add a _normal_ (i.e. Beanie, Hoodie etc.) product to the cart and ensure you can check out successfully.
|
||||
- Then add a bookable product, ensure you can check out successfully.
|
||||
|
||||
### Interaction with another payment method added by extension
|
||||
|
||||
- Edit the bookable product and set the `Check this box if the booking requires admin approval/confirmation. Payment will not be taken during checkout.` option to true.
|
||||
- Add this product to the cart and ensure you can check out.
|
||||
- Edit the bookable product and set the `Check this box if the booking requires admin approval/confirmation. Payment will not be taken during checkout.` option to true.
|
||||
- Add this product to the cart and ensure you can check out.
|
||||
|
||||
### Payment filtering by extensions
|
||||
|
||||
- Enable the Cash on Delivery payment method.
|
||||
- Install the `@woocommerce/extend-cart-checkout-block` template by using the following command. Run this from your `wp-content/plugins` directory: `npx @wordpress/create-block -t @woocommerce/extend-cart-checkout-block payment-test-plugin`.
|
||||
- This will install a plugin called `Payment Test Plugin`. Find this and activate it.
|
||||
- By default, this example template has the following code [https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/extend-cart-checkout-block/src/js/filters.js.mustache#L17](https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/extend-cart-checkout-block/src/js/filters.js.mustache#L17) which will disable COD if the billing city is Denver.
|
||||
- Go to the front-end and enter Denver in the billing city.
|
||||
- Ensure COD is removed as an option.
|
||||
- Change Denver to something else and ensure COD reappears as an option.
|
||||
- Enable the Cash on Delivery payment method.
|
||||
- Install the `@woocommerce/extend-cart-checkout-block` template by using the following command. Run this from your `wp-content/plugins` directory: `npx @wordpress/create-block -t @woocommerce/extend-cart-checkout-block payment-test-plugin`.
|
||||
- This will install a plugin called `Payment Test Plugin`. Find this and activate it.
|
||||
- By default, this example template has the following code [https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/extend-cart-checkout-block/src/js/filters.js.mustache#L17](https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/extend-cart-checkout-block/src/js/filters.js.mustache#L17) which will disable COD if the billing city is Denver.
|
||||
- Go to the front-end and enter Denver in the billing city.
|
||||
- Ensure COD is removed as an option.
|
||||
- Change Denver to something else and ensure COD reappears as an option.
|
||||
|
||||
## Checkout
|
||||
|
||||
|
@ -79,15 +79,15 @@ In the position linked in point 1, add `eventRegistration` as a new argument to
|
|||
|
||||
```js
|
||||
usePaymentProcessing(
|
||||
onStripeError,
|
||||
error,
|
||||
stripe,
|
||||
billing,
|
||||
emitResponse,
|
||||
sourceId,
|
||||
setSourceId,
|
||||
onPaymentProcessing,
|
||||
eventRegistration
|
||||
onStripeError,
|
||||
error,
|
||||
stripe,
|
||||
billing,
|
||||
emitResponse,
|
||||
sourceId,
|
||||
setSourceId,
|
||||
onPaymentProcessing,
|
||||
eventRegistration
|
||||
);
|
||||
```
|
||||
|
||||
|
@ -114,37 +114,37 @@ In the location linked in point 3, add the following:
|
|||
|
||||
```js
|
||||
const unsubscribeValidationBeforeProcessing =
|
||||
eventRegistration.onCheckoutValidationBeforeProcessing( ( a ) => {
|
||||
console.log( 'onCheckoutValidationBeforeProcessing', a );
|
||||
} );
|
||||
eventRegistration.onCheckoutValidationBeforeProcessing( ( a ) => {
|
||||
console.log( 'onCheckoutValidationBeforeProcessing', a );
|
||||
} );
|
||||
```
|
||||
|
||||
#### `onCheckoutAfterProcessingWithError`
|
||||
|
||||
```js
|
||||
const unsubscribeOnCheckoutAfterProcessingWithError =
|
||||
eventRegistration.onCheckoutAfterProcessingWithError( ( a ) => {
|
||||
console.log( 'onCheckoutAfterProcessingWithError', a );
|
||||
} );
|
||||
eventRegistration.onCheckoutAfterProcessingWithError( ( a ) => {
|
||||
console.log( 'onCheckoutAfterProcessingWithError', a );
|
||||
} );
|
||||
```
|
||||
|
||||
#### `onCheckoutAfterProcessingWithSuccess`
|
||||
|
||||
```js
|
||||
const unsubscribeOnCheckoutAfterProcessingWithSuccess =
|
||||
eventRegistration.onCheckoutAfterProcessingWithSuccess( ( a ) => {
|
||||
console.log( 'onCheckoutAfterProcessingWithSuccess', a );
|
||||
} );
|
||||
eventRegistration.onCheckoutAfterProcessingWithSuccess( ( a ) => {
|
||||
console.log( 'onCheckoutAfterProcessingWithSuccess', a );
|
||||
} );
|
||||
```
|
||||
|
||||
#### `onCheckoutBeforeProcessing` (deprecated)
|
||||
|
||||
```js
|
||||
const unsubscribeOnCheckoutBeforeProcessing =
|
||||
eventRegistration.onCheckoutBeforeProcessing( ( a ) => {
|
||||
// Expect a deprecated message here.
|
||||
console.log( 'onCheckoutBeforeProcessing', a );
|
||||
} );
|
||||
eventRegistration.onCheckoutBeforeProcessing( ( a ) => {
|
||||
// Expect a deprecated message here.
|
||||
console.log( 'onCheckoutBeforeProcessing', a );
|
||||
} );
|
||||
```
|
||||
|
||||
Then, in the returned function, [https://github.com/woocommerce/woocommerce-gateway-stripe/blob/8ffd22aff3b06eda02a1ae2fd8368b71450b36a9/client/blocks/credit-card/use-payment-processing.js#L147-L149](https://github.com/woocommerce/woocommerce-gateway-stripe/blob/8ffd22aff3b06eda02a1ae2fd8368b71450b36a9/client/blocks/credit-card/use-payment-processing.js#L147-L149) below, add:
|
||||
|
@ -163,24 +163,26 @@ After these changes have been made, your file should look like this: [https://gi
|
|||
1. Ensure you can check out correctly.
|
||||
2. Press the `Place Order` button and ensure all checkout controls are disabled while processing is taking place.
|
||||
3. After making the code changes above, you need to use the Stripe payment method (entering new card details in this component each time!)
|
||||
<img width="647" alt="image" src="https://user-images.githubusercontent.com/5656702/175654613-4f94853a-f96c-4cb8-9f07-d759d049db8a.png">
|
||||
<img width="647" alt="image" src="https://user-images.githubusercontent.com/5656702/175654613-4f94853a-f96c-4cb8-9f07-d759d049db8a.png">
|
||||
|
||||
4. In the console section of dev tools, enable the `Preserve log` option.
|
||||
5. Then do the following:
|
||||
|
||||
- Check out using a valid card. You should see a message telling you `onCheckoutBeforeProcessing` is deprecated then when you check out you should see, in the same order, the following logs:
|
||||
- `onCheckoutValidationBeforeProcessing` `{}`
|
||||
- `onCheckoutBeforeProcessing` `{}`
|
||||
- `onCheckoutAfterProcessingWithSuccess` `{redirectUrl, orderId, customerId, orderNotes, processingResponse }
|
||||
- Check out using a valid card. You should see a message telling you `onCheckoutBeforeProcessing` is deprecated then when you check out you should see, in the same order, the following logs:
|
||||
|
||||
- Check out using an invalid card, you should only see:
|
||||
- `onCheckoutValidationBeforeProcessing` `{}`
|
||||
- `onCheckoutBeforeProcessing` `{}`
|
||||
- `onCheckoutValidationBeforeProcessing` `{}`
|
||||
- `onCheckoutBeforeProcessing` `{}`
|
||||
- `onCheckoutAfterProcessingWithSuccess` `{redirectUrl, orderId, customerId, orderNotes, paymentResult }
|
||||
|
||||
- Reload the checkout page and then go to [https://github.com/woocommerce/woocommerce-blocks/blob/029b379138906872dec3ed920fcb23d24404a3f2/src/StoreApi/Schemas/V1/CheckoutSchema.php#L26-L25](https://github.com/woocommerce/woocommerce-blocks/blob/029b379138906872dec3ed920fcb23d24404a3f2/src/StoreApi/Schemas/V1/CheckoutSchema.php#L26-L25) and introduce a syntax error. Try to check out using a valid card, then an invalid card you should see:
|
||||
- `onCheckoutValidationBeforeProcessing` `{}`
|
||||
- `onCheckoutBeforeProcessing` `{}`
|
||||
- `onCheckoutAfterProcessingWithError` `{redirectUrl, orderId, customerId, orderNotes, processingResponse }`
|
||||
- Check out using an invalid card, you should only see:
|
||||
|
||||
- `onCheckoutValidationBeforeProcessing` `{}`
|
||||
- `onCheckoutBeforeProcessing` `{}`
|
||||
|
||||
- Reload the checkout page and then go to [https://github.com/woocommerce/woocommerce-blocks/blob/029b379138906872dec3ed920fcb23d24404a3f2/src/StoreApi/Schemas/V1/CheckoutSchema.php#L26-L25](https://github.com/woocommerce/woocommerce-blocks/blob/029b379138906872dec3ed920fcb23d24404a3f2/src/StoreApi/Schemas/V1/CheckoutSchema.php#L26-L25) and introduce a syntax error. Try to check out using a valid card, then an invalid card you should see:
|
||||
- `onCheckoutValidationBeforeProcessing` `{}`
|
||||
- `onCheckoutBeforeProcessing` `{}`
|
||||
- `onCheckoutAfterProcessingWithError` `{redirectUrl, orderId, customerId, orderNotes, paymentResult }`
|
||||
|
||||
## WordPress.com
|
||||
|
||||
|
|
Loading…
Reference in New Issue